[LLVMdev] Debug info compileunit metadata strangeness..

Anders Waldenborg anders at 0x63.nu
Sun Mar 4 12:58:42 PST 2012


Hi,

I have a question regarding the metadata for compileunit debug info. I
find a few things in it a bit strange, but maybe there it is a reason
for it to be that way that I just don't understand (but if that is the
case I guess the documentation needs to be clearer).

Consider this C program: "int X;"

Compiled with "clang -g" it debug metadata along these lines:

 !llvm.dbg.cu = !{!0}
 !0 = metadata !{i32 786449, .....
                 metadata !1, ;; List of enums types
                 metadata !1, ;; List of retained types
                 metadata !1, ;; List of subprograms
                 metadata !3  ;; List of global variables
                } ; [ DW_TAG_compile_unit ]
 !1 = metadata !{metadata !2}
 !2 = metadata !{i32 0}
 !3 = metadata !{metadata !4}
 !4 = metadata !{metadata !5}
 !5 = metadata !{i32 786484, ...} ; [ DW_TAG_variable ]


Documentation says "List of global variables", but it is built as a
"One element list containing the list of global variables". Is there a
reason it is built that way?

Looking at DIBuilder::createCompileUnit it does indeed build it with
an extra indirection.

Another thing I find strange is the empty lists, such as "List of
enums types" in my example above. They apparently end up being
one-element lists containing "i32 0". I would expect that the
reference to the empty lists would be "null".

In other words, I'd expect it to look like this:

 !llvm.dbg.cu = !{!0}

 !0 = metadata !{i32 786449, ...
                 null,        ;; List of enums types
                 null,        ;; List of retained types
                 null,        ;; List of subprograms
                 metadata !1  ;; List of global variables
                } ; [ DW_TAG_compile_unit ]
 !1 = metadata !{metadata !2}
 !2 = metadata !{i32 786484, ...} ; [ DW_TAG_variable ]


I attached two patches that changes compileunit metadata to have the
layout I think makes sense. I do not expect these patches to be
applied (especially the second one is just a gross hack), I'm
attaching them because maybe they may help show what I'm trying to say
(a patch says more than 1000 words?).

 anders

-------------- next part --------------
From 8c6193bc46573858741be624893ff7745020ec48 Mon Sep 17 00:00:00 2001
From: Anders Waldenborg <anders at 0x63.nu>
Date: Sun, 4 Mar 2012 13:56:21 +0100
Subject: [PATCH 1/2] No indirection of in compileunit debuginfo

---
 lib/Analysis/DIBuilder.cpp |   20 +++++---------------
 1 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp
index f0bdc48..5d37123 100644
--- a/lib/Analysis/DIBuilder.cpp
+++ b/lib/Analysis/DIBuilder.cpp
@@ -82,21 +82,11 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
   assert(!Filename.empty() &&
          "Unable to create compile unit without filename");
   Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) };
-  TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
-  Value *THElts[] = { TempEnumTypes };
-  MDNode *EnumHolder = MDNode::get(VMContext, THElts);
 
+  TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
   TempRetainTypes = MDNode::getTemporary(VMContext, TElts);
-  Value *TRElts[] = { TempRetainTypes };
-  MDNode *RetainHolder = MDNode::get(VMContext, TRElts);
-
   TempSubprograms = MDNode::getTemporary(VMContext, TElts);
-  Value *TSElts[] = { TempSubprograms };
-  MDNode *SPHolder = MDNode::get(VMContext, TSElts);
-
   TempGVs = MDNode::getTemporary(VMContext, TElts);
-  Value *TVElts[] = { TempGVs };
-  MDNode *GVHolder = MDNode::get(VMContext, TVElts);
 
   Value *Elts[] = {
     GetTagConstant(VMContext, dwarf::DW_TAG_compile_unit),
@@ -110,10 +100,10 @@ void DIBuilder::createCompileUnit(unsigned Lang, StringRef Filename,
     ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized),
     MDString::get(VMContext, Flags),
     ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeVer),
-    EnumHolder,
-    RetainHolder,
-    SPHolder,
-    GVHolder
+    TempEnumTypes,
+    TempRetainTypes,
+    TempSubprograms,
+    TempGVs
   };
   TheCU = DICompileUnit(MDNode::get(VMContext, Elts));
 
