[lld] r314282 - [ELF] - Speedup -r and --emit-relocs
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 27 02:08:53 PDT 2017
Author: grimar
Date: Wed Sep 27 02:08:53 2017
New Revision: 314282
URL: http://llvm.org/viewvc/llvm-project?rev=314282&view=rev
Log:
[ELF] - Speedup -r and --emit-relocs
This is "Bug 34688 - lld much slower than bfd when linking the linux kernel"
Inside copyRelocations() we have O(N*M) algorithm, where N - amount of
relocations and M - amount of symbols in symbol table. It isincredibly slow
for linking linux kernel.
Patch creates local search tables to speedup.
With this fix link time goes for me from 12.95s to 0.55s what is almost 23x
faster. (used release LLD).
Differential revision: https://reviews.llvm.org/D38129
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=314282&r1=314281&r2=314282&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Sep 27 02:08:53 2017
@@ -384,11 +384,6 @@ InputSectionBase *InputSection::getReloc
template <class ELFT, class RelTy>
void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
InputSectionBase *RelocatedSection = getRelocatedSection();
-
- // Loop is slow and have complexity O(N*M), where N - amount of
- // relocations and M - amount of symbols in symbol table.
- // That happens because getSymbolIndex(...) call below performs
- // simple linear search.
for (const RelTy &Rel : Rels) {
uint32_t Type = Rel.getType(Config->IsMips64EL);
SymbolBody &Body = this->getFile<ELFT>()->getRelocTargetSym(Rel);
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=314282&r1=314281&r2=314282&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Sep 27 02:08:53 2017
@@ -1355,18 +1355,24 @@ void SymbolTableBaseSection::addSymbol(S
}
size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) {
- auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) {
- if (E.Symbol == Body)
- return true;
- // This is used for -r, so we have to handle multiple section
- // symbols being combined.
- if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
- return Body->getOutputSection() == E.Symbol->getOutputSection();
- return false;
+ // Initializes symbol lookup tables lazily. This is used only
+ // for -r or -emit-relocs.
+ llvm::call_once(OnceFlag, [&] {
+ SymbolIndexMap.reserve(Symbols.size());
+ size_t I = 0;
+ for (const SymbolTableEntry &E : Symbols) {
+ if (E.Symbol->Type == STT_SECTION)
+ SectionIndexMap[E.Symbol->getOutputSection()] = ++I;
+ else
+ SymbolIndexMap[E.Symbol] = ++I;
+ }
});
- if (I == Symbols.end())
- return 0;
- return I - Symbols.begin() + 1;
+
+ // Section symbols are mapped based on their output sections
+ // to maintain their semantics.
+ if (Body->Type == STT_SECTION)
+ return SectionIndexMap.lookup(Body->getOutputSection());
+ return SymbolIndexMap.lookup(Body);
}
template <class ELFT>
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=314282&r1=314281&r2=314282&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Sep 27 02:08:53 2017
@@ -418,6 +418,10 @@ protected:
std::vector<SymbolTableEntry> Symbols;
StringTableSection &StrTabSec;
+
+ llvm::once_flag OnceFlag;
+ llvm::DenseMap<SymbolBody *, size_t> SymbolIndexMap;
+ llvm::DenseMap<OutputSection *, size_t> SectionIndexMap;
};
template <class ELFT>
More information about the llvm-commits
mailing list