[llvm] r311373 - [lld/pdb] Speed up construction of publics & globals addr map.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 21 13:08:40 PDT 2017


Author: zturner
Date: Mon Aug 21 13:08:40 2017
New Revision: 311373

URL: http://llvm.org/viewvc/llvm-project?rev=311373&view=rev
Log:
[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

Modified:
    llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp

Modified: llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp?rev=311373&r1=311372&r2=311373&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp Mon Aug 21 13:08:40 2017
@@ -169,21 +169,15 @@ Error GSIStreamBuilder::finalizeMsfLayou
   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;
+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 PSL.Name < PSR.Name;
+  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(c
 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> computeA
   // 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]));
   }




More information about the llvm-commits mailing list