[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