[lld] a2fc964 - [ELF] Replace SymbolTable::forEachSymbol with iterator_range symbols()
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 26 09:11:41 PST 2019
Author: Fangrui Song
Date: 2019-11-26T09:09:32-08:00
New Revision: a2fc96441788fba1e4709d63677f34ed8e321dae
URL: https://github.com/llvm/llvm-project/commit/a2fc96441788fba1e4709d63677f34ed8e321dae
DIFF: https://github.com/llvm/llvm-project/commit/a2fc96441788fba1e4709d63677f34ed8e321dae.diff
LOG: [ELF] Replace SymbolTable::forEachSymbol with iterator_range symbols()
D62381 introduced forEachSymbol(). It seems that many call sites cannot
be parallelized because the body shared some states. Replace
forEachSymbol with iterator_range<filter_iterator<...>> symbols() to
simplify code and improve debuggability (std::function calls take some
frames).
It also allows us to use early return to simplify code added in D69650.
Reviewed By: grimar
Differential Revision: https://reviews.llvm.org/D70505
Added:
Modified:
lld/ELF/Driver.cpp
lld/ELF/LTO.cpp
lld/ELF/MarkLive.cpp
lld/ELF/Relocations.cpp
lld/ELF/SymbolTable.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index b13bb5e00def..a0987259d24b 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1408,13 +1408,13 @@ static void handleUndefinedGlob(StringRef arg) {
}
std::vector<Symbol *> syms;
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols()) {
// Calling Sym->fetch() from here is not safe because it may
// add new symbols to the symbol table, invalidating the
// current iterator. So we just keep a note.
if (pat->match(sym->getName()))
syms.push_back(sym);
- });
+ }
for (Symbol *sym : syms)
handleUndefined(sym);
@@ -1440,10 +1440,10 @@ static void handleLibcall(StringRef name) {
// result, the passes after the symbol resolution won't see any
// symbols of type CommonSymbol.
static void replaceCommonSymbols() {
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols()) {
auto *s = dyn_cast<CommonSymbol>(sym);
if (!s)
- return;
+ continue;
auto *bss = make<BssSection>("COMMON", s->size, s->alignment);
bss->file = s->file;
@@ -1451,7 +1451,7 @@ static void replaceCommonSymbols() {
inputSections.push_back(bss);
s->replace(Defined{s->file, s->getName(), s->binding, s->stOther, s->type,
/*value=*/0, s->size, bss});
- });
+ }
}
// If all references to a DSO happen to be weak, the DSO is not added
@@ -1459,15 +1459,15 @@ static void replaceCommonSymbols() {
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
static void demoteSharedSymbols() {
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols()) {
auto *s = dyn_cast<SharedSymbol>(sym);
if (!s || s->getFile().isNeeded)
- return;
+ continue;
bool used = s->used;
s->replace(Undefined{nullptr, s->getName(), STB_WEAK, s->stOther, s->type});
s->used = used;
- });
+ }
}
// The section referred to by `s` is considered address-significant. Set the
@@ -1503,10 +1503,9 @@ static void findKeepUniqueSections(opt::InputArgList &args) {
// Symbols in the dynsym could be address-significant in other executables
// or DSOs, so we conservatively mark them as address-significant.
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (sym->includeInDynsym())
markAddrsig(sym);
- });
// Visit the address-significance table in each object file and mark each
// referenced symbol as address-significant.
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 6da409568c8b..524d552b0b84 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -145,12 +145,12 @@ BitcodeCompiler::BitcodeCompiler() {
config->ltoPartitions);
// Initialize usedStartStop.
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols()) {
StringRef s = sym->getName();
for (StringRef prefix : {"__start_", "__stop_"})
if (s.startswith(prefix))
usedStartStop.insert(s.substr(prefix.size()));
- });
+ }
}
BitcodeCompiler::~BitcodeCompiler() = default;
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 62fb8fe83a2e..bb0105c28928 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -219,10 +219,9 @@ template <class ELFT> void MarkLive<ELFT>::run() {
// Preserve externally-visible symbols if the symbols defined by this
// file can interrupt other ELF file's symbols at runtime.
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (sym->includeInDynsym() && sym->partition == partition)
markSymbol(sym);
- });
// If this isn't the main partition, that's all that we need to preserve.
if (partition != 1) {
@@ -330,11 +329,10 @@ template <class ELFT> void markLive() {
sec->markLive();
// If a DSO defines a symbol referenced in a regular object, it is needed.
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (auto *s = dyn_cast<SharedSymbol>(sym))
if (s->isUsedInRegularObj && !s->isWeak())
s->getFile().isNeeded = true;
- });
return;
}
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index a4fc1ffbd1e7..80e1de24316f 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -799,10 +799,11 @@ static const Symbol *getAlternativeSpelling(const Undefined &sym,
break;
}
if (!s)
- symtab->forEachSymbol([&](Symbol *sym) {
- if (!s && canSuggestExternCForCXX(name, sym->getName()))
+ for (Symbol *sym : symtab->symbols())
+ if (canSuggestExternCForCXX(name, sym->getName())) {
s = sym;
- });
+ break;
+ }
if (s) {
pre_hint = " to declare ";
post_hint = " as extern \"C\"?";
diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h
index d3be0cb6450f..507af8d2be75 100644
--- a/lld/ELF/SymbolTable.h
+++ b/lld/ELF/SymbolTable.h
@@ -32,15 +32,19 @@ namespace elf {
// add*() functions, which are called by input files as they are parsed. There
// is one add* function per symbol type.
class SymbolTable {
-public:
- void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
+ struct FilterOutPlaceholder {
+ bool operator()(Symbol *S) const { return !S->isPlaceholder(); }
+ };
+ using iterator = llvm::filter_iterator<std::vector<Symbol *>::const_iterator,
+ FilterOutPlaceholder>;
- void forEachSymbol(llvm::function_ref<void(Symbol *)> fn) {
- for (Symbol *sym : symVector)
- if (!sym->isPlaceholder())
- fn(sym);
+public:
+ llvm::iterator_range<iterator> symbols() const {
+ return llvm::make_filter_range(symVector, FilterOutPlaceholder());
}
+ void wrap(Symbol *sym, Symbol *real, Symbol *wrap);
+
Symbol *insert(StringRef name);
Symbol *addSymbol(const Symbol &newSym);
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 3de1230150d6..ebca612f77af 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1238,10 +1238,9 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
// We want both global and local symbols. We get the global ones from the
// symbol table and iterate the object files for the local ones.
- symtab->forEachSymbol([&](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (!sym->isLazy())
addSym(*sym);
- });
for (InputFile *file : objectFiles)
for (Symbol *sym : file->getSymbols())
@@ -1734,8 +1733,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
for (Partition &part : partitions)
finalizeSynthetic(part.ehFrame);
- symtab->forEachSymbol(
- [](Symbol *s) { s->isPreemptible = computeIsPreemptible(*s); });
+ for (Symbol *sym : symtab->symbols())
+ sym->isPreemptible = computeIsPreemptible(*sym);
// Change values of linker-script-defined symbols from placeholders (assigned
// by declareSymbols) to actual definitions.
@@ -1769,19 +1768,18 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
return symtab->soNames.count(needed);
});
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols())
if (sym->isUndefined() && !sym->isWeak())
if (auto *f = dyn_cast_or_null<SharedFile>(sym->file))
if (f->allNeededIsKnown)
error(toString(f) + ": undefined reference to " + toString(*sym));
- });
}
// Now that we have defined all possible global symbols including linker-
// synthesized ones. Visit all symbols to give the finishing touches.
- symtab->forEachSymbol([](Symbol *sym) {
+ for (Symbol *sym : symtab->symbols()) {
if (!includeInSymtab(*sym))
- return;
+ continue;
if (in.symTab)
in.symTab->addSymbol(sym);
@@ -1791,7 +1789,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (file->isNeeded && !sym->isUndefined())
addVerneed(sym);
}
- });
+ }
// We also need to scan the dynamic relocation tables of the other partitions
// and add any referenced symbols to the partition's dynsym.
More information about the llvm-commits
mailing list