|
8 | 8 | //
|
9 | 9 | //===----------------------------------------------------------------------===//
|
10 | 10 |
|
| 11 | +#include <unordered_map> |
| 12 | + |
11 | 13 | #include "DWARFVisitor.h"
|
12 | 14 | #include "llvm/ObjectYAML/DWARFYAML.h"
|
13 | 15 |
|
@@ -49,19 +51,41 @@ template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
|
49 | 51 | // TODO: This code appears to assume that abbreviation codes increment by 1
|
50 | 52 | // so that lookups are linear. In LLVM output that is true, but it might not
|
51 | 53 | // be in general.
|
| 54 | + // Create a map of [byte offset into the abbreviation section] => [index in |
| 55 | + // DebugInfo.AbbrevDecls]. This avoids linear search for each CU. |
| 56 | + std::unordered_map<size_t, size_t> abbrByteOffsetToDeclsIndex; |
| 57 | + for (size_t i = 0; i < DebugInfo.AbbrevDecls.size(); i++) { |
| 58 | + auto offset = DebugInfo.AbbrevDecls[i].ListOffset; |
| 59 | + // The offset is the same for all entries for the same CU, so only note the |
| 60 | + // first as that is where the list for the CU (that LLVM DeclSet) begins. |
| 61 | + // That is, DebugInfo.AbbrevDecls looks like this: |
| 62 | + // |
| 63 | + // i CU Abbrev ListOffset |
| 64 | + // ============================ |
| 65 | + // 0 X X1 150 |
| 66 | + // 1 X X2 150 |
| 67 | + // 2 X X3 150 |
| 68 | + // .. |
| 69 | + // 6 Y Y1 260 |
| 70 | + // 7 Y Y2 260 |
| 71 | + // |
| 72 | + // Note how multiple rows i have the same CU. All those abbrevs have the |
| 73 | + // same ListOffset, which is the byte offset into the abbreviation section |
| 74 | + // for that set of abbreviations. |
| 75 | + if (abbrByteOffsetToDeclsIndex.count(offset)) { |
| 76 | + continue; |
| 77 | + } |
| 78 | + abbrByteOffsetToDeclsIndex[offset] = i; |
| 79 | + } |
52 | 80 | for (auto &Unit : DebugInfo.CompileUnits) {
|
53 | 81 | // AbbrOffset is the byte offset into the abbreviation section, which we
|
54 | 82 | // need to find among the Abbrev's ListOffsets (which are the byte offsets
|
55 | 83 | // of where that abbreviation list begins).
|
56 | 84 | // TODO: Optimize this to not be O(#CUs * #abbrevs).
|
57 |
| - size_t AbbrevStart = -1; |
58 |
| - for (size_t i = 0; i < DebugInfo.AbbrevDecls.size(); i++) { |
59 |
| - if (DebugInfo.AbbrevDecls[i].ListOffset == Unit.AbbrOffset) { |
60 |
| - AbbrevStart = i; |
61 |
| - break; |
62 |
| - } |
63 |
| - } |
64 |
| - assert(AbbrevStart != -1); // must find the list |
| 85 | + auto offset = Unit.AbbrOffset; |
| 86 | + assert(abbrByteOffsetToDeclsIndex.count(offset)); |
| 87 | + size_t AbbrevStart = abbrByteOffsetToDeclsIndex[offset]; |
| 88 | + assert(DebugInfo.AbbrevDecls[AbbrevStart].ListOffset == offset); |
65 | 89 | // Find the last entry in this abbreviation list.
|
66 | 90 | size_t AbbrevEnd = AbbrevStart;
|
67 | 91 | while (AbbrevEnd < DebugInfo.AbbrevDecls.size() &&
|
|
0 commit comments