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