mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[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
This commit is contained in:
parent
54f163f8a4
commit
3c9a842f53
@ -49,6 +49,22 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream,
|
|||||||
|
|
||||||
Error finalizeOptimizationRemarks(
|
Error finalizeOptimizationRemarks(
|
||||||
std::unique_ptr<ToolOutputFile> DiagOutputFile);
|
std::unique_ptr<ToolOutputFile> DiagOutputFile);
|
||||||
|
|
||||||
|
/// Returns the BitcodeModule that is ThinLTO.
|
||||||
|
BitcodeModule *findThinLTOModule(MutableArrayRef<BitcodeModule> BMs);
|
||||||
|
|
||||||
|
/// Variant of the above.
|
||||||
|
Expected<BitcodeModule> findThinLTOModule(MemoryBufferRef MBRef);
|
||||||
|
|
||||||
|
/// Distributed ThinLTO: load the referenced modules, keeping their buffers
|
||||||
|
/// alive in the provided OwnedImportLifetimeManager. Returns false if the
|
||||||
|
/// operation failed.
|
||||||
|
bool loadReferencedModules(
|
||||||
|
const Module &M, const ModuleSummaryIndex &CombinedIndex,
|
||||||
|
FunctionImporter::ImportMapTy &ImportList,
|
||||||
|
MapVector<llvm::StringRef, llvm::BitcodeModule> &ModuleMap,
|
||||||
|
std::vector<std::unique_ptr<llvm::MemoryBuffer>>
|
||||||
|
&OwnedImportsLifetimeManager);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,11 @@ static cl::opt<LTOBitcodeEmbedding> EmbedBitcode(
|
|||||||
"Embed post merge, but before optimizations")),
|
"Embed post merge, but before optimizations")),
|
||||||
cl::desc("Embed LLVM bitcode in object files produced by LTO"));
|
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) {
|
LLVM_ATTRIBUTE_NORETURN static void reportOpenError(StringRef Path, Twine Msg) {
|
||||||
errs() << "failed to open " << Path << ": " << Msg << '\n';
|
errs() << "failed to open " << Path << ": " << Msg << '\n';
|
||||||
errs().flush();
|
errs().flush();
|
||||||
@ -583,6 +588,21 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
|
|||||||
if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
|
if (Conf.PreOptModuleHook && !Conf.PreOptModuleHook(Task, Mod))
|
||||||
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
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
|
// When linking an ELF shared object, dso_local should be dropped. We
|
||||||
// conservatively do this for -fpic.
|
// conservatively do this for -fpic.
|
||||||
bool ClearDSOLocalOnDeclarations =
|
bool ClearDSOLocalOnDeclarations =
|
||||||
@ -623,11 +643,81 @@ Error lto::thinBackend(const Config &Conf, unsigned Task, AddStreamFn AddStream,
|
|||||||
if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
|
if (Conf.PostImportModuleHook && !Conf.PostImportModuleHook(Task, Mod))
|
||||||
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
||||||
|
|
||||||
if (!opt(Conf, TM.get(), Task, Mod, /*IsThinLTO=*/true,
|
return OptimizeAndCodegen(Mod, TM.get(), std::move(DiagnosticOutputFile));
|
||||||
/*ExportSummary=*/nullptr, /*ImportSummary=*/&CombinedIndex,
|
|
||||||
CmdArgs))
|
|
||||||
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
|
||||||
|
|
||||||
codegen(Conf, TM.get(), AddStream, Task, Mod, CombinedIndex);
|
|
||||||
return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BitcodeModule *lto::findThinLTOModule(MutableArrayRef<BitcodeModule> BMs) {
|
||||||
|
if (ThinLTOAssumeMerged && BMs.size() == 1)
|
||||||
|
return BMs.begin();
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user