diff options
author | Alexey Samsonov <samsonov@google.com> | 2013-10-01 16:52:46 +0000 |
---|---|---|
committer | Alexey Samsonov <samsonov@google.com> | 2013-10-01 16:52:46 +0000 |
commit | 041f7c8d65a653701cb9ed464911cd44b19ab47e (patch) | |
tree | f9f4025e174e809e78cd7d27fb1724e0a0784e1a /lib/DebugInfo | |
parent | 52c9016db0560644a03ca661302e45143372f2fc (diff) | |
download | external_llvm-041f7c8d65a653701cb9ed464911cd44b19ab47e.zip external_llvm-041f7c8d65a653701cb9ed464911cd44b19ab47e.tar.gz external_llvm-041f7c8d65a653701cb9ed464911cd44b19ab47e.tar.bz2 |
[DebugInfo] Simplify and speedup .debug_aranges parsing
Parsing .debug_aranges section now takes O(nlogn) operations instead
of O(n^2), where "n" is the number of address ranges. With this change,
the time required to symbolize an address from a random large
Clang-generated binary drops from 165 seconds to 1.5 seconds.
No functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191781 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r-- | lib/DebugInfo/DWARFDebugAranges.cpp | 83 |
1 files changed, 25 insertions, 58 deletions
diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp index 6aa40b3..3038649 100644 --- a/lib/DebugInfo/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARFDebugAranges.cpp @@ -16,69 +16,36 @@ #include <cassert> using namespace llvm; -namespace { - class CountArangeDescriptors { - public: - CountArangeDescriptors(uint32_t &count_ref) : Count(count_ref) {} - void operator()(const DWARFDebugArangeSet &Set) { - Count += Set.getNumDescriptors(); - } - uint32_t &Count; - }; - - class AddArangeDescriptors { - public: - AddArangeDescriptors(DWARFDebugAranges::RangeColl &Ranges, - DWARFDebugAranges::ParsedCUOffsetColl &CUOffsets) - : RangeCollection(Ranges), - CUOffsetCollection(CUOffsets) {} - void operator()(const DWARFDebugArangeSet &Set) { - DWARFDebugAranges::Range Range; - Range.CUOffset = Set.getCompileUnitDIEOffset(); - CUOffsetCollection.insert(Range.CUOffset); - - for (uint32_t i = 0, n = Set.getNumDescriptors(); i < n; ++i) { - const DWARFDebugArangeSet::Descriptor *ArangeDescPtr = - Set.getDescriptor(i); - Range.LowPC = ArangeDescPtr->Address; - Range.Length = ArangeDescPtr->Length; - - // Insert each item in increasing address order so binary searching - // can later be done! - DWARFDebugAranges::RangeColl::iterator InsertPos = - std::lower_bound(RangeCollection.begin(), RangeCollection.end(), - Range); - RangeCollection.insert(InsertPos, Range); - } - - } - DWARFDebugAranges::RangeColl &RangeCollection; - DWARFDebugAranges::ParsedCUOffsetColl &CUOffsetCollection; - }; -} - void DWARFDebugAranges::extract(DataExtractor DebugArangesData) { if (!DebugArangesData.isValidOffset(0)) return; - uint32_t offset = 0; - - typedef std::vector<DWARFDebugArangeSet> SetCollection; - SetCollection sets; - - DWARFDebugArangeSet set; - Range range; - while (set.extract(DebugArangesData, &offset)) - sets.push_back(set); - - uint32_t count = 0; - - std::for_each(sets.begin(), sets.end(), CountArangeDescriptors(count)); + uint32_t Offset = 0; + typedef std::vector<DWARFDebugArangeSet> RangeSetColl; + RangeSetColl Sets; + DWARFDebugArangeSet Set; + uint32_t TotalRanges = 0; + + while (Set.extract(DebugArangesData, &Offset)) { + Sets.push_back(Set); + TotalRanges += Set.getNumDescriptors(); + } + if (TotalRanges == 0) + return; - if (count > 0) { - Aranges.reserve(count); - AddArangeDescriptors range_adder(Aranges, ParsedCUOffsets); - std::for_each(sets.begin(), sets.end(), range_adder); + Aranges.reserve(TotalRanges); + for (RangeSetColl::const_iterator I = Sets.begin(), E = Sets.end(); I != E; + ++I) { + uint32_t CUOffset = I->getCompileUnitDIEOffset(); + + for (uint32_t i = 0, n = I->getNumDescriptors(); i < n; ++i) { + const DWARFDebugArangeSet::Descriptor *ArangeDescPtr = + I->getDescriptor(i); + uint64_t LowPC = ArangeDescPtr->Address; + uint64_t HighPC = LowPC + ArangeDescPtr->Length; + appendRange(CUOffset, LowPC, HighPC); + } } + sortAndMinimize(); } void DWARFDebugAranges::generate(DWARFContext *CTX) { |