19d46ef67baf92022f82a49bb2eb8b737b2bdbe95Michael Gottesman//===- ObjCARCContract.cpp - ObjC ARC Optimization ------------------------===// 23a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// 33a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// The LLVM Compiler Infrastructure 43a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// 53a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// This file is distributed under the University of Illinois Open Source 63a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// License. See LICENSE.TXT for details. 73a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// 83a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//===----------------------------------------------------------------------===// 93a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// \file 103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// This file defines late ObjC ARC optimizations. ARC stands for Automatic 113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Reference Counting and is a system for managing reference counts for objects 123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// in Objective C. 133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// 1465c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// This specific file mainly deals with ``contracting'' multiple lower level 1565c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// operations into singular higher level operations through pattern matching. 1665c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// 173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them 183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// by name, and hardwires knowledge of their semantics. 193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// 203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are 213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// used. Naive LLVM IR transformations which would otherwise be 223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// behavior-preserving may break these assumptions. 233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// 243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman//===----------------------------------------------------------------------===// 253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// TODO: ObjCARCContract could insert PHI nodes when uses aren't 273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman// dominated by single calls. 283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#define DEBUG_TYPE "objc-arc-contract" 303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "ObjCARC.h" 312e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman#include "ARCRuntimeEntryPoints.h" 323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "DependencyAnalysis.h" 337a7102d17f979918042bc040e27288d64a6bea5fMichael Gottesman#include "ProvenanceAnalysis.h" 343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/ADT/Statistic.h" 353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/Analysis/Dominators.h" 363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/IR/InlineAsm.h" 373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/IR/Operator.h" 389ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman#include "llvm/Support/Debug.h" 393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm; 413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm::objcarc; 423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumPeeps, "Number of calls peephole-optimized"); 443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed"); 453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmannamespace { 473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// \brief Late ARC optimizations 483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// 493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// These change the IR in a way that makes it difficult to be analyzed by 503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// ObjCARCOpt, so it's run late. 513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman class ObjCARCContract : public FunctionPass { 523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool Changed; 533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AliasAnalysis *AA; 543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DominatorTree *DT; 553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ProvenanceAnalysis PA; 562e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman ARCRuntimeEntryPoints EP; 573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// A flag indicating whether this optimization pass should run. 593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool Run; 603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// The inline asm string to insert between calls and RetainRV calls to make 623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// the optimization work on targets which need it. 633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman const MDString *RetainRVMarker; 643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// The set of inserted objc_storeStrong calls. If at the end of walking the 663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// function we have found no alloca instructions, these calls can be marked 673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// "tail". 683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<CallInst *, 8> StoreStrongCalls; 693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 70f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman bool OptimizeRetainCall(Function &F, Instruction *Retain); 71f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool ContractAutorelease(Function &F, Instruction *Autorelease, 733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InstructionClass Class, 743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<Instruction *, 4> 753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &DependingInstructions, 763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<const BasicBlock *, 4> 773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &Visited); 783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman void ContractRelease(Instruction *Release, 803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman inst_iterator &Iter); 813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman virtual void getAnalysisUsage(AnalysisUsage &AU) const; 833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman virtual bool doInitialization(Module &M); 843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman virtual bool runOnFunction(Function &F); 853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman public: 873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman static char ID; 883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ObjCARCContract() : FunctionPass(ID) { 893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman initializeObjCARCContractPass(*PassRegistry::getPassRegistry()); 903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman }; 923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanchar ObjCARCContract::ID = 0; 953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanINITIALIZE_PASS_BEGIN(ObjCARCContract, 963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman "objc-arc-contract", "ObjC ARC contraction", false, false) 973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanINITIALIZE_AG_DEPENDENCY(AliasAnalysis) 983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanINITIALIZE_PASS_DEPENDENCY(DominatorTree) 993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanINITIALIZE_PASS_END(ObjCARCContract, 1003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman "objc-arc-contract", "ObjC ARC contraction", false, false) 1013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanPass *llvm::createObjCARCContractPass() { 1033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return new ObjCARCContract(); 1043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 1053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanvoid ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const { 1073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AU.addRequired<AliasAnalysis>(); 1083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AU.addRequired<DominatorTree>(); 1093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AU.setPreservesCFG(); 1103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 1113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 112f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a 113f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// return value. We do this late so we do not disrupt the dataflow analysis in 114f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// ObjCARCOpt. 115f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesmanbool 116f11a6856cc28875133cef0f7bbad2b7de3a83776Michael GottesmanObjCARCContract::OptimizeRetainCall(Function &F, Instruction *Retain) { 117f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman ImmutableCallSite CS(GetObjCArg(Retain)); 118f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman const Instruction *Call = CS.getInstruction(); 119f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (!Call) 120f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 121f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (Call->getParent() != Retain->getParent()) 122f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 123f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 124f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Check that the call is next to the retain. 125f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman BasicBlock::const_iterator I = Call; 126f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman ++I; 127f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman while (IsNoopInstruction(I)) ++I; 128f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (&*I != Retain) 129f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 130f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 131f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Turn it to an objc_retainAutoreleasedReturnValue. 132f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman Changed = true; 133f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman ++NumPeeps; 134f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 135f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman DEBUG(dbgs() << "Transforming objc_retain => " 136f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman "objc_retainAutoreleasedReturnValue since the operand is a " 137f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman "return value.\nOld: "<< *Retain << "\n"); 138f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 139f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // We do not have to worry about tail calls/does not throw since 140f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // retain/retainRV have the same properties. 1412e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_RetainRV); 1422e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman cast<CallInst>(Retain)->setCalledFunction(Decl); 143f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 144f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman DEBUG(dbgs() << "New: " << *Retain << "\n"); 145f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return true; 146f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman} 147f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 1483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Merge an autorelease with a retain into a fused call. 1493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanbool 1503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanObjCARCContract::ContractAutorelease(Function &F, Instruction *Autorelease, 1513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InstructionClass Class, 1523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<Instruction *, 4> 1533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &DependingInstructions, 1543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<const BasicBlock *, 4> 1553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &Visited) { 1563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman const Value *Arg = GetObjCArg(Autorelease); 1573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Check that there are no instructions between the retain and the autorelease 1593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // (such as an autorelease_pop) which may change the count. 1603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CallInst *Retain = 0; 1613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Class == IC_AutoreleaseRV) 1623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman FindDependencies(RetainAutoreleaseRVDep, Arg, 1633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Autorelease->getParent(), Autorelease, 1643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions, Visited, PA); 1653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else 1663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman FindDependencies(RetainAutoreleaseDep, Arg, 1673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Autorelease->getParent(), Autorelease, 1683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions, Visited, PA); 1693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Visited.clear(); 1713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (DependingInstructions.size() != 1) { 1723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions.clear(); 1733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 1743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 1753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin()); 1773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions.clear(); 1783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Retain || 1803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman GetBasicInstructionClass(Retain) != IC_Retain || 1813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman GetObjCArg(Retain) != Arg) 1823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 1833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 1853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++NumPeeps; 1863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "ObjCARCContract::ContractAutorelease: Fusing " 1883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman "retain/autorelease. Erasing: " << *Autorelease << "\n" 1893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman " Old Retain: " 1903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman << *Retain << "\n"); 1913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1922e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman Constant *Decl = EP.get(Class == IC_AutoreleaseRV ? 1932e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman ARCRuntimeEntryPoints::EPT_RetainAutoreleaseRV : 1942e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman ARCRuntimeEntryPoints::EPT_RetainAutorelease); 1952e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman Retain->setCalledFunction(Decl); 1963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << " New Retain: " 1983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman << *Retain << "\n"); 1993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman EraseInstruction(Autorelease); 2013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return true; 2023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 2033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Attempt to merge an objc_release with a store, load, and objc_retain to form 2053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// an objc_storeStrong. This can be a little tricky because the instructions 2063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// don't always appear in order, and there may be unrelated intervening 2073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// instructions. 2083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanvoid ObjCARCContract::ContractRelease(Instruction *Release, 2093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman inst_iterator &Iter) { 2103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman LoadInst *Load = dyn_cast<LoadInst>(GetObjCArg(Release)); 2113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Load || !Load->isSimple()) return; 2123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // For now, require everything to be in one basic block. 2143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *BB = Release->getParent(); 2153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Load->getParent() != BB) return; 2163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Walk down to find the store and the release, which may be in either order. 2183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock::iterator I = Load, End = BB->end(); 2193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++I; 2203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AliasAnalysis::Location Loc = AA->getLocation(Load); 2213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreInst *Store = 0; 2223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool SawRelease = false; 2233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (; !Store || !SawRelease; ++I) { 2243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (I == End) 2253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return; 2263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Inst = I; 2283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Inst == Release) { 2293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SawRelease = true; 2303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 2313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 2323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InstructionClass Class = GetBasicInstructionClass(Inst); 2343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Unrelated retains are harmless. 2363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (IsRetain(Class)) 2373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 2383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Store) { 2403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // The store is the point where we're going to put the objc_storeStrong, 2413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // so make sure there are no uses after it. 2423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (CanUse(Inst, Load, PA, Class)) 2433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return; 2443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } else if (AA->getModRefInfo(Inst, Loc) & AliasAnalysis::Mod) { 2453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // We are moving the load down to the store, so check for anything 2463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // else which writes to the memory between the load and the store. 2473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Store = dyn_cast<StoreInst>(Inst); 2483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Store || !Store->isSimple()) return; 2493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Store->getPointerOperand() != Loc.Ptr) return; 2503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 2513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 2523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Value *New = StripPointerCastsAndObjCCalls(Store->getValueOperand()); 2543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Walk up to find the retain. 2563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman I = Store; 2573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock::iterator Begin = BB->begin(); 2583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman while (I != Begin && GetBasicInstructionClass(I) != IC_Retain) 2593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman --I; 2603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Retain = I; 2613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (GetBasicInstructionClass(Retain) != IC_Retain) return; 2623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (GetObjCArg(Retain) != New) return; 2633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 2653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++NumStoreStrongs; 2663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman LLVMContext &C = Release->getContext(); 2683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 2693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *I8XX = PointerType::getUnqual(I8X); 2703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Value *Args[] = { Load->getPointerOperand(), New }; 2723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Args[0]->getType() != I8XX) 2733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Args[0] = new BitCastInst(Args[0], I8XX, "", Store); 2743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Args[1]->getType() != I8X) 2753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Args[1] = new BitCastInst(Args[1], I8X, "", Store); 2762e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman Constant *Decl = EP.get(ARCRuntimeEntryPoints::EPT_StoreStrong); 2772e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman CallInst *StoreStrong = CallInst::Create(Decl, Args, "", Store); 2783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrong->setDoesNotThrow(); 2793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrong->setDebugLoc(Store->getDebugLoc()); 2803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // We can't set the tail flag yet, because we haven't yet determined 2823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // whether there are any escaping allocas. Remember this call, so that 2833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // we can set the tail flag once we know it's safe. 2843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrongCalls.insert(StoreStrong); 2853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&*Iter == Store) ++Iter; 2873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Store->eraseFromParent(); 2883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Release->eraseFromParent(); 2893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman EraseInstruction(Retain); 2903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Load->use_empty()) 2913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Load->eraseFromParent(); 2923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 2933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanbool ObjCARCContract::doInitialization(Module &M) { 2953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If nothing in the Module uses ARC, don't do anything. 2963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Run = ModuleHasARC(M); 2973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Run) 2983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 2993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3002e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman EP.Initialize(&M); 3013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Initialize RetainRVMarker. 3033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman RetainRVMarker = 0; 3043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (NamedMDNode *NMD = 3053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker")) 3063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (NMD->getNumOperands() == 1) { 3073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman const MDNode *N = NMD->getOperand(0); 3083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (N->getNumOperands() == 1) 3093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (const MDString *S = dyn_cast<MDString>(N->getOperand(0))) 3103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman RetainRVMarker = S; 3113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 3123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 3143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 3153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanbool ObjCARCContract::runOnFunction(Function &F) { 3173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!EnableARCOpts) 3183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 3193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If nothing in the Module uses ARC, don't do anything. 3213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Run) 3223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 3233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = false; 3253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AA = &getAnalysis<AliasAnalysis>(); 3263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DT = &getAnalysis<DominatorTree>(); 3273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman PA.setAA(&getAnalysis<AliasAnalysis>()); 3293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Track whether it's ok to mark objc_storeStrong calls with the "tail" 3313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // keyword. Be conservative if the function has variadic arguments. 3323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // It seems that functions which "return twice" are also unsafe for the 3333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // "tail" argument, because they are setjmp, which could need to 3343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // return to an earlier stack state. 3353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool TailOkForStoreStrongs = !F.isVarArg() && 3363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman !F.callsFunctionThatReturnsTwice(); 3373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // For ObjC library calls which return their argument, replace uses of the 3393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // argument with uses of the call return value, if it dominates the use. This 3403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // reduces register pressure. 3413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<Instruction *, 4> DependingInstructions; 3423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<const BasicBlock *, 4> Visited; 3433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) { 3443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Inst = &*I++; 3453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "ObjCARCContract: Visiting: " << *Inst << "\n"); 3473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Only these library routines return their argument. In particular, 3493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_retainBlock does not necessarily return its argument. 3503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InstructionClass Class = GetBasicInstructionClass(Inst); 3513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman switch (Class) { 3523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_FusedRetainAutorelease: 3533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_FusedRetainAutoreleaseRV: 3543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 3553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_Autorelease: 3563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_AutoreleaseRV: 3573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (ContractAutorelease(F, Inst, Class, DependingInstructions, Visited)) 3583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 3593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 360f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman case IC_Retain: 361f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Attempt to convert retains to retainrvs if they are next to function 362f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // calls. 363f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (!OptimizeRetainCall(F, Inst)) 364f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman break; 365f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // If we succeed in our optimization, fall through. 366f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // FALLTHROUGH 3673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_RetainRV: { 3683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If we're compiling for a target which needs a special inline-asm 3693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // marker to do the retainAutoreleasedReturnValue optimization, 3703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // insert it now. 3713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!RetainRVMarker) 3723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 3733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock::iterator BBI = Inst; 3743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *InstParent = Inst->getParent(); 3753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Step up to see if the call immediately precedes the RetainRV call. 3773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If it's an invoke, we have to cross a block boundary. And we have 3783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // to carefully dodge no-op instructions. 3793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman do { 3803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&*BBI == InstParent->begin()) { 3813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *Pred = InstParent->getSinglePredecessor(); 3823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Pred) 3833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman goto decline_rv_optimization; 3843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BBI = Pred->getTerminator(); 3853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 3863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 3873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman --BBI; 388f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman } while (IsNoopInstruction(BBI)); 3893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&*BBI == GetObjCArg(Inst)) { 3913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "ObjCARCContract: Adding inline asm marker for " 3923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman "retainAutoreleasedReturnValue optimization.\n"); 3933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 3943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InlineAsm *IA = 3953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()), 3963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /*isVarArg=*/false), 3973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman RetainRVMarker->getString(), 3983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /*Constraints=*/"", /*hasSideEffects=*/true); 3993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CallInst::Create(IA, "", Inst); 4003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman decline_rv_optimization: 4023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 4033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_InitWeak: { 4053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_initWeak(p, null) => *p = null 4063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CallInst *CI = cast<CallInst>(Inst); 407f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman if (IsNullOrUndef(CI->getArgOperand(1))) { 4083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Value *Null = 4093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ConstantPointerNull::get(cast<PointerType>(CI->getType())); 4103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 4113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman new StoreInst(Null, CI->getArgOperand(0), CI); 4123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n" 4143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman << " New = " << *Null << "\n"); 4153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CI->replaceAllUsesWith(Null); 4173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CI->eraseFromParent(); 4183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 4203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_Release: 4223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ContractRelease(Inst, I); 4233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 4243a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman case IC_User: 4253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Be conservative if the function has any alloca instructions. 4263a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Technically we only care about escaping alloca instructions, 4273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // but this is sufficient to handle some interesting cases. 4283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (isa<AllocaInst>(Inst)) 4293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman TailOkForStoreStrongs = false; 4303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 4311f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall case IC_IntrinsicUser: 4321f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall // Remove calls to @clang.arc.use(...). 4331f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall Inst->eraseFromParent(); 4341f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall continue; 4353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman default: 4363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 4373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "ObjCARCContract: Finished List.\n\n"); 4403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Don't use GetObjCArg because we don't want to look through bitcasts 4423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // and such; to do the replacement, the argument must have type i8*. 4433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman const Value *Arg = cast<CallInst>(Inst)->getArgOperand(0); 4443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (;;) { 4453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If we're compiling bugpointed code, don't get in trouble. 4463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!isa<Instruction>(Arg) && !isa<Argument>(Arg)) 4473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 4483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Look through the uses of the pointer. 4493a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); 4503a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman UI != UE; ) { 4513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Use &U = UI.getUse(); 4523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman unsigned OperandNo = UI.getOperandNo(); 4533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++UI; // Increment UI now, because we may unlink its element. 4543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If the call's return value dominates a use of the call's argument 4563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // value, rewrite the use to use the return value. We check for 4573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // reachability here because an unreachable call is considered to 4583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // trivially dominate itself, which would lead us to rewriting its 4593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // argument in terms of its return value, which would lead to 4603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // infinite loops in GetObjCArg. 4613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) { 4623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 4633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Replacement = Inst; 4643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *UseTy = U.get()->getType(); 4653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) { 4663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // For PHI nodes, insert the bitcast in the predecessor block. 4673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo); 4683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *BB = PHI->getIncomingBlock(ValNo); 4693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Replacement->getType() != UseTy) 4703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Replacement = new BitCastInst(Replacement, UseTy, "", 4713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &BB->back()); 4723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // While we're here, rewrite all edges for this PHI, rather 4733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // than just one use at a time, to minimize the number of 4743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // bitcasts we emit. 4753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) 4763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (PHI->getIncomingBlock(i) == BB) { 4773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Keep the UI iterator valid. 4783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&PHI->getOperandUse( 4793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman PHINode::getOperandNumForIncomingValue(i)) == 4803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &UI.getUse()) 4813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++UI; 4823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman PHI->setIncomingValue(i, Replacement); 4833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } else { 4853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Replacement->getType() != UseTy) 4863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Replacement = new BitCastInst(Replacement, UseTy, "", 4873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman cast<Instruction>(U.getUser())); 4883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman U.set(Replacement); 4893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If Arg is a no-op casted pointer, strip one level of casts and iterate. 4943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg)) 4953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = BI->getOperand(0); 4963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else if (isa<GEPOperator>(Arg) && 4973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman cast<GEPOperator>(Arg)->hasAllZeroIndices()) 4983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = cast<GEPOperator>(Arg)->getPointerOperand(); 4993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else if (isa<GlobalAlias>(Arg) && 5003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman !cast<GlobalAlias>(Arg)->mayBeOverridden()) 5013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = cast<GlobalAlias>(Arg)->getAliasee(); 5023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else 5033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 5043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 5053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 5063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 5073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If this function has no escaping allocas or suspicious vararg usage, 5083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_storeStrong calls can be marked with the "tail" keyword. 5093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (TailOkForStoreStrongs) 5103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (SmallPtrSet<CallInst *, 8>::iterator I = StoreStrongCalls.begin(), 5113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman E = StoreStrongCalls.end(); I != E; ++I) 5123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman (*I)->setTailCall(); 5133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrongCalls.clear(); 5143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 5153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return Changed; 5163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 517