[lld] c671e80 - [ELF] Parallelize demoteSymbolsAndComputeIsPreemptible (#207310)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 2 20:00:35 PDT 2026
Author: Fangrui Song
Date: 2026-07-03T03:00:30Z
New Revision: c671e80a2f3055d61f3f7a2a0aabee4d8d184bbd
URL: https://github.com/llvm/llvm-project/commit/c671e80a2f3055d61f3f7a2a0aabee4d8d184bbd
DIFF: https://github.com/llvm/llvm-project/commit/c671e80a2f3055d61f3f7a2a0aabee4d8d184bbd.diff
LOG: [ELF] Parallelize demoteSymbolsAndComputeIsPreemptible (#207310)
Each symbol's demotion and isPreemptible bit is independent.
Linking clang release is 1.02x as fast on an x86-64 machine.
Added:
Modified:
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 56cd9548a5f59..49d3f903b3743 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -261,25 +261,31 @@ static void demoteDefined(Defined &sym, DenseMap<SectionBase *, size_t> &map) {
// references to /DISCARD/ discarded symbols will lead to errors.
static void demoteSymbolsAndComputeIsPreemptible(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Demote symbols");
- DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
- for (Symbol *sym : ctx.symtab->getSymbols()) {
- if (auto *d = dyn_cast<Defined>(sym)) {
- if (d->section && !d->section->isLive())
- demoteDefined(*d, sectionIndexMap[d->file]);
- } else {
- auto *s = dyn_cast<SharedSymbol>(sym);
- if (sym->isLazy() || (s && !cast<SharedFile>(s->file)->isNeeded)) {
- uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK);
- Undefined(ctx.internalFile, sym->getName(), binding, sym->stOther,
- sym->type)
- .overwrite(*sym);
- sym->versionId = VER_NDX_GLOBAL;
+ ArrayRef<Symbol *> syms = ctx.symtab->getSymbols();
+ constexpr size_t chunkSize = 4096;
+ parallelFor(0, (syms.size() + chunkSize - 1) / chunkSize, [&](size_t c) {
+ DenseMap<InputFile *, DenseMap<SectionBase *, size_t>> sectionIndexMap;
+ size_t begin = c * chunkSize;
+ for (Symbol *sym :
+ syms.slice(begin, std::min(chunkSize, syms.size() - begin))) {
+ if (auto *d = dyn_cast<Defined>(sym)) {
+ if (d->section && !d->section->isLive())
+ demoteDefined(*d, sectionIndexMap[d->file]);
+ } else {
+ auto *s = dyn_cast<SharedSymbol>(sym);
+ if (sym->isLazy() || (s && !cast<SharedFile>(s->file)->isNeeded)) {
+ uint8_t binding = sym->isLazy() ? sym->binding : uint8_t(STB_WEAK);
+ Undefined(ctx.internalFile, sym->getName(), binding, sym->stOther,
+ sym->type)
+ .overwrite(*sym);
+ sym->versionId = VER_NDX_GLOBAL;
+ }
}
- }
- sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
- computeIsPreemptible(ctx, *sym);
- }
+ sym->isPreemptible = (sym->isUndefined() || sym->isExported) &&
+ computeIsPreemptible(ctx, *sym);
+ }
+ });
}
static OutputSection *findSection(Ctx &ctx, StringRef name) {
More information about the llvm-commits
mailing list