diff options
author | Mircea Trofin <mtrofin@google.com> | 2020-09-16 12:08:15 -0700 |
---|---|---|
committer | Mircea Trofin <mtrofin@google.com> | 2020-09-22 13:12:11 -0700 |
commit | cf112382ddd0d717edf0b8a3e5b061de925258e9 (patch) | |
tree | 78bc2aa17895f85a280087a575f706a6b5fd348c /llvm/lib/LTO/LTOBackend.cpp | |
parent | c45596147938191b0ffde91ee8d506e315bf4c8f (diff) | |
download | llvm-cf112382ddd0d717edf0b8a3e5b061de925258e9.zip llvm-cf112382ddd0d717edf0b8a3e5b061de925258e9.tar.gz llvm-cf112382ddd0d717edf0b8a3e5b061de925258e9.tar.bz2 |
[ThinLTO] Option to bypass function importing.
This completes the circle, complementing -lto-embed-bitcode
(specifically, post-merge-pre-opt). Using -thinlto-assume-merged skips
function importing. The index file is still needed for the other data it
contains.
Differential Revision: https://reviews.llvm.org/D87949
Diffstat (limited to 'llvm/lib/LTO/LTOBackend.cpp')
-rw-r--r-- | llvm/lib/LTO/LTOBackend.cpp | 102 |
1 files changed, 96 insertions, 6 deletions
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 4c5778e..fc39c1a 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -69,6 +69,11 @@ static cl::opt<LTOBitcodeEmbedding> EmbedBitcode( "Embed post merge, but before optimizations")), cl::desc("Embed LLVM bitcode in object files produced by LTO")); +static cl::opt<bool> ThinLTOAssumeMerged( + "thinlto-assume-merged", cl::init(false), + cl::desc("Assume the input has already undergone ThinLTO function " + "importing and the other pre-optimization pipeline changes.")); + LLVM_ATTRIBUTE_NORETURN static void reportOpenError(StringRef Path, Twine Msg) { errs() << "failed to open " << Path << ": " << Msg << '\n'; errs().flush(); @@ -583,6 +588,21 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + auto OptimizeAndCodegen = + [&](Module &Mod, TargetMachine *TM, + std::unique_ptr<ToolOutputFile> DiagnosticOutputFile) { + if (!opt(Conf, TM, Task, Mod, /*IsThinLTO=*/true, + /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex, + CmdArgs)) + return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + + codegen(Conf, TM, AddStream, Task, Mod, CombinedIndex); + return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + }; + + if (ThinLTOAssumeMerged) + return OptimizeAndCodegen(Mod, TM.get(), std::move(DiagnosticOutputFile)); + // When linking an ELF shared object, dso_local should be dropped. We // conservatively do this for -fpic. bool ClearDSOLocalOnDeclarations = @@ -623,11 +643,81 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream, if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); - if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true, - /*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex, - CmdArgs)) - return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + return OptimizeAndCodegen(Mod, TM.get(), std::move(DiagnosticOutputFile)); +} + +BitcodeModule *lto::findThinLTOModule(MutableArrayRef<BitcodeModule> BMs) { + if (ThinLTOAssumeMerged && BMs.size() == 1) + return BMs.begin(); - codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex); - return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); + for (BitcodeModule &BM : BMs) { + Expected<BitcodeLTOInfo> LTOInfo = BM.getLTOInfo(); + if (LTOInfo && LTOInfo->IsThinLTO) + return &BM; + } + return nullptr; } + +Expected<BitcodeModule> lto::findThinLTOModule(MemoryBufferRef MBRef) { + Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); + if (!BMsOrErr) + return BMsOrErr.takeError(); + + // The bitcode file may contain multiple modules, we want the one that is + // marked as being the ThinLTO module. + if (const BitcodeModule *Bm = lto::findThinLTOModule(*BMsOrErr)) + return *Bm; + + return make_error<StringError>("Could not find module summary", + inconvertibleErrorCode()); +} + +bool lto::loadReferencedModules( + const Module &M, const ModuleSummaryIndex &CombinedIndex, + FunctionImporter::ImportMapTy &ImportList, + MapVector<llvm::StringRef, llvm::BitcodeModule> &ModuleMap, + std::vector<std::unique_ptr<llvm::MemoryBuffer>> + &OwnedImportsLifetimeManager) { + if (ThinLTOAssumeMerged) + return true; + // We can simply import the values mentioned in the combined index, since + // we should only invoke this using the individual indexes written out + // via a WriteIndexesThinBackend. + for (const auto &GlobalList : CombinedIndex) { + // Ignore entries for undefined references. + if (GlobalList.second.SummaryList.empty()) + continue; + + auto GUID = GlobalList.first; + for (const auto &Summary : GlobalList.second.SummaryList) { + // Skip the summaries for the importing module. These are included to + // e.g. record required linkage changes. + if (Summary->modulePath() == M.getModuleIdentifier()) + continue; + // Add an entry to provoke importing by thinBackend. + ImportList[Summary->modulePath()].insert(GUID); + } + } + + for (auto &I : ImportList) { + ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr = + llvm::MemoryBuffer::getFile(I.first()); + if (!MBOrErr) { + errs() << "Error loading imported file '" << I.first() + << "': " << MBOrErr.getError().message() << "\n"; + return false; + } + + Expected<BitcodeModule> BMOrErr = findThinLTOModule(**MBOrErr); + if (!BMOrErr) { + handleAllErrors(BMOrErr.takeError(), [&](ErrorInfoBase &EIB) { + errs() << "Error loading imported file '" << I.first() + << "': " << EIB.message() << '\n'; + }); + return false; + } + ModuleMap.insert({I.first(), *BMOrErr}); + OwnedImportsLifetimeManager.push_back(std::move(*MBOrErr)); + } + return true; +}
\ No newline at end of file |