Skip to content

Commit 1c6b0f7

Browse files
authored
[RemoveDI] Add support for debug records to debugify (#87383)
This patch changes debugify to support debug variable records, and subsequently to no longer convert modules automatically to intrinsics when entering debugify.
1 parent 38895e6 commit 1c6b0f7

17 files changed

+142
-73
lines changed

llvm/lib/CodeGen/MachineDebugify.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
6565
// all the others.
6666
Function *DbgValF = M.getFunction("llvm.dbg.value");
6767
DbgValueInst *EarliestDVI = nullptr;
68+
DbgVariableRecord *EarliestDVR = nullptr;
6869
DenseMap<unsigned, DILocalVariable *> Line2Var;
6970
DIExpression *Expr = nullptr;
7071
if (DbgValF) {
@@ -80,6 +81,20 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
8081
Expr = DVI->getExpression();
8182
}
8283
}
84+
for (BasicBlock &BB : F) {
85+
for (Instruction &I : BB) {
86+
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
87+
if (!DVR.isDbgValue())
88+
continue;
89+
unsigned Line = DVR.getDebugLoc().getLine();
90+
assert(Line != 0 && "debugify should not insert line 0 locations");
91+
Line2Var[Line] = DVR.getVariable();
92+
if (!EarliestDVR || Line < EarliestDVR->getDebugLoc().getLine())
93+
EarliestDVR = &DVR;
94+
Expr = DVR.getExpression();
95+
}
96+
}
97+
}
8398
if (Line2Var.empty())
8499
return true;
85100

@@ -109,7 +124,8 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
109124
// Find a suitable local variable for the DBG_VALUE.
110125
unsigned Line = MI.getDebugLoc().getLine();
111126
if (!Line2Var.count(Line))
112-
Line = EarliestDVI->getDebugLoc().getLine();
127+
Line = EarliestDVI ? EarliestDVI->getDebugLoc().getLine()
128+
: EarliestDVR->getDebugLoc().getLine();
113129
DILocalVariable *LocalVar = Line2Var[Line];
114130
assert(LocalVar && "No variable for current line?");
115131
VarSet.insert(LocalVar);

llvm/lib/Transforms/Utils/Debugify.cpp

Lines changed: 44 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,6 @@ bool llvm::applyDebugifyMetadata(
8787
return false;
8888
}
8989

90-
bool NewDebugMode = M.IsNewDbgInfoFormat;
91-
if (NewDebugMode)
92-
M.convertFromNewDbgValues();
93-
9490
DIBuilder DIB(M);
9591
LLVMContext &Ctx = M.getContext();
9692
auto *Int32Ty = Type::getInt32Ty(Ctx);
@@ -214,9 +210,6 @@ bool llvm::applyDebugifyMetadata(
214210
if (!M.getModuleFlag(DIVersionKey))
215211
M.addModuleFlag(Module::Warning, DIVersionKey, DEBUG_METADATA_VERSION);
216212

217-
if (NewDebugMode)
218-
M.convertToNewDbgValues();
219-
220213
return true;
221214
}
222215

@@ -311,10 +304,6 @@ bool llvm::collectDebugInfoMetadata(Module &M,
311304
return false;
312305
}
313306

