From a3268784908fb1d74d7896a207bbe12cc99f865a Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Mon, 21 Aug 2017 20:08:40 +0000 Subject: [PATCH] [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 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311373 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp index dd41202e346..e84f25dfeef 100644 --- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ b/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(*LS)); - PublicSym32 PSR = - cantFail(SymbolDeserializer::deserializeAs(*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 &LS, + const std::pair &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 computeAddrMap(ArrayRef 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 PublicsByAddr; + + std::vector DeserializedPublics; + std::vector> PublicsByAddr; std::vector 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(Sym))); + PublicsByAddr.emplace_back(&Sym, &DeserializedPublics.back()); SymOffsets.push_back(SymOffset); SymOffset += Sym.length(); } @@ -206,8 +208,8 @@ static std::vector computeAddrMap(ArrayRef Records) { // Fill in the symbol offsets in the appropriate order. std::vector 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])); } -- 2.40.0