Skip to content

Commit c672ba7

Browse files
authored
[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.
1 parent f4a4e2f commit c672ba7

19 files changed

+469
-60
lines changed

llvm/include/llvm/IR/DebugInfo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,12 @@ class DebugInfoFinder {
102102
/// Process a single instruction and collect debug info anchors.
103103
void processInstruction(const Module &M, const Instruction &I);
104104

105-
/// Process DbgVariableIntrinsic.
106-
void processVariable(const Module &M, const DbgVariableIntrinsic &DVI);
105+
/// Process a DILocalVariable.
106+
void processVariable(const Module &M, const DILocalVariable *DVI);
107107
/// Process debug info location.
108108
void processLocation(const Module &M, const DILocation *Loc);
109+
// Process a DPValue, much like a DbgVariableIntrinsic.
110+
void processDPValue(const Module &M, const DPValue &DPV);
109111

110112
/// Process subprogram.
111113
void processSubprogram(DISubprogram *SP);

llvm/lib/IR/DebugInfo.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,13 @@ void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {
205205
void DebugInfoFinder::processInstruction(const Module &M,
206206
const Instruction &I) {
207207
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
208-
processVariable(M, *DVI);
208+
processVariable(M, DVI->getVariable());
209209

210210
if (auto DbgLoc = I.getDebugLoc())
211211
processLocation(M, DbgLoc.get());
212+
213+
for (const DPValue &DPV : I.getDbgValueRange())
214+
processDPValue(M, DPV);
212215
}
213216

214217
void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
@@ -218,6 +221,11 @@ void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
218221
processLocation(M, Loc->getInlinedAt());
219222
}
220223

224+
void DebugInfoFinder::processDPValue(const Module &M, const DPValue &DPV) {
225+
processVariable(M, DPV.getVariable());
226+
processLocation(M, DPV.getDebugLoc().get());
227+
}
228+
221229
void DebugInfoFinder::processType(DIType *DT) {
222230
if (!addType(DT))
223231
return;
@@ -292,15 +300,7 @@ void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
292300
}
293301

294302
void DebugInfoFinder::processVariable(const Module &M,
295-
const DbgVariableIntrinsic &DVI) {
296-
auto *N = dyn_cast<MDNode>(DVI.getVariable());
297-
if (!N)
298-
return;
299-
300-
auto *DV = dyn_cast<DILocalVariable>(N);
301-
if (!DV)
302-
return;
303-
303+
const DILocalVariable *DV) {
304304
if (!NodesSeen.insert(DV).second)
305305
return;
306306
processScope(DV->getScope());

llvm/lib/Transforms/Scalar/CallSiteSplitting.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ static void splitCallSite(CallBase &CB,
402402
NewPN->insertBefore(&*TailBB->begin());
403403
CurrentI->replaceAllUsesWith(NewPN);
404404
}
405+
CurrentI->dropDbgValues();
405406
CurrentI->eraseFromParent();
406407
// We are done once we handled the first original instruction in TailBB.
407408
if (CurrentI == OriginalBegin)

llvm/lib/Transforms/Scalar/JumpThreading.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,8 +3118,8 @@ bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
31183118
if (!isa<PHINode>(&*BI))
31193119
ToRemove.push_back(&*BI);
31203120

3121-
Instruction *InsertionPoint = &*BB->getFirstInsertionPt();
3122-
assert(InsertionPoint && "Empty block?");
3121+
BasicBlock::iterator InsertionPoint = BB->getFirstInsertionPt();
3122+
assert(InsertionPoint != BB->end() && "Empty block?");
31233123
// Substitute with Phis & remove.
31243124
for (auto *Inst : reverse(ToRemove)) {
31253125
if (!Inst->use_empty()) {
@@ -3129,6 +3129,7 @@ bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
31293129
NewPN->insertBefore(InsertionPoint);
31303130
Inst->replaceAllUsesWith(NewPN);
31313131
}
3132+
Inst->dropDbgValues();
31323133
Inst->eraseFromParent();
31333134
}
31343135
return true;

llvm/lib/Transforms/Utils/CloneFunction.cpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
9494
const char *NameSuffix, ClonedCodeInfo *CodeInfo,
9595
ValueMapTypeRemapper *TypeMapper,
9696
ValueMaterializer *Materializer) {
97+
NewFunc->setIsNewDbgInfoFormat(OldFunc->IsNewDbgInfoFormat);
9798
assert(NameSuffix && "NameSuffix cannot be null!");
9899

99100
#ifndef NDEBUG
@@ -271,9 +272,13 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
271272
BB = cast<BasicBlock>(VMap[&OldFunc->front()])->getIterator(),
272273
BE = NewFunc->end();
273274
BB != BE; ++BB)
274-
// Loop over all instructions, fixing each one as we find it...
275-
for (Instruction &II : *BB)
275+
// Loop over all instructions, fixing each one as we find it, and any
276+
// attached debug-info records.
277+
for (Instruction &II : *BB) {
276278
RemapInstruction(&II, VMap, RemapFlag, TypeMapper, Materializer);
279+
RemapDPValueRange(II.getModule(), II.getDbgValueRange(), VMap, RemapFlag,
280+
TypeMapper, Materializer);
281+
}
277282

278283
// Only update !llvm.dbg.cu for DifferentModule (not CloneModule). In the
279284
// same module, the compile unit will already be listed (or not). When
@@ -331,6 +336,7 @@ Function *llvm::CloneFunction(Function *F, ValueToValueMapTy &VMap,
331336
// Create the new function...
332337
Function *NewF = Function::Create(FTy, F->getLinkage(), F->getAddressSpace(),
333338
F->getName(), F->getParent());
339+
NewF->setIsNewDbgInfoFormat(F->IsNewDbgInfoFormat);
334340

335341
// Loop over the arguments, copying the names of the mapped arguments over...
336342
Function::arg_iterator DestI = NewF->arg_begin();
@@ -496,6 +502,22 @@ void PruningFunctionCloner::CloneBlock(
496502
bool hasCalls = false, hasDynamicAllocas = false, hasStaticAllocas = false;
497503
bool hasMemProfMetadata = false;
498504

505+
// Keep a cursor pointing at the last place we cloned debug-info records from.
506+
BasicBlock::const_iterator DbgCursor = StartingInst;
507+
auto CloneDbgRecordsToHere =
508+
[NewBB, &DbgCursor](Instruction *NewInst, BasicBlock::const_iterator II) {
509+
if (!NewBB->IsNewDbgInfoFormat)
510+
return;
511+
512+
// Clone debug-info records onto this instruction. Iterate through any
513+
// source-instructions we've cloned and then subsequently optimised
514+
// away, so that their debug-info doesn't go missing.
515+
for (; DbgCursor != II; ++DbgCursor)
516+
NewInst->cloneDebugInfoFrom(&*DbgCursor, std::nullopt, false);
517+
NewInst->cloneDebugInfoFrom(&*II);
518+
DbgCursor = std::next(II);
519+
};
520+
499521
// Loop over all instructions, and copy them over, DCE'ing as we go. This
500522
// loop doesn't include the terminator.
501523
for (BasicBlock::const_iterator II = StartingInst, IE = --BB->end(); II != IE;
@@ -545,6 +567,8 @@ void PruningFunctionCloner::CloneBlock(
545567
hasMemProfMetadata |= II->hasMetadata(LLVMContext::MD_memprof);
546568
}
547569

570+
CloneDbgRecordsToHere(NewInst, II);
571+
548572
if (CodeInfo) {
549573
CodeInfo->OrigVMap[&*II] = NewInst;
550574
if (auto *CB = dyn_cast<CallBase>(&*II))
@@ -602,6 +626,9 @@ void PruningFunctionCloner::CloneBlock(
602626
if (OldTI->hasName())
603627
NewInst->setName(OldTI->getName() + NameSuffix);
604628
NewInst->insertInto(NewBB, NewBB->end());
629+
630+
CloneDbgRecordsToHere(NewInst, OldTI->getIterator());
631+
605632
VMap[OldTI] = NewInst; // Add instruction map to value.
606633

607634
if (CodeInfo) {
@@ -613,6 +640,13 @@ void PruningFunctionCloner::CloneBlock(
613640

614641
// Recursively clone any reachable successor blocks.
615642
append_range(ToClone, successors(BB->getTerminator()));
643+
} else {
644+
// If we didn't create a new terminator, clone DPValues from the old
645+
// terminator onto the new terminator.
646+
Instruction *NewInst = NewBB->getTerminator();
647+
assert(NewInst);
648+
649+
CloneDbgRecordsToHere(NewInst, OldTI->getIterator());
616650
}
617651

618652
if (CodeInfo) {
@@ -850,12 +884,22 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
850884
TypeMapper, Materializer);
851885
}
852886

887+
// Do the same for DPValues, touching all the instructions in the cloned
888+
// range of blocks.
889+
Function::iterator Begin = cast<BasicBlock>(VMap[StartingBB])->getIterator();
890+
for (BasicBlock &BB : make_range(Begin, NewFunc->end())) {
891+
for (Instruction &I : BB) {
892+
RemapDPValueRange(I.getModule(), I.getDbgValueRange(), VMap,
893+
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
894+
TypeMapper, Materializer);
895+
}
896+
}
897+
853898
// Simplify conditional branches and switches with a constant operand. We try
854899
// to prune these out when cloning, but if the simplification required
855900
// looking through PHI nodes, those are only available after forming the full
856901
// basic block. That may leave some here, and we still want to prune the dead
857902
// code as early as possible.
858-
Function::iterator Begin = cast<BasicBlock>(VMap[StartingBB])->getIterator();
859903
for (BasicBlock &BB : make_range(Begin, NewFunc->end()))
860904
ConstantFoldTerminator(&BB);
861905

@@ -944,10 +988,15 @@ void llvm::CloneAndPruneFunctionInto(
944988
void llvm::remapInstructionsInBlocks(ArrayRef<BasicBlock *> Blocks,
945989
ValueToValueMapTy &VMap) {
946990
// Rewrite the code to refer to itself.
947-
for (auto *BB : Blocks)
948-
for (auto &Inst : *BB)
991+
for (auto *BB : Blocks) {
992+
Module *M = BB->getModule();
993+
for (auto &Inst : *BB) {
994+
RemapDPValueRange(Inst.getModule(), Inst.getDbgValueRange(), VMap,
995+
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
949996
RemapInstruction(&Inst, VMap,
950997
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
998+
}
999+
}
9511000
}
9521001

9531002
/// Clones a loop \p OrigLoop. Returns the loop and the blocks in \p
@@ -1071,6 +1120,7 @@ BasicBlock *llvm::DuplicateInstructionsInSplitBetween(
10711120
Instruction *New = BI->clone();
10721121
New->setName(BI->getName());
10731122
New->insertBefore(NewTerm);
1123+
New->cloneDebugInfoFrom(&*BI);
10741124
ValueMapping[&*BI] = New;
10751125

10761126
// Remap operands to patch up intra-block references.

llvm/lib/Transforms/Utils/CloneModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ std::unique_ptr<Module> llvm::CloneModule(
6161
New->setDataLayout(M.getDataLayout());
6262
New->setTargetTriple(M.getTargetTriple());
6363
New->setModuleInlineAsm(M.getModuleInlineAsm());
64+
New->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
6465

6566
// Loop over all of the global variables, making corresponding globals in the
6667
// new module. Here we add them to the VMap and to the new Module. We

llvm/lib/Transforms/Utils/InlineFunction.cpp

Lines changed: 63 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,48 +1666,71 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
16661666
// the call site location instead.
16671667
bool NoInlineLineTables = Fn->hasFnAttribute("no-inline-line-tables");
16681668

1669-
for (; FI != Fn->end(); ++FI) {
1670-
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end();
1671-
BI != BE; ++BI) {
1672-
// Loop metadata needs to be updated so that the start and end locs
1673-
// reference inlined-at locations.
1674-
auto updateLoopInfoLoc = [&Ctx, &InlinedAtNode,
1675-
&IANodes](Metadata *MD) -> Metadata * {
1676-
if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
1677-
return inlineDebugLoc(Loc, InlinedAtNode, Ctx, IANodes).get();
1678-
return MD;
1679-
};
1680-
updateLoopMetadataDebugLocations(*BI, updateLoopInfoLoc);
1681-
1682-
if (!NoInlineLineTables)
1683-
if (DebugLoc DL = BI->getDebugLoc()) {
1684-
DebugLoc IDL =
1685-
inlineDebugLoc(DL, InlinedAtNode, BI->getContext(), IANodes);
1686-
BI->setDebugLoc(IDL);
1687-
continue;
1688-
}
1669+
// Helper-util for updating the metadata attached to an instruction.
1670+
auto UpdateInst = [&](Instruction &I) {
1671+
// Loop metadata needs to be updated so that the start and end locs
1672+
// reference inlined-at locations.
1673+
auto updateLoopInfoLoc = [&Ctx, &InlinedAtNode,
1674+
&IANodes](Metadata *MD) -> Metadata * {
1675+
if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
1676+
return inlineDebugLoc(Loc, InlinedAtNode, Ctx, IANodes).get();
1677+
return MD;
1678+
};
1679+
updateLoopMetadataDebugLocations(I, updateLoopInfoLoc);
1680+
1681+
if (!NoInlineLineTables)
1682+
if (DebugLoc DL = I.getDebugLoc()) {
1683+
DebugLoc IDL =
1684+
inlineDebugLoc(DL, InlinedAtNode, I.getContext(), IANodes);
1685+
I.setDebugLoc(IDL);
1686+
return;
1687+
}
16891688

1690-
if (CalleeHasDebugInfo && !NoInlineLineTables)
1691-
continue;
1689+
if (CalleeHasDebugInfo && !NoInlineLineTables)
1690+
return;
16921691

1693-
// If the inlined instruction has no line number, or if inline info
1694-
// is not being generated, make it look as if it originates from the call
1695-
// location. This is important for ((__always_inline, __nodebug__))
1696-
// functions which must use caller location for all instructions in their
1697-
// function body.
1692+
// If the inlined instruction has no line number, or if inline info
1693+
// is not being generated, make it look as if it originates from the call
1694+
// location. This is important for ((__always_inline, __nodebug__))
1695+
// functions which must use caller location for all instructions in their
1696+
// function body.
16981697

1699-
// Don't update static allocas, as they may get moved later.
1700-
if (auto *AI = dyn_cast<AllocaInst>(BI))
1701-
if (allocaWouldBeStaticInEntry(AI))
1702-
continue;
1698+
// Don't update static allocas, as they may get moved later.
1699+
if (auto *AI = dyn_cast<AllocaInst>(&I))
1700+
if (allocaWouldBeStaticInEntry(AI))
1701+
return;
17031702

1704-
// Do not force a debug loc for pseudo probes, since they do not need to
1705-
// be debuggable, and also they are expected to have a zero/null dwarf
1706-
// discriminator at this point which could be violated otherwise.
1707-
if (isa<PseudoProbeInst>(BI))
1708-
continue;
1703+
// Do not force a debug loc for pseudo probes, since they do not need to
1704+
// be debuggable, and also they are expected to have a zero/null dwarf
1705+
// discriminator at this point which could be violated otherwise.
1706+
if (isa<PseudoProbeInst>(I))
1707+
return;
1708+
1709+
I.setDebugLoc(TheCallDL);
1710+
};
17091711

1710-
BI->setDebugLoc(TheCallDL);
1712+
// Helper-util for updating debug-info records attached to instructions.
1713+
auto UpdateDPV = [&](DPValue *DPV) {
1714+
assert(DPV->getDebugLoc() && "Debug Value must have debug loc");
1715+
if (NoInlineLineTables) {
1716+
DPV->setDebugLoc(TheCallDL);
1717+
return;
1718+
}
1719+
DebugLoc DL = DPV->getDebugLoc();
1720+
DebugLoc IDL =
1721+
inlineDebugLoc(DL, InlinedAtNode,
1722+
DPV->getMarker()->getParent()->getContext(), IANodes);
1723+
DPV->setDebugLoc(IDL);
1724+
};
1725+
1726+
// Iterate over all instructions, updating metadata and debug-info records.
1727+
for (; FI != Fn->end(); ++FI) {
1728+
for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE;
1729+
++BI) {
1730+
UpdateInst(*BI);
1731+
for (DPValue &DPV : BI->getDbgValueRange()) {
1732+
UpdateDPV(&DPV);
1733+
}
17111734
}
17121735

17131736
// Remove debug info intrinsics if we're not keeping inline info.
@@ -1717,11 +1740,12 @@ static void fixupLineNumbers(Function *Fn, Function::iterator FI,
17171740
if (isa<DbgInfoIntrinsic>(BI)) {
17181741
BI = BI->eraseFromParent();
17191742
continue;
1743+
} else {
1744+
BI->dropDbgValues();
17201745
}
17211746
++BI;
17221747
}
17231748
}
1724-
17251749
}
17261750
}
17271751

@@ -2402,6 +2426,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
24022426
// Transfer all of the allocas over in a block. Using splice means
24032427
// that the instructions aren't removed from the symbol table, then
24042428
// reinserted.
2429+
I.setTailBit(true);
24052430
Caller->getEntryBlock().splice(InsertPoint, &*FirstNewBlock,
24062431
AI->getIterator(), I);
24072432
}

0 commit comments

Comments
 (0)