llvm.org GIT mirror llvm / 17f7d09
[DebugInfo] Further simplify DWARFDebugAranges. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191779 91177308-0d34-0410-b5e6-96231b3b80d8 Alexey Samsonov 6 years ago
2 changed file(s) with 48 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
1414 #include
1515 #include
1616 using namespace llvm;
17
18 // Compare function DWARFDebugAranges::Range structures
19 static bool RangeLessThan(const DWARFDebugAranges::Range &range1,
20 const DWARFDebugAranges::Range &range2) {
21 return range1.LoPC < range2.LoPC;
22 }
2317
2418 namespace {
2519 class CountArangeDescriptors {
3933 CUOffsetCollection(CUOffsets) {}
4034 void operator()(const DWARFDebugArangeSet &Set) {
4135 DWARFDebugAranges::Range Range;
42 Range.Offset = Set.getCompileUnitDIEOffset();
43 CUOffsetCollection.insert(Range.Offset);
36 Range.CUOffset = Set.getCompileUnitDIEOffset();
37 CUOffsetCollection.insert(Range.CUOffset);
4438
4539 for (uint32_t i = 0, n = Set.getNumDescriptors(); i < n; ++i) {
4640 const DWARFDebugArangeSet::Descriptor *ArangeDescPtr =
4741 Set.getDescriptor(i);
48 Range.LoPC = ArangeDescPtr->Address;
42 Range.LowPC = ArangeDescPtr->Address;
4943 Range.Length = ArangeDescPtr->Length;
5044
5145 // Insert each item in increasing address order so binary searching
5246 // can later be done!
5347 DWARFDebugAranges::RangeColl::iterator InsertPos =
5448 std::lower_bound(RangeCollection.begin(), RangeCollection.end(),
55 Range, RangeLessThan);
49 Range);
5650 RangeCollection.insert(InsertPos, Range);
5751 }
5852
9791 }
9892 }
9993 }
100 sort(true, /* overlap size */ 0);
94 sortAndMinimize();
10195 }
10296
10397 void DWARFDebugAranges::dump(raw_ostream &OS) const {
108102
109103 void DWARFDebugAranges::Range::dump(raw_ostream &OS) const {
110104 OS << format("{0x%8.8x}: [0x%8.8" PRIx64 " - 0x%8.8" PRIx64 ")\n",
111 Offset, LoPC, HiPC());
105 CUOffset, LowPC, HighPC());
112106 }
113107
114108 void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
115109 uint64_t HighPC) {
116110 if (!Aranges.empty()) {
117 if (Aranges.back().Offset == CUOffset && Aranges.back().HiPC() == LowPC) {
118 Aranges.back().setHiPC(HighPC);
111 if (Aranges.back().CUOffset == CUOffset &&
112 Aranges.back().HighPC() == LowPC) {
113 Aranges.back().setHighPC(HighPC);
119114 return;
120115 }
121116 }
122117 Aranges.push_back(Range(LowPC, HighPC, CUOffset));
123118 }
124119
125 void DWARFDebugAranges::sort(bool Minimize, uint32_t OverlapSize) {
120 void DWARFDebugAranges::sortAndMinimize() {
126121 const size_t orig_arange_size = Aranges.size();
127122 // Size of one? If so, no sorting is needed
128123 if (orig_arange_size <= 1)
129124 return;
130125 // Sort our address range entries
131 std::stable_sort(Aranges.begin(), Aranges.end(), RangeLessThan);
132
133 if (!Minimize)
134 return;
126 std::stable_sort(Aranges.begin(), Aranges.end());
135127
136128 // Most address ranges are contiguous from function to function
137129 // so our new ranges will likely be smaller. We calculate the size
145137 // copy the new minimal stuff over to the new collection.
146138 size_t minimal_size = 1;
147139 for (size_t i = 1; i < orig_arange_size; ++i) {
148 if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i], OverlapSize))
140 if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i]))
149141 ++minimal_size;
150142 }
151143
160152 uint32_t j = 0;
161153 minimal_aranges[j] = Aranges[0];
162154 for (size_t i = 1; i < orig_arange_size; ++i) {
163 if (Range::SortedOverlapCheck(minimal_aranges[j], Aranges[i],
164 OverlapSize)) {
165 minimal_aranges[j].setHiPC (Aranges[i].HiPC());
155 if (Range::SortedOverlapCheck(minimal_aranges[j], Aranges[i])) {
156 minimal_aranges[j].setHighPC(Aranges[i].HighPC());
166157 } else {
167158 // Only increment j if we aren't merging
168159 minimal_aranges[++j] = Aranges[i];
169160 }
170161 }
171 assert (j+1 == minimal_size);
162 assert(j+1 == minimal_size);
172163
173164 // Now swap our new minimal aranges into place. The local
174165 // minimal_aranges will then contian the old big collection
181172 Range range(Address);
182173 RangeCollIterator begin = Aranges.begin();
183174 RangeCollIterator end = Aranges.end();
184 RangeCollIterator pos = std::lower_bound(begin, end, range, RangeLessThan);
175 RangeCollIterator pos =
176 std::lower_bound(begin, end, range);
185177
186 if (pos != end && pos->LoPC <= Address && Address < pos->HiPC()) {
187 return pos->Offset;
178 if (pos != end && pos->containsAddress(Address)) {
179 return pos->CUOffset;
188180 } else if (pos != begin) {
189181 --pos;
190 if (pos->LoPC <= Address && Address < pos->HiPC())
191 return (*pos).Offset;
182 if (pos->containsAddress(Address))
183 return pos->CUOffset;
192184 }
193185 }
194186 return -1U;
2020 class DWARFDebugAranges {
2121 public:
2222 struct Range {
23 explicit Range(uint64_t lo = -1ULL, uint64_t hi = -1ULL,
24 uint32_t off = -1U)
25 : LoPC(lo), Length(hi-lo), Offset(off) {}
23 explicit Range(uint64_t LowPC = -1ULL, uint64_t HighPC = -1ULL,
24 uint32_t CUOffset = -1U)
25 : LowPC(LowPC), Length(HighPC - LowPC), CUOffset(CUOffset) {}
2626
27 void clear() {
28 LoPC = -1ULL;
29 Length = 0;
30 Offset = -1U;
27 void setHighPC(uint64_t HighPC) {
28 if (HighPC == -1ULL || HighPC <= LowPC)
29 Length = 0;
30 else
31 Length = HighPC - LowPC;
32 }
33 uint64_t HighPC() const {
34 if (Length)
35 return LowPC + Length;
36 return -1ULL;
37 }
38 bool containsAddress(uint64_t Address) const {
39 return LowPC <= Address && Address < HighPC();
3140 }
3241
33 void setHiPC(uint64_t HiPC) {
34 if (HiPC == -1ULL || HiPC <= LoPC)
35 Length = 0;
36 else
37 Length = HiPC - LoPC;
38 }
39 uint64_t HiPC() const {
40 if (Length)
41 return LoPC + Length;
42 return -1ULL;
43 }
44 bool isValidRange() const { return Length > 0; }
45
46 static bool SortedOverlapCheck(const Range &curr_range,
47 const Range &next_range, uint32_t n) {
48 if (curr_range.Offset != next_range.Offset)
49 return false;
50 return curr_range.HiPC() + n >= next_range.LoPC;
42 bool operator <(const Range &other) const {
43 return LowPC < other.LowPC;
5144 }
5245
53 bool contains(const Range &range) const {
54 return LoPC <= range.LoPC && range.HiPC() <= HiPC();
46 static bool SortedOverlapCheck(const Range &Left, const Range &Right) {
47 if (Left.CUOffset != Right.CUOffset)
48 return false;
49 return Left.HighPC() >= Right.LowPC;
5550 }
5651
5752 void dump(raw_ostream &OS) const;
58 uint64_t LoPC; // Start of address range
59 uint32_t Length; // End of address range (not including this address)
60 uint32_t Offset; // Offset of the compile unit or die
53 uint64_t LowPC; // Start of address range.
54 uint32_t Length; // End of address range (not including this address).
55 uint32_t CUOffset; // Offset of the compile unit or die.
6156 };
6257
6358 void clear() {
6762 void extract(DataExtractor DebugArangesData);
6863 void generate(DWARFContext *CTX);
6964
70 // Use appendRange multiple times and then call sort.
65 // Use appendRange multiple times and then call sortAndMinimize.
7166 void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC);
72 void sort(bool Minimize, uint32_t OverlapSize);
67 void sortAndMinimize();
7368
7469 void dump(raw_ostream &OS) const;
7570 uint32_t findAddress(uint64_t Address) const;