Index: ELF/LTO.h =================================================================== --- ELF/LTO.h +++ ELF/LTO.h @@ -56,6 +56,8 @@ std::unique_ptr IndexFile; llvm::DenseSet ThinIndices; }; + +void thinLTOCreateEmptyIndex(); } // namespace elf } // namespace lld Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -211,18 +211,24 @@ checkError(LTOObj->add(std::move(F.Obj), Resols)); } -static void createEmptyIndex(StringRef ModulePath) { - std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(ModulePath)); - std::unique_ptr OS = openFile(Path + ".thinlto.bc"); - if (!OS) - return; +// If LazyObjFile has not been added to link, emit empty index files. +// This is needed because this is what GNU gold plugin does and we have a +// distributed build system that depends on that behavior. +void elf::thinLTOCreateEmptyIndex() { + for (LazyObjFile *F : LazyObjFiles) { + if (F->AddedToLink || !isBitcode(F->MB)) + continue; + std::string Path = replaceThinLTOSuffix(getThinLTOOutputFile(F->getName())); + std::unique_ptr OS = openFile(Path + ".thinlto.bc"); + if (!OS) + continue; - ModuleSummaryIndex M(/*HaveGVs*/ false); - M.setSkipModuleByDistributedBackend(); - WriteIndexToFile(M, *OS); - - if (Config->ThinLTOEmitImportsFiles) - openFile(Path + ".imports"); + ModuleSummaryIndex M(/*HaveGVs*/ false); + M.setSkipModuleByDistributedBackend(); + WriteIndexToFile(M, *OS); + if (Config->ThinLTOEmitImportsFiles) + openFile(Path + ".imports"); + } } // Merge all the bitcode files we have seen, codegen the result @@ -258,13 +264,8 @@ openFile(Path + ".imports"); } - // If LazyObjFile has not been added to link, emit empty index files. - // This is needed because this is what GNU gold plugin does and we have a - // distributed build system that depends on that behavior. if (Config->ThinLTOIndexOnly) { - for (LazyObjFile *F : LazyObjFiles) - if (!F->AddedToLink && isBitcode(F->MB)) - createEmptyIndex(F->getName()); + thinLTOCreateEmptyIndex(); if (!Config->LTOObjPath.empty()) saveBuffer(Buf[0], Config->LTOObjPath); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -115,8 +115,11 @@ // Because all bitcode files that the program consists of are passed // to the compiler at once, it can do whole-program optimization. template void SymbolTable::addCombinedLTOObject() { - if (BitcodeFiles.empty()) + if (BitcodeFiles.empty()) { + if (Config->ThinLTOIndexOnly) + thinLTOCreateEmptyIndex(); return; + } // Compile bitcode files and replace bitcode symbols. LTO.reset(new BitcodeCompiler); Index: test/ELF/lto/thinlto-index-only.ll =================================================================== --- test/ELF/lto/thinlto-index-only.ll +++ test/ELF/lto/thinlto-index-only.ll @@ -38,6 +38,12 @@ ; RUN: ls %t1.o.thinlto.bc ; RUN: ls %t1.o.imports +; Ensure LLD generates an empty index for a lazy object file even if there is no non-lazy bitcode file. +; RUN: rm -f %t1.o.thinlto.bc +; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnu /dev/null -o %tdummy.o +; RUN: ld.lld --plugin-opt=thinlto-index-only -shared %tdummy.o --start-lib %t1.o --end-lib +; RUN: ls %t1.o.thinlto.bc + ; Ensure lld generates an error if unable to write an empty index file ; for lazy object file that is not added to link. ; RUN: rm -f %t1.o.thinlto.bc