Skip to content

Commit 3bf72bf

Browse files
authored
[DebugInfo][RemoveDIs] Extract DPValues in CodeExtractor like dbg.values (#73252)
CodeExtractor shifts dbg.value intrinsics out of the region being extracted and updates them to be appropriate in the extracted function. With new non-intrinsic variable locations, we need to manually do this too, with DPValues. Most of this patch shifts and refactors some utilities in fixupDebugInfoPostExtraction so that we can add a single extra helper lambda that iterates over DPValues and applies update-utilities. We also have to assign the IsNewDbgInfoFormat flag in a bunch of places -- this normally gets set the moment you insert a block into a function (or function into a module), however a few blocks are constructed here before being inserted, thus we have to do some manual setup. Tested via LoopExtractor_alloca.ll, which invokes debugify.
1 parent b053359 commit 3bf72bf

File tree

2 files changed

+58
-24
lines changed

2 files changed

+58
-24
lines changed

llvm/lib/Transforms/Utils/CodeExtractor.cpp

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ void CodeExtractor::severSplitPHINodesOfExits(
768768
NewBB = BasicBlock::Create(ExitBB->getContext(),
769769
ExitBB->getName() + ".split",
770770
ExitBB->getParent(), ExitBB);
771+
NewBB->IsNewDbgInfoFormat = ExitBB->IsNewDbgInfoFormat;
771772
SmallVector<BasicBlock *, 4> Preds(predecessors(ExitBB));
772773
for (BasicBlock *PredBB : Preds)
773774
if (Blocks.count(PredBB))
@@ -889,6 +890,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
889890
Function *newFunction = Function::Create(
890891
funcType, GlobalValue::InternalLinkage, oldFunction->getAddressSpace(),
891892
oldFunction->getName() + "." + SuffixToUse, M);
893+
newFunction->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat;
892894

893895
// Inherit all of the target dependent attributes and white-listed
894896
// target independent attributes.
@@ -1505,10 +1507,14 @@ void CodeExtractor::calculateNewCallTerminatorWeights(
15051507
static void eraseDebugIntrinsicsWithNonLocalRefs(Function &F) {
15061508
for (Instruction &I : instructions(F)) {
15071509
SmallVector<DbgVariableIntrinsic *, 4> DbgUsers;
1508-
findDbgUsers(DbgUsers, &I);
1510+
SmallVector<DPValue *, 4> DPValues;
1511+
findDbgUsers(DbgUsers, &I, &DPValues);
15091512
for (DbgVariableIntrinsic *DVI : DbgUsers)
15101513
if (DVI->getFunction() != &F)
15111514
DVI->eraseFromParent();
1515+
for (DPValue *DPV : DPValues)
1516+
if (DPV->getFunction() != &F)
1517+
DPV->eraseFromParent();
15121518
}
15131519
}
15141520

@@ -1544,6 +1550,16 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
15441550
/*LineNo=*/0, SPType, /*ScopeLine=*/0, DINode::FlagZero, SPFlags);
15451551
NewFunc.setSubprogram(NewSP);
15461552

1553+
auto IsInvalidLocation = [&NewFunc](Value *Location) {
1554+
// Location is invalid if it isn't a constant or an instruction, or is an
1555+
// instruction but isn't in the new function.
1556+
if (!Location ||
1557+
(!isa<Constant>(Location) && !isa<Instruction>(Location)))
1558+
return true;
1559+
Instruction *LocationInst = dyn_cast<Instruction>(Location);
1560+
return LocationInst && LocationInst->getFunction() != &NewFunc;
1561+
};
1562+
15471563
// Debug intrinsics in the new function need to be updated in one of two
15481564
// ways:
15491565
// 1) They need to be deleted, because they describe a value in the old
@@ -1552,8 +1568,41 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
15521568
// point to a variable in the wrong scope.
15531569
SmallDenseMap<DINode *, DINode *> RemappedMetadata;
15541570
SmallVector<Instruction *, 4> DebugIntrinsicsToDelete;
1571+
SmallVector<DPValue *, 4> DPVsToDelete;
15551572
DenseMap<const MDNode *, MDNode *> Cache;
1573+
1574+
auto GetUpdatedDIVariable = [&](DILocalVariable *OldVar) {
1575+
DINode *&NewVar = RemappedMetadata[OldVar];
1576+
if (!NewVar) {
1577+
DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
1578+
*OldVar->getScope(), *NewSP, Ctx, Cache);
1579+
NewVar = DIB.createAutoVariable(
1580+
NewScope, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
1581+
OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
1582+
OldVar->getAlignInBits());
1583+
}
1584+
return cast<DILocalVariable>(NewVar);
1585+
};
1586+
1587+
auto UpdateDPValuesOnInst = [&](Instruction &I) -> void {
1588+
for (auto &DPV : I.getDbgValueRange()) {
1589+
// Apply the two updates that dbg.values get: invalid operands, and
1590+
// variable metadata fixup.
1591+
// FIXME: support dbg.assign form of DPValues.
1592+
if (any_of(DPV.location_ops(), IsInvalidLocation)) {
1593+
DPVsToDelete.push_back(&DPV);
1594+
continue;
1595+
}
1596+
if (!DPV.getDebugLoc().getInlinedAt())
1597+
DPV.setVariable(GetUpdatedDIVariable(DPV.getVariable()));
1598+
DPV.setDebugLoc(DebugLoc::replaceInlinedAtSubprogram(DPV.getDebugLoc(),
1599+
*NewSP, Ctx, Cache));
1600+
}
1601+
};
1602+
15561603
for (Instruction &I : instructions(NewFunc)) {
1604+
UpdateDPValuesOnInst(I);
1605+
15571606
auto *DII = dyn_cast<DbgInfoIntrinsic>(&I);
15581607
if (!DII)
15591608
continue;
@@ -1575,16 +1624,6 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
15751624
continue;
15761625
}
15771626

1578-
auto IsInvalidLocation = [&NewFunc](Value *Location) {
1579-
// Location is invalid if it isn't a constant or an instruction, or is an
1580-
// instruction but isn't in the new function.
1581-
if (!Location ||
1582-
(!isa<Constant>(Location) && !isa<Instruction>(Location)))
1583-
return true;
1584-
Instruction *LocationInst = dyn_cast<Instruction>(Location);
1585-
return LocationInst && LocationInst->getFunction() != &NewFunc;
1586-
};
1587-
15881627
auto *DVI = cast<DbgVariableIntrinsic>(DII);
15891628
// If any of the used locations are invalid, delete the intrinsic.
15901629
if (any_of(DVI->location_ops(), IsInvalidLocation)) {
@@ -1599,23 +1638,14 @@ static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
15991638
}
16001639
// If the variable was in the scope of the old function, i.e. it was not
16011640
// inlined, point the intrinsic to a fresh variable within the new function.
1602-
if (!DVI->getDebugLoc().getInlinedAt()) {
1603-
DILocalVariable *OldVar = DVI->getVariable();
1604-
DINode *&NewVar = RemappedMetadata[OldVar];
1605-
if (!NewVar) {
1606-
DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram(
1607-
*OldVar->getScope(), *NewSP, Ctx, Cache);
1608-
NewVar = DIB.createAutoVariable(
1609-
NewScope, OldVar->getName(), OldVar->getFile(), OldVar->getLine(),
1610-
OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero,
1611-
OldVar->getAlignInBits());
1612-
}
1613-
DVI->setVariable(cast<DILocalVariable>(NewVar));
1614-
}
1641+
if (!DVI->getDebugLoc().getInlinedAt())
1642+
DVI->setVariable(GetUpdatedDIVariable(DVI->getVariable()));
16151643
}
16161644

