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.
initializeObjCARCOpts(PassRegistry & Registry)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
LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R)41 void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) {
42 initializeObjCARCOpts(*unwrap(R));
43 }
44
createCallInstWithColors(FunctionCallee Func,ArrayRef<Value * > Args,const Twine & NameStr,Instruction * InsertBefore,const DenseMap<BasicBlock *,ColorVector> & BlockColors)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>
insertAfterInvokes(Function & F,DominatorTree * DT)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
insertRVCall(Instruction * InsertPt,CallBase * AnnotatedCall)95 CallInst *BundledRetainClaimRVs::insertRVCall(Instruction *InsertPt,
96 CallBase *AnnotatedCall) {
97 DenseMap<BasicBlock *, ColorVector> BlockColors;
98 return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors);
99 }
100
insertRVCallWithColors(Instruction * InsertPt,CallBase * AnnotatedCall,const DenseMap<BasicBlock *,ColorVector> & BlockColors)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
~BundledRetainClaimRVs()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