Skip to content

Commit 2e39b57

Browse files
committed
Reapply "[RemoveDIs] Print non-intrinsic debug info in textual IR output (#79281)"
This reapplication changes debug intrinsic declaration removal to only take place when printing final IR, so that the processing format of the Module does not affect the output. This reverts commit d128448.
1 parent f2bb6c4 commit 2e39b57

14 files changed

+245
-109
lines changed

Diff for: llvm/include/llvm/IR/Module.h

+12
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ class LLVM_EXTERNAL_VISIBILITY Module {
218218
/// \ref BasicBlock.
219219
bool IsNewDbgInfoFormat;
220220

221+
/// Used when printing this module in the new debug info format; removes all
222+
/// declarations of debug intrinsics that are replaced by non-intrinsic
223+
/// records in the new format.
224+
void removeDebugIntrinsicDeclarations();
225+
221226
/// \see BasicBlock::convertToNewDbgValues.
222227
void convertToNewDbgValues() {
223228
for (auto &F : *this) {
@@ -234,6 +239,13 @@ class LLVM_EXTERNAL_VISIBILITY Module {
234239
IsNewDbgInfoFormat = false;
235240
}
236241

242+
void setIsNewDbgInfoFormat(bool UseNewFormat) {
243+
if (UseNewFormat && !IsNewDbgInfoFormat)
244+
convertToNewDbgValues();
245+
else if (!UseNewFormat && IsNewDbgInfoFormat)
246+
convertFromNewDbgValues();
247+
}
248+
237249
/// The Module constructor. Note that there is no default constructor. You
238250
/// must provide a name for the module upon construction.
239251
explicit Module(StringRef ModuleID, LLVMContext& C);

Diff for: llvm/include/llvm/IR/PrintPasses.h

+19
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,25 @@ std::string doSystemDiff(StringRef Before, StringRef After,
7878
StringRef OldLineFormat, StringRef NewLineFormat,
7979
StringRef UnchangedLineFormat);
8080

81+
/// Used to temporarily set the debug info format of a function, module, or
82+
/// basic block for the duration of this object's lifetime, after which the
83+
/// prior state will be restored.
84+
template <typename T> class ScopedDbgInfoFormatSetter {
85+
T &Obj;
86+
bool OldState;
87+
88+
public:
89+
ScopedDbgInfoFormatSetter(T &Obj, bool NewState)
90+
: Obj(Obj), OldState(Obj.IsNewDbgInfoFormat) {
91+
Obj.setIsNewDbgInfoFormat(NewState);
92+
}
93+
~ScopedDbgInfoFormatSetter() { Obj.setIsNewDbgInfoFormat(OldState); }
94+
};
95+
96+
template <typename T>
97+
ScopedDbgInfoFormatSetter(T &Obj, bool NewState)
98+
-> ScopedDbgInfoFormatSetter<T>;
99+
81100
} // namespace llvm
82101

83102
#endif // LLVM_IR_PRINTPASSES_H

Diff for: llvm/lib/IR/AsmWriter.cpp

+32-43
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ class SlotTracker : public AbstractSlotTrackerStorage {
861861
/// Add all of the metadata from an instruction.
862862
void processInstructionMetadata(const Instruction &I);
863863

864-
/// Add all of the metadata from an instruction.
864+
/// Add all of the metadata from a DbgRecord.
865865
void processDbgRecordMetadata(const DbgRecord &DPV);
866866
};
867867

@@ -1140,6 +1140,9 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
11401140

11411141
void SlotTracker::processDbgRecordMetadata(const DbgRecord &DR) {
11421142
if (const DPValue *DPV = dyn_cast<const DPValue>(&DR)) {
1143+
// Process metadata used by DbgRecords; we only specifically care about the
1144+
// DILocalVariable, DILocation, and DIAssignID fields, as the Value and
1145+
// Expression fields should only be printed inline and so do not use a slot.
11431146
CreateMetadataSlot(DPV->getVariable());
11441147
if (DPV->isDbgAssign())
11451148
CreateMetadataSlot(DPV->getAssignID());
@@ -2703,6 +2706,7 @@ class AssemblyWriter {
27032706
void printDPValue(const DPValue &DPI);
27042707
void printDPLabel(const DPLabel &DPL);
27052708
void printDbgRecord(const DbgRecord &DPI);
2709+
void printDbgRecordLine(const DbgRecord &DPI);
27062710

27072711
void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
27082712
void printUseLists(const Function *F);
@@ -3885,9 +3889,6 @@ void AssemblyWriter::printTypeIdentities() {
38853889

38863890
/// printFunction - Print all aspects of a function.
38873891
void AssemblyWriter::printFunction(const Function *F) {
3888-
bool ConvertBack = F->IsNewDbgInfoFormat;
3889-
if (ConvertBack)
3890-
const_cast<Function *>(F)->convertFromNewDbgValues();
38913892
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
38923893

38933894
if (F->isMaterializable())
@@ -4030,8 +4031,6 @@ void AssemblyWriter::printFunction(const Function *F) {
40304031
Out << "}\n";
40314032
}
40324033

4033-
if (ConvertBack)
4034-
const_cast<Function *>(F)->convertToNewDbgValues();
40354034
Machine.purgeFunction();
40364035
}
40374036

@@ -4098,6 +4097,8 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
40984097

40994098
// Output all of the instructions in the basic block...
41004099
for (const Instruction &I : *BB) {
4100+
for (const DbgRecord &DR : I.getDbgValueRange())
4101+
printDbgRecordLine(DR);
41014102
printInstructionLine(I);
41024103
}
41034104

@@ -4611,12 +4612,10 @@ void AssemblyWriter::printDbgRecord(const DbgRecord &DR) {
46114612
llvm_unreachable("Unexpected DbgRecord kind");
46124613
}
46134614

4614-
void AssemblyWriter::printDPValue(const DPValue &Value) {
4615-
// There's no formal representation of a DPValue -- print purely as a
4616-
// debugging aid.
4617-
Out << " DPValue ";
4618-
4619-
switch (Value.getType()) {
4615+
void AssemblyWriter::printDPValue(const DPValue &DPV) {
4616+
auto WriterCtx = getContext();
4617+
Out << "#dbg_";
4618+
switch (DPV.getType()) {
46204619
case DPValue::LocationType::Value:
46214620
Out << "value";
46224621
break;
@@ -4629,35 +4628,39 @@ void AssemblyWriter::printDPValue(const DPValue &Value) {
46294628
default:
46304629
llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
46314630
}
4632-
Out << " { ";
4633-
auto WriterCtx = getContext();
4634-
WriteAsOperandInternal(Out, Value.getRawLocation(), WriterCtx, true);
4631+
Out << "(";
4632+
WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true);
46354633
Out << ", ";
4636-
WriteAsOperandInternal(Out, Value.getVariable(), WriterCtx, true);
4634+
WriteAsOperandInternal(Out, DPV.getVariable(), WriterCtx, true);
46374635
Out << ", ";
4638-
WriteAsOperandInternal(Out, Value.getExpression(), WriterCtx, true);
4636+
WriteAsOperandInternal(Out, DPV.getExpression(), WriterCtx, true);
46394637
Out << ", ";
4640-
if (Value.isDbgAssign()) {
4641-
WriteAsOperandInternal(Out, Value.getAssignID(), WriterCtx, true);
4638+
if (DPV.isDbgAssign()) {
4639+
WriteAsOperandInternal(Out, DPV.getAssignID(), WriterCtx, true);
46424640
Out << ", ";
4643-
WriteAsOperandInternal(Out, Value.getRawAddress(), WriterCtx, true);
4641+
WriteAsOperandInternal(Out, DPV.getRawAddress(), WriterCtx, true);
46444642
Out << ", ";
4645-
WriteAsOperandInternal(Out, Value.getAddressExpression(), WriterCtx, true);
4643+
WriteAsOperandInternal(Out, DPV.getAddressExpression(), WriterCtx, true);
46464644
Out << ", ";
46474645
}
4648-
WriteAsOperandInternal(Out, Value.getDebugLoc().get(), WriterCtx, true);
4649-
Out << " marker @" << Value.getMarker();
4650-
Out << " }";
4646+
WriteAsOperandInternal(Out, DPV.getDebugLoc().getAsMDNode(), WriterCtx, true);
4647+
Out << ")";
4648+
}
4649+
4650+
/// printDbgRecordLine - Print a DbgRecord with indentation and a newline
4651+
/// character.
4652+
void AssemblyWriter::printDbgRecordLine(const DbgRecord &DR) {
4653+
// Print lengthier indentation to bring out-of-line with instructions.
4654+
Out << " ";
4655+
printDbgRecord(DR);
4656+
Out << '\n';
46514657
}
46524658

46534659
void AssemblyWriter::printDPLabel(const DPLabel &Label) {
4654-
// There's no formal representation of a DPLabel -- print purely as
4655-
// a debugging aid.
4656-
Out << " DPLabel { ";
46574660
auto WriterCtx = getContext();
4661+
Out << "#dbg_label(";
46584662
WriteAsOperandInternal(Out, Label.getLabel(), WriterCtx, true);
4659-
Out << " marker @" << Label.getMarker();
4660-
Out << " }";
4663+
Out << ")";
46614664
}
46624665

46634666
void AssemblyWriter::printMetadataAttachments(
@@ -4805,19 +4808,11 @@ void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
48054808

48064809
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
48074810
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
4808-
// RemoveDIs: always print with debug-info in intrinsic format.
4809-
bool ConvertAfter = IsNewDbgInfoFormat;
4810-
if (IsNewDbgInfoFormat)
4811-
const_cast<Module *>(this)->convertFromNewDbgValues();
4812-
48134811
SlotTracker SlotTable(this);
48144812
formatted_raw_ostream OS(ROS);
48154813
AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
48164814
ShouldPreserveUseListOrder);
48174815
W.printModule(this);
4818-
4819-
if (ConvertAfter)
4820-
const_cast<Module *>(this)->convertToNewDbgValues();
48214816
}
48224817

48234818
void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
@@ -4908,8 +4903,6 @@ void DPValue::print(raw_ostream &ROS, bool IsForDebug) const {
49084903

49094904
void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
49104905
bool IsForDebug) const {
4911-
// There's no formal representation of a DPMarker -- print purely as a
4912-
// debugging aid.
49134906
formatted_raw_ostream OS(ROS);
49144907
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
49154908
SlotTracker &SlotTable =
@@ -4931,8 +4924,6 @@ void DPLabel::print(raw_ostream &ROS, bool IsForDebug) const {
49314924

49324925
void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
49334926
bool IsForDebug) const {
4934-
// There's no formal representation of a DPValue -- print purely as a
4935-
// debugging aid.
49364927
formatted_raw_ostream OS(ROS);
49374928
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
49384929
SlotTracker &SlotTable =
@@ -4950,8 +4941,6 @@ void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
49504941

49514942
void DPLabel::print(raw_ostream &ROS, ModuleSlotTracker &MST,
49524943
bool IsForDebug) const {
4953-
// There's no formal representation of a DbgLabelRecord -- print purely as
4954-
// a debugging aid.
49554944
formatted_raw_ostream OS(ROS);
49564945
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
49574946
SlotTracker &SlotTable =

Diff for: llvm/lib/IR/BasicBlock.cpp

-4
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,6 @@ DPMarker *BasicBlock::createMarker(InstListType::iterator It) {
6161
}
6262

6363
void BasicBlock::convertToNewDbgValues() {
64-
// Is the command line option set?
65-
if (!UseNewDbgInfoFormat)
66-
return;
67-
6864
IsNewDbgInfoFormat = true;
6965

7066
// Iterate over all instructions in the instruction list, collecting dbg.value

Diff for: llvm/lib/IR/IRPrintingPasses.cpp

+16-16
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323

2424
using namespace llvm;
2525

26+
cl::opt<bool> WriteNewDbgInfoFormat(
27+
"write-experimental-debuginfo",
28+
cl::desc("Write debug info in the new non-intrinsic format"),
29+
cl::init(false));
30+
2631
namespace {
2732

2833
class PrintModulePassWrapper : public ModulePass {
@@ -39,11 +44,14 @@ class PrintModulePassWrapper : public ModulePass {
3944
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
4045

4146
bool runOnModule(Module &M) override {
42-
// RemoveDIs: there's no textual representation of the DPValue debug-info,
43-
// convert to dbg.values before writing out.
44-
bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
45-
if (IsNewDbgInfoFormat)
46-
M.convertFromNewDbgValues();
47+
// RemoveDIs: Regardless of the format we've processed this module in, use
48+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
49+
ScopedDbgInfoFormatSetter FormatSetter(M, WriteNewDbgInfoFormat);
50+
// Remove intrinsic declarations when printing in the new format.
51+
// TODO: Move this into Module::setIsNewDbgInfoFormat when we're ready to
52+
// update test output.
53+
if (WriteNewDbgInfoFormat)
54+
M.removeDebugIntrinsicDeclarations();
4755

4856
if (llvm::isFunctionInPrintList("*")) {
4957
if (!Banner.empty())
@@ -62,9 +70,6 @@ class PrintModulePassWrapper : public ModulePass {
6270
}
6371
}
6472

65-
if (IsNewDbgInfoFormat)
66-
M.convertToNewDbgValues();
67-
6873
return false;
6974
}
7075

@@ -87,11 +92,9 @@ class PrintFunctionPassWrapper : public FunctionPass {
8792

8893
// This pass just prints a banner followed by the function as it's processed.
8994
bool runOnFunction(Function &F) override {
90-
// RemoveDIs: there's no textual representation of the DPValue debug-info,
91-
// convert to dbg.values before writing out.
92-
bool IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
93-
if (IsNewDbgInfoFormat)
94-
F.convertFromNewDbgValues();
95+
// RemoveDIs: Regardless of the format we've processed this function in, use
96+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
97+
ScopedDbgInfoFormatSetter FormatSetter(F, WriteNewDbgInfoFormat);
9598

9699
if (isFunctionInPrintList(F.getName())) {
97100
if (forcePrintModuleIR())
@@ -101,9 +104,6 @@ class PrintFunctionPassWrapper : public FunctionPass {
101104
OS << Banner << '\n' << static_cast<Value &>(F);
102105
}
103106

104-
if (IsNewDbgInfoFormat)
105-
F.convertToNewDbgValues();
106-
107107
return false;
108108
}
109109

Diff for: llvm/lib/IR/Module.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ Module::~Module() {
8585
IFuncList.clear();
8686
}
8787

88+
void Module::removeDebugIntrinsicDeclarations() {
89+
auto *DeclareIntrinsicFn =
90+
Intrinsic::getDeclaration(this, Intrinsic::dbg_declare);
91+
assert((!isMaterialized() || DeclareIntrinsicFn->hasZeroLiveUses()) &&
92+
"Debug declare intrinsic should have had uses removed.");
93+
DeclareIntrinsicFn->eraseFromParent();
94+
auto *ValueIntrinsicFn =
95+
Intrinsic::getDeclaration(this, Intrinsic::dbg_value);
96+
assert((!isMaterialized() || ValueIntrinsicFn->hasZeroLiveUses()) &&
97+
"Debug value intrinsic should have had uses removed.");
98+
ValueIntrinsicFn->eraseFromParent();
99+
auto *AssignIntrinsicFn =
100+
Intrinsic::getDeclaration(this, Intrinsic::dbg_assign);
101+
assert((!isMaterialized() || AssignIntrinsicFn->hasZeroLiveUses()) &&
102+
"Debug assign intrinsic should have had uses removed.");
103+
AssignIntrinsicFn->eraseFromParent();
104+
auto *LabelntrinsicFn = Intrinsic::getDeclaration(this, Intrinsic::dbg_label);
105+
assert((!isMaterialized() || LabelntrinsicFn->hasZeroLiveUses()) &&
106+
"Debug label intrinsic should have had uses removed.");
107+
LabelntrinsicFn->eraseFromParent();
108+
}
109+
88110
std::unique_ptr<RandomNumberGenerator>
89111
Module::createRNG(const StringRef Name) const {
90112
SmallString<32> Salt(Name);

Diff for: llvm/lib/IRPrinter/IRPrintingPasses.cpp

+13-16
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
using namespace llvm;
2424

25+
extern cl::opt<bool> WriteNewDbgInfoFormat;
26+
2527
PrintModulePass::PrintModulePass() : OS(dbgs()) {}
2628
PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
2729
bool ShouldPreserveUseListOrder,
@@ -31,11 +33,14 @@ PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
3133
EmitSummaryIndex(EmitSummaryIndex) {}
3234

3335
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
34-
// RemoveDIs: there's no textual representation of the DPValue debug-info,
35-
// convert to dbg.values before writing out.
36-
bool ShouldConvert = M.IsNewDbgInfoFormat;
37-
if (ShouldConvert)
38-
M.convertFromNewDbgValues();
36+
// RemoveDIs: Regardless of the format we've processed this module in, use
37+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
38+
ScopedDbgInfoFormatSetter FormatSetter(M, WriteNewDbgInfoFormat);
39+
// Remove intrinsic declarations when printing in the new format.
40+
// TODO: Move this into Module::setIsNewDbgInfoFormat when we're ready to
41+
// update test output.
42+
if (WriteNewDbgInfoFormat)
43+
M.removeDebugIntrinsicDeclarations();
3944

4045
if (llvm::isFunctionInPrintList("*")) {
4146
if (!Banner.empty())
@@ -63,9 +68,6 @@ PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
6368
Index->print(OS);
6469
}
6570

66-
if (ShouldConvert)
67-
M.convertToNewDbgValues();
68-
6971
return PreservedAnalyses::all();
7072
}
7173

@@ -75,11 +77,9 @@ PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
7577

7678
PreservedAnalyses PrintFunctionPass::run(Function &F,
7779
FunctionAnalysisManager &) {
78-
// RemoveDIs: there's no textual representation of the DPValue debug-info,
79-
// convert to dbg.values before writing out.
80-
bool ShouldConvert = F.IsNewDbgInfoFormat;
81-
if (ShouldConvert)
82-
F.convertFromNewDbgValues();
80+
// RemoveDIs: Regardless of the format we've processed this function in, use
81+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
82+
ScopedDbgInfoFormatSetter FormatSetter(F, WriteNewDbgInfoFormat);
8383

8484
if (isFunctionInPrintList(F.getName())) {
8585
if (forcePrintModuleIR())
@@ -88,8 +88,5 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
8888
OS << Banner << '\n' << static_cast<Value &>(F);
8989
}
9090

91-
if (ShouldConvert)
92-
F.convertToNewDbgValues();
93-
9491
return PreservedAnalyses::all();
9592
}

0 commit comments

Comments
 (0)