summaryrefslogtreecommitdiff
path: root/tools/llvm-link
diff options
context:
space:
mode:
Diffstat (limited to 'tools/llvm-link')
-rw-r--r--tools/llvm-link/llvm-link.cpp49
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;