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.

llvm-svn: 266364
This commit is contained in:
Rafael Espindola 2016-04-14 20:42:43 +00:00
parent 5cb666add7
commit 7f0b727235
4 changed files with 19 additions and 14 deletions

View File

@ -113,8 +113,8 @@ template <class ELFT> void elf::markLive(SymbolTable<ELFT> *Symtab) {
// 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);
}

View File

@ -273,9 +273,15 @@ template <class ELFT> void SymbolTable<ELFT>::resolve(SymbolBody *New) {
// 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 *SymbolTable<ELFT>::find(StringRef Name) {
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) {

View File

@ -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

View File

@ -1232,8 +1232,8 @@ template <class ELFT> void Writer<ELFT>::createSections() {
// 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())