diff options
author | David Blaikie <dblaikie@gmail.com> | 2014-05-27 18:37:48 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2014-05-27 18:37:48 +0000 |
commit | 254d093f991287bea06e47c27ef2e14db36b1c59 (patch) | |
tree | 957787852e37aee1067aa0c24d4fa517da8f940d /lib/CodeGen/AsmPrinter | |
parent | def5a057976fe7ab21c8a6e6ccf1311d20971f4f (diff) | |
download | llvm-254d093f991287bea06e47c27ef2e14db36b1c59.tar.gz llvm-254d093f991287bea06e47c27ef2e14db36b1c59.tar.bz2 llvm-254d093f991287bea06e47c27ef2e14db36b1c59.tar.xz |
DebugInfo: Lazily construct subprogram definition DIEs.
A further step to correctly emitting concrete out of line definitions
preceeding inlined instances of the same program.
To do this, emission of subprograms must be delayed until required since
we don't know which (abstract only (if there's no out of line
definition), concrete only (if there are no inlined instances), or both)
DIEs are required at the start of the module.
To reduce the test churn in the following commit that actually fixes the
bug, this commit introduces the lazy DIE construction and cleans up test
cases that are impacted by the changes in the resulting DIE ordering.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209675 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6234f12dd2..421cdbd95f 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -314,7 +314,7 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) { // scope then create and insert DIEs for these variables. DIE &DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU, DISubprogram SP) { - DIE *SPDie = SPCU.getDIE(SP); + DIE *SPDie = SPCU.getOrCreateSubprogramDIE(SP); assert(SPDie && "Unable to find subprogram DIE!"); @@ -525,15 +525,18 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, DISubprogram SP(Scope->getScopeNode()); - if (!ProcessedSPNodes.insert(SP)) + DIE *&AbsDef = AbstractSPDies[SP]; + if (AbsDef) return; // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram // was inlined from another compile unit. DwarfCompileUnit &SPCU = *SPMap[SP]; - DIE *AbsDef = SPCU.getDIE(SP); - assert(AbsDef); - AbstractSPDies.insert(std::make_pair(SP, AbsDef)); + AbsDef = SPCU.getOrCreateSubprogramDIE(SP); + + if (!ProcessedSPNodes.insert(SP)) + return; + SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); createAndAddScopeChildren(SPCU, Scope, *AbsDef); } @@ -781,7 +784,7 @@ void DwarfDebug::beginModule() { CU.createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i))); DIArray SPs = CUNode.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) - constructSubprogramDIE(CU, SPs.getElement(i)); + SPMap.insert(std::make_pair(SPs.getElement(i), &CU)); DIArray EnumTypes = CUNode.getEnumTypes(); for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) CU.getOrCreateTypeDIE(EnumTypes.getElement(i)); @@ -818,8 +821,17 @@ void DwarfDebug::finishSubprogramDefinitions() { DIArray Subprograms = TheCU.getSubprograms(); for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { DISubprogram SP(Subprograms.getElement(i)); - if (DIE *D = SPCU->getDIE(SP)) - SPCU->applySubprogramAttributes(SP, *D); + // Perhaps the subprogram is in another CU (such as due to comdat + // folding, etc), in which case ignore it here. + if (SPMap[SP] != SPCU) + continue; + DIE *D = SPCU->getDIE(SP); + if (!D) + // Lazily construct the subprogram if we didn't see either concrete or + // inlined versions during codegen. + D = SPCU->getOrCreateSubprogramDIE(SP); + SPCU->applySubprogramAttributes(SP, *D); + SPCU->addGlobalName(SP.getName(), *D, resolve(SP.getContext())); } } } @@ -863,11 +875,11 @@ void DwarfDebug::collectDeadVariables() { } void DwarfDebug::finalizeModuleInfo() { + finishSubprogramDefinitions(); + // Collect info for variables that were optimized out. collectDeadVariables(); - finishSubprogramDefinitions(); - // Handle anything that needs to be done on a per-unit basis after // all other generation. for (const auto &TheU : getUnits()) { |