[lld] r266364 - Specialize the symbol table data structure a bit.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 14 13:42:43 PDT 2016


Author: rafael
Date: Thu Apr 14 15:42:43 2016
New Revision: 266364

URL: http://llvm.org/viewvc/llvm-project?rev=266364&view=rev
Log:
Specialize the symbol table data structure a bit.

We never need to iterate over the K,V pairs, so we can avoid copying the
key as MapVector does.

This is a small speedup on most benchmarks.

Modified:
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=266364&r1=266363&r2=266364&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Thu Apr 14 15:42:43 2016
@@ -113,8 +113,8 @@ template <class ELFT> void elf::markLive
   // Preserve externally-visible symbols if the symbols defined by this
   // file can interrupt other ELF file's symbols at runtime.
   if (Config->Shared || Config->ExportDynamic) {
-    for (const std::pair<SymName, Symbol *> &P : Symtab->getSymbols()) {
-      SymbolBody *B = P.second->Body;
+    for (const Symbol *S : Symtab->getSymbols()) {
+      SymbolBody *B = S->Body;
       if (B->getVisibility() == STV_DEFAULT)
         MarkSymbol(B);
     }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=266364&r1=266363&r2=266364&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Apr 14 15:42:43 2016
@@ -273,9 +273,15 @@ template <class ELFT> void SymbolTable<E
 // Find an existing symbol or create and insert a new one.
 template <class ELFT> Symbol *SymbolTable<ELFT>::insert(SymbolBody *New) {
   StringRef Name = New->getName();
-  Symbol *&Sym = Symtab[Name];
-  if (!Sym)
+  unsigned NumSyms = SymVector.size();
+  auto P = Symtab.insert(std::make_pair(Name, NumSyms));
+  Symbol *Sym;
+  if (P.second) {
     Sym = new (Alloc) Symbol{New};
+    SymVector.push_back(Sym);
+  } else {
+    Sym = SymVector[P.first->second];
+  }
   New->setBackref(Sym);
   return Sym;
 }
@@ -284,7 +290,7 @@ template <class ELFT> SymbolBody *Symbol
   auto It = Symtab.find(Name);
   if (It == Symtab.end())
     return nullptr;
-  return It->second->Body;
+  return SymVector[It->second]->Body;
 }
 
 template <class ELFT> void SymbolTable<ELFT>::addLazy(Lazy *L) {

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=266364&r1=266363&r2=266364&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Thu Apr 14 15:42:43 2016
@@ -12,7 +12,7 @@
 
 #include "InputFiles.h"
 #include "LTO.h"
-#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/DenseMap.h"
 
 namespace lld {
 namespace elf {
@@ -69,9 +69,7 @@ public:
   void addFile(std::unique_ptr<InputFile> File);
   void addCombinedLtoObject();
 
-  const llvm::MapVector<SymName, Symbol *> &getSymbols() const {
-    return Symtab;
-  }
+  llvm::ArrayRef<Symbol *> getSymbols() const { return SymVector; }
 
   const std::vector<std::unique_ptr<ObjectFile<ELFT>>> &getObjectFiles() const {
     return ObjectFiles;
@@ -106,11 +104,12 @@ private:
   // The order the global symbols are in is not defined. We can use an arbitrary
   // order, but it has to be reproducible. That is true even when cross linking.
   // The default hashing of StringRef produces different results on 32 and 64
-  // bit systems so we use a MapVector. That is arbitrary, deterministic but
-  // a bit inefficient.
+  // bit systems so we use a map to a vector. That is arbitrary, deterministic
+  // but a bit inefficient.
   // FIXME: Experiment with passing in a custom hashing or sorting the symbols
   // once symbol resolution is finished.
-  llvm::MapVector<SymName, Symbol *> Symtab;
+  llvm::DenseMap<SymName, unsigned> Symtab;
+  std::vector<Symbol *> SymVector;
   llvm::BumpPtrAllocator Alloc;
 
   // Comdat groups define "link once" sections. If two comdat groups have the

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=266364&r1=266363&r2=266364&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Apr 14 15:42:43 2016
@@ -1232,8 +1232,8 @@ template <class ELFT> void Writer<ELFT>:
   // Now that we have defined all possible symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
   std::vector<DefinedCommon *> CommonSymbols;
-  for (auto &P : Symtab.getSymbols()) {
-    SymbolBody *Body = P.second->Body;
+  for (Symbol *S : Symtab.getSymbols()) {
+    SymbolBody *Body = S->Body;
     if (Body->isUndefined() && !Body->isWeak()) {
       auto *U = dyn_cast<UndefinedElf<ELFT>>(Body);
       if (!U || !U->canKeepUndefined())




More information about the llvm-commits mailing list