From 3f2f9695c5fd922037e7c3ec257ed18e2d4c4b8e Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Wed, 8 Oct 2014 22:20:02 +0000 Subject: [PATCH] Push DwarfDebug::constructScopeDIE down into DwarfCompileUnit One of many steps to generalize subprogram emission to both the DWO and non-DWO sections (to emit -gmlt-like data under fission). Once the functions are pushed down into DwarfCompileUnit some of the data structures will be pushed at least into DwarfFile so that they can be unique per-file, allowing emission to both files independently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@219345 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/iterator_range.h | 4 ++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 59 +++++++++++++++++++++ lib/CodeGen/AsmPrinter/DwarfCompileUnit.h | 4 ++ lib/CodeGen/AsmPrinter/DwarfDebug.h | 45 +++++++++------- 4 files changed, 94 insertions(+), 18 deletions(-) diff --git a/include/llvm/ADT/iterator_range.h b/include/llvm/ADT/iterator_range.h index dd17d6c8f7b..d004ead71f9 100644 --- a/include/llvm/ADT/iterator_range.h +++ b/include/llvm/ADT/iterator_range.h @@ -48,6 +48,10 @@ public: template iterator_range make_range(T x, T y) { return iterator_range(std::move(x), std::move(y)); } + +template iterator_range make_range(std::pair p) { + return iterator_range(std::move(p.first), std::move(p.second)); +} } #endif diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index b48ecfaf27b..bd33c265bef 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -319,4 +319,63 @@ DIE &DwarfCompileUnit::updateSubprogramScopeDIE(DISubprogram SP) { return *SPDie; } +// Construct a DIE for this scope. +void DwarfCompileUnit::constructScopeDIE( + LexicalScope *Scope, SmallVectorImpl> &FinalChildren) { + if (!Scope || !Scope->getScopeNode()) + return; + + DIScope DS(Scope->getScopeNode()); + + assert((Scope->getInlinedAt() || !DS.isSubprogram()) && + "Only handle inlined subprograms here, use " + "constructSubprogramScopeDIE for non-inlined " + "subprograms"); + + SmallVector, 8> Children; + + // We try to create the scope DIE first, then the children DIEs. This will + // avoid creating un-used children then removing them later when we find out + // the scope DIE is null. + std::unique_ptr ScopeDIE; + if (Scope->getParent() && DS.isSubprogram()) { + ScopeDIE = DD->constructInlinedScopeDIE(*this, Scope); + if (!ScopeDIE) + return; + // We create children when the scope DIE is not null. + DD->createScopeChildrenDIE(*this, Scope, Children); + } else { + // Early exit when we know the scope DIE is going to be null. + if (DD->isLexicalScopeDIENull(Scope)) + return; + + unsigned ChildScopeCount; + + // We create children here when we know the scope DIE is not going to be + // null and the children will be added to the scope DIE. + DD->createScopeChildrenDIE(*this, Scope, Children, &ChildScopeCount); + + // There is no need to emit empty lexical block DIE. + for (const auto &E : DD->findImportedEntitiesForScope(DS)) + Children.push_back( + constructImportedEntityDIE(DIImportedEntity(E.second))); + // If there are only other scopes as children, put them directly in the + // parent instead, as this scope would serve no purpose. + if (Children.size() == ChildScopeCount) { + FinalChildren.insert(FinalChildren.end(), + std::make_move_iterator(Children.begin()), + std::make_move_iterator(Children.end())); + return; + } + ScopeDIE = DD->constructLexicalScopeDIE(*this, Scope); + assert(ScopeDIE && "Scope DIE should not be null."); + } + + // Add children + for (auto &I : Children) + ScopeDIE->addChild(std::move(I)); + + FinalChildren.push_back(std::move(ScopeDIE)); +} + } // end llvm namespace diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index a98ab26cc0f..0c4ad4923f1 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -26,6 +26,7 @@ class DIE; class DwarfDebug; class DwarfFile; class MCSymbol; +class LexicalScope; class DwarfCompileUnit : public DwarfUnit { /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding @@ -68,6 +69,9 @@ public: /// variables in this scope then create and insert DIEs for these /// variables. DIE &updateSubprogramScopeDIE(DISubprogram SP); + + void constructScopeDIE(LexicalScope *Scope, + SmallVectorImpl> &FinalChildren); }; } // end llvm namespace diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 52cd9e7e422..9deaa94ca06 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -349,25 +349,11 @@ class DwarfDebug : public AsmPrinterHandler { void ensureAbstractVariableIsCreatedIfScoped(const DIVariable &Var, const MDNode *Scope); - /// \brief A helper function to check whether the DIE for a given Scope is - /// going to be null. - bool isLexicalScopeDIENull(LexicalScope *Scope); - /// \brief A helper function to construct a RangeSpanList for a given /// lexical scope. void addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE, const SmallVectorImpl &Range); - /// \brief Construct new DW_TAG_lexical_block for this scope and - /// attach DW_AT_low_pc/DW_AT_high_pc labels. - std::unique_ptr constructLexicalScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope); - - /// \brief This scope represents inlined body of a function. Construct - /// DIE to represent this concrete inlined copy of the function. - std::unique_ptr constructInlinedScopeDIE(DwarfCompileUnit &TheCU, - LexicalScope *Scope); - /// \brief Construct a DIE for this scope. void constructScopeDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope, SmallVectorImpl> &FinalChildren); @@ -379,10 +365,6 @@ class DwarfDebug : public AsmPrinterHandler { /// \brief Construct a DIE for this subprogram scope. void constructSubprogramScopeDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope); - /// A helper function to create children of a Scope DIE. - DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope, - SmallVectorImpl> &Children, - unsigned *ChildScopeCount = nullptr); /// \brief Emit initial Dwarf sections with a label at the start of each one. void emitSectionLabels(); @@ -680,6 +662,33 @@ public: const MachineFunction *getCurrentFunction() const { return CurFn; } const MCSymbol *getFunctionBeginSym() const { return FunctionBeginSym; } const MCSymbol *getFunctionEndSym() const { return FunctionEndSym; } + + iterator_range findImportedEntitiesForScope(const MDNode *Scope) const { + return make_range(std::equal_range( + ScopesWithImportedEntities.begin(), ScopesWithImportedEntities.end(), + std::pair(Scope, nullptr), less_first())); + } + + /// \brief A helper function to check whether the DIE for a given Scope is + /// going to be null. + bool isLexicalScopeDIENull(LexicalScope *Scope); + + // FIXME: Sink these functions down into DwarfFile/Dwarf*Unit. + + /// \brief Construct new DW_TAG_lexical_block for this scope and + /// attach DW_AT_low_pc/DW_AT_high_pc labels. + std::unique_ptr constructLexicalScopeDIE(DwarfCompileUnit &TheCU, + LexicalScope *Scope); + + /// \brief This scope represents inlined body of a function. Construct + /// DIE to represent this concrete inlined copy of the function. + std::unique_ptr constructInlinedScopeDIE(DwarfCompileUnit &TheCU, + LexicalScope *Scope); + + /// A helper function to create children of a Scope DIE. + DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope, + SmallVectorImpl> &Children, + unsigned *ChildScopeCount = nullptr); }; } // End of namespace llvm -- 2.34.1