1 //===-- ObjCARC.cpp -------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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.
13 //===----------------------------------------------------------------------===//
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"
29 using namespace llvm::objcarc
;
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
);
42 void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R
) {
43 initializeObjCARCOpts(*unwrap(R
));
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
;
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();
59 OpBundles
.emplace_back("funclet", EHPad
);
62 return CallInst::Create(FTy
, Callee
, Args
, OpBundles
, NameStr
, InsertBefore
);
66 BundledRetainClaimRVs::insertAfterInvokes(Function
&F
, DominatorTree
*DT
) {
67 bool Changed
= false, CFGChanged
= false;
69 for (BasicBlock
&BB
: F
) {
70 auto *I
= dyn_cast
<InvokeInst
>(BB
.getTerminator());
75 if (!objcarc::hasAttachedCallOpBundle(I
))
78 BasicBlock
*DestBB
= I
->getNormalDest();
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
));
87 // We don't have to call insertRVCallWithColors since DestBB is the normal
88 // destination of the invoke.
89 insertRVCall(&*DestBB
->getFirstInsertionPt(), I
);
93 return std::make_pair(Changed
, CFGChanged
);
96 CallInst
*BundledRetainClaimRVs::insertRVCall(Instruction
*InsertPt
,
97 CallBase
*AnnotatedCall
) {
98 DenseMap
<BasicBlock
*, ColorVector
> BlockColors
;
99 return insertRVCallWithColors(InsertPt
, AnnotatedCall
, BlockColors
);
102 CallInst
*BundledRetainClaimRVs::insertRVCallWithColors(
103 Instruction
*InsertPt
, CallBase
*AnnotatedCall
,
104 const DenseMap
<BasicBlock
*, ColorVector
> &BlockColors
) {
105 IRBuilder
<> Builder(InsertPt
);
106 bool IsRetainRV
= objcarc::hasAttachedCallOpBundle(AnnotatedCall
, true);
107 Function
*Func
= EP
.get(IsRetainRV
? ARCRuntimeEntryPointKind::RetainRV
108 : ARCRuntimeEntryPointKind::ClaimRV
);
109 Type
*ParamTy
= Func
->getArg(0)->getType();
110 Value
*CallArg
= Builder
.CreateBitCast(AnnotatedCall
, ParamTy
);
112 createCallInstWithColors(Func
, CallArg
, "", InsertPt
, BlockColors
);
113 RVCalls
[Call
] = AnnotatedCall
;
117 BundledRetainClaimRVs::~BundledRetainClaimRVs() {
119 // At this point, we know that the annotated calls can't be tail calls as
120 // they are followed by marker instructions and retainRV/claimRV calls. Mark
121 // them as notail, so that the backend knows these calls can't be tail
123 for (auto P
: RVCalls
)
124 if (auto *CI
= dyn_cast
<CallInst
>(P
.second
))
125 CI
->setTailCallKind(CallInst::TCK_NoTail
);
127 for (auto P
: RVCalls
)
128 EraseInstruction(P
.first
);