-- 
1.7.9.1

-------------- next part --------------
From 92c9c2646f767d7b532da5b5f548936a52a453fa Mon Sep 17 00:00:00 2001
From: Anders Waldenborg <anders at 0x63.nu>
Date: Sun, 4 Mar 2012 20:42:24 +0100
Subject: [PATCH 2/2] hack: make empty lists null in compileunit debuginfo

---
 lib/Analysis/DIBuilder.cpp |   56 ++++++++++++++++++++++++++++---------------
 1 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/lib/Analysis/DIBuilder.cpp b/lib/Analysis/DIBuilder.cpp
index 5d37123..b18a60e 100644
--- a/lib/Analysis/DIBuilder.cpp
+++ b/lib/Analysis/DIBuilder.cpp
@@ -36,30 +36,46 @@ DIBuilder::DIBuilder(Module &m)
 
 /// finalize - Construct any deferred debug info descriptors.
 void DIBuilder::finalize() {
-  DIArray Enums = getOrCreateArray(AllEnumTypes);
-  DIType(TempEnumTypes).replaceAllUsesWith(Enums);
-
-  DIArray RetainTypes = getOrCreateArray(AllRetainTypes);
-  DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes);
-
-  DIArray SPs = getOrCreateArray(AllSubprograms);
-  DIType(TempSubprograms).replaceAllUsesWith(SPs);
-  for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
-    DISubprogram SP(SPs.getElement(i));
-    if (NamedMDNode *NMD = getFnSpecificMDNode(M, SP)) {
-      SmallVector<Value *, 4> Variables;
-      for (unsigned ii = 0, ee = NMD->getNumOperands(); ii != ee; ++ii)
-        Variables.push_back(NMD->getOperand(ii));
-      if (MDNode *Temp = SP.getVariablesNodes()) {
-        DIArray AV = getOrCreateArray(Variables);
-        DIType(Temp).replaceAllUsesWith(AV);
+  if (AllEnumTypes.empty()) {
+    TheCU->replaceOperandWith(10, NULL);
+  } else {
+    DIArray Enums = getOrCreateArray(AllEnumTypes);
+    DIType(TempEnumTypes).replaceAllUsesWith(Enums);
+  }
+
+  if (AllRetainTypes.empty()) {
+    TheCU->replaceOperandWith(11, NULL);
+  } else {
+    DIArray RetainTypes = getOrCreateArray(AllRetainTypes);
+    DIType(TempRetainTypes).replaceAllUsesWith(RetainTypes);
+  }
+
+  if (AllSubprograms.empty()) {
+    TheCU->replaceOperandWith(12, NULL);
+  } else {
+    DIArray SPs = getOrCreateArray(AllSubprograms);
+    DIType(TempSubprograms).replaceAllUsesWith(SPs);
+    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
+      DISubprogram SP(SPs.getElement(i));
+      if (NamedMDNode *NMD = getFnSpecificMDNode(M, SP)) {
+	SmallVector<Value *, 4> Variables;
+	for (unsigned ii = 0, ee = NMD->getNumOperands(); ii != ee; ++ii)
+	  Variables.push_back(NMD->getOperand(ii));
+	if (MDNode *Temp = SP.getVariablesNodes()) {
+	  DIArray AV = getOrCreateArray(Variables);
+	  DIType(Temp).replaceAllUsesWith(AV);
+	}
+	NMD->eraseFromParent();
       }
-      NMD->eraseFromParent();
     }
   }
 
-  DIArray GVs = getOrCreateArray(AllGVs);
-  DIType(TempGVs).replaceAllUsesWith(GVs);
+  if (AllGVs.empty()) {
+    TheCU->replaceOperandWith(13, NULL);
+  } else {
+    DIArray GVs = getOrCreateArray(AllGVs);
+    DIType(TempGVs).replaceAllUsesWith(GVs);
+  }
 }
 
 /// getNonCompileUnitScope - If N is compile unit return NULL otherwise return
-- 
1.7.9.1



More information about the llvm-dev mailing list