summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorDehao Chen <dehao@google.com>2017-04-19 20:09:38 +0000
committerDehao Chen <dehao@google.com>2017-04-19 20:09:38 +0000
commita364f09f185f65c3d23d93a313177ca8da3d7877 (patch)
tree8dda0f2421d3f3db90830b7bda71d73391329c7d /llvm/lib/DebugInfo
parent6e2ec5f10ecca4db786cb5d2c3c4f1701a940385 (diff)
downloadbcm5719-llvm-a364f09f185f65c3d23d93a313177ca8da3d7877.tar.gz
bcm5719-llvm-a364f09f185f65c3d23d93a313177ca8da3d7877.zip
Using address range map to speedup finding inline stack for address.
Summary: In the current implementation, to find inline stack for an address incurs expensive linear search in 2 places: * linear search for the top-level DIE * recursive linear traverse the DIE tree to find the path to the leaf DIE In this patch, a map is built from address to its corresponding leaf DIE. The inline stack is built by traversing from the leaf DIE up to the root DIE. This speeds up batch symbolization by ~10X without noticible memory overhead. Reviewers: dblaikie Reviewed By: dblaikie Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32177 llvm-svn: 300742
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp26
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp65
2 files changed, 48 insertions, 43 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index b88cc636d84..24039eb3520 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -352,32 +352,6 @@ void DWARFDie::dump(raw_ostream &OS, unsigned RecurseDepth,
}
}
-void DWARFDie::getInlinedChainForAddress(
- const uint64_t Address, SmallVectorImpl<DWARFDie> &InlinedChain) const {
- if (isNULL())
- return;
- DWARFDie DIE(*this);
- while (DIE) {
- // Append current DIE to inlined chain only if it has correct tag
- // (e.g. it is not a lexical block).
- if (DIE.isSubroutineDIE())
- InlinedChain.push_back(DIE);
-
- // Try to get child which also contains provided address.
- DWARFDie Child = DIE.getFirstChild();
- while (Child) {
- if (Child.addressRangeContainsAddress(Address)) {
- // Assume there is only one such child.
- break;
- }
- Child = Child.getSibling();
- }
- DIE = Child;
- }
- // Reverse the obtained chain to make the root of inlined chain last.
- std::reverse(InlinedChain.begin(), InlinedChain.end());
-}
-
DWARFDie DWARFDie::getParent() const {
if (isValid())
return U->getParent(Die);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 4ee8e8f46d2..f76b917283c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -343,36 +343,67 @@ void DWARFUnit::collectAddressRanges(DWARFAddressRangesVector &CURanges) {
clearDIEs(true);
}
-DWARFDie
-DWARFUnit::getSubprogramForAddress(uint64_t Address) {
- extractDIEsIfNeeded(false);
- for (const DWARFDebugInfoEntry &D : DieArray) {
- DWARFDie DIE(this, &D);
- if (DIE.isSubprogramDIE() &&
- DIE.addressRangeContainsAddress(Address)) {
- return DIE;
+void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
+ if (Die.isSubroutineDIE()) {
+ for (const auto &R : Die.getAddressRanges()) {
+ // Ignore 0-sized ranges.
+ if (R.first == R.second)
+ continue;
+ auto B = AddrDieMap.upper_bound(R.first);
+ if (B != AddrDieMap.begin() && R.first < (--B)->second.first) {
+ // The range is a sub-range of existing ranges, we need to split the
+ // existing range.
+ if (R.second < B->second.first)
+ AddrDieMap[R.second] = B->second;
+ if (R.first > B->first)
+ AddrDieMap[B->first].first = R.first;
+ }
+ AddrDieMap[R.first] = std::make_pair(R.second, Die);
}
}
- return DWARFDie();
+ // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
+ // simplify the logic to update AddrDieMap. The child's range will always
+ // be equal or smaller than the parent's range. With this assumption, when
+ // adding one range into the map, it will at most split a range into 3
+ // sub-ranges.
+ for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
+ updateAddressDieMap(Child);
+}
+
+DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
+ extractDIEsIfNeeded(false);
+ if (AddrDieMap.empty())
+ updateAddressDieMap(getUnitDIE());
+ auto R = AddrDieMap.upper_bound(Address);
+ if (R == AddrDieMap.begin())
+ return DWARFDie();
+ // upper_bound's previous item contains Address.
+ --R;
+ if (Address >= R->second.first)
+ return DWARFDie();
+ return R->second.second;
}
void
DWARFUnit::getInlinedChainForAddress(uint64_t Address,
SmallVectorImpl<DWARFDie> &InlinedChain) {
- // First, find a subprogram that contains the given address (the root
+ // First, find the subroutine that contains the given address (the leaf
// of inlined chain).
- DWARFDie SubprogramDIE;
+ DWARFDie SubroutineDIE;
// Try to look for subprogram DIEs in the DWO file.
parseDWO();
if (DWO)
- SubprogramDIE = DWO->getUnit()->getSubprogramForAddress(Address);
+ SubroutineDIE = DWO->getUnit()->getSubroutineForAddress(Address);
else
- SubprogramDIE = getSubprogramForAddress(Address);
+ SubroutineDIE = getSubroutineForAddress(Address);
- // Get inlined chain rooted at this subprogram DIE.
- if (SubprogramDIE)
- SubprogramDIE.getInlinedChainForAddress(Address, InlinedChain);
- else
+ if (SubroutineDIE) {
+ while (SubroutineDIE) {
+ if (SubroutineDIE.isSubroutineDIE())
+ InlinedChain.push_back(SubroutineDIE);
+ SubroutineDIE = SubroutineDIE.getParent();
+ }
+ } else
InlinedChain.clear();
}
OpenPOWER on IntegriCloud