Index: llvm/include/llvm/LTO/LTO.h =================================================================== --- llvm/include/llvm/LTO/LTO.h +++ llvm/include/llvm/LTO/LTO.h @@ -210,13 +210,15 @@ /// appends ".thinlto.bc" and writes the index to that path. If /// ShouldEmitImportsFiles is true it also writes a list of imported files to a /// similar path with ".imports" appended instead. +/// LinkedObjectsFile is an output stream to write the list of object files for +/// the final ThinLTO linking. Can be nullptr. /// OnWrite is callback which receives module identifier and notifies LTO user /// that index file for the module (and optionally imports file) was created. using IndexWriteCallback = std::function; ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles, - std::string LinkedObjectsFile, + raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite); /// This class implements a resolution-based interface to LLVM's LTO Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -1038,10 +1038,7 @@ class WriteIndexesThinBackend : public ThinBackendProc { std::string OldPrefix, NewPrefix; bool ShouldEmitImportsFiles; - - std::string LinkedObjectsFileName; - std::unique_ptr LinkedObjectsFile; - + raw_fd_ostream *LinkedObjectsFile; lto::IndexWriteCallback OnWrite; public: @@ -1049,11 +1046,11 @@ Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap &ModuleToDefinedGVSummaries, std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles, - std::string LinkedObjectsFileName, lto::IndexWriteCallback OnWrite) + raw_fd_ostream *LinkedObjectsFile, lto::IndexWriteCallback OnWrite) : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), OldPrefix(OldPrefix), NewPrefix(NewPrefix), ShouldEmitImportsFiles(ShouldEmitImportsFiles), - LinkedObjectsFileName(LinkedObjectsFileName), OnWrite(OnWrite) {} + LinkedObjectsFile(LinkedObjectsFile), OnWrite(OnWrite) {} Error start( unsigned Task, BitcodeModule BM, @@ -1065,21 +1062,14 @@ std::string NewModulePath = getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix); - std::error_code EC; - if (!LinkedObjectsFileName.empty()) { - if (!LinkedObjectsFile) { - LinkedObjectsFile = llvm::make_unique( - LinkedObjectsFileName, EC, sys::fs::OpenFlags::F_None); - if (EC) - return errorCodeToError(EC); - } + if (LinkedObjectsFile) *LinkedObjectsFile << NewModulePath << '\n'; - } std::map ModuleToSummariesForIndex; gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries, ImportList, ModuleToSummariesForIndex); + std::error_code EC; raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC, sys::fs::OpenFlags::F_None); if (EC) @@ -1101,11 +1091,9 @@ }; } // end anonymous namespace -ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix, - std::string NewPrefix, - bool ShouldEmitImportsFiles, - std::string LinkedObjectsFile, - IndexWriteCallback OnWrite) { +ThinBackend lto::createWriteIndexesThinBackend( + std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles, + raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite) { return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, const StringMap &ModuleToDefinedGVSummaries, AddStreamFn AddStream, NativeObjectCache Cache) { Index: llvm/test/tools/gold/X86/thinlto_no_objects.ll =================================================================== --- /dev/null +++ llvm/test/tools/gold/X86/thinlto_no_objects.ll @@ -0,0 +1,18 @@ +; Check that thinlto-index-only= always creates linked objects file, even +; if nothing to add there. + +; Non-ThinLTO file should not get into list of linked objects. +; RUN: opt %s -o %t.o + +; RUN: rm -f %t3 +; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \ +; RUN: --plugin-opt=thinlto \ +; RUN: --plugin-opt=thinlto-index-only=%t3 \ +; RUN: -o %t5 \ +; RUN: %t.o + +; RUN: cat %t3 | count 0 + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + Index: llvm/tools/gold/gold-plugin.cpp =================================================================== --- llvm/tools/gold/gold-plugin.cpp +++ llvm/tools/gold/gold-plugin.cpp @@ -736,7 +736,12 @@ std::tie(OldPrefix, NewPrefix) = PrefixReplace.split(';'); } -static std::unique_ptr createLTO(IndexWriteCallback OnIndexWrite) { +/// Creates instance of LTO. +/// OnIndexWrite is callback to let caller know when LTO writes index files. +/// LinkedObjectsFile is an output stream to write the list of object files for +/// the final ThinLTO linking. Can be nullptr. +static std::unique_ptr createLTO(IndexWriteCallback OnIndexWrite, + raw_fd_ostream *LinkedObjectsFile) { Config Conf; ThinBackend Backend; @@ -760,9 +765,9 @@ if (options::thinlto_index_only) { std::string OldPrefix, NewPrefix; getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix); - Backend = createWriteIndexesThinBackend( - OldPrefix, NewPrefix, options::thinlto_emit_imports_files, - options::thinlto_linked_objects_file, OnIndexWrite); + Backend = createWriteIndexesThinBackend(OldPrefix, NewPrefix, + options::thinlto_emit_imports_files, + LinkedObjectsFile, OnIndexWrite); } Conf.OverrideTriple = options::triple; @@ -844,6 +849,21 @@ } } +// Creates and returns output stream with a list of object files for final +// linking of distributed ThinLTO. +static std::unique_ptr CreateLinkedObjectsFile() { + if (options::thinlto_linked_objects_file.empty()) + return nullptr; + assert(options::thinlto_index_only); + std::error_code EC; + auto LinkedObjectsFile = llvm::make_unique( + options::thinlto_linked_objects_file, EC, sys::fs::OpenFlags::F_None); + if (EC) + message(LDPL_FATAL, "Failed to create '%s': %s", + options::thinlto_linked_objects_file.c_str(), EC.message().c_str()); + return LinkedObjectsFile; +} + /// Runs LTO and return a list of pairs . static std::vector, bool>> runLTO() { // Map to own RAII objects that manage the file opening and releasing @@ -856,10 +876,12 @@ // Owns string objects and tells if index file was already created. StringMap ObjectToIndexFileState; - std::unique_ptr Lto = - createLTO([&ObjectToIndexFileState](const std::string &Identifier) { + std::unique_ptr LinkedObjects = CreateLinkedObjectsFile(); + std::unique_ptr Lto = createLTO( + [&ObjectToIndexFileState](const std::string &Identifier) { ObjectToIndexFileState[Identifier] = true; - }); + }, + LinkedObjects.get()); std::string OldPrefix, NewPrefix; if (options::thinlto_index_only) Index: llvm/tools/llvm-lto2/llvm-lto2.cpp =================================================================== --- llvm/tools/llvm-lto2/llvm-lto2.cpp +++ llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -243,7 +243,11 @@ ThinBackend Backend; if (ThinLTODistributedIndexes) - Backend = createWriteIndexesThinBackend("", "", true, "", {}); + Backend = createWriteIndexesThinBackend(/* OldPrefix */ "", + /* NewPrefix */ "", + /* ShouldEmitImportsFiles */ true, + /* LinkedObjectsFile */ nullptr, + /* OnWrite */ {}); else Backend = createInProcessThinBackend(Threads); LTO Lto(std::move(Conf), std::move(Backend));