[ELF] Parallelize demoteAndCopyLocalSymbols. NFC (#187970)

Use parallelFor to process files in parallel, collecting Symbol*
pointers per-file, then merge into the symbol table serially.

Linking clang-14 (208K .symtab entries) is 1.04x as fast.
This commit is contained in:
Fangrui Song 2026-03-22 21:52:55 -07:00 committed by GitHub
parent c911b84923
commit 036b755dae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -492,9 +492,11 @@ bool elf::includeInSymtab(Ctx &ctx, const Symbol &b) {
// - copy eligible symbols to .symTab
static void demoteAndCopyLocalSymbols(Ctx &ctx) {
llvm::TimeTraceScope timeScope("Add local symbols");
for (ELFFileBase *file : ctx.objectFiles) {
auto symsVec =
std::make_unique<SmallVector<Symbol *, 0>[]>(ctx.objectFiles.size());
parallelFor(0, ctx.objectFiles.size(), [&](size_t i) {
DenseMap<SectionBase *, size_t> sectionIndexMap;
for (Symbol *b : file->getLocalSymbols()) {
for (Symbol *b : ctx.objectFiles[i]->getLocalSymbols()) {
assert(b->isLocal() && "should have been caught in initializeSymbols()");
auto *dr = dyn_cast<Defined>(b);
if (!dr)
@ -504,9 +506,12 @@ static void demoteAndCopyLocalSymbols(Ctx &ctx) {
demoteDefined(*dr, sectionIndexMap);
else if (ctx.in.symTab && includeInSymtab(ctx, *b) &&
shouldKeepInSymtab(ctx, *dr))
ctx.in.symTab->addSymbol(b);
symsVec[i].push_back(b);
}
}
});
for (auto &syms : ArrayRef(symsVec.get(), ctx.objectFiles.size()))
for (Symbol *sym : syms)
ctx.in.symTab->addSymbol(sym);
}
// Create a section symbol for each output section so that we can represent