<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Nov 19, 2013 at 3:08 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dblaikie<br>
Date: Tue Nov 19 17:08:21 2013<br>
New Revision: 195166<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=195166&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=195166&view=rev</a><br>
Log:<br>
DebugInfo: Partial implementation of DWARF type units.<br>
<br>
Emit DW_TAG_type_units into the debug_info section using compile unit<br>
headers. This is bogus/unusable by debuggers, but testable and provides<br>
more isolated review.<br>
<br>
Subsequent patches will include support for type unit headers and<br>
emission into the debug_types section, as well as comdat grouping the<br>
types based on their hash. Also the CompileUnit type will be renamed<br>
'Unit' and relevant portions pulled out into respective CompileUnit and<br>
TypeUnit types.<br>
<br>
Modified:<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp Tue Nov 19 17:08:21 2013<br>
@@ -114,18 +114,19 @@ DIE::~DIE() {<br>
<br>
/// Climb up the parent chain to get the compile unit DIE to which this DIE<br>
/// belongs.<br>
-const DIE *DIE::getCompileUnit() const {<br>
- const DIE *Cu = getCompileUnitOrNull();<br>
+const DIE *DIE::getUnit() const {<br>
+ const DIE *Cu = getUnitOrNull();<br></blockquote><div><br></div><div>Hi David,</div><div><br></div><div>To help reviewing the changes, it is better to separate changes to getCompileUnit and getCompileUnitOrNull to a separate patch.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
assert(Cu && "We should not have orphaned DIEs.");<br>
return Cu;<br>
}<br>
<br>
/// Climb up the parent chain to get the compile unit DIE this DIE belongs<br>
/// to. Return NULL if DIE is not added to an owner yet.<br>
-const DIE *DIE::getCompileUnitOrNull() const {<br>
+const DIE *DIE::getUnitOrNull() const {<br>
const DIE *p = this;<br>
while (p) {<br>
- if (p->getTag() == dwarf::DW_TAG_compile_unit)<br>
+ if (p->getTag() == dwarf::DW_TAG_compile_unit ||<br>
+ p->getTag() == dwarf::DW_TAG_type_unit)<br></blockquote><div><br></div><div>Same here.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
return p;<br>
p = p->getParent();<br>
}<br>
@@ -227,6 +228,7 @@ void DIEInteger::EmitValue(AsmPrinter *A<br>
case dwarf::DW_FORM_ref4: // Fall thru<br>
case dwarf::DW_FORM_data4: Size = 4; break;<br>
case dwarf::DW_FORM_ref8: // Fall thru<br>
+ case dwarf::DW_FORM_ref_sig8: // Fall thru<br>
case dwarf::DW_FORM_data8: Size = 8; break;<br>
case dwarf::DW_FORM_GNU_str_index: Asm->EmitULEB128(Integer); return;<br>
case dwarf::DW_FORM_GNU_addr_index: Asm->EmitULEB128(Integer); return;<br>
@@ -253,6 +255,7 @@ unsigned DIEInteger::SizeOf(AsmPrinter *<br>
case dwarf::DW_FORM_ref4: // Fall thru<br>
case dwarf::DW_FORM_data4: return sizeof(int32_t);<br>
case dwarf::DW_FORM_ref8: // Fall thru<br>
+ case dwarf::DW_FORM_ref_sig8: // Fall thru<br>
case dwarf::DW_FORM_data8: return sizeof(int64_t);<br>
case dwarf::DW_FORM_GNU_str_index: return MCAsmInfo::getULEB128Size(Integer);<br>
case dwarf::DW_FORM_GNU_addr_index: return MCAsmInfo::getULEB128Size(Integer);<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.h Tue Nov 19 17:08:21 2013<br>
@@ -146,12 +146,12 @@ namespace llvm {<br>
const std::vector<DIE *> &getChildren() const { return Children; }<br>
const SmallVectorImpl<DIEValue*> &getValues() const { return Values; }<br>
DIE *getParent() const { return Parent; }<br>
- /// Climb up the parent chain to get the compile unit DIE this DIE belongs<br>
- /// to.<br>
- const DIE *getCompileUnit() const;<br>
- /// Similar to getCompileUnit, returns null when DIE is not added to an<br>
+ /// Climb up the parent chain to get the compile or type unit DIE this DIE<br>
+ /// belongs to.<br>
+ const DIE *getUnit() const;<br>
+ /// Similar to getUnit, returns null when DIE is not added to an<br>
/// owner yet.<br>
- const DIE *getCompileUnitOrNull() const;<br>
+ const DIE *getUnitOrNull() const;<br></blockquote><div>Same here.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
void setOffset(unsigned O) { Offset = O; }<br>
void setSize(unsigned S) { Size = S; }<br>
<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp Tue Nov 19 17:08:21 2013<br>
@@ -92,10 +92,12 @@ void DIEHash::addParentContext(const DIE<br>
// outermost such construct...<br>
SmallVector<const DIE *, 1> Parents;<br>
const DIE *Cur = &Parent;<br>
- while (Cur->getTag() != dwarf::DW_TAG_compile_unit) {<br>
+ while (Cur->getParent()) {<br>
Parents.push_back(Cur);<br>
Cur = Cur->getParent();<br>
}<br>
+ assert(Cur->getTag() == dwarf::DW_TAG_compile_unit ||<br>
+ Cur->getTag() == dwarf::DW_TAG_type_unit);<br>
<br>
// Reverse iterate over our list to go from the outermost construct to the<br>
// innermost.<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Nov 19 17:08:21 2013<br>
@@ -29,18 +29,30 @@<br>
#include "llvm/Target/TargetMachine.h"<br>
#include "llvm/Target/TargetLoweringObjectFile.h"<br>
#include "llvm/Target/TargetRegisterInfo.h"<br>
+#include "llvm/Support/CommandLine.h"<br>
<br>
using namespace llvm;<br>
<br>
+static cl::opt<bool> GenerateTypeUnits("generate-type-units", cl::Hidden,<br>
+ cl::desc("Generate DWARF4 type units."),<br>
+ cl::init(false));<br>
+<br>
/// CompileUnit - Compile unit constructor.<br>
CompileUnit::CompileUnit(unsigned UID, DIE *D, DICompileUnit Node,<br>
AsmPrinter *A, DwarfDebug *DW, DwarfUnits *DWU)<br>
: UniqueID(UID), Node(Node), CUDie(D), Asm(A), DD(DW), DU(DWU),<br>
- IndexTyDie(0), DebugInfoOffset(0) {<br>
+ IndexTyDie(0), Language(Node.getLanguage()) {<br></blockquote><div>Is removing initialization to DebugInfoOffset intentional?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);<br>
insertDIE(Node, D);<br>
}<br>
<br>
+CompileUnit::CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,<br>
+ DwarfDebug *DD, DwarfUnits *DU)<br>
+ : UniqueID(UID), Node(NULL), CUDie(D), Asm(A), DD(DD), DU(DU),<br>
+ IndexTyDie(0), Language(Language) {<br></blockquote><div>Should we initialize DebugInfoOffset here?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);<br>
+}<br>
+<br>
/// ~CompileUnit - Destructor for compile unit.<br>
CompileUnit::~CompileUnit() {<br>
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)<br>
@@ -102,7 +114,9 @@ int64_t CompileUnit::getDefaultLowerBoun<br>
static bool isShareableAcrossCUs(DIDescriptor D) {<br>
// When the MDNode can be part of the type system, the DIE can be<br>
// shared across CUs.<br>
- return D.isType() || (D.isSubprogram() && !DISubprogram(D).isDefinition());<br>
+ return (D.isType() ||<br>
+ (D.isSubprogram() && !DISubprogram(D).isDefinition())) &&<br>
+ !GenerateTypeUnits;<br></blockquote><div><br></div><div>It is nice if we can have a comment explaining why when generating type units, we don't share MDNodes.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
}<br>
<br>
/// getDIE - Returns the debug information entry map slot for the<br>
@@ -281,8 +295,8 @@ void CompileUnit::addDIEEntry(DIE *Die,<br>
<br>
void CompileUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,<br>
DIEEntry *Entry) {<br>
- const DIE *DieCU = Die->getCompileUnitOrNull();<br>
- const DIE *EntryCU = Entry->getEntry()->getCompileUnitOrNull();<br>
+ const DIE *DieCU = Die->getUnitOrNull();<br>
+ const DIE *EntryCU = Entry->getEntry()->getUnitOrNull();<br>
if (!DieCU)<br>
// We assume that Die belongs to this CU, if it is not linked to any CU yet.<br>
DieCU = getCUDie();<br>
@@ -871,6 +885,22 @@ DIE *CompileUnit::getOrCreateContextDIE(<br>
return getDIE(Context);<br>
}<br>
<br>
+DIE *CompileUnit::createTypeDIE(DICompositeType Ty) {<br>
+ DIE *ContextDIE = getOrCreateContextDIE(resolve(Ty.getContext()));<br>
+<br>
+ DIE *TyDIE = getDIE(Ty);<br>
+ if (TyDIE)<br>
+ return TyDIE;<br>
+<br>
+ // Create new type.<br>
+ TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);<br>
+<br>
+ constructTypeDIEImpl(*TyDIE, Ty);<br>
+<br>
+ updateAcceleratorTables(Ty, TyDIE);<br>
+ return TyDIE;<br>
+}<br>
+<br>
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the<br>
/// given DIType.<br>
DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {<br>
@@ -1112,6 +1142,9 @@ static bool isTypeUnitScoped(DIType Ty,<br>
<br>
/// Return true if the type should be split out into a type unit.<br>
static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {<br>
+ if (!GenerateTypeUnits)<br>
+ return false;<br>
+<br>
uint16_t Tag = CTy.getTag();<br>
<br>
switch (Tag) {<br>
@@ -1130,7 +1163,16 @@ static bool shouldCreateTypeUnit(DICompo<br>
<br>
/// constructTypeDIE - Construct type DIE from DICompositeType.<br>
void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {<br>
- // Get core information.<br>
+ // If this is a type applicable to a type unit it then add it to the<br>
+ // list of types we'll compute a hash for later.<br>
+ if (shouldCreateTypeUnit(CTy, DD))<br>
+ DD->addTypeUnitType(&Buffer, CTy);<br>
+ else<br>
+ constructTypeDIEImpl(Buffer, CTy);<br>
+}<br>
+<br>
+void CompileUnit::constructTypeDIEImpl(DIE &Buffer, DICompositeType CTy) {<br>
+ // Add name if not anonymous or intermediate type.<br>
StringRef Name = CTy.getName();<br>
<br>
uint64_t Size = CTy.getSizeInBits() >> 3;<br>
@@ -1296,10 +1338,6 @@ void CompileUnit::constructTypeDIE(DIE &<br>
addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,<br>
RLang);<br>
}<br>
- // If this is a type applicable to a type unit it then add it to the<br>
- // list of types we'll compute a hash for later.<br>
- if (shouldCreateTypeUnit(CTy, DD))<br>
- DD->addTypeUnitType(&Buffer);<br>
}<br>
<br>
/// constructTemplateTypeParameterDIE - Construct new DIE for the given<br>
@@ -1510,7 +1548,6 @@ static const ConstantExpr *getMergedGlob<br>
<br>
/// createGlobalVariableDIE - create global variable DIE.<br>
void CompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {<br>
-<br>
// Check for pre-existence.<br>
if (getDIE(GV))<br>
return;<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h Tue Nov 19 17:08:21 2013<br>
@@ -93,14 +93,18 @@ class CompileUnit {<br>
// DIEIntegerOne - A preallocated DIEValue because 1 is used frequently.<br>
DIEInteger *DIEIntegerOne;<br>
<br>
+ uint16_t Language;<br>
+<br>
public:<br>
CompileUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,<br>
DwarfDebug *DW, DwarfUnits *DWU);<br>
+ CompileUnit(unsigned UID, DIE *D, uint16_t Language, AsmPrinter *A,<br>
+ DwarfDebug *DW, DwarfUnits *DWU);<br>
~CompileUnit();<br>
<br>
// Accessors.<br>
unsigned getUniqueID() const { return UniqueID; }<br>
- uint16_t getLanguage() const { return Node.getLanguage(); }<br>
+ uint16_t getLanguage() const { return Language; }<br>
DICompileUnit getNode() const { return Node; }<br>
DIE *getCUDie() const { return CUDie.get(); }<br>
const StringMap<DIE *> &getGlobalNames() const { return GlobalNames; }<br>
@@ -311,6 +315,9 @@ public:<br>
DIE *getOrCreateTypeDIE(const MDNode *N);<br>
<br>
/// getOrCreateContextDIE - Get context owner's DIE.<br>
+ DIE *createTypeDIE(DICompositeType Ty);<br>
+<br>
+ /// getOrCreateContextDIE - Get context owner's DIE.<br>
DIE *getOrCreateContextDIE(DIScope Context);<br>
<br>
/// createGlobalVariableDIE - create global variable DIE.<br>
@@ -328,6 +335,10 @@ public:<br>
DIE *createAndAddDIE(unsigned Tag, DIE &Parent,<br>
DIDescriptor N = DIDescriptor());<br>
<br>
+ /// constructTypeDIEImpl - Construct type DIE that is not a type unit<br>
+ /// reference from a DICompositeType.<br>
+ void constructTypeDIEImpl(DIE &Buffer, DICompositeType CTy);<br>
+<br>
/// Compute the size of a header for this unit, not including the initial<br>
/// length field.<br>
unsigned getHeaderSize() const {<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Nov 19 17:08:21 2013<br>
@@ -1051,22 +1051,6 @@ void DwarfDebug::finalizeModuleInfo() {<br>
// Attach DW_AT_inline attribute with inlined subprogram DIEs.<br>
computeInlinedDIEs();<br>
<br>
- // Split out type units and conditionally add an ODR tag to the split<br>
- // out type.<br>
- // FIXME: Do type splitting.<br>
- for (unsigned i = 0, e = TypeUnits.size(); i != e; ++i) {<br>
- DIE *Die = TypeUnits[i];<br>
- DIEHash Hash;<br>
- // If we've requested ODR hashes and it's applicable for an ODR hash then<br>
- // add the ODR signature now.<br>
- // FIXME: This should be added onto the type unit, not the type, but this<br>
- // works as an intermediate stage.<br>
- if (GenerateODRHash && shouldAddODRHash(CUMap.begin()->second, Die))<br>
- CUMap.begin()->second->addUInt(Die, dwarf::DW_AT_GNU_odr_signature,<br>
- dwarf::DW_FORM_data8,<br>
- Hash.computeDIEODRSignature(*Die));<br>
- }<br>
-<br>
// Handle anything that needs to be done on a per-cu basis.<br>
for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),<br>
CUE = CUMap.end();<br>
@@ -2071,7 +2055,7 @@ void DwarfDebug::emitDIE(DIE *Die, Array<br>
// For DW_FORM_ref_addr, output the offset from beginning of debug info<br>
// section. Origin->getOffset() returns the offset from start of the<br>
// compile unit.<br>
- CompileUnit *CU = CUDieMap.lookup(Origin->getCompileUnit());<br>
+ CompileUnit *CU = CUDieMap.lookup(Origin->getUnit());<br>
assert(CU && "CUDie should belong to a CU.");<br>
Addr += CU->getDebugInfoOffset();<br>
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())<br>
@@ -2083,7 +2067,7 @@ void DwarfDebug::emitDIE(DIE *Die, Array<br>
DIEEntry::getRefAddrSize(Asm));<br>
} else {<br>
// Make sure Origin belong to the same CU.<br>
- assert(Die->getCompileUnit() == Origin->getCompileUnit() &&<br>
+ assert(Die->getUnit() == Origin->getUnit() &&<br>
"The referenced DIE should belong to the same CU in ref4");<br>
Asm->EmitInt32(Addr);<br>
}<br>
@@ -3063,3 +3047,57 @@ void DwarfDebug::emitDebugStrDWO() {<br>
InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),<br>
OffSec, StrSym);<br>
}<br>
+<br>
+void DwarfDebug::addTypeUnitType(DIE *RefDie, DICompositeType CTy) {<br>
+ DenseMap<const MDNode*, std::pair<uint64_t, SmallVectorImpl<DIE*>* > >::iterator I = TypeUnits.find(CTy);<br>
+ SmallVector<DIE *, 8> References;<br>
+ References.push_back(RefDie);<br>
+ if (I != TypeUnits.end()) {<br>
+ if (I->second.second) {<br>
+ I->second.second->push_back(RefDie);<br>
+ return;<br>
+ }<br>
+ } else {<br>
+ DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);<br>
+ CompileUnit *NewCU =<br>
+ new CompileUnit(GlobalCUIndexCount++, UnitDie,<br>
+ dwarf::DW_LANG_C_plus_plus, Asm, this, &InfoHolder);<br>
+ CUDieMap.insert(std::make_pair(UnitDie, NewCU));<br>
+ NewCU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,<br>
+ dwarf::DW_LANG_C_plus_plus);<br>
+<br>
+ // Register the type in the TypeUnits map with a vector of references to be<br>
+ // populated whenever a reference is required.<br>
+ I = TypeUnits.insert(std::make_pair(CTy, std::make_pair(0, &References)))<br>
+ .first;<br>
+<br>
+ // Construct the type, this may, recursively, require more type units that<br>
+ // may in turn require this type again - in which case they will add DIEs to<br>
+ // the References vector.<br>
+ DIE *Die = NewCU->createTypeDIE(CTy);<br>
+<br>
+ if (GenerateODRHash && shouldAddODRHash(NewCU, Die))<br>
+ NewCU->addUInt(UnitDie, dwarf::DW_AT_GNU_odr_signature,<br>
+ dwarf::DW_FORM_data8,<br>
+ DIEHash().computeDIEODRSignature(*Die));<br>
+ // FIXME: This won't handle circularly referential structures, as the DIE<br>
+ // may have references to other DIEs still under construction and missing<br>
+ // their signature. Hashing should walk through the signatures to their<br>
+ // referenced type, or possibly walk the precomputed hashes of related types<br>
+ // at the end.<br>
+ uint64_t Signature = DIEHash().computeTypeSignature(*Die);<br>
+<br>
+ // Remove the References vector and add the type hash.<br>
+ I->second.first = Signature;<br>
+ I->second.second = NULL;<br>
+<br>
+<br>
+ InfoHolder.addUnit(NewCU);<br>
+ }<br>
+<br>
+ // Populate all the signatures.<br>
+ for (unsigned i = 0, e = References.size(); i != e; ++i) {<br>
+ CUMap.begin()->second->addUInt(References[i], dwarf::DW_AT_signature,<br>
+ dwarf::DW_FORM_ref_sig8, I->second.first);<br>
+ }<br>
+}<br>
<br>
Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)<br>
+++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Nov 19 17:08:21 2013<br>
@@ -37,6 +37,7 @@ class MachineFrameInfo;<br>
class MachineModuleInfo;<br>
class MachineOperand;<br>
class MCAsmInfo;<br>
+class MCObjectFileInfo;<br>
class DIEAbbrev;<br>
class DIE;<br>
class DIEBlock;<br>
@@ -443,7 +444,7 @@ class DwarfDebug {<br>
ImportedEntityMap ScopesWithImportedEntities;<br>
<br>
// Holder for types that are going to be extracted out into a type unit.<br>
- std::vector<DIE *> TypeUnits;<br>
+ DenseMap<const MDNode *, std::pair<uint64_t, SmallVectorImpl<DIE*>* > > TypeUnits;<br></blockquote><div><br></div><div>Can you add a comment here explaining the pair?</div><div><br></div><div>Thanks,</div>
<div>Manman</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
// Whether to emit the pubnames/pubtypes sections.<br>
bool HasDwarfPubSections;<br>
@@ -695,7 +696,7 @@ public:<br>
<br>
/// \brief Add a DIE to the set of types that we're going to pull into<br>
/// type units.<br>
- void addTypeUnitType(DIE *Die) { TypeUnits.push_back(Die); }<br>
+ void addTypeUnitType(DIE *Die, DICompositeType CTy);<br>
<br>
/// \brief Add a label so that arange data can be generated for it.<br>
void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }<br>
<br>
Modified: llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll?rev=195166&r1=195165&r2=195166&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll?rev=195166&r1=195165&r2=195166&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll (original)<br>
+++ llvm/trunk/test/DebugInfo/X86/generate-odr-hash.ll Tue Nov 19 17:08:21 2013<br>
@@ -1,6 +1,6 @@<br>
; REQUIRES: object-emission<br>
<br>
-; RUN: llc %s -o %t -filetype=obj -O0 -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu<br>
+; RUN: llc %s -o %t -filetype=obj -O0 -generate-type-units -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu<br>
; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s<br>
;<br>
; Generated from:<br>
@@ -44,9 +44,12 @@<br>
; wombat wom;<br>
<br>
; Check that we generate a hash for bar and the value.<br>
+; CHECK-LABEL: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x200520c0d5b90eff)<br>
; CHECK: DW_TAG_structure_type<br>
; CHECK-NEXT: debug_str{{.*}}"bar"<br>
-; CHECK: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x200520c0d5b90eff)<br>
+<br>
+; Check that we generate a hash for fluffy and the value.<br>
+; CHECK-LABEL: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x9a0124d5a0c21c52)<br>
; CHECK: DW_TAG_namespace<br>
; CHECK-NEXT: debug_str{{.*}}"echidna"<br>
; CHECK: DW_TAG_namespace<br>
@@ -55,34 +58,36 @@<br>
; CHECK-NEXT: debug_str{{.*}}"mongoose"<br>
; CHECK: DW_TAG_class_type<br>
; CHECK-NEXT: debug_str{{.*}}"fluffy"<br>
-; CHECK: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x9a0124d5a0c21c52)<br>
<br>
; We emit no hash for walrus since the type is contained in an anonymous<br>
; namespace and won't violate any ODR-ness.<br>
+; CHECK: DW_TAG_type_unit<br>
+; CHECK-NOT: NULL<br>
+; CHECK-NOT: DW_AT_GNU_odr_signature<br>
; CHECK: DW_TAG_structure_type<br>
; CHECK-NEXT: debug_str{{.*}}"walrus"<br>
; CHECK-NEXT: DW_AT_byte_size<br>
; CHECK-NEXT: DW_AT_decl_file<br>
; CHECK-NEXT: DW_AT_decl_line<br>
-; CHECK-NOT: DW_AT_GNU_odr_signature<br>
; CHECK: DW_TAG_subprogram<br>
<br>
+<br>
; Check that we generate a hash for wombat and the value, but not for the<br>
; anonymous type contained within.<br>
+; CHECK: DW_TAG_type_unit<br>
; CHECK: DW_TAG_structure_type<br>
-; CHECK-NEXT: debug_str{{.*}}wombat<br>
-; CHECK: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x685bcc220141e9d7)<br>
+; The signature for the outer 'wombat' type - this can be FileChecked once the<br>
+; type units are moved to their own section with the full type unit header<br>
+; including the signature<br>
+; CHECK: DW_AT_signature [DW_FORM_ref_sig8] (0x73776f130648b986)<br>
; CHECK: DW_TAG_structure_type<br>
-; CHECK-NEXT: DW_AT_byte_size<br>
-; CHECK-NEXT: DW_AT_decl_file<br>
-; CHECK-NEXT: DW_AT_decl_line<br>
+; CHECK-NOT: DW_AT_name<br>
+; CHECK-NOT: DW_AT_GNU_odr_signature<br>
; CHECK: DW_TAG_member<br>
; CHECK-NEXT: debug_str{{.*}}"a"<br>
-<br>
-; Check that we don't generate a hash for baz.<br>
+; CHECK-LABEL: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x685bcc220141e9d7)<br>
; CHECK: DW_TAG_structure_type<br>
-; CHECK-NEXT: debug_str{{.*}}"baz"<br>
-; CHECK-NOT: DW_AT_GNU_odr_signature<br>
+; CHECK-NEXT: debug_str{{.*}}"wombat"<br>
<br>
%struct.bar = type { i8 }<br>
%"class.echidna::capybara::mongoose::fluffy" = type { i32, i32 }<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>