From 7414b5dffddbde8a039bad1a5ff23ad3c3c3a896 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 19 Sep 2017 15:13:55 +0000 Subject: [PATCH] dwarfdump: Delay parsing abbreviations until they're needed This speeds up dumping specific DIEs by not parsing abbreviations for units that are not used. (this is also handy to have in eventually to speed up llvm-symbolizer for .dwp files, where parsing most of the DWP file can be avoided by using the index) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313635 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h | 6 ++-- include/llvm/DebugInfo/DWARF/DWARFUnit.h | 7 ++-- lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp | 32 +++++++++++++++---- lib/DebugInfo/DWARF/DWARFUnit.cpp | 11 ++++--- 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index 963f285c109..d277ec382ba 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -56,8 +56,9 @@ class DWARFDebugAbbrev { using DWARFAbbreviationDeclarationSetMap = std::map; - DWARFAbbreviationDeclarationSetMap AbbrDeclSets; + mutable DWARFAbbreviationDeclarationSetMap AbbrDeclSets; mutable DWARFAbbreviationDeclarationSetMap::const_iterator PrevAbbrOffsetPos; + mutable Optional Data; public: DWARFDebugAbbrev(); @@ -66,10 +67,11 @@ public: getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const; void dump(raw_ostream &OS) const; + void parse() const; void extract(DataExtractor Data); - bool empty() const { return begin() == end(); } DWARFAbbreviationDeclarationSetMap::const_iterator begin() const { + parse(); return AbbrDeclSets.begin(); } diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 6e85e71e5b3..ebe8cc66d4f 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -139,7 +139,8 @@ class DWARFUnit { uint32_t Offset; uint32_t Length; - const DWARFAbbreviationDeclarationSet *Abbrevs; + mutable const DWARFAbbreviationDeclarationSet *Abbrevs; + uint64_t AbbrOffset; uint8_t UnitType; llvm::Optional BaseAddr; /// The compile unit debug information entry items. @@ -231,9 +232,7 @@ public: return FormParams.getDwarfOffsetByteSize(); } - const DWARFAbbreviationDeclarationSet *getAbbreviations() const { - return Abbrevs; - } + const DWARFAbbreviationDeclarationSet *getAbbreviations() const; uint8_t getUnitType() const { return UnitType; } diff --git a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp index 76dd2e4c21b..4830c36a8ee 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp @@ -68,9 +68,7 @@ DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration( return &Decls[AbbrCode - FirstAbbrCode]; } -DWARFDebugAbbrev::DWARFDebugAbbrev() { - clear(); -} +DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); } void DWARFDebugAbbrev::clear() { AbbrDeclSets.clear(); @@ -79,18 +77,29 @@ void DWARFDebugAbbrev::clear() { void DWARFDebugAbbrev::extract(DataExtractor Data) { clear(); + this->Data = Data; +} +void DWARFDebugAbbrev::parse() const { + if (!Data) + return; uint32_t Offset = 0; DWARFAbbreviationDeclarationSet AbbrDecls; - while (Data.isValidOffset(Offset)) { + auto I = AbbrDeclSets.begin(); + while (Data->isValidOffset(Offset)) { + while (I != AbbrDeclSets.end() && I->first < Offset) + ++I; uint32_t CUAbbrOffset = Offset; - if (!AbbrDecls.extract(Data, &Offset)) + if (!AbbrDecls.extract(*Data, &Offset)) break; - AbbrDeclSets[CUAbbrOffset] = std::move(AbbrDecls); + AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls))); } + Data = None; } void DWARFDebugAbbrev::dump(raw_ostream &OS) const { + parse(); + if (AbbrDeclSets.empty()) { OS << "< EMPTY >\n"; return; @@ -115,5 +124,16 @@ DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const { return &(Pos->second); } + if (Data && CUAbbrOffset < Data->getData().size()) { + uint32_t Offset = CUAbbrOffset; + DWARFAbbreviationDeclarationSet AbbrDecls; + if (!AbbrDecls.extract(*Data, &Offset)) + return nullptr; + PrevAbbrOffsetPos = + AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls))) + .first; + return &PrevAbbrOffsetPos->second; + } + return nullptr; } diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index 813960ca95d..4467b4ac309 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -94,7 +94,6 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { // FIXME: Support DWARF64. FormParams.Format = DWARF32; FormParams.Version = debug_info.getU16(offset_ptr); - uint64_t AbbrOffset; if (FormParams.Version >= 5) { UnitType = debug_info.getU8(offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr); @@ -124,9 +123,7 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) { // Keep track of the highest DWARF version we encounter across all units. Context.setMaxVersionIfGreater(getVersion()); - - Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); - return Abbrevs != nullptr; + return true; } bool DWARFUnit::extract(DataExtractor debug_info, uint32_t *offset_ptr) { @@ -452,3 +449,9 @@ DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { } return DWARFDie(); } + +const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { + if (!Abbrevs) + Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset); + return Abbrevs; +} -- 2.40.0