aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Transforms/Utils/InlineFunction.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp349
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();
}