static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(M.get(), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } // Note that when ODR merging types cannot verify input files in here When // doing that debug metadata in the src module might already be pointing to // the destination. if (DisableDITypeMap && verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a module summary index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. if (!SummaryIndex.empty()) { std::unique_ptr<ModuleSummaryIndex> Index = ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex)); // Conservatively mark all internal values as promoted, since this tool // does not do the ThinLink that would normally determine what values to // promote. for (auto &I : *Index) { for (auto &S : I.second) { if (GlobalValue::isLocalLinkage(S->linkage())) S->setLinkage(GlobalValue::ExternalLinkage); } } // Promotion if (renameModuleForThinLTO(*M, *Index)) return true; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a function index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } Index = std::move(IndexOrErr.get()); } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags, Index.get())) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; // If requested for testing, preserve modules by releasing them from // the unique_ptr before the are freed. This can help catch any // cross-module references from e.g. unneeded metadata references // that aren't properly set to null but instead mapped to the source // module version. The bitcode writer will assert if it finds any such // cross-module references. if (PreserveModules) M.release(); } return true; }
static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L, const cl::list<std::string> &Files, unsigned Flags) { // Filter out flags that don't apply to the first file we load. unsigned ApplicableFlags = Flags & Linker::Flags::OverrideFromSrc; for (const auto &File : Files) { std::unique_ptr<Module> M = loadFile(argv0, File, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << File << "'\n"; return false; } // Note that when ODR merging types cannot verify input files in here When // doing that debug metadata in the src module might already be pointing to // the destination. if (DisableDITypeMap && verifyModule(*M, &errs())) { errs() << argv0 << ": " << File << ": error: input module is broken!\n"; return false; } // If a module summary index is supplied, load it so linkInModule can treat // local functions/variables as exported and promote if necessary. if (!SummaryIndex.empty()) { ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr = llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } auto Index = std::move(IndexOrErr.get()); // Promotion if (renameModuleForThinLTO(*M, *Index)) return true; } if (Verbose) errs() << "Linking in '" << File << "'\n"; if (L.linkInModule(std::move(M), ApplicableFlags)) return false; // All linker flags apply to linking of subsequent files. ApplicableFlags = Flags; } return true; }
/// 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(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. std::unique_ptr<Module> M = loadFile(argv0, FileName, Context, false); if (!M.get()) { errs() << argv0 << ": error loading file '" << FileName << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = M->getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } 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, 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; }
/// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { if (SummaryIndex.empty()) return true; std::unique_ptr<ModuleSummaryIndex> Index = ExitOnErr(llvm::getModuleSummaryIndexForFile(SummaryIndex)); // Map of Module -> List of globals to import from the Module std::map<StringRef, DenseSet<const GlobalValue *>> ModuleToGlobalsToImportMap; auto ModuleLoader = [&Context](const char *argv0, const std::string &Identifier) { return loadFile(argv0, Identifier, Context, false); }; ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader); for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. auto &SrcModule = ModuleLoaderCache(argv0, FileName); if (verifyModule(SrcModule, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = SrcModule.getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; auto &Entry = ModuleToGlobalsToImportMap[SrcModule.getModuleIdentifier()]; Entry.insert(F); ExitOnErr(F->materialize()); } // Do the actual import of globals now, one Module at a time for (auto &GlobalsToImportPerModule : ModuleToGlobalsToImportMap) { // Get the module for the import auto &GlobalsToImport = GlobalsToImportPerModule.second; std::unique_ptr<Module> SrcModule = ModuleLoaderCache.takeModule(GlobalsToImportPerModule.first); assert(&Context == &SrcModule->getContext() && "Context mismatch"); // If modules were created with lazy metadata loading, materialize it // now, before linking it (otherwise this will be a noop). ExitOnErr(SrcModule->materializeMetadata()); UpgradeDebugInfo(*SrcModule); // Linkage Promotion and renaming if (renameModuleForThinLTO(*SrcModule, *Index, &GlobalsToImport)) return true; // Instruct the linker to not automatically import linkonce defintion. unsigned Flags = Linker::Flags::DontForceLinkLinkonceODR; if (L.linkInModule(std::move(SrcModule), Flags, &GlobalsToImport)) return false; } return true; }
/// Import any functions requested via the -import option. static bool importFunctions(const char *argv0, LLVMContext &Context, Linker &L) { for (const auto &Import : Imports) { // Identify the requested function and its bitcode source file. size_t Idx = Import.find(':'); if (Idx == std::string::npos) { errs() << "Import parameter bad format: " << Import << "\n"; return false; } std::string FunctionName = Import.substr(0, Idx); std::string FileName = Import.substr(Idx + 1, std::string::npos); // Load the specified source module. std::unique_ptr<Module> M = loadFile(argv0, FileName, Context); if (!M.get()) { errs() << argv0 << ": error loading file '" << FileName << "'\n"; return false; } if (verifyModule(*M, &errs())) { errs() << argv0 << ": " << FileName << ": error: input module is broken!\n"; return false; } Function *F = M->getFunction(FunctionName); if (!F) { errs() << "Ignoring import request for non-existent function " << FunctionName << " from " << FileName << "\n"; continue; } // We cannot import weak_any functions without possibly affecting the // order they are seen and selected by the linker, changing program // semantics. if (F->hasWeakAnyLinkage()) { errs() << "Ignoring import request for weak-any function " << FunctionName << " from " << FileName << "\n"; continue; } if (Verbose) errs() << "Importing " << FunctionName << " from " << FileName << "\n"; std::unique_ptr<FunctionInfoIndex> Index; if (!FunctionIndex.empty()) { ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler); std::error_code EC = IndexOrErr.getError(); if (EC) { errs() << EC.message() << '\n'; return false; } Index = std::move(IndexOrErr.get()); } // Link in the specified function. DenseSet<const GlobalValue *> FunctionsToImport; FunctionsToImport.insert(F); if (L.linkInModule(*M, Linker::Flags::None, Index.get(), &FunctionsToImport)) return false; } return true; }