1 //===-- ObjCARC.cpp -------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements common infrastructure for libLLVMObjCARCOpts.a, which 10 // implements several scalar transformations over the LLVM intermediate 11 // representation, including the C bindings for that library. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ObjCARC.h" 16 #include "llvm-c/Initialization.h" 17 #include "llvm/Analysis/ObjCARCUtil.h" 18 #include "llvm/IR/IRBuilder.h" 19 #include "llvm/IR/Instructions.h" 20 #include "llvm/InitializePasses.h" 21 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 22 23 namespace llvm { 24 class PassRegistry; 25 } 26 27 using namespace llvm; 28 using namespace llvm::objcarc; 29 30 /// initializeObjCARCOptsPasses - Initialize all passes linked into the 31 /// ObjCARCOpts library. 32 void llvm::initializeObjCARCOpts(PassRegistry &Registry) { 33 initializeObjCARCAAWrapperPassPass(Registry); 34 initializeObjCARCAPElimPass(Registry); 35 initializeObjCARCExpandPass(Registry); 36 initializeObjCARCContractLegacyPassPass(Registry); 37 initializeObjCARCOptLegacyPassPass(Registry); 38 initializePAEvalPass(Registry); 39 } 40 41 void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) { 42 initializeObjCARCOpts(*unwrap(R)); 43 } 44 45 CallInst *objcarc::createCallInstWithColors( 46 FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, 47 Instruction *InsertBefore, 48 const DenseMap<BasicBlock *, ColorVector> &BlockColors) { 49 FunctionType *FTy = Func.getFunctionType(); 50 Value *Callee = Func.getCallee(); 51 SmallVector<OperandBundleDef, 1> OpBundles; 52 53 if (!BlockColors.empty()) { 54 const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second; 55 assert(CV.size() == 1 && "non-unique color for block!"); 56 Instruction *EHPad = CV.front()->getFirstNonPHI(); 57 if (EHPad->isEHPad()) 58 OpBundles.emplace_back("funclet", EHPad); 59 } 60 61 return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore); 62 } 63 64 std::pair<bool, bool> 65 BundledRetainClaimRVs::insertAfterInvokes(Function &F, DominatorTree *DT) { 66 bool Changed = false, CFGChanged = false; 67 68 for (BasicBlock &BB : F) { 69 auto *I = dyn_cast<InvokeInst>(BB.getTerminator()); 70 71 if (!I) 72 continue; 73 74 if (!objcarc::hasAttachedCallOpBundle(I)) 75 continue; 76 77 BasicBlock *DestBB = I->getNormalDest(); 78 79 if (!DestBB->getSinglePredecessor()) { 80 assert(I->getSuccessor(0) == DestBB && 81 "the normal dest is expected to be the first successor"); 82 DestBB = SplitCriticalEdge(I, 0, CriticalEdgeSplittingOptions(DT)); 83 CFGChanged = true; 84 } 85 86 // We don't have to call insertRVCallWithColors since DestBB is the normal 87 // destination of the invoke. 88 insertRVCall(&*DestBB->getFirstInsertionPt(), I); 89 Changed = true; 90 } 91 92 return std::make_pair(Changed, CFGChanged); 93 } 94 95 CallInst *BundledRetainClaimRVs::insertRVCall(Instruction *InsertPt, 96 CallBase *AnnotatedCall) { 97 DenseMap<BasicBlock *, ColorVector> BlockColors; 98 return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors); 99 } 100 101 CallInst *BundledRetainClaimRVs::insertRVCallWithColors( 102 Instruction *InsertPt, CallBase *AnnotatedCall, 103 const DenseMap<BasicBlock *, ColorVector> &BlockColors) { 104 IRBuilder<> Builder(InsertPt); 105 Function *Func = *objcarc::getAttachedARCFunction(AnnotatedCall); 106 assert(Func && "operand isn't a Function"); 107 Type *ParamTy = Func->getArg(0)->getType(); 108 Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy); 109 auto *Call = 110 createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors); 111 RVCalls[Call] = AnnotatedCall; 112 return Call; 113 } 114 115 BundledRetainClaimRVs::~BundledRetainClaimRVs() { 116 for (auto P : RVCalls) { 117 if (ContractPass) { 118 CallBase *CB = P.second; 119 // At this point, we know that the annotated calls can't be tail calls 120 // as they are followed by marker instructions and retainRV/claimRV 121 // calls. Mark them as notail so that the backend knows these calls 122 // can't be tail calls. 123 if (auto *CI = dyn_cast<CallInst>(CB)) 124 CI->setTailCallKind(CallInst::TCK_NoTail); 125 } 126 127 EraseInstruction(P.first); 128 } 129 130 RVCalls.clear(); 131 } 132