diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-11 12:38:11 +0000 |
commit | e3b557809604d036af6e00c60f012c2025b59a5e (patch) | |
tree | 8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Transforms/Utils/InlineFunction.cpp | |
parent | 08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff) |
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 349 |
1 files changed, 295 insertions, 54 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 878f9477a29d..399c9a43793f 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -12,8 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" @@ -27,6 +25,7 @@ #include "llvm/Analysis/CaptureTracking.h" #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/MemoryProfileInfo.h" #include "llvm/Analysis/ObjCARCAnalysisUtils.h" #include "llvm/Analysis/ObjCARCUtil.h" #include "llvm/Analysis/ProfileSummaryInfo.h" @@ -70,11 +69,15 @@ #include <cstdint> #include <iterator> #include <limits> +#include <optional> #include <string> #include <utility> #include <vector> +#define DEBUG_TYPE "inline-function" + using namespace llvm; +using namespace llvm::memprof; using ProfileCount = Function::ProfileCount; static cl::opt<bool> @@ -547,13 +550,6 @@ static BasicBlock *HandleCallsInBlockInlinedThroughInvoke( if (!CI || CI->doesNotThrow()) continue; - if (CI->isInlineAsm()) { - InlineAsm *IA = cast<InlineAsm>(CI->getCalledOperand()); - if (!IA->canThrow()) { - continue; - } - } - // We do not need to (and in fact, cannot) convert possibly throwing calls // to @llvm.experimental_deoptimize (resp. @llvm.experimental.guard) into // invokes. The caller's "segment" of the deoptimization continuation @@ -782,6 +778,140 @@ static void HandleInlinedEHPad(InvokeInst *II, BasicBlock *FirstNewBlock, UnwindDest->removePredecessor(InvokeBB); } +static bool haveCommonPrefix(MDNode *MIBStackContext, + MDNode *CallsiteStackContext) { + assert(MIBStackContext->getNumOperands() > 0 && + CallsiteStackContext->getNumOperands() > 0); + // Because of the context trimming performed during matching, the callsite + // context could have more stack ids than the MIB. We match up to the end of + // the shortest stack context. + for (auto MIBStackIter = MIBStackContext->op_begin(), + CallsiteStackIter = CallsiteStackContext->op_begin(); + MIBStackIter != MIBStackContext->op_end() && + CallsiteStackIter != CallsiteStackContext->op_end(); + MIBStackIter++, CallsiteStackIter++) { + auto *Val1 = mdconst::dyn_extract<ConstantInt>(*MIBStackIter); + auto *Val2 = mdconst::dyn_extract<ConstantInt>(*CallsiteStackIter); + assert(Val1 && Val2); + if (Val1->getZExtValue() != Val2->getZExtValue()) + return false; + } + return true; +} + +static void removeMemProfMetadata(CallBase *Call) { + Call->setMetadata(LLVMContext::MD_memprof, nullptr); +} + +static void removeCallsiteMetadata(CallBase *Call) { + Call->setMetadata(LLVMContext::MD_callsite, nullptr); +} + +static void updateMemprofMetadata(CallBase *CI, + const std::vector<Metadata *> &MIBList) { + assert(!MIBList.empty()); + // Remove existing memprof, which will either be replaced or may not be needed + // if we are able to use a single allocation type function attribute. + removeMemProfMetadata(CI); + CallStackTrie CallStack; + for (Metadata *MIB : MIBList) + CallStack.addCallStack(cast<MDNode>(MIB)); + bool MemprofMDAttached = CallStack.buildAndAttachMIBMetadata(CI); + assert(MemprofMDAttached == CI->hasMetadata(LLVMContext::MD_memprof)); + if (!MemprofMDAttached) + // If we used a function attribute remove the callsite metadata as well. + removeCallsiteMetadata(CI); +} + +// Update the metadata on the inlined copy ClonedCall of a call OrigCall in the +// inlined callee body, based on the callsite metadata InlinedCallsiteMD from +// the call that was inlined. +static void propagateMemProfHelper(const CallBase *OrigCall, + CallBase *ClonedCall, + MDNode *InlinedCallsiteMD) { + MDNode *OrigCallsiteMD = ClonedCall->getMetadata(LLVMContext::MD_callsite); + MDNode *ClonedCallsiteMD = nullptr; + // Check if the call originally had callsite metadata, and update it for the + // new call in the inlined body. + if (OrigCallsiteMD) { + // The cloned call's context is now the concatenation of the original call's + // callsite metadata and the callsite metadata on the call where it was + // inlined. + ClonedCallsiteMD = MDNode::concatenate(OrigCallsiteMD, InlinedCallsiteMD); + ClonedCall->setMetadata(LLVMContext::MD_callsite, ClonedCallsiteMD); + } + + // Update any memprof metadata on the cloned call. + MDNode *OrigMemProfMD = ClonedCall->getMetadata(LLVMContext::MD_memprof); + if (!OrigMemProfMD) + return; + // We currently expect that allocations with memprof metadata also have + // callsite metadata for the allocation's part of the context. + assert(OrigCallsiteMD); + + // New call's MIB list. + std::vector<Metadata *> NewMIBList; + + // For each MIB metadata, check if its call stack context starts with the + // new clone's callsite metadata. If so, that MIB goes onto the cloned call in + // the inlined body. If not, it stays on the out-of-line original call. + for (auto &MIBOp : OrigMemProfMD->operands()) { + MDNode *MIB = dyn_cast<MDNode>(MIBOp); + // Stack is first operand of MIB. + MDNode *StackMD = getMIBStackNode(MIB); + assert(StackMD); + // See if the new cloned callsite context matches this profiled context. + if (haveCommonPrefix(StackMD, ClonedCallsiteMD)) + // Add it to the cloned call's MIB list. + NewMIBList.push_back(MIB); + } + if (NewMIBList.empty()) { + removeMemProfMetadata(ClonedCall); + removeCallsiteMetadata(ClonedCall); + return; + } + if (NewMIBList.size() < OrigMemProfMD->getNumOperands()) + updateMemprofMetadata(ClonedCall, NewMIBList); +} + +// Update memprof related metadata (!memprof and !callsite) based on the +// inlining of Callee into the callsite at CB. The updates include merging the +// inlined callee's callsite metadata with that of the inlined call, +// and moving the subset of any memprof contexts to the inlined callee +// allocations if they match the new inlined call stack. +// FIXME: Replace memprof metadata with function attribute if all MIB end up +// having the same behavior. Do other context trimming/merging optimizations +// too. +static void +propagateMemProfMetadata(Function *Callee, CallBase &CB, + bool ContainsMemProfMetadata, + const ValueMap<const Value *, WeakTrackingVH> &VMap) { + MDNode *CallsiteMD = CB.getMetadata(LLVMContext::MD_callsite); + // Only need to update if the inlined callsite had callsite metadata, or if + // there was any memprof metadata inlined. + if (!CallsiteMD && !ContainsMemProfMetadata) + return; + + // Propagate metadata onto the cloned calls in the inlined callee. + for (const auto &Entry : VMap) { + // See if this is a call that has been inlined and remapped, and not + // simplified away in the process. + auto *OrigCall = dyn_cast_or_null<CallBase>(Entry.first); + auto *ClonedCall = dyn_cast_or_null<CallBase>(Entry.second); + if (!OrigCall || !ClonedCall) + continue; + // If the inlined callsite did not have any callsite metadata, then it isn't + // involved in any profiled call contexts, and we can remove any memprof + // metadata on the cloned call. + if (!CallsiteMD) { + removeMemProfMetadata(ClonedCall); + removeCallsiteMetadata(ClonedCall); + continue; + } + propagateMemProfHelper(OrigCall, ClonedCall, CallsiteMD); + } +} + /// When inlining a call site that has !llvm.mem.parallel_loop_access, /// !llvm.access.group, !alias.scope or !noalias metadata, that metadata should /// be propagated to all memory-accessing cloned instructions. @@ -911,7 +1041,7 @@ void ScopedAliasMetadataDeepCloner::clone() { SmallVector<TempMDTuple, 16> DummyNodes; for (const MDNode *I : MD) { - DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), None)); + DummyNodes.push_back(MDTuple::getTemporary(I->getContext(), std::nullopt)); MDMap[I].reset(DummyNodes.back().get()); } @@ -1061,13 +1191,13 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, IsFuncCall = true; if (CalleeAAR) { - FunctionModRefBehavior MRB = CalleeAAR->getModRefBehavior(Call); + MemoryEffects ME = CalleeAAR->getMemoryEffects(Call); // We'll retain this knowledge without additional metadata. - if (AAResults::onlyAccessesInaccessibleMem(MRB)) + if (ME.onlyAccessesInaccessibleMem()) continue; - if (AAResults::onlyAccessesArgPointees(MRB)) + if (ME.onlyAccessesArgPointees()) IsArgMemOnlyCall = true; } @@ -1307,23 +1437,26 @@ static void AddAlignmentAssumptions(CallBase &CB, InlineFunctionInfo &IFI) { Function *CalledFunc = CB.getCalledFunction(); for (Argument &Arg : CalledFunc->args()) { - unsigned Align = Arg.getType()->isPointerTy() ? Arg.getParamAlignment() : 0; - if (Align && !Arg.hasPassPointeeByValueCopyAttr() && !Arg.hasNUses(0)) { - if (!DTCalculated) { - DT.recalculate(*CB.getCaller()); - DTCalculated = true; - } - - // If we can already prove the asserted alignment in the context of the - // caller, then don't bother inserting the assumption. - Value *ArgVal = CB.getArgOperand(Arg.getArgNo()); - if (getKnownAlignment(ArgVal, DL, &CB, AC, &DT) >= Align) - continue; + if (!Arg.getType()->isPointerTy() || Arg.hasPassPointeeByValueCopyAttr() || + Arg.hasNUses(0)) + continue; + MaybeAlign Alignment = Arg.getParamAlign(); + if (!Alignment) + continue; - CallInst *NewAsmp = - IRBuilder<>(&CB).CreateAlignmentAssumption(DL, ArgVal, Align); - AC->registerAssumption(cast<AssumeInst>(NewAsmp)); + if (!DTCalculated) { + DT.recalculate(*CB.getCaller()); + DTCalculated = true; } + // If we can already prove the asserted alignment in the context of the + // caller, then don't bother inserting the assumption. + Value *ArgVal = CB.getArgOperand(Arg.getArgNo()); + if (getKnownAlignment(ArgVal, DL, &CB, AC, &DT) >= *Alignment) + continue; + + CallInst *NewAsmp = IRBuilder<>(&CB).CreateAlignmentAssumption( + DL, ArgVal, Alignment->value()); + AC->registerAssumption(cast<AssumeInst>(NewAsmp)); } } @@ -1423,7 +1556,7 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg, Instruction *TheCall, const Function *CalledFunc, InlineFunctionInfo &IFI, - unsigned ByValAlignment) { + MaybeAlign ByValAlignment) { assert(cast<PointerType>(Arg->getType()) ->isOpaqueOrPointeeTypeMatches(ByValType)); Function *Caller = TheCall->getFunction(); @@ -1436,7 +1569,7 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg, // If the byval argument has a specified alignment that is greater than the // passed in pointer, then we either have to round up the input pointer or // give up on this transformation. - if (ByValAlignment <= 1) // 0 = unspecified, 1 = no particular alignment. + if (ByValAlignment.valueOrOne() == 1) return Arg; AssumptionCache *AC = @@ -1444,8 +1577,8 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg, // If the pointer is already known to be sufficiently aligned, or if we can // round it up to a larger alignment, then we don't need a temporary. - if (getOrEnforceKnownAlignment(Arg, Align(ByValAlignment), DL, TheCall, - AC) >= ByValAlignment) + if (getOrEnforceKnownAlignment(Arg, *ByValAlignment, DL, TheCall, AC) >= + *ByValAlignment) return Arg; // Otherwise, we have to make a memcpy to get a safe alignment. This is bad @@ -1453,13 +1586,13 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg, } // Create the alloca. If we have DataLayout, use nice alignment. - Align Alignment(DL.getPrefTypeAlignment(ByValType)); + Align Alignment = DL.getPrefTypeAlign(ByValType); // If the byval had an alignment specified, we *must* use at least that // alignment, as it is required by the byval argument (and uses of the // pointer inside the callee). - if (ByValAlignment > 0) - Alignment = std::max(Alignment, Align(ByValAlignment)); + if (ByValAlignment) + Alignment = std::max(Alignment, *ByValAlignment); Value *NewAlloca = new AllocaInst(ByValType, DL.getAllocaAddrSpace(), nullptr, Alignment, @@ -1595,6 +1728,94 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI, } } +#undef DEBUG_TYPE +#define DEBUG_TYPE "assignment-tracking" +/// Find Alloca and linked DbgAssignIntrinsic for locals escaped by \p CB. +static at::StorageToVarsMap collectEscapedLocals(const DataLayout &DL, + const CallBase &CB) { + at::StorageToVarsMap EscapedLocals; + SmallPtrSet<const Value *, 4> SeenBases; + + LLVM_DEBUG( + errs() << "# Finding caller local variables escaped by callee\n"); + for (const Value *Arg : CB.args()) { + LLVM_DEBUG(errs() << "INSPECT: " << *Arg << "\n"); + if (!Arg->getType()->isPointerTy()) { + LLVM_DEBUG(errs() << " | SKIP: Not a pointer\n"); + continue; + } + + const Instruction *I = dyn_cast<Instruction>(Arg); + if (!I) { + LLVM_DEBUG(errs() << " | SKIP: Not result of instruction\n"); + continue; + } + + // Walk back to the base storage. + assert(Arg->getType()->isPtrOrPtrVectorTy()); + APInt TmpOffset(DL.getIndexTypeSizeInBits(Arg->getType()), 0, false); + const AllocaInst *Base = dyn_cast<AllocaInst>( + Arg->stripAndAccumulateConstantOffsets(DL, TmpOffset, true)); + if (!Base) { + LLVM_DEBUG(errs() << " | SKIP: Couldn't walk back to base storage\n"); + continue; + } + + assert(Base); + LLVM_DEBUG(errs() << " | BASE: " << *Base << "\n"); + // We only need to process each base address once - skip any duplicates. + if (!SeenBases.insert(Base).second) + continue; + + // Find all local variables associated with the backing storage. + for (auto *DAI : at::getAssignmentMarkers(Base)) { + // Skip variables from inlined functions - they are not local variables. + if (DAI->getDebugLoc().getInlinedAt()) + continue; + LLVM_DEBUG(errs() << " > DEF : " << *DAI << "\n"); + EscapedLocals[Base].insert(at::VarRecord(DAI)); + } + } + return EscapedLocals; +} + +static void trackInlinedStores(Function::iterator Start, Function::iterator End, + const CallBase &CB) { + LLVM_DEBUG(errs() << "trackInlinedStores into " + << Start->getParent()->getName() << " from " + << CB.getCalledFunction()->getName() << "\n"); + std::unique_ptr<DataLayout> DL = std::make_unique<DataLayout>(CB.getModule()); + at::trackAssignments(Start, End, collectEscapedLocals(*DL, CB), *DL); +} + +/// Update inlined instructions' DIAssignID metadata. We need to do this +/// otherwise a function inlined more than once into the same function +/// will cause DIAssignID to be shared by many instructions. +static void fixupAssignments(Function::iterator Start, Function::iterator End) { + // Map {Old, New} metadata. Not used directly - use GetNewID. + DenseMap<DIAssignID *, DIAssignID *> Map; + auto GetNewID = [&Map](Metadata *Old) { + DIAssignID *OldID = cast<DIAssignID>(Old); + if (DIAssignID *NewID = Map.lookup(OldID)) + return NewID; + DIAssignID *NewID = DIAssignID::getDistinct(OldID->getContext()); + Map[OldID] = NewID; + return NewID; + }; + // Loop over all the inlined instructions. If we find a DIAssignID + // attachment or use, replace it with a new version. + for (auto BBI = Start; BBI != End; ++BBI) { + for (Instruction &I : *BBI) { + if (auto *ID = I.getMetadata(LLVMContext::MD_DIAssignID)) + I.setMetadata(LLVMContext::MD_DIAssignID, GetNewID(ID)); + else if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I)) + DAI->setAssignId(GetNewID(DAI->getAssignID())); + } + } +} +#undef DEBUG_TYPE +#define DEBUG_TYPE "inline-function" + /// Update the block frequencies of the caller after a callee has been inlined. /// /// Each block cloned into the caller has its block frequency scaled by the @@ -1636,7 +1857,8 @@ static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap, BlockFrequencyInfo *CallerBFI) { if (CalleeEntryCount.isSynthetic() || CalleeEntryCount.getCount() < 1) return; - auto CallSiteCount = PSI ? PSI->getProfileCount(TheCall, CallerBFI) : None; + auto CallSiteCount = + PSI ? PSI->getProfileCount(TheCall, CallerBFI) : std::nullopt; int64_t CallCount = std::min(CallSiteCount.value_or(0), CalleeEntryCount.getCount()); updateProfileCallee(Callee, -CallCount, &VMap); @@ -1784,6 +2006,7 @@ inlineRetainOrClaimRVCalls(CallBase &CB, objcarc::ARCInstKind RVCallKind, /// exists in the instruction stream. Similarly this will inline a recursive /// function by one level. llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, + bool MergeAttributes, AAResults *CalleeAAR, bool InsertLifetime, Function *ForwardVarArgsTo) { @@ -1814,6 +2037,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, continue; if (Tag == LLVMContext::OB_clang_arc_attachedcall) continue; + if (Tag == LLVMContext::OB_kcfi) + continue; return InlineResult::failure("unsupported operand bundle"); } @@ -1874,7 +2099,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, if (CallerPersonality) { EHPersonality Personality = classifyEHPersonality(CallerPersonality); if (isScopedEHPersonality(Personality)) { - Optional<OperandBundleUse> ParentFunclet = + std::optional<OperandBundleUse> ParentFunclet = CB.getOperandBundle(LLVMContext::OB_funclet); if (ParentFunclet) CallSiteEHPad = cast<FuncletPadInst>(ParentFunclet->Inputs.front()); @@ -1963,7 +2188,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, if (CB.isByValArgument(ArgNo)) { ActualArg = HandleByValArgument(CB.getParamByValType(ArgNo), ActualArg, &CB, CalledFunc, IFI, - CalledFunc->getParamAlignment(ArgNo)); + CalledFunc->getParamAlign(ArgNo)); if (ActualArg != *AI) ByValInits.push_back( {ActualArg, (Value *)*AI, CB.getParamByValType(ArgNo)}); @@ -2019,7 +2244,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, HandleByValArgumentInit(Init.Ty, Init.Dst, Init.Src, Caller->getParent(), &*FirstNewBlock, IFI); - Optional<OperandBundleUse> ParentDeopt = + std::optional<OperandBundleUse> ParentDeopt = CB.getOperandBundle(LLVMContext::OB_deopt); if (ParentDeopt) { SmallVector<OperandBundleDef, 2> OpDefs; @@ -2077,6 +2302,15 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, fixupLineNumbers(Caller, FirstNewBlock, &CB, CalledFunc->getSubprogram() != nullptr); + if (isAssignmentTrackingEnabled(*Caller->getParent())) { + // Interpret inlined stores to caller-local variables as assignments. + trackInlinedStores(FirstNewBlock, Caller->end(), CB); + + // Update DIAssignID metadata attachments and uses so that they are + // unique to this inlined instance. + fixupAssignments(FirstNewBlock, Caller->end()); + } + // Now clone the inlined noalias scope metadata. SAMetadataCloner.clone(); SAMetadataCloner.remap(FirstNewBlock, Caller->end()); @@ -2088,6 +2322,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // function which feed into its return value. AddReturnAttributes(CB, VMap); + propagateMemProfMetadata(CalledFunc, CB, + InlinedFunctionInfo.ContainsMemProfMetadata, VMap); + // Propagate metadata on the callsite if necessary. PropagateCallSiteMetadata(CB, FirstNewBlock, Caller->end()); @@ -2096,7 +2333,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, for (BasicBlock &NewBlock : make_range(FirstNewBlock->getIterator(), Caller->end())) for (Instruction &I : NewBlock) - if (auto *II = dyn_cast<AssumeInst>(&I)) + if (auto *II = dyn_cast<CondGuardInst>(&I)) IFI.GetAssumptionCache(*Caller).registerAssumption(II); } @@ -2136,8 +2373,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Transfer all of the allocas over in a block. Using splice means // that the instructions aren't removed from the symbol table, then // reinserted. - Caller->getEntryBlock().getInstList().splice( - InsertPoint, FirstNewBlock->getInstList(), AI->getIterator(), I); + Caller->getEntryBlock().splice(InsertPoint, &*FirstNewBlock, + AI->getIterator(), I); } } @@ -2270,7 +2507,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, if (!AllocaTypeSize.isScalable() && AllocaArraySize != std::numeric_limits<uint64_t>::max() && std::numeric_limits<uint64_t>::max() / AllocaArraySize >= - AllocaTypeSize.getFixedSize()) { + AllocaTypeSize.getFixedValue()) { AllocaSize = ConstantInt::get(Type::getInt64Ty(AI->getContext()), AllocaArraySize * AllocaTypeSize); } @@ -2480,10 +2717,10 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // the calling basic block. if (Returns.size() == 1 && std::distance(FirstNewBlock, Caller->end()) == 1) { // Move all of the instructions right before the call. - OrigBB->getInstList().splice(CB.getIterator(), FirstNewBlock->getInstList(), - FirstNewBlock->begin(), FirstNewBlock->end()); + OrigBB->splice(CB.getIterator(), &*FirstNewBlock, FirstNewBlock->begin(), + FirstNewBlock->end()); // Remove the cloned basic block. - Caller->getBasicBlockList().pop_back(); + Caller->back().eraseFromParent(); // If the call site was an invoke instruction, add a branch to the normal // destination. @@ -2507,6 +2744,9 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Since we are now done with the return instruction, delete it also. Returns[0]->eraseFromParent(); + if (MergeAttributes) + AttributeFuncs::mergeAttributesForInlining(*Caller, *CalledFunc); + // We are now done with the inlining. return InlineResult::success(); } @@ -2556,9 +2796,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Now that the function is correct, make it a little bit nicer. In // particular, move the basic blocks inserted from the end of the function // into the space made by splitting the source basic block. - Caller->getBasicBlockList().splice(AfterCallBB->getIterator(), - Caller->getBasicBlockList(), FirstNewBlock, - Caller->end()); + Caller->splice(AfterCallBB->getIterator(), Caller, FirstNewBlock, + Caller->end()); // Handle all of the return instructions that we just cloned in, and eliminate // any users of the original call/invoke instruction. @@ -2618,8 +2857,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Splice the code from the return block into the block that it will return // to, which contains the code that was after the call. - AfterCallBB->getInstList().splice(AfterCallBB->begin(), - ReturnBB->getInstList()); + AfterCallBB->splice(AfterCallBB->begin(), ReturnBB); if (CreatedBranchToNormalDest) CreatedBranchToNormalDest->setDebugLoc(Returns[0]->getDebugLoc()); @@ -2649,13 +2887,13 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, // Splice the code entry block into calling block, right before the // unconditional branch. CalleeEntry->replaceAllUsesWith(OrigBB); // Update PHI nodes - OrigBB->getInstList().splice(Br->getIterator(), CalleeEntry->getInstList()); + OrigBB->splice(Br->getIterator(), CalleeEntry); // Remove the unconditional branch. - OrigBB->getInstList().erase(Br); + Br->eraseFromParent(); // Now we can remove the CalleeEntry block, which is now empty. - Caller->getBasicBlockList().erase(CalleeEntry); + CalleeEntry->eraseFromParent(); // If we inserted a phi node, check to see if it has a single value (e.g. all // the entries are the same or undef). If so, remove the PHI so it doesn't @@ -2670,5 +2908,8 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, } } + if (MergeAttributes) + AttributeFuncs::mergeAttributesForInlining(*Caller, *CalledFunc); + return InlineResult::success(); } |