[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Transforms / ObjCARC / ObjCARC.cpp
blob06b12149f5971e4f52b2f1da2d7fdca71fffe1b4
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.
13 //===----------------------------------------------------------------------===//
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"
24 namespace llvm {
25 class PassRegistry;
28 using namespace llvm;
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();
58 if (EHPad->isEHPad())
59 OpBundles.emplace_back("funclet", EHPad);
62 return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore);
65 std::pair<bool, bool>
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());
72 if (!I)
73 continue;
75 if (!objcarc::hasAttachedCallOpBundle(I))
76 continue;
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));
84 CFGChanged = true;
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;
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);
111 auto *Call =
112 createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors);
113 RVCalls[Call] = AnnotatedCall;
114 return Call;
117 BundledRetainClaimRVs::~BundledRetainClaimRVs() {
118 if (ContractPass) {
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
122 // calls.
123 for (auto P : RVCalls)
124 if (auto *CI = dyn_cast<CallInst>(P.second))
125 CI->setTailCallKind(CallInst::TCK_NoTail);
126 } else {
127 for (auto P : RVCalls)
128 EraseInstruction(P.first);
131 RVCalls.clear();