From 036b755daedb3b45b750d85493b1a93de8bafb8e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 22 Mar 2026 21:52:55 -0700 Subject: [PATCH] [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. --- lld/ELF/Writer.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index c84e4df76745..b8ec53e78f6e 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -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[]>(ctx.objectFiles.size()); + parallelFor(0, ctx.objectFiles.size(), [&](size_t i) { DenseMap 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(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