[llvm] r224325 - IR: Make MDNode::dump() useful by adding addresses

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Dec 15 23:09:38 PST 2014


Author: dexonsmith
Date: Tue Dec 16 01:09:37 2014
New Revision: 224325

URL: http://llvm.org/viewvc/llvm-project?rev=224325&view=rev
Log:
IR: Make MDNode::dump() useful by adding addresses

It's horrible to inspect `MDNode`s in a debugger.  All of their operands
that are `MDNode`s get dumped as `<badref>`, since we can't assign
metadata slots in the context of a `Metadata::dump()`.  (Why not?  Why
not assign numbers lazily?  Because then each time you called `dump()`,
a given `MDNode` could have a different lazily assigned number.)

Fortunately, the C memory model gives us perfectly good identifiers for
`MDNode`.  Add pointer addresses to the dumps, transforming this:

    (lldb) e N->dump()
    !{i32 662302, i32 26, <badref>, null}

    (lldb) e ((MDNode*)N->getOperand(2))->dump()
    !{i32 4, !"foo"}

into:

    (lldb) e N->dump()
    !{i32 662302, i32 26, <0x100706ee0>, null}

    (lldb) e ((MDNode*)0x100706ee0)->dump()
    !{i32 4, !"foo"}

and this:

    (lldb) e N->dump()
    0x101200248 = !{<badref>, <badref>, <badref>, <badref>, <badref>}

    (lldb) e N->getOperand(0)
    (const llvm::MDOperand) $0 = {
      MD = 0x00000001012004e0
    }
    (lldb) e N->getOperand(1)
    (const llvm::MDOperand) $1 = {
      MD = 0x00000001012004e0
    }
    (lldb) e N->getOperand(2)
    (const llvm::MDOperand) $2 = {
      MD = 0x0000000101200058
    }
    (lldb) e N->getOperand(3)
    (const llvm::MDOperand) $3 = {
      MD = 0x00000001012004e0
    }
    (lldb) e N->getOperand(4)
    (const llvm::MDOperand) $4 = {
      MD = 0x0000000101200058
    }
    (lldb) e ((MDNode*)0x00000001012004e0)->dump()
    !{}

    (lldb) e ((MDNode*)0x0000000101200058)->dump()
    !{null}

into:

    (lldb) e N->dump()
    !{<0x1012004e0>, <0x1012004e0>, <0x101200058>, <0x1012004e0>, <0x101200058>}

    (lldb) e ((MDNode*)0x1012004e0)->dump()
    !{}

    (lldb) e ((MDNode*)0x101200058)->dump()
    !{null}

Modified:
    llvm/trunk/lib/IR/AsmWriter.cpp
    llvm/trunk/unittests/IR/MetadataTest.cpp

Modified: llvm/trunk/lib/IR/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/AsmWriter.cpp?rev=224325&r1=224324&r2=224325&view=diff
==============================================================================
--- llvm/trunk/lib/IR/AsmWriter.cpp (original)
+++ llvm/trunk/lib/IR/AsmWriter.cpp Tue Dec 16 01:09:37 2014
@@ -1362,7 +1362,9 @@ static void WriteAsOperandInternal(raw_o
       Machine = new SlotTracker(Context);
     int Slot = Machine->getMetadataSlot(N);
     if (Slot == -1)
-      Out << "<badref>";
+      // Give the pointer value instead of "badref", since this comes up all
+      // the time when debugging.
+      Out << "<" << N << ">";
     else
       Out << '!' << Slot;
     return;

Modified: llvm/trunk/unittests/IR/MetadataTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/MetadataTest.cpp?rev=224325&r1=224324&r2=224325&view=diff
==============================================================================
--- llvm/trunk/unittests/IR/MetadataTest.cpp (original)
+++ llvm/trunk/unittests/IR/MetadataTest.cpp Tue Dec 16 01:09:37 2014
@@ -22,6 +22,12 @@ namespace {
 class MetadataTest : public testing::Test {
 protected:
   LLVMContext Context;
+  MDNode *getNode() { return MDNode::get(Context, None); }
+  MDNode *getNode(Metadata *MD) { return MDNode::get(Context, MD); }
+  MDNode *getNode(Metadata *MD1, Metadata *MD2) {
+    Metadata *MDs[] = {MD1, MD2};
+    return MDNode::get(Context, MDs);
+  }
 };
 typedef MetadataTest MDStringTest;
 
@@ -163,6 +169,39 @@ TEST_F(MDNodeTest, SelfReference) {
   }
 }
 
+TEST_F(MDNodeTest, Print) {
+  Constant *C = ConstantInt::get(Type::getInt32Ty(Context), 7);
+  MDString *S = MDString::get(Context, "foo");
+  MDNode *N0 = getNode();
+  MDNode *N1 = getNode(N0);
+  MDNode *N2 = getNode(N0, N1);
+
+  Metadata *Args[] = {ConstantAsMetadata::get(C), S, nullptr, N0, N1, N2};
+  MDNode *N = MDNode::get(Context, Args);
+
+  std::string Expected;
+  {
+    raw_string_ostream OS(Expected);
+    OS << "metadata !{";
+    C->printAsOperand(OS);
+    OS << ", ";
+    S->printAsOperand(OS, false);
+    OS << ", null";
+    MDNode *Nodes[] = {N0, N1, N2};
+    for (auto *Node : Nodes)
+      OS << ", <" << (void *)Node << ">";
+    OS << "}\n";
+  }
+
+  std::string Actual;
+  {
+    raw_string_ostream OS(Actual);
+    N->print(OS);
+  }
+
+  EXPECT_EQ(Expected, Actual);
+}
+
 typedef MetadataTest MetadataAsValueTest;
 
 TEST_F(MetadataAsValueTest, MDNode) {





More information about the llvm-commits mailing list