Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -319,6 +319,18 @@ return Default; } +// We need to call readSymbols() on each LazyObjectFile to let it +// construct per-file internal data structure. Do that in parallel. +static void readLazyObjects(ArrayRef Files) { + std::vector V; + for (InputFile *F : Files) + if (auto *Lazy = dyn_cast(F)) + V.push_back(Lazy); + + parallelForEach(V.begin(), V.end(), + [](LazyObjectFile *F) { F->readSymbols(); }); +} + void LinkerDriver::main(ArrayRef ArgsArr, bool CanExitEarly) { ELFOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); @@ -380,6 +392,7 @@ inferMachineType(); setConfigs(); checkOptions(Args); + readLazyObjects(Files); if (ErrorCount) return; Index: lld/ELF/InputFiles.h =================================================================== --- lld/ELF/InputFiles.h +++ lld/ELF/InputFiles.h @@ -226,6 +226,7 @@ } template void parse(); + void readSymbols(); MemoryBufferRef getBuffer(); InputFile *fetch(); @@ -234,7 +235,9 @@ template std::vector getElfSymbols(); std::vector getBitcodeSymbols(); + llvm::Optional> Symbols; bool Seen = false; + llvm::BumpPtrAllocator Alloc; }; // An ArchiveFile object represents a .a file. Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -984,8 +984,11 @@ return createObjectFile(MBRef); } +void LazyObjectFile::readSymbols() { Symbols = getSymbols(); } + template void LazyObjectFile::parse() { - for (StringRef Sym : getSymbols()) + assert(Symbols.hasValue()); + for (StringRef Sym : *Symbols) Symtab::X->addLazyObject(Sym, *this); } @@ -1017,6 +1020,11 @@ std::vector LazyObjectFile::getBitcodeSymbols() { std::unique_ptr Obj = check(lto::InputFile::create(this->MB), toString(this)); + + // Since this function is called inside parallel_for, + // we want to use a per-object allocator. + StringSaver Saver(Alloc); + std::vector V; for (const lto::InputFile::Symbol &Sym : Obj->symbols()) if (!Sym.isUndefined())