Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
35294 views
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
BasicBlock::iterator 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(BasicBlock::iterator InsertPt,
75
CallBase *AnnotatedCall) {
76
DenseMap<BasicBlock *, ColorVector> BlockColors;
77
return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors);
78
}
79
80
CallInst *BundledRetainClaimRVs::insertRVCallWithColors(
81
BasicBlock::iterator InsertPt, CallBase *AnnotatedCall,
82
const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
83
IRBuilder<> Builder(InsertPt->getParent(), 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
112