[llvm] [RemoveDIs] Print non-intrinsic debug info in textual IR output (PR #79281)
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 5 08:09:07 PST 2024
https://github.com/SLTozer updated https://github.com/llvm/llvm-project/pull/79281
>From f07f32889cce969e3f4ef3cf0bfc8d390b2f9dc7 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 17 Jan 2024 16:38:36 +0000
Subject: [PATCH 1/5] Enable printing of DPValues in IR
---
llvm/include/llvm/IR/Module.h | 4 +
llvm/lib/IR/AsmWriter.cpp | 70 +++++++---------
llvm/lib/IR/BasicBlock.cpp | 4 -
llvm/lib/IR/IRPrintingPasses.cpp | 46 +++++++----
llvm/lib/IR/Module.cpp | 18 +++++
llvm/lib/IRPrinter/IRPrintingPasses.cpp | 49 ++++++++----
.../print-non-instruction-debug-info.ll | 80 +++++++++++++++++++
7 files changed, 199 insertions(+), 72 deletions(-)
create mode 100644 llvm/test/DebugInfo/print-non-instruction-debug-info.ll
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 68a89dc45c283..1ed456e6f7499 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -218,11 +218,15 @@ class LLVM_EXTERNAL_VISIBILITY Module {
/// \ref BasicBlock.
bool IsNewDbgInfoFormat;
+ void removeDebugIntrinsicDeclarations();
+
/// \see BasicBlock::convertToNewDbgValues.
void convertToNewDbgValues() {
for (auto &F : *this) {
F.convertToNewDbgValues();
}
+ // Remove the declarations of the old debug intrinsics, if any exist.
+ removeDebugIntrinsicDeclarations();
IsNewDbgInfoFormat = true;
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 3c15784a0ed5e..d56b08336eb5f 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -860,7 +860,7 @@ class SlotTracker : public AbstractSlotTrackerStorage {
/// Add all of the metadata from an instruction.
void processInstructionMetadata(const Instruction &I);
- /// Add all of the metadata from an instruction.
+ /// Add all of the metadata from a DPValue.
void processDPValueMetadata(const DPValue &DPV);
};
@@ -1138,6 +1138,9 @@ void SlotTracker::processFunctionMetadata(const Function &F) {
}
void SlotTracker::processDPValueMetadata(const DPValue &DPV) {
+ // Process metadata used by DPValues; we only specifically care about the
+ // DILocalVariable, DILocation, and DIAssignID fields, as the Value and
+ // Expression fields should only be printed inline and so do not use a slot.
CreateMetadataSlot(DPV.getVariable());
CreateMetadataSlot(DPV.getDebugLoc());
if (DPV.isDbgAssign()) {
@@ -2654,6 +2657,7 @@ class AssemblyWriter {
void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
void writeAllAttributeGroups();
+
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
void printAlias(const GlobalAlias *GA);
@@ -2662,10 +2666,11 @@ class AssemblyWriter {
void printFunction(const Function *F);
void printArgument(const Argument *FA, AttributeSet Attrs);
void printBasicBlock(const BasicBlock *BB);
+ void printDPValueLine(const DPValue &DPV);
void printInstructionLine(const Instruction &I);
void printInstruction(const Instruction &I);
void printDPMarker(const DPMarker &DPI);
- void printDPValue(const DPValue &DPI);
+ void printDPValue(const DPValue &DPV);
void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
void printUseLists(const Function *F);
@@ -3848,9 +3853,6 @@ void AssemblyWriter::printTypeIdentities() {
/// printFunction - Print all aspects of a function.
void AssemblyWriter::printFunction(const Function *F) {
- bool ConvertBack = F->IsNewDbgInfoFormat;
- if (ConvertBack)
- const_cast<Function *>(F)->convertFromNewDbgValues();
if (AnnotationWriter) AnnotationWriter->emitFunctionAnnot(F, Out);
if (F->isMaterializable())
@@ -3993,8 +3995,6 @@ void AssemblyWriter::printFunction(const Function *F) {
Out << "}\n";
}
- if (ConvertBack)
- const_cast<Function *>(F)->convertToNewDbgValues();
Machine.purgeFunction();
}
@@ -4061,6 +4061,8 @@ void AssemblyWriter::printBasicBlock(const BasicBlock *BB) {
// Output all of the instructions in the basic block...
for (const Instruction &I : *BB) {
+ for (const DPValue &DPV : I.getDbgValueRange())
+ printDPValueLine(DPV);
printInstructionLine(I);
}
@@ -4091,12 +4093,6 @@ void AssemblyWriter::printInfoComment(const Value &V) {
if (AnnotationWriter) {
AnnotationWriter->printInfoComment(V, Out);
- } else if (const Instruction *I = dyn_cast<Instruction>(&V)) {
- if (I->DbgMarker) {
- // In the new, experimental DPValue representation of debug-info, print
- // out which instructions have DPMarkers and where they are.
- Out << "; dbgmarker @ " << I->DbgMarker;
- }
}
}
@@ -4571,12 +4567,10 @@ void AssemblyWriter::printDPMarker(const DPMarker &Marker) {
return;
}
-void AssemblyWriter::printDPValue(const DPValue &Value) {
- // There's no formal representation of a DPValue -- print purely as a
- // debugging aid.
- Out << " DPValue ";
-
- switch (Value.getType()) {
+void AssemblyWriter::printDPValue(const DPValue &DPV) {
+ auto WriterCtx = getContext();
+ Out << "#dbg_";
+ switch (DPV.getType()) {
case DPValue::LocationType::Value:
Out << "value";
break;
@@ -4588,28 +4582,34 @@ void AssemblyWriter::printDPValue(const DPValue &Value) {
break;
default:
llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
- }
+ };
Out << " { ";
- auto WriterCtx = getContext();
- WriteAsOperandInternal(Out, Value.getRawLocation(), WriterCtx, true);
+ WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true);
Out << ", ";
- WriteAsOperandInternal(Out, Value.getVariable(), WriterCtx, true);
+ WriteAsOperandInternal(Out, DPV.getVariable(), WriterCtx, true);
Out << ", ";
- WriteAsOperandInternal(Out, Value.getExpression(), WriterCtx, true);
+ WriteAsOperandInternal(Out, DPV.getExpression(), WriterCtx, true);
Out << ", ";
- if (Value.isDbgAssign()) {
- WriteAsOperandInternal(Out, Value.getAssignID(), WriterCtx, true);
+ if (DPV.isDbgAssign()) {
+ WriteAsOperandInternal(Out, DPV.getAssignID(), WriterCtx, true);
Out << ", ";
- WriteAsOperandInternal(Out, Value.getRawAddress(), WriterCtx, true);
+ WriteAsOperandInternal(Out, DPV.getRawAddress(), WriterCtx, true);
Out << ", ";
- WriteAsOperandInternal(Out, Value.getAddressExpression(), WriterCtx, true);
+ WriteAsOperandInternal(Out, DPV.getAddressExpression(), WriterCtx, true);
Out << ", ";
}
- WriteAsOperandInternal(Out, Value.getDebugLoc().get(), WriterCtx, true);
- Out << " marker @" << Value.getMarker();
+ WriteAsOperandInternal(Out, DPV.getDebugLoc().getAsMDNode(), WriterCtx, true);
Out << " }";
}
+/// printDPValueLine - Print a DPValue with indentation and a newline character.
+void AssemblyWriter::printDPValueLine(const DPValue &DPV) {
+ // Print lengthier indentation to bring out-of-line with instructions.
+ Out << " ";
+ printDPValue(DPV);
+ Out << '\n';
+}
+
void AssemblyWriter::printMetadataAttachments(
const SmallVectorImpl<std::pair<unsigned, MDNode *>> &MDs,
StringRef Separator) {
@@ -4755,19 +4755,11 @@ void BasicBlock::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW,
bool ShouldPreserveUseListOrder, bool IsForDebug) const {
- // RemoveDIs: always print with debug-info in intrinsic format.
- bool ConvertAfter = IsNewDbgInfoFormat;
- if (IsNewDbgInfoFormat)
- const_cast<Module *>(this)->convertFromNewDbgValues();
-
SlotTracker SlotTable(this);
formatted_raw_ostream OS(ROS);
AssemblyWriter W(OS, SlotTable, this, AAW, IsForDebug,
ShouldPreserveUseListOrder);
W.printModule(this);
-
- if (ConvertAfter)
- const_cast<Module *>(this)->convertToNewDbgValues();
}
void NamedMDNode::print(raw_ostream &ROS, bool IsForDebug) const {
@@ -4875,8 +4867,6 @@ void DPMarker::print(raw_ostream &ROS, ModuleSlotTracker &MST,
void DPValue::print(raw_ostream &ROS, ModuleSlotTracker &MST,
bool IsForDebug) const {
- // There's no formal representation of a DPValue -- print purely as a
- // debugging aid.
formatted_raw_ostream OS(ROS);
SlotTracker EmptySlotTable(static_cast<const Module *>(nullptr));
SlotTracker &SlotTable =
diff --git a/llvm/lib/IR/BasicBlock.cpp b/llvm/lib/IR/BasicBlock.cpp
index dca5283283847..b2d40e5bb55af 100644
--- a/llvm/lib/IR/BasicBlock.cpp
+++ b/llvm/lib/IR/BasicBlock.cpp
@@ -61,10 +61,6 @@ DPMarker *BasicBlock::createMarker(InstListType::iterator It) {
}
void BasicBlock::convertToNewDbgValues() {
- // Is the command line option set?
- if (!UseNewDbgInfoFormat)
- return;
-
IsNewDbgInfoFormat = true;
// Iterate over all instructions in the instruction list, collecting dbg.value
diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp
index b19210e776ed5..dacec22a4e0c6 100644
--- a/llvm/lib/IR/IRPrintingPasses.cpp
+++ b/llvm/lib/IR/IRPrintingPasses.cpp
@@ -23,6 +23,8 @@
using namespace llvm;
+extern cl::opt<bool> WriteNewDbgInfoFormat;
+
namespace {
class PrintModulePassWrapper : public ModulePass {
@@ -39,11 +41,15 @@ class PrintModulePassWrapper : public ModulePass {
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
bool runOnModule(Module &M) override {
- // RemoveDIs: there's no textual representation of the DPValue debug-info,
- // convert to dbg.values before writing out.
- bool IsNewDbgInfoFormat = M.IsNewDbgInfoFormat;
- if (IsNewDbgInfoFormat)
- M.convertFromNewDbgValues();
+ // RemoveDIs: Regardless of the format we've processed this module in, use
+ // `WriteNewDbgInfoFormat` to determine which format we use to write it.
+ bool ShouldConvert = M.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ M.convertToNewDbgValues();
+ else
+ M.convertFromNewDbgValues();
+ }
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
@@ -62,8 +68,12 @@ class PrintModulePassWrapper : public ModulePass {
}
}
- if (IsNewDbgInfoFormat)
- M.convertToNewDbgValues();
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ M.convertFromNewDbgValues();
+ else
+ M.convertToNewDbgValues();
+ }
return false;
}
@@ -87,11 +97,15 @@ class PrintFunctionPassWrapper : public FunctionPass {
// This pass just prints a banner followed by the function as it's processed.
bool runOnFunction(Function &F) override {
- // RemoveDIs: there's no textual representation of the DPValue debug-info,
- // convert to dbg.values before writing out.
- bool IsNewDbgInfoFormat = F.IsNewDbgInfoFormat;
- if (IsNewDbgInfoFormat)
- F.convertFromNewDbgValues();
+ // RemoveDIs: Regardless of the format we've processed this function in, use
+ // `WriteNewDbgInfoFormat` to determine which format we use to write it.
+ bool ShouldConvert = F.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ F.convertToNewDbgValues();
+ else
+ F.convertFromNewDbgValues();
+ }
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR())
@@ -101,8 +115,12 @@ class PrintFunctionPassWrapper : public FunctionPass {
OS << Banner << '\n' << static_cast<Value &>(F);
}
- if (IsNewDbgInfoFormat)
- F.convertToNewDbgValues();
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ F.convertFromNewDbgValues();
+ else
+ F.convertToNewDbgValues();
+ }
return false;
}
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index eeb90a6cb3c46..e883eead72749 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -85,6 +85,24 @@ Module::~Module() {
IFuncList.clear();
}
+void Module::removeDebugIntrinsicDeclarations() {
+ auto *DeclareIntrinsicFn =
+ Intrinsic::getDeclaration(this, Intrinsic::dbg_declare);
+ assert(DeclareIntrinsicFn->hasZeroLiveUses() &&
+ "Debug declare intrinsic should have had uses removed.");
+ DeclareIntrinsicFn->eraseFromParent();
+ auto *ValueIntrinsicFn =
+ Intrinsic::getDeclaration(this, Intrinsic::dbg_value);
+ assert(ValueIntrinsicFn->hasZeroLiveUses() &&
+ "Debug value intrinsic should have had uses removed.");
+ ValueIntrinsicFn->eraseFromParent();
+ auto *AssignIntrinsicFn =
+ Intrinsic::getDeclaration(this, Intrinsic::dbg_assign);
+ assert(AssignIntrinsicFn->hasZeroLiveUses() &&
+ "Debug assign intrinsic should have had uses removed.");
+ AssignIntrinsicFn->eraseFromParent();
+}
+
std::unique_ptr<RandomNumberGenerator>
Module::createRNG(const StringRef Name) const {
SmallString<32> Salt(Name);
diff --git a/llvm/lib/IRPrinter/IRPrintingPasses.cpp b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
index 52b242b4dcd52..d770e0be3e85c 100644
--- a/llvm/lib/IRPrinter/IRPrintingPasses.cpp
+++ b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
@@ -22,6 +22,11 @@
using namespace llvm;
+cl::opt<bool> WriteNewDbgInfoFormat(
+ "write-experimental-debuginfo",
+ cl::desc("Write debug info in the new non-intrinsic format"),
+ cl::init(false));
+
PrintModulePass::PrintModulePass() : OS(dbgs()) {}
PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
bool ShouldPreserveUseListOrder,
@@ -31,11 +36,15 @@ PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
EmitSummaryIndex(EmitSummaryIndex) {}
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
- // RemoveDIs: there's no textual representation of the DPValue debug-info,
- // convert to dbg.values before writing out.
- bool ShouldConvert = M.IsNewDbgInfoFormat;
- if (ShouldConvert)
- M.convertFromNewDbgValues();
+ // RemoveDIs: Regardless of the format we've processed this module in, use
+ // `WriteNewDbgInfoFormat` to determine which format we use to write it.
+ bool ShouldConvert = M.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ M.convertToNewDbgValues();
+ else
+ M.convertFromNewDbgValues();
+ }
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
@@ -63,8 +72,12 @@ PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
Index->print(OS);
}
- if (ShouldConvert)
- M.convertToNewDbgValues();
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ M.convertFromNewDbgValues();
+ else
+ M.convertToNewDbgValues();
+ }
return PreservedAnalyses::all();
}
@@ -75,11 +88,15 @@ PrintFunctionPass::PrintFunctionPass(raw_ostream &OS, const std::string &Banner)
PreservedAnalyses PrintFunctionPass::run(Function &F,
FunctionAnalysisManager &) {
- // RemoveDIs: there's no textual representation of the DPValue debug-info,
- // convert to dbg.values before writing out.
- bool ShouldConvert = F.IsNewDbgInfoFormat;
- if (ShouldConvert)
- F.convertFromNewDbgValues();
+ // RemoveDIs: Regardless of the format we've processed this function in, use
+ // `WriteNewDbgInfoFormat` to determine which format we use to write it.
+ bool ShouldConvert = F.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ F.convertToNewDbgValues();
+ else
+ F.convertFromNewDbgValues();
+ }
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR())
@@ -88,8 +105,12 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
OS << Banner << '\n' << static_cast<Value &>(F);
}
- if (ShouldConvert)
- F.convertToNewDbgValues();
+ if (ShouldConvert) {
+ if (WriteNewDbgInfoFormat)
+ F.convertFromNewDbgValues();
+ else
+ F.convertToNewDbgValues();
+ }
return PreservedAnalyses::all();
}
diff --git a/llvm/test/DebugInfo/print-non-instruction-debug-info.ll b/llvm/test/DebugInfo/print-non-instruction-debug-info.ll
new file mode 100644
index 0000000000000..fcb7d22fee6fa
--- /dev/null
+++ b/llvm/test/DebugInfo/print-non-instruction-debug-info.ll
@@ -0,0 +1,80 @@
+;; Test that we can write in the new debug info format.
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=false < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: opt --passes=verify -S --write-experimental-debuginfo=true < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+
+;; Test also that the new flag is independent of the flag that enables use of
+;; these non-instruction debug info during LLVM passes.
+; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=false < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,OLDDBG --implicit-check-not=llvm.dbg
+; RUN: opt --passes=verify -S --try-experimental-debuginfo-iterators --write-experimental-debuginfo=true < %s \
+; RUN: | FileCheck %s --check-prefixes=CHECK,NEWDBG --implicit-check-not=llvm.dbg
+
+; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]])
+; CHECK-NEXT: entry:
+; OLDDBG-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL_A]], metadata ![[VAR_A:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_1:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_value { i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]] }
+; CHECK-NEXT: {{^}} %[[VAL_B:[0-9a-zA-Z]+]] = alloca
+; OLDDBG-NEXT: call void @llvm.dbg.declare(metadata ptr %[[VAL_B]], metadata ![[VAR_B:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_2:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_declare { ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]] }
+; CHECK-NEXT: {{^}} %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
+; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_value { !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]] }
+; CHECK-NEXT: {{^}} store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
+; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
+; NEWDBG-NEXT: {{^}} #dbg_assign { i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]] }
+; CHECK-NEXT: {{^}} ret i32
+
+; OLDDBG-DAG: declare void @llvm.dbg.value
+; OLDDBG-DAG: declare void @llvm.dbg.declare
+; OLDDBG-DAG: declare void @llvm.dbg.assign
+
+; CHECK-DAG: llvm.dbg.cu
+; CHECK-DAG: ![[VAR_A]] = !DILocalVariable(name: "a"
+; CHECK-DAG: ![[VAR_B]] = !DILocalVariable(name: "b"
+; CHECK-DAG: ![[LOC_1]] = !DILocation(line: 3, column: 15
+; CHECK-DAG: ![[LOC_2]] = !DILocation(line: 3, column: 20
+; CHECK-DAG: ![[LOC_3]] = !DILocation(line: 3, column: 25
+; CHECK-DAG: ![[LOC_4]] = !DILocation(line: 3, column: 30
+
+define dso_local i32 @f(i32 %a) !dbg !7 {
+entry:
+ call void @llvm.dbg.value(metadata i32 %a, metadata !20, metadata !DIExpression()), !dbg !30
+ %b = alloca i32, !dbg !30, !DIAssignID !40
+ call void @llvm.dbg.declare(metadata ptr %b, metadata !21, metadata !DIExpression()), !dbg !31
+ %add = add i32 %a, 5, !dbg !31
+ call void @llvm.dbg.value(metadata !DIArgList(i32 %a, i32 %add), metadata !20, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg !32
+ store i32 %add, ptr %b, !dbg !32, !DIAssignID !40
+ call void @llvm.dbg.assign(metadata i32 %add, metadata !21, metadata !DIExpression(), metadata !40, metadata ptr %b, metadata !DIExpression()), !dbg !33
+ ret i32 %add, !dbg !33
+
+}
+
+declare void @llvm.dbg.value(metadata, metadata, metadata)
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+declare void @llvm.dbg.assign(metadata, metadata, metadata, metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 18.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
+!1 = !DIFile(filename: "print.c", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = !{i32 1, !"wchar_size", i32 4}
+!6 = !{!"clang version 18.0.0"}
+!7 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 3, type: !8, isLocal: false, isDefinition: true, scopeLine: 3, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !13)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!12, !12}
+!12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!13 = !{!20, !21}
+!20 = !DILocalVariable(name: "a", arg: 1, scope: !7, file: !1, line: 3, type: !12)
+!21 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !12)
+!30 = !DILocation(line: 3, column: 15, scope: !7)
+!31 = !DILocation(line: 3, column: 20, scope: !7)
+!32 = !DILocation(line: 3, column: 25, scope: !7)
+!33 = !DILocation(line: 3, column: 30, scope: !7)
+!40 = distinct !DIAssignID()
\ No newline at end of file
>From 8668d890b4d4ecea1bddef17be7549f0ceae758b Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 24 Jan 2024 12:39:51 +0000
Subject: [PATCH 2/5] Reorder functions to make more sense
---
llvm/lib/IR/AsmWriter.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d56b08336eb5f..bb5eb31499c2b 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2666,11 +2666,11 @@ class AssemblyWriter {
void printFunction(const Function *F);
void printArgument(const Argument *FA, AttributeSet Attrs);
void printBasicBlock(const BasicBlock *BB);
- void printDPValueLine(const DPValue &DPV);
void printInstructionLine(const Instruction &I);
void printInstruction(const Instruction &I);
void printDPMarker(const DPMarker &DPI);
void printDPValue(const DPValue &DPV);
+ void printDPValueLine(const DPValue &DPV);
void printUseListOrder(const Value *V, const std::vector<unsigned> &Shuffle);
void printUseLists(const Function *F);
>From ddc9740d7becd953e230a12b25d3b43e69018da6 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 24 Jan 2024 12:48:27 +0000
Subject: [PATCH 3/5] Clang-format
---
llvm/lib/IR/AsmWriter.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index bb5eb31499c2b..75485fd7354a7 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2657,7 +2657,6 @@ class AssemblyWriter {
void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
void writeAllAttributeGroups();
-
void printTypeIdentities();
void printGlobal(const GlobalVariable *GV);
void printAlias(const GlobalAlias *GA);
>From a182f3ccf0c256378ec5cf5eeb7dc0484b7e15db Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Wed, 24 Jan 2024 17:33:02 +0000
Subject: [PATCH 4/5] Review comments: semicolon, shortened conversion logic
---
llvm/include/llvm/IR/Module.h | 7 ++++++
llvm/lib/IR/AsmWriter.cpp | 2 +-
llvm/lib/IR/IRPrintingPasses.cpp | 32 +++++--------------------
llvm/lib/IRPrinter/IRPrintingPasses.cpp | 32 +++++--------------------
4 files changed, 20 insertions(+), 53 deletions(-)
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 1ed456e6f7499..0038d677f9324 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -238,6 +238,13 @@ class LLVM_EXTERNAL_VISIBILITY Module {
IsNewDbgInfoFormat = false;
}
+ void setIsNewDbgInfoFormat(bool NewFlag) {
+ if (NewFlag && !IsNewDbgInfoFormat)
+ convertToNewDbgValues();
+ else if (!NewFlag && IsNewDbgInfoFormat)
+ convertFromNewDbgValues();
+ }
+
/// The Module constructor. Note that there is no default constructor. You
/// must provide a name for the module upon construction.
explicit Module(StringRef ModuleID, LLVMContext& C);
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 75485fd7354a7..1798f435b7bee 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4581,7 +4581,7 @@ void AssemblyWriter::printDPValue(const DPValue &DPV) {
break;
default:
llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
- };
+ }
Out << " { ";
WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true);
Out << ", ";
diff --git a/llvm/lib/IR/IRPrintingPasses.cpp b/llvm/lib/IR/IRPrintingPasses.cpp
index dacec22a4e0c6..c757178340740 100644
--- a/llvm/lib/IR/IRPrintingPasses.cpp
+++ b/llvm/lib/IR/IRPrintingPasses.cpp
@@ -43,13 +43,8 @@ class PrintModulePassWrapper : public ModulePass {
bool runOnModule(Module &M) override {
// RemoveDIs: Regardless of the format we've processed this module in, use
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
- bool ShouldConvert = M.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- M.convertToNewDbgValues();
- else
- M.convertFromNewDbgValues();
- }
+ bool UsedNewDbgInfoFormat = M.IsNewDbgInfoFormat;
+ M.setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
@@ -68,12 +63,7 @@ class PrintModulePassWrapper : public ModulePass {
}
}
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- M.convertFromNewDbgValues();
- else
- M.convertToNewDbgValues();
- }
+ M.setIsNewDbgInfoFormat(UsedNewDbgInfoFormat);
return false;
}
@@ -99,13 +89,8 @@ class PrintFunctionPassWrapper : public FunctionPass {
bool runOnFunction(Function &F) override {
// RemoveDIs: Regardless of the format we've processed this function in, use
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
- bool ShouldConvert = F.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- F.convertToNewDbgValues();
- else
- F.convertFromNewDbgValues();
- }
+ bool UsedNewDbgInfoFormat = F.IsNewDbgInfoFormat;
+ F.setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR())
@@ -115,12 +100,7 @@ class PrintFunctionPassWrapper : public FunctionPass {
OS << Banner << '\n' << static_cast<Value &>(F);
}
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- F.convertFromNewDbgValues();
- else
- F.convertToNewDbgValues();
- }
+ F.setIsNewDbgInfoFormat(UsedNewDbgInfoFormat);
return false;
}
diff --git a/llvm/lib/IRPrinter/IRPrintingPasses.cpp b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
index d770e0be3e85c..2e5426a0a3a43 100644
--- a/llvm/lib/IRPrinter/IRPrintingPasses.cpp
+++ b/llvm/lib/IRPrinter/IRPrintingPasses.cpp
@@ -38,13 +38,8 @@ PrintModulePass::PrintModulePass(raw_ostream &OS, const std::string &Banner,
PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
// RemoveDIs: Regardless of the format we've processed this module in, use
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
- bool ShouldConvert = M.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- M.convertToNewDbgValues();
- else
- M.convertFromNewDbgValues();
- }
+ bool UsedNewDbgInfoFormat = M.IsNewDbgInfoFormat;
+ M.setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (llvm::isFunctionInPrintList("*")) {
if (!Banner.empty())
@@ -72,12 +67,7 @@ PreservedAnalyses PrintModulePass::run(Module &M, ModuleAnalysisManager &AM) {
Index->print(OS);
}
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- M.convertFromNewDbgValues();
- else
- M.convertToNewDbgValues();
- }
+ M.setIsNewDbgInfoFormat(UsedNewDbgInfoFormat);
return PreservedAnalyses::all();
}
@@ -90,13 +80,8 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
FunctionAnalysisManager &) {
// RemoveDIs: Regardless of the format we've processed this function in, use
// `WriteNewDbgInfoFormat` to determine which format we use to write it.
- bool ShouldConvert = F.IsNewDbgInfoFormat != WriteNewDbgInfoFormat;
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- F.convertToNewDbgValues();
- else
- F.convertFromNewDbgValues();
- }
+ bool UsedNewDbgInfoFormat = F.IsNewDbgInfoFormat;
+ F.setIsNewDbgInfoFormat(WriteNewDbgInfoFormat);
if (isFunctionInPrintList(F.getName())) {
if (forcePrintModuleIR())
@@ -105,12 +90,7 @@ PreservedAnalyses PrintFunctionPass::run(Function &F,
OS << Banner << '\n' << static_cast<Value &>(F);
}
- if (ShouldConvert) {
- if (WriteNewDbgInfoFormat)
- F.convertFromNewDbgValues();
- else
- F.convertToNewDbgValues();
- }
+ F.setIsNewDbgInfoFormat(UsedNewDbgInfoFormat);
return PreservedAnalyses::all();
}
>From 5f904fb23bfeb3281bede9a46958f23e6e10e8a0 Mon Sep 17 00:00:00 2001
From: Stephen Tozer <Stephen.Tozer at Sony.com>
Date: Mon, 5 Feb 2024 16:08:43 +0000
Subject: [PATCH 5/5] Changed from braces to parentheses and changed flag name
---
llvm/include/llvm/IR/Module.h | 6 +++---
llvm/lib/IR/AsmWriter.cpp | 4 ++--
llvm/test/DebugInfo/print-non-instruction-debug-info.ll | 8 ++++----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 0038d677f9324..92a50e93a9391 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -238,10 +238,10 @@ class LLVM_EXTERNAL_VISIBILITY Module {
IsNewDbgInfoFormat = false;
}
- void setIsNewDbgInfoFormat(bool NewFlag) {
- if (NewFlag && !IsNewDbgInfoFormat)
+ void setIsNewDbgInfoFormat(bool UseNewFormat) {
+ if (UseNewFormat && !IsNewDbgInfoFormat)
convertToNewDbgValues();
- else if (!NewFlag && IsNewDbgInfoFormat)
+ else if (!UseNewFormat && IsNewDbgInfoFormat)
convertFromNewDbgValues();
}
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index 1798f435b7bee..a7b663f999173 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -4582,7 +4582,7 @@ void AssemblyWriter::printDPValue(const DPValue &DPV) {
default:
llvm_unreachable("Tried to print a DPValue with an invalid LocationType!");
}
- Out << " { ";
+ Out << "(";
WriteAsOperandInternal(Out, DPV.getRawLocation(), WriterCtx, true);
Out << ", ";
WriteAsOperandInternal(Out, DPV.getVariable(), WriterCtx, true);
@@ -4598,7 +4598,7 @@ void AssemblyWriter::printDPValue(const DPValue &DPV) {
Out << ", ";
}
WriteAsOperandInternal(Out, DPV.getDebugLoc().getAsMDNode(), WriterCtx, true);
- Out << " }";
+ Out << ")";
}
/// printDPValueLine - Print a DPValue with indentation and a newline character.
diff --git a/llvm/test/DebugInfo/print-non-instruction-debug-info.ll b/llvm/test/DebugInfo/print-non-instruction-debug-info.ll
index fcb7d22fee6fa..3adf73f444b53 100644
--- a/llvm/test/DebugInfo/print-non-instruction-debug-info.ll
+++ b/llvm/test/DebugInfo/print-non-instruction-debug-info.ll
@@ -14,16 +14,16 @@
; CHECK: @f(i32 %[[VAL_A:[0-9a-zA-Z]+]])
; CHECK-NEXT: entry:
; OLDDBG-NEXT: call void @llvm.dbg.value(metadata i32 %[[VAL_A]], metadata ![[VAR_A:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_1:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_value { i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_value(i32 %[[VAL_A]], ![[VAR_A:[0-9]+]], !DIExpression(), ![[LOC_1:[0-9]+]])
; CHECK-NEXT: {{^}} %[[VAL_B:[0-9a-zA-Z]+]] = alloca
; OLDDBG-NEXT: call void @llvm.dbg.declare(metadata ptr %[[VAL_B]], metadata ![[VAR_B:[0-9]+]], metadata !DIExpression()), !dbg ![[LOC_2:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_declare { ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_declare(ptr %[[VAL_B]], ![[VAR_B:[0-9]+]], !DIExpression(), ![[LOC_2:[0-9]+]])
; CHECK-NEXT: {{^}} %[[VAL_ADD:[0-9a-zA-Z]+]] = add i32 %[[VAL_A]], 5
; OLDDBG-NEXT: call void @llvm.dbg.value(metadata !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), metadata ![[VAR_A]], metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus)), !dbg ![[LOC_3:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_value { !DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_value(!DIArgList(i32 %[[VAL_A]], i32 %[[VAL_ADD]]), ![[VAR_A]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus), ![[LOC_3:[0-9]+]])
; CHECK-NEXT: {{^}} store i32 %[[VAL_ADD]]{{.+}}, !DIAssignID ![[ASSIGNID:[0-9]+]]
; OLDDBG-NEXT: call void @llvm.dbg.assign(metadata i32 %[[VAL_ADD]], metadata ![[VAR_B]], metadata !DIExpression(), metadata ![[ASSIGNID]], metadata ptr %[[VAL_B]], metadata !DIExpression()), !dbg ![[LOC_4:[0-9]+]]
-; NEWDBG-NEXT: {{^}} #dbg_assign { i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]] }
+; NEWDBG-NEXT: {{^}} #dbg_assign(i32 %[[VAL_ADD]], ![[VAR_B]], !DIExpression(), ![[ASSIGNID]], ptr %[[VAL_B]], !DIExpression(), ![[LOC_4:[0-9]+]])
; CHECK-NEXT: {{^}} ret i32
; OLDDBG-DAG: declare void @llvm.dbg.value
More information about the llvm-commits
mailing list