From e5a619173274bf2a9033ea1c8b2346f1bee2766b Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Thu, 17 Dec 2015 17:14:09 +0000 Subject: [ThinLTO] Metadata linking for imported functions Summary: Second patch split out from http://reviews.llvm.org/D14752. Maps metadata as a post-pass from each module when importing complete, suturing up final metadata to the temporary metadata left on the imported instructions. This entails saving the mapping from bitcode value id to temporary metadata in the importing pass, and from bitcode value id to final metadata during the metadata linking postpass. Depends on D14825. Reviewers: dexonsmith, joker.eph Subscribers: davidxl, llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D14838 llvm-svn: 255909 --- llvm/tools/llvm-link/llvm-link.cpp | 49 ++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 7 deletions(-) (limited to 'llvm/tools/llvm-link/llvm-link.cpp') diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp index 326ecba3ae9..a32383028ae 100644 --- a/llvm/tools/llvm-link/llvm-link.cpp +++ b/llvm/tools/llvm-link/llvm-link.cpp @@ -106,16 +106,21 @@ static cl::opt PreserveAssemblyUseListOrder( // Read the specified bitcode file in and return it. This routine searches the // link path for the specified file to try to find it... // -static std::unique_ptr -loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) { +static std::unique_ptr loadFile(const char *argv0, + const std::string &FN, + LLVMContext &Context, + bool MaterializeMetadata = true) { SMDiagnostic Err; if (Verbose) errs() << "Loading '" << FN << "'\n"; - std::unique_ptr Result = getLazyIRFileModule(FN, Err, Context); + std::unique_ptr Result = + getLazyIRFileModule(FN, Err, Context, !MaterializeMetadata); if (!Result) Err.print(argv0, errs()); - Result->materializeMetadata(); - UpgradeDebugInfo(*Result); + if (MaterializeMetadata) { + Result->materializeMetadata(); + UpgradeDebugInfo(*Result); + } return Result; } @@ -148,6 +153,8 @@ static void diagnosticHandlerWithContext(const DiagnosticInfo &DI, void *C) { /// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { + StringMap>> + ModuleToTempMDValsMap; for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); @@ -159,7 +166,7 @@ static bool importFunctions(const char *argv0, LLVMContext &Context, std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. - std::unique_ptr M = loadFile(argv0, FileName, Context); + std::unique_ptr M = loadFile(argv0, FileName, Context, false); if (!M.get()) { errs() << argv0 << ": error loading file '" << FileName << "'\n"; return false; @@ -201,11 +208,39 @@ static bool importFunctions(const char *argv0, LLVMContext &Context, Index = std::move(IndexOrErr.get()); } + // Save the mapping of value ids to temporary metadata created when + // importing this function. If we have already imported from this module, + // add new temporary metadata to the existing mapping. + auto &TempMDVals = ModuleToTempMDValsMap[FileName]; + if (!TempMDVals) + TempMDVals = llvm::make_unique>(); + // Link in the specified function. DenseSet FunctionsToImport; FunctionsToImport.insert(F); if (L.linkInModule(std::move(M), Linker::Flags::None, Index.get(), - &FunctionsToImport)) + &FunctionsToImport, TempMDVals.get())) + return false; + } + + // Now link in metadata for all modules from which we imported functions. + for (StringMapEntry>> &SME : + ModuleToTempMDValsMap) { + // Load the specified source module. + std::unique_ptr M = loadFile(argv0, SME.getKey(), Context, true); + if (!M.get()) { + errs() << argv0 << ": error loading file '" << SME.getKey() << "'\n"; + return false; + } + + if (verifyModule(*M, &errs())) { + errs() << argv0 << ": " << SME.getKey() + << ": error: input module is broken!\n"; + return false; + } + + // Link in all necessary metadata from this module. + if (L.linkInMetadata(*M, SME.getValue().get())) return false; } return true; -- cgit v1.2.3