[lld] r261066 - Use stable_partition instead of erasing all elements and fill it again.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 16 21:40:01 PST 2016


Author: ruiu
Date: Tue Feb 16 23:40:01 2016
New Revision: 261066

URL: http://llvm.org/viewvc/llvm-project?rev=261066&view=rev
Log:
Use stable_partition instead of erasing all elements and fill it again.

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=261066&r1=261065&r2=261066&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Feb 16 23:40:01 2016
@@ -398,7 +398,7 @@ unsigned GnuHashTableSection<ELFT>::calc
 }
 
 template <class ELFT> void GnuHashTableSection<ELFT>::finalize() {
-  unsigned NumHashed = HashedSymbols.size();
+  unsigned NumHashed = Symbols.size();
   NBuckets = calcNBuckets(NumHashed);
   MaskWords = calcMaskWords(NumHashed);
   // Second hash shift estimation: just predefined values.
@@ -413,7 +413,7 @@ template <class ELFT> void GnuHashTableS
 
 template <class ELFT> void GnuHashTableSection<ELFT>::writeTo(uint8_t *Buf) {
   writeHeader(Buf);
-  if (HashedSymbols.empty())
+  if (Symbols.empty())
     return;
   writeBloomFilter(Buf);
   writeHashTable(Buf);
@@ -423,7 +423,7 @@ template <class ELFT>
 void GnuHashTableSection<ELFT>::writeHeader(uint8_t *&Buf) {
   auto *P = reinterpret_cast<Elf_Word *>(Buf);
   *P++ = NBuckets;
-  *P++ = Out<ELFT>::DynSymTab->getNumSymbols() - HashedSymbols.size();
+  *P++ = Out<ELFT>::DynSymTab->getNumSymbols() - Symbols.size();
   *P++ = MaskWords;
   *P++ = Shift2;
   Buf = reinterpret_cast<uint8_t *>(P);
@@ -434,7 +434,7 @@ void GnuHashTableSection<ELFT>::writeBlo
   unsigned C = sizeof(Elf_Off) * 8;
 
   auto *Masks = reinterpret_cast<Elf_Off *>(Buf);
-  for (const HashedSymbolData &Item : HashedSymbols) {
+  for (const HashedSymbolData &Item : Symbols) {
     size_t Pos = (Item.Hash / C) & (MaskWords - 1);
     uintX_t V = (uintX_t(1) << (Item.Hash % C)) |
                 (uintX_t(1) << ((Item.Hash >> Shift2) % C));
@@ -450,7 +450,7 @@ void GnuHashTableSection<ELFT>::writeHas
 
   int PrevBucket = -1;
   int I = 0;
-  for (const HashedSymbolData &Item : HashedSymbols) {
+  for (const HashedSymbolData &Item : Symbols) {
     int Bucket = Item.Hash % NBuckets;
     assert(PrevBucket <= Bucket);
     if (Bucket != PrevBucket) {
@@ -471,32 +471,33 @@ static bool includeInGnuHashTable(Symbol
   return !B->isUndefined();
 }
 
+// Add symbols to this symbol hash table. Note that this function
+// destructively sort a given vector -- which is needed because
+// GNU-style hash table places some sorting requirements.
 template <class ELFT>
 void GnuHashTableSection<ELFT>::addSymbols(
-    std::vector<std::pair<SymbolBody *, size_t>> &Symbols) {
-  std::vector<std::pair<SymbolBody *, size_t>> NotHashed;
-  NotHashed.reserve(Symbols.size());
-  HashedSymbols.reserve(Symbols.size());
-  for (const std::pair<SymbolBody *, size_t> &P : Symbols) {
-    SymbolBody *B = P.first;
-    if (includeInGnuHashTable(B))
-      HashedSymbols.push_back(
-          HashedSymbolData{B, P.second, hashGnu(B->getName())});
-    else
-      NotHashed.push_back(P);
-  }
-  if (HashedSymbols.empty())
+    std::vector<std::pair<SymbolBody *, size_t>> &V) {
+  auto Mid = std::stable_partition(V.begin(), V.end(),
+                                   [](std::pair<SymbolBody *, size_t> &P) {
+                                     return !includeInGnuHashTable(P.first);
+                                   });
+  if (Mid == V.end())
     return;
+  for (auto I = Mid, E = V.end(); I != E; ++I) {
+    SymbolBody *B = I->first;
+    size_t StrOff = I->second;
+    Symbols.push_back({B, StrOff, hashGnu(B->getName())});
+  }
 
-  unsigned NBuckets = calcNBuckets(HashedSymbols.size());
-  std::stable_sort(HashedSymbols.begin(), HashedSymbols.end(),
+  unsigned NBuckets = calcNBuckets(Symbols.size());
+  std::stable_sort(Symbols.begin(), Symbols.end(),
                    [&](const HashedSymbolData &L, const HashedSymbolData &R) {
                      return L.Hash % NBuckets < R.Hash % NBuckets;
                    });
 
-  Symbols = std::move(NotHashed);
-  for (const HashedSymbolData &Item : HashedSymbols)
-    Symbols.push_back(std::make_pair(Item.Body, Item.STName));
+  V.erase(Mid, V.end());
+  for (const HashedSymbolData &Item : Symbols)
+    V.push_back({Item.Body, Item.STName});
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=261066&r1=261065&r2=261066&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Feb 16 23:40:01 2016
@@ -417,7 +417,7 @@ private:
     uint32_t Hash;
   };
 
-  std::vector<HashedSymbolData> HashedSymbols;
+  std::vector<HashedSymbolData> Symbols;
 
   unsigned MaskWords;
   unsigned NBuckets;




More information about the llvm-commits mailing list