X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFDebugAranges.cpp;h=fe7e46d63ba15402870a8a117fc96d00ead23604;hb=79f9f85c04e1ed29670ed7a87df879bb5b42a0f1;hp=dfab7886b572e257e60ab5ce830dfad88cb03814;hpb=72df68895059f778ae2f6b1264fc98415133b66e;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARFDebugAranges.cpp index dfab7886b57..fe7e46d63ba 100644 --- a/lib/DebugInfo/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARFDebugAranges.cpp @@ -10,37 +10,28 @@ #include "DWARFDebugAranges.h" #include "DWARFCompileUnit.h" #include "DWARFContext.h" +#include "DWARFDebugArangeSet.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" #include #include +#include using namespace llvm; void DWARFDebugAranges::extract(DataExtractor DebugArangesData) { if (!DebugArangesData.isValidOffset(0)) return; uint32_t Offset = 0; - typedef std::vector 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; - - Aranges.reserve(TotalRanges); - for (const auto &I : Sets) { - uint32_t CUOffset = I.getCompileUnitDIEOffset(); - - for (const auto &Desc : I.descriptors()) { + uint32_t CUOffset = Set.getCompileUnitDIEOffset(); + for (const auto &Desc : Set.descriptors()) { uint64_t LowPC = Desc.Address; uint64_t HighPC = Desc.getEndAddress(); appendRange(CUOffset, LowPC, HighPC); } + ParsedCUOffsets.insert(CUOffset); } } @@ -58,73 +49,64 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) { // manually build aranges for the rest of them. for (const auto &CU : CTX->compile_units()) { uint32_t CUOffset = CU->getOffset(); - if (ParsedCUOffsets.insert(CUOffset).second) - CU->buildAddressRangeTable(this, true, CUOffset); + if (ParsedCUOffsets.insert(CUOffset).second) { + DWARFAddressRangesVector CURanges; + CU->collectAddressRanges(CURanges); + for (const auto &R : CURanges) { + appendRange(CUOffset, R.first, R.second); + } + } } - sortAndMinimize(); + construct(); } -void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC, - uint64_t HighPC) { - if (!Aranges.empty()) { - if (Aranges.back().CUOffset == CUOffset && - Aranges.back().HighPC() == LowPC) { - Aranges.back().setHighPC(HighPC); - return; - } - } - Aranges.push_back(Range(LowPC, HighPC, CUOffset)); +void DWARFDebugAranges::clear() { + Endpoints.clear(); + Aranges.clear(); + ParsedCUOffsets.clear(); } -void DWARFDebugAranges::sortAndMinimize() { - const size_t orig_arange_size = Aranges.size(); - // Size of one? If so, no sorting is needed - if (orig_arange_size <= 1) - return; - // Sort our address range entries - std::stable_sort(Aranges.begin(), Aranges.end()); - - // Most address ranges are contiguous from function to function - // so our new ranges will likely be smaller. We calculate the size - // of the new ranges since although std::vector objects can be resized, - // the will never reduce their allocated block size and free any excesss - // memory, so we might as well start a brand new collection so it is as - // small as possible. - - // First calculate the size of the new minimal arange vector - // so we don't have to do a bunch of re-allocations as we - // copy the new minimal stuff over to the new collection. - size_t minimal_size = 1; - for (size_t i = 1; i < orig_arange_size; ++i) { - if (!Range::SortedOverlapCheck(Aranges[i-1], Aranges[i])) - ++minimal_size; - } - - // If the sizes are the same, then no consecutive aranges can be - // combined, we are done. - if (minimal_size == orig_arange_size) +void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC, + uint64_t HighPC) { + if (LowPC >= HighPC) return; + Endpoints.emplace_back(LowPC, CUOffset, true); + Endpoints.emplace_back(HighPC, CUOffset, false); +} - // Else, make a new RangeColl that _only_ contains what we need. - RangeColl minimal_aranges; - minimal_aranges.resize(minimal_size); - uint32_t j = 0; - minimal_aranges[j] = Aranges[0]; - for (size_t i = 1; i < orig_arange_size; ++i) { - if (Range::SortedOverlapCheck(minimal_aranges[j], Aranges[i])) { - minimal_aranges[j].setHighPC(Aranges[i].HighPC()); +void DWARFDebugAranges::construct() { + std::multiset ValidCUs; // Maintain the set of CUs describing + // a current address range. + std::sort(Endpoints.begin(), Endpoints.end()); + uint64_t PrevAddress = -1ULL; + for (const auto &E : Endpoints) { + if (PrevAddress < E.Address && ValidCUs.size() > 0) { + // If the address range between two endpoints is described by some + // CU, first try to extend the last range in Aranges. If we can't + // do it, start a new range. + if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress && + ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) { + Aranges.back().setHighPC(E.Address); + } else { + Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin()); + } + } + // Update the set of valid CUs. + if (E.IsRangeStart) { + ValidCUs.insert(E.CUOffset); } else { - // Only increment j if we aren't merging - minimal_aranges[++j] = Aranges[i]; + auto CUPos = ValidCUs.find(E.CUOffset); + assert(CUPos != ValidCUs.end()); + ValidCUs.erase(CUPos); } + PrevAddress = E.Address; } - assert(j+1 == minimal_size); + assert(ValidCUs.empty()); - // Now swap our new minimal aranges into place. The local - // minimal_aranges will then contian the old big collection - // which will get freed. - minimal_aranges.swap(Aranges); + // Endpoints are not needed now. + std::vector EmptyEndpoints; + EmptyEndpoints.swap(Endpoints); } uint32_t DWARFDebugAranges::findAddress(uint64_t Address) const {