314-
bool NewDebugMode = M.IsNewDbgInfoFormat;
315-
if (NewDebugMode)
316-
M.convertFromNewDbgValues();
317-
318307
uint64_t FunctionsCnt = DebugInfoBeforePass.DIFunctions.size();
319308
// Visit each instruction.
320309
for (Function &F : Functions) {
@@ -349,20 +338,23 @@ bool llvm::collectDebugInfoMetadata(Module &M,
349338

350339
// Cllect dbg.values and dbg.declare.
351340
if (DebugifyLevel > Level::Locations) {
352-
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
341+
auto HandleDbgVariable = [&](auto *DbgVar) {
353342
if (!SP)
354-
continue;
343+
return;
355344
// Skip inlined variables.
356-
if (I.getDebugLoc().getInlinedAt())
357-
continue;
345+
if (DbgVar->getDebugLoc().getInlinedAt())
346+
return;
358347
// Skip undef values.
359-
if (DVI->isKillLocation())
360-
continue;
348+
if (DbgVar->isKillLocation())
349+
return;
361350

362-
auto *Var = DVI->getVariable();
351+
auto *Var = DbgVar->getVariable();
363352
DebugInfoBeforePass.DIVariables[Var]++;
364-
continue;
365-
}
353+
};
354+
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
355+
HandleDbgVariable(&DVR);
356+
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
357+
HandleDbgVariable(DVI);
366358
}
367359

368360
// Skip debug instructions other than dbg.value and dbg.declare.
@@ -379,9 +371,6 @@ bool llvm::collectDebugInfoMetadata(Module &M,
379371
}
380372
}
381373

382-
if (NewDebugMode)
383-
M.convertToNewDbgValues();
384-
385374
return true;
386375
}
387376

@@ -561,10 +550,6 @@ bool llvm::checkDebugInfoMetadata(Module &M,
561550
return false;
562551
}
563552

564-
bool NewDebugMode = M.IsNewDbgInfoFormat;
565-
if (NewDebugMode)
566-
M.convertFromNewDbgValues();
567-
568553
// Map the debug info holding DIs after a pass.
569554
DebugInfoPerPass DebugInfoAfterPass;
570555

@@ -599,20 +584,23 @@ bool llvm::checkDebugInfoMetadata(Module &M,
599584

600585
// Collect dbg.values and dbg.declares.
601586
if (DebugifyLevel > Level::Locations) {
602-
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
587+
auto HandleDbgVariable = [&](auto *DbgVar) {
603588
if (!SP)
604-
continue;
589+
return;
605590
// Skip inlined variables.
606-
if (I.getDebugLoc().getInlinedAt())
607-
continue;
591+
if (DbgVar->getDebugLoc().getInlinedAt())
592+
return;
608593
// Skip undef values.
609-
if (DVI->isKillLocation())
610-
continue;
594+
if (DbgVar->isKillLocation())
595+
return;
611596

612-
auto *Var = DVI->getVariable();
597+
auto *Var = DbgVar->getVariable();
613598
DebugInfoAfterPass.DIVariables[Var]++;
614-
continue;
615-
}
599+
};
600+
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
601+
HandleDbgVariable(&DVR);
602+
if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
603+
HandleDbgVariable(DVI);
616604
}
617605

618606
// Skip debug instructions other than dbg.value and dbg.declare.
@@ -675,16 +663,14 @@ bool llvm::checkDebugInfoMetadata(Module &M,
675663
// the debugging information from the previous pass.
676664
DebugInfoBeforePass = DebugInfoAfterPass;
677665

678-
if (NewDebugMode)
679-
M.convertToNewDbgValues();
680-
681666
LLVM_DEBUG(dbgs() << "\n\n");
682667
return Result;
683668
}
684669

