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" 384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h" 393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm; 413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmanusing namespace llvm::objcarc; 423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 43dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "objc-arc-contract" 44dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumPeeps, "Number of calls peephole-optimized"); 463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael GottesmanSTATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed"); 473a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 48ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 49ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Declarations 50ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 51ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesmannamespace { 533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// \brief Late ARC optimizations 543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// 553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// These change the IR in a way that makes it difficult to be analyzed by 563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// ObjCARCOpt, so it's run late. 573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman class ObjCARCContract : public FunctionPass { 583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool Changed; 593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman AliasAnalysis *AA; 603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DominatorTree *DT; 613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ProvenanceAnalysis PA; 622e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman ARCRuntimeEntryPoints EP; 633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// A flag indicating whether this optimization pass should run. 653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman bool Run; 663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// The inline asm string to insert between calls and RetainRV calls to make 683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// the optimization work on targets which need it. 693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman const MDString *RetainRVMarker; 703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// The set of inserted objc_storeStrong calls. If at the end of walking the 723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// function we have found no alloca instructions, these calls can be marked 733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /// "tail". 743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SmallPtrSet<CallInst *, 8> StoreStrongCalls; 753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Returns true if we eliminated Inst. 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool tryToPeepholeInstruction(Function &F, Instruction *Inst, 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines inst_iterator &Iter, 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<Instruction *> &DepInsts, 80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<const BasicBlock *> &Visited, 81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool &TailOkForStoreStrong); 82f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool optimizeRetainCall(Function &F, Instruction *Retain); 843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool 86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines contractAutorelease(Function &F, Instruction *Autorelease, 87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ARCInstKind Class, 88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<Instruction *> &DependingInstructions, 89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<const BasicBlock *> &Visited); 90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines void tryToContractReleaseIntoStoreStrong(Instruction *Release, 92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines inst_iterator &Iter); 933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void getAnalysisUsage(AnalysisUsage &AU) const override; 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool doInitialization(Module &M) override; 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool runOnFunction(Function &F) override; 973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman public: 993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman static char ID; 1003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ObjCARCContract() : FunctionPass(ID) { 1013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman initializeObjCARCContractPass(*PassRegistry::getPassRegistry()); 1023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 1033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman }; 1043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 1053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Implementation 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 1093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 110f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a 111f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// return value. We do this late so we do not disrupt the dataflow analysis in 112f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman/// ObjCARCOpt. 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) { 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ImmutableCallSite CS(GetArgRCIdentityRoot(Retain)); 115f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman const Instruction *Call = CS.getInstruction(); 116f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (!Call) 117f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 118f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (Call->getParent() != Retain->getParent()) 119f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 120f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 121f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Check that the call is next to the retain. 122f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman BasicBlock::const_iterator I = Call; 123f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman ++I; 124f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman while (IsNoopInstruction(I)) ++I; 125f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman if (&*I != Retain) 126f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return false; 127f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 128f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Turn it to an objc_retainAutoreleasedReturnValue. 129f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman Changed = true; 130f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman ++NumPeeps; 131f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 132f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman DEBUG(dbgs() << "Transforming objc_retain => " 133f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman "objc_retainAutoreleasedReturnValue since the operand is a " 134f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman "return value.\nOld: "<< *Retain << "\n"); 135f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 136f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // We do not have to worry about tail calls/does not throw since 137f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // retain/retainRV have the same properties. 1384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV); 1392e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman cast<CallInst>(Retain)->setCalledFunction(Decl); 140f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 141f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman DEBUG(dbgs() << "New: " << *Retain << "\n"); 142f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman return true; 143f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman} 144f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman 1453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman/// Merge an autorelease with a retain into a fused call. 146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::contractAutorelease( 147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function &F, Instruction *Autorelease, ARCInstKind Class, 148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<Instruction *> &DependingInstructions, 149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<const BasicBlock *> &Visited) { 150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const Value *Arg = GetArgRCIdentityRoot(Autorelease); 1513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Check that there are no instructions between the retain and the autorelease 1533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // (such as an autorelease_pop) which may change the count. 154dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallInst *Retain = nullptr; 155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Class == ARCInstKind::AutoreleaseRV) 1563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman FindDependencies(RetainAutoreleaseRVDep, Arg, 1573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Autorelease->getParent(), Autorelease, 1583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions, Visited, PA); 1593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else 1603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman FindDependencies(RetainAutoreleaseDep, Arg, 1613a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Autorelease->getParent(), Autorelease, 1623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions, Visited, PA); 1633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Visited.clear(); 1653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (DependingInstructions.size() != 1) { 1663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions.clear(); 1673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 1683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 1693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin()); 1713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DependingInstructions.clear(); 1723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 173ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain || 174ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines GetArgRCIdentityRoot(Retain) != Arg) 1753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return false; 1763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 1783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++NumPeeps; 1793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 180ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << " Fusing retain/autorelease!\n" 181ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines " Autorelease:" << *Autorelease << "\n" 182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines " Retain: " << *Retain << "\n"); 1833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 184ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Constant *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV 1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV 1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar : ARCRuntimeEntryPointKind::RetainAutorelease); 1872e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman Retain->setCalledFunction(Decl); 1883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 189ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << " New RetainAutorelease: " << *Retain << "\n"); 1903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 1913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman EraseInstruction(Autorelease); 1923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return true; 1933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 1943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 195ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load, 196ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Release, 197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ProvenanceAnalysis &PA, 198ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AliasAnalysis *AA) { 199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StoreInst *Store = nullptr; 200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool SawRelease = false; 2013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 202ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Get the location associated with Load. 203ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AliasAnalysis::Location Loc = AA->getLocation(Load); 2043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 2053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Walk down to find the store and the release, which may be in either order. 206ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto I = std::next(BasicBlock::iterator(Load)), 207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines E = Load->getParent()->end(); 208ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines I != E; ++I) { 209ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If we found the store we were looking for and saw the release, 210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // break. There is no more work to be done. 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Store && SawRelease) 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines break; 2133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Now we know that we have not seen either the store or the release. If I 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // is the the release, mark that we saw the release and continue. 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Inst = &*I; 2173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Inst == Release) { 2183a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman SawRelease = true; 2193a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 2203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 2213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Otherwise, we check if Inst is a "good" store. Grab the instruction class 223ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // of Inst. 224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ARCInstKind Class = GetBasicARCInstKind(Inst); 2253a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 226ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If Inst is an unrelated retain, we don't care about it. 227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 228ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // TODO: This is one area where the optimization could be made more 229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // aggressive. 2303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (IsRetain(Class)) 2313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman continue; 2323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 233ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If we have seen the store, but not the release... 2343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Store) { 235ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We need to make sure that it is safe to move the release from its 236ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // current position to the store. This implies proving that any 237ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // instruction in between Store and the Release conservatively can not use 238ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so 239ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // continue... 240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!CanUse(Inst, Load, PA, Class)) { 241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 243ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 244ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Otherwise, be conservative and return nullptr. 245ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 2463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 247ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 248ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Ok, now we know we have not seen a store yet. See if Inst can write to 249ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // our load location, if it can not, just ignore the instruction. 250ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!(AA->getModRefInfo(Inst, Loc) & AliasAnalysis::Mod)) 251ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 252ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 253ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Store = dyn_cast<StoreInst>(Inst); 254ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 255ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If Inst can, then check if Inst is a simple store. If Inst is not a 256ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // store or a store that is not simple, then we have some we do not 257ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // understand writing to this memory implying we can not move the load 258ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // over the write to any subsequent store that we may find. 259ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Store || !Store->isSimple()) 260ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 261ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 262ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Then make sure that the pointer we are storing to is Ptr. If so, we 263ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // found our Store! 264ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Store->getPointerOperand() == Loc.Ptr) 265ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 266ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 267ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Otherwise, we have an unknown store to some other ptr that clobbers 268ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Loc.Ptr. Bail! 269ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 2703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 2713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 272ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If we did not find the store or did not see the release, fail. 273ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Store || !SawRelease) 274ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 275ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 276ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We succeeded! 277ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Store; 278ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 2793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 280ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic Instruction * 281ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesfindRetainForStoreStrongContraction(Value *New, StoreInst *Store, 282ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Release, 283ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ProvenanceAnalysis &PA) { 284ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Walk up from the Store to find the retain. 285ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::iterator I = Store; 286ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock::iterator Begin = Store->getParent()->begin(); 287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines while (I != Begin && GetBasicARCInstKind(I) != ARCInstKind::Retain) { 288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Inst = &*I; 289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // It is only safe to move the retain to the store if we can prove 291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // conservatively that nothing besides the release can decrement reference 292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // counts in between the retain and the store. 293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (CanDecrementRefCount(Inst, New, PA) && Inst != Release) 294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 2953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman --I; 296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 2973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Retain = I; 298ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (GetBasicARCInstKind(Retain) != ARCInstKind::Retain) 299ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 300ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (GetArgRCIdentityRoot(Retain) != New) 301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Retain; 303ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 304ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 305ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// Attempt to merge an objc_release with a store, load, and objc_retain to form 306ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// an objc_storeStrong. An objc_storeStrong: 307ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 308ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// objc_storeStrong(i8** %old_ptr, i8* new_value) 309ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 310ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// is equivalent to the following IR sequence: 311ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 312ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ; Load old value. 313ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// %old_value = load i8** %old_ptr (1) 314ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ; Increment the new value and then release the old value. This must occur 316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ; in order in case old_value releases new_value in its destructor causing 317ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ; us to potentially have a dangling ptr. 318ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// tail call i8* @objc_retain(i8* %new_value) (2) 319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// tail call void @objc_release(i8* %old_value) (3) 320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 321ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// ; Store the new_value into old_ptr 322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// store i8* %new_value, i8** %old_ptr (4) 323ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 324ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// The safety of this optimization is based around the following 325ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// considerations: 326ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 327ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 1. We are forming the store strong at the store. Thus to perform this 328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// optimization it must be safe to move the retain, load, and release to 329ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// (4). 330ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 2. We need to make sure that any re-orderings of (1), (2), (3), (4) are 331ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// safe. 332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ObjCARCContract::tryToContractReleaseIntoStoreStrong(Instruction *Release, 333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines inst_iterator &Iter) { 334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // See if we are releasing something that we just loaded. 335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release)); 336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Load || !Load->isSimple()) 337ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 338ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For now, require everything to be in one basic block. 340ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines BasicBlock *BB = Release->getParent(); 341ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Load->getParent() != BB) 342ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 344ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // First scan down the BB from Load, looking for a store of the RCIdentityRoot 345ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // of Load's 346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StoreInst *Store = 347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines findSafeStoreForStoreStrongContraction(Load, Release, PA, AA); 348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If we fail, bail. 349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Store) 350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Then find what new_value's RCIdentity Root is. 353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Value *New = GetRCIdentityRoot(Store->getValueOperand()); 354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Then walk up the BB and look for a retain on New without any intervening 356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // instructions which conservatively might decrement ref counts. 357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Retain = 358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines findRetainForStoreStrongContraction(New, Store, Release, PA); 359ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 360ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If we fail, bail. 361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Retain) 362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return; 3633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 3653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++NumStoreStrongs; 3663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG( 368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines llvm::dbgs() << " Contracting retain, release into objc_storeStrong.\n" 369ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " Old:\n" 370ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " Store: " << *Store << "\n" 371ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " Release: " << *Release << "\n" 372ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " Retain: " << *Retain << "\n" 373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << " Load: " << *Load << "\n"); 374ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman LLVMContext &C = Release->getContext(); 3763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C)); 3773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *I8XX = PointerType::getUnqual(I8X); 3783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Value *Args[] = { Load->getPointerOperand(), New }; 3803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Args[0]->getType() != I8XX) 3813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Args[0] = new BitCastInst(Args[0], I8XX, "", Store); 3823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Args[1]->getType() != I8X) 3833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Args[1] = new BitCastInst(Args[1], I8X, "", Store); 3844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Constant *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong); 3852e696cf61c30c68c595b0b000d368a834ddc63b9Michael Gottesman CallInst *StoreStrong = CallInst::Create(Decl, Args, "", Store); 3863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrong->setDoesNotThrow(); 3873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrong->setDebugLoc(Store->getDebugLoc()); 3883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 3893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // We can't set the tail flag yet, because we haven't yet determined 3903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // whether there are any escaping allocas. Remember this call, so that 3913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // we can set the tail flag once we know it's safe. 3923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrongCalls.insert(StoreStrong); 3933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 394ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(llvm::dbgs() << " New Store Strong: " << *StoreStrong << "\n"); 395ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 3963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&*Iter == Store) ++Iter; 3973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Store->eraseFromParent(); 3983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Release->eraseFromParent(); 3993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman EraseInstruction(Retain); 4003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Load->use_empty()) 4013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Load->eraseFromParent(); 4023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 4033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 404ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::tryToPeepholeInstruction( 405ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Function &F, Instruction *Inst, inst_iterator &Iter, 406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<Instruction *> &DependingInsts, 407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSetImpl<const BasicBlock *> &Visited, 408ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool &TailOkForStoreStrongs) { 4093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Only these library routines return their argument. In particular, 4103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_retainBlock does not necessarily return its argument. 411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ARCInstKind Class = GetBasicARCInstKind(Inst); 4123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman switch (Class) { 413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::FusedRetainAutorelease: 414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::FusedRetainAutoreleaseRV: 415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::Autorelease: 417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::AutoreleaseRV: 418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return contractAutorelease(F, Inst, Class, DependingInsts, Visited); 419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::Retain: 420f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // Attempt to convert retains to retainrvs if they are next to function 421f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // calls. 422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!optimizeRetainCall(F, Inst)) 423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 424f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // If we succeed in our optimization, fall through. 425f11a6856cc28875133cef0f7bbad2b7de3a83776Michael Gottesman // FALLTHROUGH 426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::RetainRV: { 4273a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If we're compiling for a target which needs a special inline-asm 4283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // marker to do the retainAutoreleasedReturnValue optimization, 4293a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // insert it now. 4303a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!RetainRVMarker) 431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 4323a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock::iterator BBI = Inst; 4333a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *InstParent = Inst->getParent(); 4343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4353a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Step up to see if the call immediately precedes the RetainRV call. 4363a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If it's an invoke, we have to cross a block boundary. And we have 4373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // to carefully dodge no-op instructions. 4383a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman do { 4393a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (&*BBI == InstParent->begin()) { 4403a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *Pred = InstParent->getSinglePredecessor(); 4413a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!Pred) 4423a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman goto decline_rv_optimization; 4433a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BBI = Pred->getTerminator(); 4443a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 4453a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4463a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman --BBI; 447f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman } while (IsNoopInstruction(BBI)); 4483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (&*BBI == GetArgRCIdentityRoot(Inst)) { 450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Adding inline asm marker for " 4513a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman "retainAutoreleasedReturnValue optimization.\n"); 4523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 4533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InlineAsm *IA = 4543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()), 4553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /*isVarArg=*/false), 4563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman RetainRVMarker->getString(), 4573a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman /*Constraints=*/"", /*hasSideEffects=*/true); 4583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CallInst::Create(IA, "", Inst); 4593a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 4603a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman decline_rv_optimization: 461ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 4623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 463ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::InitWeak: { 4643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_initWeak(p, null) => *p = null 4653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CallInst *CI = cast<CallInst>(Inst); 466f0a15d88afce23453ff55894400035014ad46a15Michael Gottesman if (IsNullOrUndef(CI->getArgOperand(1))) { 4673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Value *Null = 4683a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ConstantPointerNull::get(cast<PointerType>(CI->getType())); 4693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 4703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman new StoreInst(Null, CI->getArgOperand(0), CI); 4713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n" 4733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman << " New = " << *Null << "\n"); 4743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 4753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CI->replaceAllUsesWith(Null); 4763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman CI->eraseFromParent(); 4773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 478ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 4793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 480ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::Release: 481ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Try to form an objc store strong from our release. If we fail, there is 482ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // nothing further to do below, so continue. 483ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines tryToContractReleaseIntoStoreStrong(Inst, Iter); 484ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 485ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::User: 4863a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Be conservative if the function has any alloca instructions. 4873a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Technically we only care about escaping alloca instructions, 4883a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // but this is sufficient to handle some interesting cases. 4893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (isa<AllocaInst>(Inst)) 4903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman TailOkForStoreStrongs = false; 491ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 492ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines case ARCInstKind::IntrinsicUser: 4931f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall // Remove calls to @clang.arc.use(...). 4941f9c4407c0e66f0c473ed5d6e3abcedda3a838c9John McCall Inst->eraseFromParent(); 495ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 4963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman default: 497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return true; 4983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 501ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Top Level Driver 503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 504ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::runOnFunction(Function &F) { 506ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!EnableARCOpts) 507ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 508ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 509ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If nothing in the Module uses ARC, don't do anything. 510ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Run) 511ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 5123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 513ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Changed = false; 514ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AA = &getAnalysis<AliasAnalysis>(); 515ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); 516ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 517ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines PA.setAA(&getAnalysis<AliasAnalysis>()); 518ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 519ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n"); 520ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 521ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Track whether it's ok to mark objc_storeStrong calls with the "tail" 522ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // keyword. Be conservative if the function has variadic arguments. 523ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // It seems that functions which "return twice" are also unsafe for the 524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // "tail" argument, because they are setjmp, which could need to 525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // return to an earlier stack state. 526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool TailOkForStoreStrongs = 527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines !F.isVarArg() && !F.callsFunctionThatReturnsTwice(); 5283a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // For ObjC library calls which return their argument, replace uses of the 530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // argument with uses of the call return value, if it dominates the use. This 531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // reduces register pressure. 532ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSet<Instruction *, 4> DependingInstructions; 533ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines SmallPtrSet<const BasicBlock *, 4> Visited; 534ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) { 535ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Instruction *Inst = &*I++; 536ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 537ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines DEBUG(dbgs() << "Visiting: " << *Inst << "\n"); 538ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 539ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // First try to peephole Inst. If there is nothing further we can do in 540ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // terms of undoing objc-arc-expand, process the next inst. 541ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (tryToPeepholeInstruction(F, Inst, I, DependingInstructions, Visited, 542ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines TailOkForStoreStrongs)) 543ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines continue; 544ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Otherwise, try to undo objc-arc-expand. 546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts 5483a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // and such; to do the replacement, the argument must have type i8*. 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Value *Arg = cast<CallInst>(Inst)->getArgOperand(0); 550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // TODO: Change this to a do-while. 5523a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (;;) { 5533a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If we're compiling bugpointed code, don't get in trouble. 5543a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (!isa<Instruction>(Arg) && !isa<Argument>(Arg)) 5553a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 5563a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Look through the uses of the pointer. 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); 5583a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman UI != UE; ) { 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Increment UI now, because we may unlink its element. 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Use &U = *UI++; 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned OperandNo = U.getOperandNo(); 5623a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 5633a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If the call's return value dominates a use of the call's argument 5643a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // value, rewrite the use to use the return value. We check for 5653a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // reachability here because an unreachable call is considered to 5663a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // trivially dominate itself, which would lead us to rewriting its 5673a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // argument in terms of its return value, which would lead to 568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // infinite loops in GetArgRCIdentityRoot. 5693a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (DT->isReachableFromEntry(U) && DT->dominates(Inst, U)) { 5703a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Changed = true; 5713a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Instruction *Replacement = Inst; 5723a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Type *UseTy = U.get()->getType(); 5733a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) { 5743a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // For PHI nodes, insert the bitcast in the predecessor block. 5753a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo); 5763a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman BasicBlock *BB = PHI->getIncomingBlock(ValNo); 5773a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Replacement->getType() != UseTy) 5783a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Replacement = new BitCastInst(Replacement, UseTy, "", 5793a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman &BB->back()); 5803a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // While we're here, rewrite all edges for this PHI, rather 5813a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // than just one use at a time, to minimize the number of 5823a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // bitcasts we emit. 5833a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i) 5843a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (PHI->getIncomingBlock(i) == BB) { 5853a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // Keep the UI iterator valid. 58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (UI != UE && 58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines &PHI->getOperandUse( 58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines PHINode::getOperandNumForIncomingValue(i)) == &*UI) 5893a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman ++UI; 5903a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman PHI->setIncomingValue(i, Replacement); 5913a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 5923a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } else { 5933a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (Replacement->getType() != UseTy) 5943a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Replacement = new BitCastInst(Replacement, UseTy, "", 5953a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman cast<Instruction>(U.getUser())); 5963a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman U.set(Replacement); 5973a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 5983a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 5993a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 6003a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 6013a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If Arg is a no-op casted pointer, strip one level of casts and iterate. 6023a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg)) 6033a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = BI->getOperand(0); 6043a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else if (isa<GEPOperator>(Arg) && 6053a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman cast<GEPOperator>(Arg)->hasAllZeroIndices()) 6063a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = cast<GEPOperator>(Arg)->getPointerOperand(); 6073a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else if (isa<GlobalAlias>(Arg) && 6083a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman !cast<GlobalAlias>(Arg)->mayBeOverridden()) 6093a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman Arg = cast<GlobalAlias>(Arg)->getAliasee(); 6103a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman else 6113a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman break; 6123a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 6133a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman } 6143a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 6153a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // If this function has no escaping allocas or suspicious vararg usage, 6163a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman // objc_storeStrong calls can be marked with the "tail" keyword. 6173a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman if (TailOkForStoreStrongs) 61837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines for (CallInst *CI : StoreStrongCalls) 61937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CI->setTailCall(); 6203a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman StoreStrongCalls.clear(); 6213a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman 6223a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman return Changed; 6233a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman} 624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Misc Pass Manager 627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines//===----------------------------------------------------------------------===// 628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hineschar ObjCARCContract::ID = 0; 630ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_BEGIN(ObjCARCContract, "objc-arc-contract", 631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "ObjC ARC contraction", false, false) 632ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_AG_DEPENDENCY(AliasAnalysis) 633ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) 634ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesINITIALIZE_PASS_END(ObjCARCContract, "objc-arc-contract", 635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "ObjC ARC contraction", false, false) 636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const { 638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<AliasAnalysis>(); 639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.addRequired<DominatorTreeWrapperPass>(); 640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines AU.setPreservesCFG(); 641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 642ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 643ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesPass *llvm::createObjCARCContractPass() { return new ObjCARCContract(); } 644ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 645ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool ObjCARCContract::doInitialization(Module &M) { 646ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // If nothing in the Module uses ARC, don't do anything. 647ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Run = ModuleHasARC(M); 648ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Run) 649ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 650ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 6514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar EP.init(&M); 652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Initialize RetainRVMarker. 654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RetainRVMarker = nullptr; 655ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (NamedMDNode *NMD = 656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker")) 657ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (NMD->getNumOperands() == 1) { 658ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MDNode *N = NMD->getOperand(0); 659ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (N->getNumOperands() == 1) 660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (const MDString *S = dyn_cast<MDString>(N->getOperand(0))) 661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RetainRVMarker = S; 662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return false; 665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 666