Skip to content

Commit aa43649

Browse files
committed
Reapply "[RemoveDIs] Print non-intrinsic debug info in textual IR output (#79281)"
Fixes the prior issue in which the symbol for a cl-arg was unavailable to some binaries. This reverts commit dc06d75.
1 parent ada70f5 commit aa43649

20 files changed

+272
-146
lines changed

llvm/include/llvm/IR/Module.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,18 @@ class LLVM_EXTERNAL_VISIBILITY Module {
218218
/// \ref BasicBlock.
219219
bool IsNewDbgInfoFormat;
220220

221+
/// Used when converting this module to 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) {
224229
F.convertToNewDbgValues();
225230
}
231+
// Remove the declarations of the old debug intrinsics, if any exist.
232+
removeDebugIntrinsicDeclarations();
226233
IsNewDbgInfoFormat = true;
227234
}
228235

@@ -234,6 +241,13 @@ class LLVM_EXTERNAL_VISIBILITY Module {
234241
IsNewDbgInfoFormat = false;
235242
}
236243

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

llvm/include/llvm/IR/PrintPasses.h

Lines changed: 19 additions & 0 deletions
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

llvm/lib/IR/AsmWriter.cpp

Lines changed: 32 additions & 43 deletions
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 =

llvm/lib/IR/BasicBlock.cpp

Lines changed: 0 additions & 4 deletions
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

llvm/lib/IR/IRPrintingPasses.cpp

Lines changed: 11 additions & 16 deletions
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,9 @@ 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);
4750

4851
if (llvm::isFunctionInPrintList("*")) {
4952
if (!Banner.empty())
@@ -62,9 +65,6 @@ class PrintModulePassWrapper : public ModulePass {
6265
}
6366
}
6467

65-
if (IsNewDbgInfoFormat)
66-
M.convertToNewDbgValues();
67-
6868
return false;
6969
}
7070

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

8888
// This pass just prints a banner followed by the function as it's processed.
8989
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();
90+
// RemoveDIs: Regardless of the format we've processed this function in, use
91+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
92+
ScopedDbgInfoFormatSetter FormatSetter(F, WriteNewDbgInfoFormat);
9593

9694
if (isFunctionInPrintList(F.getName())) {
9795
if (forcePrintModuleIR())
@@ -101,9 +99,6 @@ class PrintFunctionPassWrapper : public FunctionPass {
10199
OS << Banner << '\n' << static_cast<Value &>(F);
102100
}
103101

104-
if (IsNewDbgInfoFormat)
105-
F.convertToNewDbgValues();
106-
107102
return false;
108103
}
109104

llvm/lib/IR/Module.cpp

Lines changed: 22 additions & 0 deletions
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);

llvm/lib/IRPrinter/IRPrintingPasses.cpp

Lines changed: 8 additions & 16 deletions
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,9 @@ 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);
3939

4040
if (llvm::isFunctionInPrintList("*")) {
4141
if (!Banner.empty())
@@ -63,9 +63,6 @@ PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
6363
Index->print(OS);
6464
}
6565

66-
if (ShouldConvert)
67-
M.convertToNewDbgValues();
68-
6966
return PreservedAnalyses::all();
7067
}
7168

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

7673
PreservedAnalyses PrintFunctionPass::run(Function &F,
7774
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();
75+
// RemoveDIs: Regardless of the format we've processed this function in, use
76+
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
77+
ScopedDbgInfoFormatSetter FormatSetter(F, WriteNewDbgInfoFormat);
8378

8479
if (isFunctionInPrintList(F.getName())) {
8580
if (forcePrintModuleIR())
@@ -88,8 +83,5 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
8883
OS << Banner << '\n' << static_cast<Value &>(F);
8984
}
9085

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

0 commit comments

Comments
 (0)