summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-08-21 20:08:40 +0000
committerZachary Turner <zturner@google.com>2017-08-21 20:08:40 +0000
commitd76dc2d31ef38be5a9edf1239ca3df5a19d3183e (patch)
tree0a5efec38153db0f6ab129a7603ce63593e9935e /llvm/lib
parent0812c5bea365d23b25d6b79a015e4a12fa28f0a1 (diff)
downloadbcm5719-llvm-d76dc2d31ef38be5a9edf1239ca3df5a19d3183e.tar.gz
bcm5719-llvm-d76dc2d31ef38be5a9edf1239ca3df5a19d3183e.zip
[lld/pdb] Speed up construction of publics & globals addr map.
computeAddrMap function calls std::stable_sort with a comparison function that computes deserialized symbols every time its called. In the result deserializeAs<PublicSym32> is called 20-30 times per symbol. It's much faster to calculate it beforehand and pass a pointer to it to the comparison function. Patch by Alex Telishev Differential Revision: https://reviews.llvm.org/D36941 llvm-svn: 311373
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp40
1 files changed, 21 insertions, 19 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index dd41202e346..e84f25dfeef 100644
--- a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -169,21 +169,15 @@ Error GSIStreamBuilder::finalizeMsfLayout() {
return Error::success();
}
-static bool comparePubSymByAddrAndName(const CVSymbol *LS, const CVSymbol *RS) {
- assert(LS->kind() == SymbolKind::S_PUB32);
- assert(RS->kind() == SymbolKind::S_PUB32);
-
- PublicSym32 PSL =
- cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(*LS));
- PublicSym32 PSR =
- cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(*RS));
-
- if (PSL.Segment != PSR.Segment)
- return PSL.Segment < PSR.Segment;
- if (PSL.Offset != PSR.Offset)
- return PSL.Offset < PSR.Offset;
-
- return PSL.Name < PSR.Name;
+static bool comparePubSymByAddrAndName(
+ const std::pair<const CVSymbol *, const PublicSym32 *> &LS,
+ const std::pair<const CVSymbol *, const PublicSym32 *> &RS) {
+ if (LS.second->Segment != RS.second->Segment)
+ return LS.second->Segment < RS.second->Segment;
+ if (LS.second->Offset != RS.second->Offset)
+ return LS.second->Offset < RS.second->Offset;
+
+ return LS.second->Name < RS.second->Name;
}
/// Compute the address map. The address map is an array of symbol offsets
@@ -191,12 +185,20 @@ static bool comparePubSymByAddrAndName(const CVSymbol *LS, const CVSymbol *RS) {
static std::vector<ulittle32_t> computeAddrMap(ArrayRef<CVSymbol> Records) {
// Make a vector of pointers to the symbols so we can sort it by address.
// Also gather the symbol offsets while we're at it.
- std::vector<const CVSymbol *> PublicsByAddr;
+
+ std::vector<PublicSym32> DeserializedPublics;
+ std::vector<std::pair<const CVSymbol *, const PublicSym32 *>> PublicsByAddr;
std::vector<uint32_t> SymOffsets;
+ DeserializedPublics.reserve(Records.size());
PublicsByAddr.reserve(Records.size());
+ SymOffsets.reserve(Records.size());
+
uint32_t SymOffset = 0;
for (const CVSymbol &Sym : Records) {
- PublicsByAddr.push_back(&Sym);
+ assert(Sym.kind() == SymbolKind::S_PUB32);
+ DeserializedPublics.push_back(
+ cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym)));
+ PublicsByAddr.emplace_back(&Sym, &DeserializedPublics.back());
SymOffsets.push_back(SymOffset);
SymOffset += Sym.length();
}
@@ -206,8 +208,8 @@ static std::vector<ulittle32_t> computeAddrMap(ArrayRef<CVSymbol> Records) {
// Fill in the symbol offsets in the appropriate order.
std::vector<ulittle32_t> AddrMap;
AddrMap.reserve(Records.size());
- for (const CVSymbol *Sym : PublicsByAddr) {
- ptrdiff_t Idx = std::distance(Records.data(), Sym);
+ for (auto &Sym : PublicsByAddr) {
+ ptrdiff_t Idx = std::distance(Records.data(), Sym.first);
assert(Idx >= 0 && size_t(Idx) < Records.size());
AddrMap.push_back(ulittle32_t(SymOffsets[Idx]));
}
OpenPOWER on IntegriCloud