diff options
Diffstat (limited to 'tools/llvm-link')
-rw-r--r-- | tools/llvm-link/llvm-link.cpp | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 326ecba3ae9..a32383028ae 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -106,16 +106,21 @@ static cl::opt<bool> 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<Module> -loadFile(const char *argv0, const std::string &FN, LLVMContext &Context) { +static std::unique_ptr<Module> loadFile(const char *argv0, + const std::string &FN, + LLVMContext &Context, + bool MaterializeMetadata = true) { SMDiagnostic Err; if (Verbose) errs() << "Loading '" << FN << "'\n"; - std::unique_ptr<Module> Result = getLazyIRFileModule(FN, Err, Context); + std::unique_ptr<Module> 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<std::unique_ptr<DenseMap<unsigned, MDNode *>>> + 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<Module> M = loadFile(argv0, FileName, Context); + std::unique_ptr<Module> 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<DenseMap<unsigned, MDNode *>>(); + // Link in the specified function. DenseSet<const GlobalValue *> 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<std::unique_ptr<DenseMap<unsigned, MDNode *>>> &SME : + ModuleToTempMDValsMap) { + // Load the specified source module. + std::unique_ptr<Module> 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; |