685670
namespace {
686-
/// Return true if a mis-sized diagnostic is issued for \p DVI.
687-
bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
671+
/// Return true if a mis-sized diagnostic is issued for \p DbgVal.
672+
template <typename DbgValTy>
673+
bool diagnoseMisSizedDbgValue(Module &M, DbgValTy *DbgVal) {
688674
// The size of a dbg.value's value operand should match the size of the
689675
// variable it corresponds to.
690676
//
@@ -693,22 +679,22 @@ bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
693679

694680
// For now, don't try to interpret anything more complicated than an empty
695681
// DIExpression. Eventually we should try to handle OP_deref and fragments.
696-
if (DVI->getExpression()->getNumElements())
682+
if (DbgVal->getExpression()->getNumElements())
697683
return false;
698684

699-
Value *V = DVI->getVariableLocationOp(0);
685+
Value *V = DbgVal->getVariableLocationOp(0);
700686
if (!V)
701687
return false;
702688

703689
Type *Ty = V->getType();
704690
uint64_t ValueOperandSize = getAllocSizeInBits(M, Ty);
705-
std::optional<uint64_t> DbgVarSize = DVI->getFragmentSizeInBits();
691+
std::optional<uint64_t> DbgVarSize = DbgVal->getFragmentSizeInBits();
706692
if (!ValueOperandSize || !DbgVarSize)
707693
return false;
708694

709695
bool HasBadSize = false;
710696
if (Ty->isIntegerTy()) {
711-
auto Signedness = DVI->getVariable()->getSignedness();
697+
auto Signedness = DbgVal->getVariable()->getSignedness();
712698
if (Signedness && *Signedness == DIBasicType::Signedness::Signed)
713699
HasBadSize = ValueOperandSize < *DbgVarSize;
714700
} else {
@@ -718,7 +704,7 @@ bool diagnoseMisSizedDbgValue(Module &M, DbgValueInst *DVI) {
718704
if (HasBadSize) {
719705
dbg() << "ERROR: dbg.value operand has size " << ValueOperandSize
720706
<< ", but its variable has size " << *DbgVarSize << ": ";
721-
DVI->print(dbg());
707+
DbgVal->print(dbg());
722708
dbg() << "\n";
723709
}
724710
return HasBadSize;
@@ -735,10 +721,6 @@ bool checkDebugifyMetadata(Module &M,
735721
return false;
736722
}
737723

738-
bool NewDebugMode = M.IsNewDbgInfoFormat;
739-
if (NewDebugMode)
740-
M.convertFromNewDbgValues();
741-
742724
auto getDebugifyOperand = [&](unsigned Idx) -> unsigned {
743725
return mdconst::extract<ConstantInt>(NMD->getOperand(Idx)->getOperand(0))
744726
->getZExtValue();
@@ -780,18 +762,23 @@ bool checkDebugifyMetadata(Module &M,
780762
}
781763

782764
// Find missing variables and mis-sized debug values.
783-
for (Instruction &I : instructions(F)) {
784-
auto *DVI = dyn_cast<DbgValueInst>(&I);
785-
if (!DVI)
786-
continue;
787-
765+
auto CheckForMisSized = [&](auto *DbgVal) {
788766
unsigned Var = ~0U;
789-
(void)to_integer(DVI->getVariable()->getName(), Var, 10);
767+
(void)to_integer(DbgVal->getVariable()->getName(), Var, 10);
790768
assert(Var <= OriginalNumVars && "Unexpected name for DILocalVariable");
791-
bool HasBadSize = diagnoseMisSizedDbgValue(M, DVI);
769+
bool HasBadSize = diagnoseMisSizedDbgValue(M, DbgVal);
792770
if (!HasBadSize)
793771
MissingVars.reset(Var - 1);
794772
HasErrors |= HasBadSize;
773+
};
774+
for (Instruction &I : instructions(F)) {
775+
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
776+
if (DVR.isDbgValue() || DVR.isDbgAssign())
777+
CheckForMisSized(&DVR);
778+
auto *DVI = dyn_cast<DbgValueInst>(&I);
779+
if (!DVI)
780+
continue;
781+
CheckForMisSized(DVI);
795782
}
796783
}
797784

@@ -820,9 +807,6 @@ bool checkDebugifyMetadata(Module &M,
820807
if (Strip)
821808
Ret = stripDebugifyMetadata(M);
822809

823-
if (NewDebugMode)
824-
M.convertToNewDbgValues();
825-
826810
return Ret;
827811
}
828812

@@ -1052,10 +1036,6 @@ FunctionPass *createCheckDebugifyFunctionPass(
10521036

10531037
PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
10541038
ModuleAnalysisManager &) {
1055-
bool NewDebugMode = M.IsNewDbgInfoFormat;
1056-
if (NewDebugMode)
1057-
M.convertFromNewDbgValues();
1058-
10591039
if (Mode == DebugifyMode::SyntheticDebugInfo)
10601040
checkDebugifyMetadata(M, M.functions(), NameOfWrappedPass,
10611041
"CheckModuleDebugify", Strip, StatsMap);
@@ -1065,9 +1045,6 @@ PreservedAnalyses NewPMCheckDebugifyPass::run(Module &M,
10651045
"CheckModuleDebugify (original debuginfo)", NameOfWrappedPass,
10661046
OrigDIVerifyBugsReportFilePath);
10671047

1068-
if (NewDebugMode)
1069-
M.convertToNewDbgValues();
1070-
10711048
return PreservedAnalyses::all();
10721049
}
10731050

llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables-x.mir

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# REQUIRES: x86-registered-target
22
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-check-debugify -o - %s 2>&1 | FileCheck %s
3+
# RUN: llc --experimental-debuginfo-iterators=false -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-check-debugify -o - %s 2>&1 | FileCheck %s
34
--- |
45
; ModuleID = 'check-line-and-variables.mir'
56
source_filename = "check-line-and-variables.c"

llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llc -debugify-check-and-strip-all-safe -o - %s 2>&1 | FileCheck %s
2+
; RUN: llc --experimental-debuginfo-iterators=false -debugify-check-and-strip-all-safe -o - %s 2>&1 | FileCheck %s
23

34
; ModuleID = 'main.c'
45
source_filename = "main.c"

llvm/test/CodeGen/Generic/MIRDebugify/check-line-and-variables.mir

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# REQUIRES: x86-registered-target
22
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,dead-mi-elimination,mir-check-debugify -o - %s 2>&1 | FileCheck %s
33
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,mir-check-debugify -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-PASS
4+
# RUN: llc --experimental-debuginfo-iterators=false -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,dead-mi-elimination,mir-check-debugify -o - %s 2>&1 | FileCheck %s
5+
# RUN: llc --experimental-debuginfo-iterators=false -mtriple=x86_64-unknown-linux-gnu -run-pass=mir-debugify,mir-check-debugify -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-PASS
46
--- |
57
; ModuleID = 'check-line-and-variables.mir'
68
source_filename = "check-line-and-variables.ll"

llvm/test/CodeGen/Generic/MIRDebugify/locations-and-values.mir

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
# RUN: llc -run-pass=mir-debugify -debugify-level=locations -o - %s | FileCheck --check-prefixes=ALL --implicit-check-not=dbg.value %s
33
# RUN: llc -run-pass=mir-debugify,mir-strip-debug,mir-debugify -o - %s | FileCheck --check-prefixes=ALL,VALUE %s
44
# RUN: llc -run-pass=mir-debugify,mir-strip-debug -o - %s | FileCheck --check-prefix=STRIP %s
5+
# RUN: llc --experimental-debuginfo-iterators=false -run-pass=mir-debugify -o - %s | FileCheck --check-prefixes=ALL,VALUE %s
6+
# RUN: llc --experimental-debuginfo-iterators=false -run-pass=mir-debugify -debugify-level=locations -o - %s | FileCheck --check-prefixes=ALL --implicit-check-not=dbg.value %s
7+
# RUN: llc --experimental-debuginfo-iterators=false -run-pass=mir-debugify,mir-strip-debug,mir-debugify -o - %s | FileCheck --check-prefixes=ALL,VALUE %s
8+
# RUN: llc --experimental-debuginfo-iterators=false -run-pass=mir-debugify,mir-strip-debug -o - %s | FileCheck --check-prefix=STRIP %s
59

610
--- |
711
; ModuleID = 'loc-only.ll'

llvm/test/CodeGen/Generic/MIRDebugify/multifunction-module.mir

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
# FIXME: Remove rm after a few weeks.
2-
# RUN: rm -f %S/multifunction-module.s
31
# RUN: llc -run-pass=mir-debugify,mir-check-debugify -o - %s 2>&1 | FileCheck %s
2+
# RUN: llc --experimental-debuginfo-iterators=false -run-pass=mir-debugify,mir-check-debugify -o - %s 2>&1 | FileCheck %s
43

54
# CHECK: Machine IR debug info check: PASS
65
# CHECK-NOT: Assertion `Var <= NumVars && "Unexpected name for DILocalVariable"'

llvm/test/DebugInfo/debugify-bogus-dbg-value.ll

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

34
define <2 x i64> @test-fun(<2 x i64> %A) !dbg !6 {
45
%and = and <2 x i64> %A, <i64 23, i64 42>, !dbg !14

llvm/test/DebugInfo/debugify-each.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,40 @@
4040
; RUN: opt -debugify-each -passes=globalopt -S -o /dev/null < %s 2> %t
4141
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS-ONE
4242

43+
; Repeat the same checks with debug intrinsics enabled.
44+
; RUN: opt --experimental-debuginfo-iterators=false -debugify-each -O3 -S -o /dev/null < %s 2> %t
45+
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS
46+
; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS
47+
; RUN: opt --experimental-debuginfo-iterators=false -disable-output -debugify-each -passes='default<O3>' %s 2> %t
48+
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS
49+
; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS
50+
51+
; RUN: opt --experimental-debuginfo-iterators=false -enable-debugify -debugify-each -O3 -S -o /dev/null < %s 2> %t
52+
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS
53+
; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS
54+
55+
; RUN: opt --experimental-debuginfo-iterators=false -debugify-each -passes='instrprof,instrprof,sroa,sccp' -S -o /dev/null < %s 2> %t
56+
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS
57+
; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS
58+
59+
; RUN: opt --experimental-debuginfo-iterators=false -debugify-each -O1 < %s | opt -O2 -o /dev/null
60+
61+
; RUN: opt --experimental-debuginfo-iterators=false -disable-output -debugify-quiet -debugify-each -O1 < %s 2>&1 | count 0
62+
63+
; RUN: opt --experimental-debuginfo-iterators=false -O1 < %s -S -o %t.before
64+
; RUN: opt --experimental-debuginfo-iterators=false -O1 -debugify-each < %s -S -o %t.after
65+
; RUN: diff %t.before %t.after
66+
67+
; RUN: opt --experimental-debuginfo-iterators=false -O1 < %s | llvm-dis -o %t.before
68+
; RUN: opt --experimental-debuginfo-iterators=false -O1 -debugify-each < %s | llvm-dis -o %t.after
69+
; RUN: diff %t.before %t.after
70+
71+
; RUN: opt --experimental-debuginfo-iterators=false -debugify-each -passes=instsimplify -S -o /dev/null < %s 2> %t
72+
; RUN: FileCheck %s -input-file=%t -check-prefix=FUNCTION-PASS-ONE
73+
74+
; RUN: opt --experimental-debuginfo-iterators=false -debugify-each -passes=globalopt -S -o /dev/null < %s 2> %t
75+
; RUN: FileCheck %s -input-file=%t -check-prefix=MODULE-PASS-ONE
76+
4377
define void @foo(i32 %arg) {
4478
call i32 asm "bswap $0", "=r,r"(i32 %arg)
4579
ret void

llvm/test/DebugInfo/debugify-export.ll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -passes=globalopt | FileCheck %s
22
; RUN: opt %s -disable-output -debugify-each -debugify-quiet -debugify-export - -passes=globalopt | FileCheck %s
33

4+
; RUN: opt --experimental-debuginfo-iterators=false %s -disable-output -debugify-each -debugify-quiet -debugify-export - -passes=globalopt | FileCheck %s
5+
; RUN: opt --experimental-debuginfo-iterators=false %s -disable-output -debugify-each -debugify-quiet -debugify-export - -passes=globalopt | FileCheck %s
6+
47
; CHECK: Pass Name
58
; CHECK-SAME: # of missing debug values
69
; CHECK-SAME: # of missing locations

0 commit comments

Comments
 (0)