Index: llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h =================================================================== --- llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h +++ llvm/trunk/include/llvm/Transforms/IPO/FunctionImport.h @@ -143,9 +143,9 @@ std::map &ModuleToSummariesForIndex); /// Emit into \p OutputFilename the files module \p ModulePath will import from. -std::error_code -EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, - const FunctionImporter::ImportMapTy &ModuleImports); +std::error_code EmitImportsFiles( + StringRef ModulePath, StringRef OutputFilename, + const std::map &ModuleToSummariesForIndex); /// Resolve WeakForLinker values in \p TheModule based on the information /// recorded in the summaries during global summary-based analysis. Index: llvm/trunk/lib/LTO/LTO.cpp =================================================================== --- llvm/trunk/lib/LTO/LTO.cpp +++ llvm/trunk/lib/LTO/LTO.cpp @@ -1097,7 +1097,8 @@ WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); if (ShouldEmitImportsFiles) { - EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports", ImportList); + EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports", + ModuleToSummariesForIndex); if (EC) return errorCodeToError(EC); } Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -758,8 +758,14 @@ ComputeCrossModuleImport(Index, ModuleToDefinedGVSummaries, ImportLists, ExportLists); + std::map ModuleToSummariesForIndex; + llvm::gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries, + ImportLists[ModulePath], + ModuleToSummariesForIndex); + std::error_code EC; - if ((EC = EmitImportsFiles(ModulePath, OutputName, ImportLists[ModulePath]))) + if ((EC = + EmitImportsFiles(ModulePath, OutputName, ModuleToSummariesForIndex))) report_fatal_error(Twine("Failed to open ") + OutputName + " to save imports lists\n"); } Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -707,15 +707,19 @@ } /// Emit the files \p ModulePath will import from into \p OutputFilename. -std::error_code -llvm::EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, - const FunctionImporter::ImportMapTy &ModuleImports) { +std::error_code llvm::EmitImportsFiles( + StringRef ModulePath, StringRef OutputFilename, + const std::map &ModuleToSummariesForIndex) { std::error_code EC; raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::F_None); if (EC) return EC; - for (auto &ILI : ModuleImports) - ImportsOS << ILI.first() << "\n"; + for (auto &ILI : ModuleToSummariesForIndex) + // The ModuleToSummariesForIndex map includes an entry for the current + // Module (needed for writing out the index files). We don't want to + // include it in the imports file, however, so filter it out. + if (ILI.first != ModulePath) + ImportsOS << ILI.first << "\n"; return std::error_code(); } Index: llvm/trunk/test/ThinLTO/X86/Inputs/emit_imports2.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/Inputs/emit_imports2.ll +++ llvm/trunk/test/ThinLTO/X86/Inputs/emit_imports2.ll @@ -0,0 +1,7 @@ +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @h() { +entry: + ret void +} Index: llvm/trunk/test/ThinLTO/X86/emit_imports.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/emit_imports.ll +++ llvm/trunk/test/ThinLTO/X86/emit_imports.ll @@ -1,17 +1,19 @@ ; RUN: opt -module-summary %s -o %t1.bc ; RUN: opt -module-summary %p/Inputs/emit_imports.ll -o %t2.bc +; RUN: opt -module-summary %p/Inputs/emit_imports2.ll -o %t2b.bc ; Include a file with an empty module summary index, to ensure that the expected ; output files are created regardless, for a distributed build system. ; RUN: opt -module-summary %p/Inputs/empty.ll -o %t3.bc ; RUN: rm -f %t3.bc.imports -; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc %t3.bc -; RUN: llvm-lto -thinlto-action=emitimports -thinlto-index %t.index.bc %t1.bc %t2.bc %t3.bc +; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc %t2b.bc %t3.bc +; RUN: llvm-lto -thinlto-action=emitimports -thinlto-index %t.index.bc %t1.bc %t2.bc %t2b.bc %t3.bc ; The imports file for this module contains the bitcode file for ; Inputs/emit_imports.ll -; RUN: cat %t1.bc.imports | count 1 +; RUN: cat %t1.bc.imports | count 2 ; RUN: cat %t1.bc.imports | FileCheck %s --check-prefix=IMPORTS1 ; IMPORTS1: emit_imports.ll.tmp2.bc +; IMPORTS1: emit_imports.ll.tmp2b.bc ; The imports file for Input/emit_imports.ll is empty as it does not import anything. ; RUN: cat %t2.bc.imports | count 0 @@ -22,13 +24,15 @@ ; RUN: rm -f %t1.thinlto.bc %t1.bc.imports ; RUN: rm -f %t2.thinlto.bc %t2.bc.imports ; RUN: rm -f %t3.bc.thinlto.bc %t3.bc.imports -; RUN: llvm-lto2 run %t1.bc %t2.bc %t3.bc -o %t.o -save-temps \ +; RUN: llvm-lto2 run %t1.bc %t2.bc %t2b.bc %t3.bc -o %t.o -save-temps \ ; RUN: -thinlto-distributed-indexes \ ; RUN: -r=%t1.bc,g, \ +; RUN: -r=%t1.bc,h, \ ; RUN: -r=%t1.bc,f,px \ -; RUN: -r=%t2.bc,g,px +; RUN: -r=%t2.bc,g,px \ +; RUN: -r=%t2b.bc,h,px -; RUN: cat %t1.bc.imports | count 1 +; RUN: cat %t1.bc.imports | count 2 ; RUN: cat %t1.bc.imports | FileCheck %s --check-prefix=IMPORTS1 ; The imports file for Input/emit_imports.ll is empty as it does not import anything. @@ -44,9 +48,11 @@ target triple = "x86_64-unknown-linux-gnu" declare void @g(...) +declare void @h(...) define void @f() { entry: call void (...) @g() + call void (...) @h() ret void }