[llvm] 1e6fe67 - [DebugInfo] Print empty MDTuples wrapped in MetadataAsValue inline

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 25 06:14:07 PDT 2023


Author: OCHyams
Date: 2023-04-25T14:13:47+01:00
New Revision: 1e6fe677f8aa98518e05218affa16e468819f5ed

URL: https://github.com/llvm/llvm-project/commit/1e6fe677f8aa98518e05218affa16e468819f5ed
DIFF: https://github.com/llvm/llvm-project/commit/1e6fe677f8aa98518e05218affa16e468819f5ed.diff

LOG: [DebugInfo] Print empty MDTuples wrapped in MetadataAsValue inline

This improves the readability of debugging intrinsics. Instead of:

    call void @llvm.dbg.value(metadata !2, ...)
    !2 = !{}

We will see:

    call void @llvm.dbg.value(metadata !{}, ...)
    !2 = !{}

Note that we still get a numbered metadata entry for the node even if it's not
used elsewhere. This is to avoid adding more context to the print functions.

This is already legal IR - LLVM can parse and understand it - so there is no
need to update the parser.

The next patches in this stack will make such empty metadata operands more
common and semantically important.

Related to https://discourse.llvm.org/t/auto-undef-debug-uses-of-a-deleted-value

Reviewed By: StephenTozer

Differential Revision: https://reviews.llvm.org/D140900

Added: 
    llvm/test/DebugInfo/Generic/empty-metadata-roundtrip.ll

Modified: 
    llvm/lib/IR/AsmWriter.cpp
    llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
    llvm/test/Transforms/GlobalOpt/metadata.ll
    llvm/test/Transforms/LoopIdiom/debug-line.ll
    llvm/unittests/IR/MetadataTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index d6e36927e73ef..38bab6a588f09 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -1328,7 +1328,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
 
 static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
                                    AsmWriterContext &WriterCtx,
-                                   bool FromValue = false);
+                                   bool FromValue = false,
+                                   bool AsOperand = false);
 
 static void WriteOptimizationInfo(raw_ostream &Out, const User *U) {
   if (const FPMathOperator *FPO = dyn_cast<const FPMathOperator>(U))
@@ -2447,7 +2448,7 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
 
   if (auto *MD = dyn_cast<MetadataAsValue>(V)) {
     WriteAsOperandInternal(Out, MD->getMetadata(), WriterCtx,
-                           /* FromValue */ true);
+                           /* FromValue */ true, /* AsOperand */ true);
     return;
   }
 
@@ -2492,8 +2493,8 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Value *V,
 }
 
 static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
