diff options
author | Manman Ren <manman.ren@gmail.com> | 2013-10-01 19:52:23 +0000 |
---|---|---|
committer | Manman Ren <manman.ren@gmail.com> | 2013-10-01 19:52:23 +0000 |
commit | 620f436b205ab75e1dd48b9af8823bc30c53fd0e (patch) | |
tree | 14f7063a4c9f6a7de435b7b16894045baeb9ffb0 /lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | dfef7cbfc6a96d129b99750f554c7dbc000d3228 (diff) | |
download | external_llvm-620f436b205ab75e1dd48b9af8823bc30c53fd0e.zip external_llvm-620f436b205ab75e1dd48b9af8823bc30c53fd0e.tar.gz external_llvm-620f436b205ab75e1dd48b9af8823bc30c53fd0e.tar.bz2 |
Debug Info: remove duplication of DIEs when a DIE is part of the type system
and it is shared across CUs.
We add a few maps in DwarfDebug to map MDNodes for the type system to the
corresponding DIEs: MDTypeNodeToDieMap, MDSPNodeToDieMap, and
MDStaticMemberNodeToDieMap. These DIEs can be shared across CUs, that is why we
keep the maps in DwarfDebug instead of CompileUnit.
Sometimes, when we try to add an attribute to a DIE, the DIE is not yet added
to its owner yet, so we don't know whether we should use ref_addr or ref4.
We create a worklist that will be processed during finalization to add
attributes with the correct form (ref_addr or ref4).
We add addDIEEntry to DwarfDebug to be a wrapper around DIE->addValue. It checks
whether we know the correct form, if not, we update the worklist
(DIEEntryWorklist).
A testing case is added to show that we only create a single DIE for a type
MDNode and we use ref_addr to refer to the type DIE.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191792 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 3826255..3f2de40 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -357,7 +357,7 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) { // scope then create and insert DIEs for these variables. DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, const MDNode *SPNode) { - DIE *SPDie = SPCU->getDIE(SPNode); + DIE *SPDie = getSPDIE(SPNode); assert(SPDie && "Unable to find subprogram DIE!"); DISubprogram SP(SPNode); @@ -511,7 +511,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(CompileUnit *TheCU, return NULL; DIScope DS(Scope->getScopeNode()); DISubprogram InlinedSP = getDISubprogram(DS); - DIE *OriginDIE = TheCU->getDIE(InlinedSP); + DIE *OriginDIE = getSPDIE(InlinedSP); if (!OriginDIE) { DEBUG(dbgs() << "Unable to find original DIE for an inlined subprogram."); return NULL; @@ -616,7 +616,7 @@ DIE *DwarfDebug::constructScopeDIE(CompileUnit *TheCU, LexicalScope *Scope) { else if (DS.isSubprogram()) { ProcessedSPNodes.insert(DS); if (Scope->isAbstractScope()) { - ScopeDIE = TheCU->getDIE(DS); + ScopeDIE = getSPDIE(DS); // Note down abstract DIE. if (ScopeDIE) AbstractSPDies.insert(std::make_pair(DS, ScopeDIE)); @@ -992,7 +992,7 @@ void DwarfDebug::collectDeadVariables() { CompileUnit *SPCU = CUMap.lookup(TheCU); assert(SPCU && "Unable to find Compile Unit!"); constructSubprogramDIE(SPCU, SP); - DIE *ScopeDIE = SPCU->getDIE(SP); + DIE *ScopeDIE = getSPDIE(SP); for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) { DIVariable DV(Variables.getElement(vi)); if (!DV.isVariable()) continue; @@ -1065,6 +1065,15 @@ void DwarfDebug::finalizeModuleInfo() { Hash.computeDIEODRSignature(Die)); } + // Process the worklist to add attributes with the correct form (ref_addr or + // ref4). + for (unsigned I = 0, E = DIEEntryWorklist.size(); I < E; I++) { + addDIEEntry(DIEEntryWorklist[I].Die, DIEEntryWorklist[I].Attribute, + dwarf::DW_FORM_ref4, DIEEntryWorklist[I].Entry); + assert(E == DIEEntryWorklist.size() && + "We should not add to the worklist during finalization."); + } + // Handle anything that needs to be done on a per-cu basis. for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(), CUE = CUMap.end(); @@ -2042,7 +2051,11 @@ void DwarfDebug::emitDIE(DIE *Die, std::vector<DIEAbbrev *> *Abbrevs) { Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr)); switch (Attr) { - case dwarf::DW_AT_abstract_origin: { + case dwarf::DW_AT_abstract_origin: + case dwarf::DW_AT_type: + case dwarf::DW_AT_friend: + case dwarf::DW_AT_specification: + case dwarf::DW_AT_containing_type: { DIEEntry *E = cast<DIEEntry>(Values[i]); DIE *Origin = E->getEntry(); unsigned Addr = Origin->getOffset(); @@ -3031,3 +3044,24 @@ void DwarfDebug::emitDebugStrDWO() { InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(), OffSec, StrSym); } + +/// When we don't know whether the correct form is ref4 or ref_addr, we create +/// a worklist item and insert it to DIEEntryWorklist. +void DwarfDebug::addDIEEntry(DIE *Die, uint16_t Attribute, uint16_t Form, + DIEEntry *Entry) { + /// Early exit when we only have a single CU. + if (GlobalCUIndexCount == 1 || Form != dwarf::DW_FORM_ref4) { + Die->addValue(Attribute, Form, Entry); + return; + } + DIE *DieCU = Die->checkCompileUnit(); + DIE *EntryCU = Entry->getEntry()->checkCompileUnit(); + if (!DieCU || !EntryCU) { + // Die or Entry is not added to an owner yet. + insertDIEEntryWorklist(Die, Attribute, Entry); + return; + } + Die->addValue(Attribute, + EntryCU == DieCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr, + Entry); +} |