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