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