mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-05 09:24:28 +00:00
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
This commit is contained in:
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user