Index: test/tools/gold/X86/thinlto_emit_imports.ll =================================================================== --- /dev/null +++ test/tools/gold/X86/thinlto_emit_imports.ll @@ -0,0 +1,27 @@ +; Generate summary sections and test gold handling. +; RUN: opt -module-summary %s -o %t.o +; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o + +; Ensure gold generates imports files if requested for distributed backends. +; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \ +; RUN: --plugin-opt=thinlto \ +; RUN: --plugin-opt=thinlto-index-only \ +; RUN: --plugin-opt=thinlto-emit-imports-files \ +; RUN: -shared %t.o %t2.o -o %t3 + +; The imports file for this module contains the bitcode file for +; Inputs/thinlto.ll +; RUN: cat %t.o.imports | count 1 +; RUN: cat %t.o.imports | FileCheck %s --check-prefix=IMPORTS1 +; IMPORTS1: test/tools/gold/X86/Output/thinlto_emit_imports.ll.tmp2.o + +; The imports file for Input/thinlto.ll is empty as it does not import anything. +; RUN: cat %t2.o.imports | count 0 + +declare void @g(...) + +define void @f() { +entry: + call void (...) @g() + ret void +} Index: tools/gold/gold-plugin.cpp =================================================================== --- tools/gold/gold-plugin.cpp +++ tools/gold/gold-plugin.cpp @@ -184,6 +184,11 @@ // the import decisions, and exit afterwards. The assumption is // that the build system will launch the backend processes. static bool thinlto_index_only = false; + // If true, when generating individual index files for distributed backends, + // also generate a "${bitcodefile}.imports" file at the same location for each + // bitcode file, listing the files it imports from in plain text. This is to + // support distributed build file staging. + static bool thinlto_emit_imports_files = false; // Additional options to pass into the code generator. // Note: This array will contain all plugin options which are not claimed // as plugin exclusive to pass to the code generator. @@ -217,6 +222,8 @@ thinlto = true; } else if (opt == "thinlto-index-only") { thinlto_index_only = true; + } else if (opt == "thinlto-emit-imports-files") { + thinlto_emit_imports_files = true; } else if (opt.size() == 2 && opt[0] == 'O') { if (opt[1] < '0' || opt[1] > '3') message(LDPL_FATAL, "Optimization level must be between 0 and 3"); @@ -1209,6 +1216,10 @@ CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); } + if (options::thinlto_emit_imports_files && !options::thinlto_index_only) + message(LDPL_WARNING, + "thinlto-emit-imports-files ignored unless thinlto-index-only"); + if (options::thinlto_index_only) { // Collect for each module the list of function it defines (GUID -> // Summary). @@ -1256,6 +1267,17 @@ } } } + if (options::thinlto_emit_imports_files) { + raw_fd_ostream ImportsOS( + (Twine(InputFile.file().name) + ".imports").str(), EC, + sys::fs::OpenFlags::F_None); + if (EC) + message(LDPL_FATAL, "Unable to open %s.imports", + InputFile.file().name, EC.message().c_str()); + if (ModuleImports != ImportLists.end()) + for (auto &ILI : ModuleImports->second) + ImportsOS << ILI.first() << "\n"; + } WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); }