-                                   AsmWriterContext &WriterCtx,
-                                   bool FromValue) {
+                                   AsmWriterContext &WriterCtx, bool FromValue,
+                                   bool AsOperand) {
   // Write DIExpressions and DIArgLists inline when used as a value. Improves
   // readability of debug info intrinsics.
   if (const DIExpression *Expr = dyn_cast<DIExpression>(MD)) {
@@ -2506,6 +2507,12 @@ static void WriteAsOperandInternal(raw_ostream &Out, const Metadata *MD,
   }
 
   if (const MDNode *N = dyn_cast<MDNode>(MD)) {
+    // Write empty metadata tuples wrapped in MetadataAsValue inline.
+    if (isa<MDTuple>(N) && !N->getNumOperands() && AsOperand) {
+      WriteMDNodeBodyInternal(Out, N, WriterCtx);
+      return;
+    }
+
     std::unique_ptr<SlotTracker> MachineStorage;
     SaveAndRestore SARMachine(WriterCtx.Machine);
     if (!WriterCtx.Machine) {
@@ -4874,7 +4881,8 @@ static void printMetadataImpl(raw_ostream &ROS, const Metadata &MD,
     WriterCtx =
         std::make_unique<AsmWriterContext>(&TypePrinter, MST.getMachine(), M);
 
-  WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true);
+  WriteAsOperandInternal(OS, &MD, *WriterCtx, /* FromValue */ true,
+                         OnlyAsOperand);
 
   auto *N = dyn_cast<MDNode>(&MD);
   if (OnlyAsOperand || !N || isa<DIExpression>(MD) || isa<DIArgList>(MD))

diff  --git a/llvm/test/DebugInfo/Generic/empty-metadata-roundtrip.ll b/llvm/test/DebugInfo/Generic/empty-metadata-roundtrip.ll
new file mode 100644
index 0000000000000..88a0e0538d648
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/empty-metadata-roundtrip.ll
@@ -0,0 +1,42 @@
+; RUN: opt -passes=verify %s -o - | opt -S -o - | FileCheck %s
+
+;; Check that an empty metadata node is printed inline when wrapped in
+;; MetadataAsValue.
+;; We still get a numbered metadata entry for the node even though it's not
+;; used elsewhere. This is a purely cosmetic result of reducing the complexity
+;; of the printing functions; it's not a requirement so it is okay to update
+;; this part of the test if that changes in the future.
+
+; CHECK: call void @llvm.dbg.declare(metadata !{},
+; CHECK: ![[#]] = !{}
+
+define dso_local void @fun() local_unnamed_addr #0 !dbg !9 {
+entry:
+  call void @llvm.dbg.declare(metadata !{}, metadata !13, metadata !DIExpression()), !dbg !15
+  ret void, !dbg !16
+}
+
+declare void @llvm.dbg.declare(metadata, metadata, metadata)
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7}
+!llvm.ident = !{!8}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 16.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "test.c", directory: "/")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 8, !"PIC Level", i32 2}
+!6 = !{i32 7, !"PIE Level", i32 2}
+!7 = !{i32 7, !"uwtable", i32 2}
+!8 = !{!"clang version 16.0.0"}
+!9 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12)
+!10 = !DISubroutineType(types: !11)
+!11 = !{null}
+!12 = !{!13}
+!13 = !DILocalVariable(name: "a", scope: !9, file: !1, line: 1, type: !14)
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!15 = !DILocation(line: 1, column: 18, scope: !9)
+!16 = !DILocation(line: 1, column: 21, scope: !9)
+

diff  --git a/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll b/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
index 18dc038fce66a..612a0be25ab17 100644
--- a/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
+++ b/llvm/test/Transforms/GlobalOpt/localize-constexpr-debuginfo.ll
@@ -11,8 +11,8 @@ define i32 @main(i32 %argc, ptr %argv) norecurse !dbg !18 {
 ; CHECK: alloca ptr
 ; Make sure the metadata is sane. Currently, we just drop the metadata,
 ; so it points to nothing.
-; CHECK: call void @llvm.dbg.value(metadata !2,
-; CHECK: !2 = !{}
+; CHECK: call void @llvm.dbg.value(metadata !{},
+
 entry:
   call void @llvm.dbg.value(metadata i32 %argc, metadata !22, metadata !23), !dbg !24
   call void @llvm.dbg.value(metadata ptr %argv, metadata !25, metadata !23), !dbg !26

diff  --git a/llvm/test/Transforms/GlobalOpt/metadata.ll b/llvm/test/Transforms/GlobalOpt/metadata.ll
index 3b6e121d7ce6e..8dda0be7452a2 100644
--- a/llvm/test/Transforms/GlobalOpt/metadata.ll
+++ b/llvm/test/Transforms/GlobalOpt/metadata.ll
@@ -18,7 +18,7 @@ define void @foo(i32 %x) {
 ; null, the ValueAsMetadata instance gets replaced by metadata !{}, or
 ; MDNode::get({}).
   call void @llvm.foo(metadata ptr @G, metadata i32 %x)
-; CHECK: call void @llvm.foo(metadata ![[EMPTY:[0-9]+]], metadata i32 %x)
+; CHECK: call void @llvm.foo(metadata !{}, metadata i32 %x)
   ret void
 }
 
@@ -29,4 +29,3 @@ declare void @llvm.foo(metadata, metadata) nounwind readnone
 
 !0 = !{ptr @G}
 ; CHECK-DAG: ![[NULL]] = distinct !{null}
-; CHECK-DAG: ![[EMPTY]] = !{}

diff  --git a/llvm/test/Transforms/LoopIdiom/debug-line.ll b/llvm/test/Transforms/LoopIdiom/debug-line.ll
index 017d63d0c14a5..7b565a1360e7e 100644
--- a/llvm/test/Transforms/LoopIdiom/debug-line.ll
+++ b/llvm/test/Transforms/LoopIdiom/debug-line.ll
@@ -18,7 +18,7 @@ define void @foo(ptr nocapture %a) nounwind ssp !dbg !0 {
 ; CHECK-NEXT:    [[EXITCOND:%.*]] = icmp ne i64 [[INDVAR_NEXT]], 1000
 ; CHECK-NEXT:    br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]], !dbg [[DBG15]]
 ; CHECK:       for.end:
-; CHECK-NEXT:    tail call void @llvm.dbg.value(metadata [[META3:![0-9]+]], metadata [[META11]], metadata !DIExpression()), !dbg [[DBG17:![0-9]+]]
+; CHECK-NEXT:    tail call void @llvm.dbg.value(metadata !{}, metadata [[META11]], metadata !DIExpression()), !dbg [[DBG17:![0-9]+]]
 ; CHECK-NEXT:    ret void, !dbg [[DBG18:![0-9]+]]
 ;
 entry:

diff  --git a/llvm/unittests/IR/MetadataTest.cpp b/llvm/unittests/IR/MetadataTest.cpp
index 5342360109d0d..fa559b4c050d8 100644
--- a/llvm/unittests/IR/MetadataTest.cpp
+++ b/llvm/unittests/IR/MetadataTest.cpp
@@ -390,18 +390,20 @@ TEST_F(MDNodeTest, PrintFromMetadataAsValue) {
 
   EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS));
   EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS));
-  EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false));
-  EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false));
-  EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true));
-  EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true));
+  EXPECT_PRINTER_EQ("distinct !{}", MAV0->printAsOperand(OS, false));
+  EXPECT_PRINTER_EQ("distinct !{}", MAV1->printAsOperand(OS, false));
+  EXPECT_PRINTER_EQ("metadata distinct !{}", MAV0->printAsOperand(OS, true));
+  EXPECT_PRINTER_EQ("metadata distinct !{}", MAV1->printAsOperand(OS, true));
 
   ModuleSlotTracker MST(&M);
   EXPECT_PRINTER_EQ("!0 = distinct !{}", MAV0->print(OS, MST));
   EXPECT_PRINTER_EQ("!1 = distinct !{}", MAV1->print(OS, MST));
-  EXPECT_PRINTER_EQ("!0", MAV0->printAsOperand(OS, false, MST));
-  EXPECT_PRINTER_EQ("!1", MAV1->printAsOperand(OS, false, MST));
-  EXPECT_PRINTER_EQ("metadata !0", MAV0->printAsOperand(OS, true, MST));
-  EXPECT_PRINTER_EQ("metadata !1", MAV1->printAsOperand(OS, true, MST));
+  EXPECT_PRINTER_EQ("distinct !{}", MAV0->printAsOperand(OS, false, MST));
+  EXPECT_PRINTER_EQ("distinct !{}", MAV1->printAsOperand(OS, false, MST));
+  EXPECT_PRINTER_EQ("metadata distinct !{}",
+                    MAV0->printAsOperand(OS, true, MST));
+  EXPECT_PRINTER_EQ("metadata distinct !{}",
+                    MAV1->printAsOperand(OS, true, MST));
 }
 
 TEST_F(MDNodeTest, PrintWithDroppedCallOperand) {


        


More information about the llvm-commits mailing list