aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse@sony.com>2023-11-26 21:24:29 +0000
committerGitHub <noreply@github.com>2023-11-26 21:24:29 +0000
commitc672ba7dde3a6ec2f6c89fcb207c9a6a8474cedc (patch)
treefcd978aedc24c8eb4b68251ad16cdda0310b5ba2 /llvm/lib/Transforms/Utils/InlineFunction.cpp
parentf4a4e2f85d819f44772b29c12a6cd2b86c14d611 (diff)
downloadllvm-c672ba7dde3a6ec2f6c89fcb207c9a6a8474cedc.zip
llvm-c672ba7dde3a6ec2f6c89fcb207c9a6a8474cedc.tar.gz
llvm-c672ba7dde3a6ec2f6c89fcb207c9a6a8474cedc.tar.bz2
[DebugInfo][RemoveDIs] Instrument inliner for non-instr debug-info (#72884)
With intrinsics representing debug-info, we just clone all the intrinsics when inlining a function and don't think about it any further. With non-instruction debug-info however we need to be a bit more careful and manually move the debug-info from one place to another. For the most part, this means keeping a "cursor" during block cloning of where we last copied debug-info from, and performing debug-info copying whenever we successfully clone another instruction. There are several utilities in LLVM for doing this, all of which now need to manually call cloneDebugInfo. The testing story for this is not well covered as we could rely on normal instruction-cloning mechanisms to do all the hard stuff. Thus, I've added a few tests to explicitly test dbg.value behaviours, ahead of them becoming not-instructions.
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/InlineFunction.cpp101
1 files changed, 63 insertions, 38 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp
index 6f36973..39d5f6e 100644
--- a/llvm/lib/Transforms/Utils/InlineFunction.cpp
+++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp
@@ -1666,48 +1666,71 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
// the call site location instead.
bool NoInlineLineTables = Fn->hasFnAttribute("no-inline-line-tables");
- for (; FI != Fn->end(); ++FI) {
- for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
- BI != BE; ++BI) {
- // Loop metadata needs to be updated so that the start and end locs
- // reference inlined-at locations.
- auto updateLoopInfoLoc = [&Ctx, &InlinedAtNode,
- &IANodes](Metadata *MD) -> Metadata * {
- if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
- return inlineDebugLoc(Loc, InlinedAtNode, Ctx, IANodes).get();
- return MD;
- };
- updateLoopMetadataDebugLocations(*BI, updateLoopInfoLoc);
-
- if (!NoInlineLineTables)
- if (DebugLoc DL = BI->getDebugLoc()) {
- DebugLoc IDL =
- inlineDebugLoc(DL, InlinedAtNode, BI->getContext(), IANodes);
- BI->setDebugLoc(IDL);
- continue;
- }
+ // Helper-util for updating the metadata attached to an instruction.
+ auto UpdateInst = [&](Instruction &I) {
+ // Loop metadata needs to be updated so that the start and end locs
+ // reference inlined-at locations.
+ auto updateLoopInfoLoc = [&Ctx, &InlinedAtNode,
+ &IANodes](Metadata *MD) -> Metadata * {
+ if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
+ return inlineDebugLoc(Loc, InlinedAtNode, Ctx, IANodes).get();
+ return MD;
+ };
+ updateLoopMetadataDebugLocations(I, updateLoopInfoLoc);
+
+ if (!NoInlineLineTables)
+ if (DebugLoc DL = I.getDebugLoc()) {
+ DebugLoc IDL =
+ inlineDebugLoc(DL, InlinedAtNode, I.getContext(), IANodes);
+ I.setDebugLoc(IDL);
+ return;
+ }
- if (CalleeHasDebugInfo && !NoInlineLineTables)
- continue;
+ if (CalleeHasDebugInfo && !NoInlineLineTables)
+ return;
- // If the inlined instruction has no line number, or if inline info
- // is not being generated, make it look as if it originates from the call
- // location. This is important for ((__always_inline, __nodebug__))
- // functions which must use caller location for all instructions in their
- // function body.
+ // If the inlined instruction has no line number, or if inline info
+ // is not being generated, make it look as if it originates from the call
+ // location. This is important for ((__always_inline, __nodebug__))
+ // functions which must use caller location for all instructions in their
+ // function body.
- // Don't update static allocas, as they may get moved later.
- if (auto *AI = dyn_cast<AllocaInst>(BI))
- if (allocaWouldBeStaticInEntry(AI))
- continue;
+ // Don't update static allocas, as they may get moved later.
+ if (auto *AI = dyn_cast<AllocaInst>(&I))
+ if (allocaWouldBeStaticInEntry(AI))
+ return;
- // Do not force a debug loc for pseudo probes, since they do not need to
- // be debuggable, and also they are expected to have a zero/null dwarf
- // discriminator at this point which could be violated otherwise.
- if (isa<PseudoProbeInst>(BI))
- continue;
+ // Do not force a debug loc for pseudo probes, since they do not need to
+ // be debuggable, and also they are expected to have a zero/null dwarf
+ // discriminator at this point which could be violated otherwise.
+ if (isa<PseudoProbeInst>(I))
+ return;
+
+ I.setDebugLoc(TheCallDL);
+ };
- BI->setDebugLoc(TheCallDL);
+ // Helper-util for updating debug-info records attached to instructions.
+ auto UpdateDPV = [&](DPValue *DPV) {
+ assert(DPV->getDebugLoc() && "Debug Value must have debug loc");
+ if (NoInlineLineTables) {
+ DPV->setDebugLoc(TheCallDL);
+ return;
+ }
+ DebugLoc DL = DPV->getDebugLoc();
+ DebugLoc IDL =
+ inlineDebugLoc(DL, InlinedAtNode,
+ DPV->getMarker()->getParent()->getContext(), IANodes);
+ DPV->setDebugLoc(IDL);
+ };
+
+ // Iterate over all instructions, updating metadata and debug-info records.
+ for (; FI != Fn->end(); ++FI) {
+ for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
+ ++BI) {
+ UpdateInst(*BI);
+ for (DPValue &DPV : BI->getDbgValueRange()) {
+ UpdateDPV(&DPV);
+ }
}
// Remove debug info intrinsics if we're not keeping inline info.
@@ -1717,11 +1740,12 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
if (isa<DbgInfoIntrinsic>(BI)) {
BI = BI->eraseFromParent();
continue;
+ } else {
+ BI->dropDbgValues();
}
++BI;
}
}
-
}
}
@@ -2402,6 +2426,7 @@ 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.
+ I.setTailBit(true);
Caller->getEntryBlock().splice(InsertPoint, &*FirstNewBlock,
AI->getIterator(), I);
}