16171645
for (auto *DII : DebugIntrinsicsToDelete)
16181646
DII->eraseFromParent();
1647+
for (auto *DPV : DPVsToDelete)
1648+
DPV->getMarker()->MarkedInstr->dropOneDbgValue(DPV);
16191649
DIB.finalizeSubprogram(NewSP);
16201650

16211651
// Fix up the scope information attached to the line locations in the new
@@ -1721,11 +1751,14 @@ CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
17211751
BasicBlock *codeReplacer = BasicBlock::Create(header->getContext(),
17221752
"codeRepl", oldFunction,
17231753
header);
1754+
codeReplacer->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat;
17241755

17251756
// The new function needs a root node because other nodes can branch to the
17261757
// head of the region, but the entry node of a function cannot have preds.
17271758
BasicBlock *newFuncRoot = BasicBlock::Create(header->getContext(),
17281759
"newFuncRoot");
1760+
newFuncRoot->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat;
1761+
17291762
auto *BranchI = BranchInst::Create(header);
17301763
// If the original function has debug info, we have to add a debug location
17311764
// to the new branch instruction from the artificial entry block.

llvm/test/Transforms/CodeExtractor/LoopExtractor_alloca.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: opt -passes=debugify,loop-simplify,loop-extract -S < %s | FileCheck %s
2+
; RUN: opt -passes=debugify,loop-simplify,loop-extract -S < %s --try-experimental-debuginfo-iterators | FileCheck %s
23

34
; This tests 2 cases:
45
; 1. loop1 should be extracted into a function, without extracting %v1 alloca.

0 commit comments

Comments
 (0)