Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/ObjCARC.cpp
35294 views
//===-- ObjCARC.cpp -------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements common infrastructure for libLLVMObjCARCOpts.a, which9// implements several scalar transformations over the LLVM intermediate10// representation, including the C bindings for that library.11//12//===----------------------------------------------------------------------===//1314#include "ObjCARC.h"15#include "llvm/Analysis/ObjCARCUtil.h"16#include "llvm/IR/IRBuilder.h"17#include "llvm/IR/Instructions.h"18#include "llvm/Transforms/Utils/BasicBlockUtils.h"1920using namespace llvm;21using namespace llvm::objcarc;2223CallInst *objcarc::createCallInstWithColors(24FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr,25BasicBlock::iterator InsertBefore,26const DenseMap<BasicBlock *, ColorVector> &BlockColors) {27FunctionType *FTy = Func.getFunctionType();28Value *Callee = Func.getCallee();29SmallVector<OperandBundleDef, 1> OpBundles;3031if (!BlockColors.empty()) {32const ColorVector &CV = BlockColors.find(InsertBefore->getParent())->second;33assert(CV.size() == 1 && "non-unique color for block!");34Instruction *EHPad = CV.front()->getFirstNonPHI();35if (EHPad->isEHPad())36OpBundles.emplace_back("funclet", EHPad);37}3839return CallInst::Create(FTy, Callee, Args, OpBundles, NameStr, InsertBefore);40}4142std::pair<bool, bool>43BundledRetainClaimRVs::insertAfterInvokes(Function &F, DominatorTree *DT) {44bool Changed = false, CFGChanged = false;4546for (BasicBlock &BB : F) {47auto *I = dyn_cast<InvokeInst>(BB.getTerminator());4849if (!I)50continue;5152if (!objcarc::hasAttachedCallOpBundle(I))53continue;5455BasicBlock *DestBB = I->getNormalDest();5657if (!DestBB->getSinglePredecessor()) {58assert(I->getSuccessor(0) == DestBB &&59"the normal dest is expected to be the first successor");60DestBB = SplitCriticalEdge(I, 0, CriticalEdgeSplittingOptions(DT));61CFGChanged = true;62}6364// We don't have to call insertRVCallWithColors since DestBB is the normal65// destination of the invoke.66insertRVCall(DestBB->getFirstInsertionPt(), I);67Changed = true;68}6970return std::make_pair(Changed, CFGChanged);71}7273CallInst *BundledRetainClaimRVs::insertRVCall(BasicBlock::iterator InsertPt,74CallBase *AnnotatedCall) {75DenseMap<BasicBlock *, ColorVector> BlockColors;76return insertRVCallWithColors(InsertPt, AnnotatedCall, BlockColors);77}7879CallInst *BundledRetainClaimRVs::insertRVCallWithColors(80BasicBlock::iterator InsertPt, CallBase *AnnotatedCall,81const DenseMap<BasicBlock *, ColorVector> &BlockColors) {82IRBuilder<> Builder(InsertPt->getParent(), InsertPt);83Function *Func = *objcarc::getAttachedARCFunction(AnnotatedCall);84assert(Func && "operand isn't a Function");85Type *ParamTy = Func->getArg(0)->getType();86Value *CallArg = Builder.CreateBitCast(AnnotatedCall, ParamTy);87auto *Call =88createCallInstWithColors(Func, CallArg, "", InsertPt, BlockColors);89RVCalls[Call] = AnnotatedCall;90return Call;91}9293BundledRetainClaimRVs::~BundledRetainClaimRVs() {94for (auto P : RVCalls) {95if (ContractPass) {96CallBase *CB = P.second;97// At this point, we know that the annotated calls can't be tail calls98// as they are followed by marker instructions and retainRV/claimRV99// calls. Mark them as notail so that the backend knows these calls100// can't be tail calls.101if (auto *CI = dyn_cast<CallInst>(CB))102CI->setTailCallKind(CallInst::TCK_NoTail);103}104105EraseInstruction(P.first);106}107108RVCalls.clear();109}110111112