#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
+#include "llvm/LTO/LTOBackend.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/Timer.h"
/// Set LLVM command line options passed through -backend-option.
void setCommandLineOpts();
- void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM,
- ModuleSummaryIndex *ModuleSummary);
+ void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
/// Generates the TargetMachine.
/// Leaves TM unchanged if it is unable to create the target machine.
}
void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
- legacy::FunctionPassManager &FPM,
- ModuleSummaryIndex *ModuleSummary) {
+ legacy::FunctionPassManager &FPM) {
if (CodeGenOpts.DisableLLVMPasses)
return;
PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
- // If we are performing a ThinLTO importing compile, invoke the LTO
- // pipeline and pass down the in-memory module summary index.
- if (ModuleSummary) {
- PMBuilder.ModuleSummary = ModuleSummary;
- PMBuilder.populateThinLTOPassManager(MPM);
- return;
- }
-
// Add target-specific passes that need to run as early as possible.
if (TM)
PMBuilder.addExtension(
if (TM)
TheModule->setDataLayout(TM->createDataLayout());
- // If we are performing a ThinLTO importing compile, load the function
- // index into memory and pass it into CreatePasses, which will add it
- // to the PassManagerBuilder and invoke LTO passes.
- std::unique_ptr<ModuleSummaryIndex> ModuleSummary;
- if (!CodeGenOpts.ThinLTOIndexFile.empty()) {
- ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
- llvm::getModuleSummaryIndexForFile(
- CodeGenOpts.ThinLTOIndexFile, [&](const DiagnosticInfo &DI) {
- TheModule->getContext().diagnose(DI);
- });
- if (std::error_code EC = IndexOrErr.getError()) {
- std::string Error = EC.message();
- errs() << "Error loading index file '" << CodeGenOpts.ThinLTOIndexFile
- << "': " << Error << "\n";
- return;
- }
- ModuleSummary = std::move(IndexOrErr.get());
- assert(ModuleSummary && "Expected non-empty module summary index");
- }
-
legacy::PassManager PerModulePasses;
PerModulePasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
PerFunctionPasses.add(
createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
- CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
+ CreatePasses(PerModulePasses, PerFunctionPasses);
legacy::PassManager CodeGenPasses;
CodeGenPasses.add(
}
}
+static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
+ std::unique_ptr<raw_pwrite_stream> OS) {
+ // If we are performing a ThinLTO importing compile, load the function index
+ // into memory and pass it into thinBackend, which will run the function
+ // importer and invoke LTO passes.
+ ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
+ llvm::getModuleSummaryIndexForFile(
+ CGOpts.ThinLTOIndexFile,
+ [&](const DiagnosticInfo &DI) { M->getContext().diagnose(DI); });
+ if (std::error_code EC = IndexOrErr.getError()) {
+ std::string Error = EC.message();
+ errs() << "Error loading index file '" << CGOpts.ThinLTOIndexFile
+ << "': " << Error << "\n";
+ return;
+ }
+ std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
+
+ auto AddStream = [&](size_t Task) { return std::move(OS); };
+
+ StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
+ ModuleToDefinedGVSummaries;
+ CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
+
+ // FIXME: We could simply import the modules mentioned in the combined index
+ // here.
+ FunctionImporter::ImportMapTy ImportList;
+ ComputeCrossModuleImportForModule(M->getModuleIdentifier(), *CombinedIndex,
+ ImportList);
+
+ std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
+ MapVector<llvm::StringRef, llvm::MemoryBufferRef> ModuleMap;
+
+ 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;
+ }
+ ModuleMap[I.first()] = (*MBOrErr)->getMemBufferRef();
+ OwnedImports.push_back(std::move(*MBOrErr));
+ }
+
+ lto::Config Conf;
+ if (Error E = thinBackend(
+ Conf, 0, AddStream, *M, *CombinedIndex, ImportList,
+ ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
+ handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
+ errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
+ });
+ }
+}
+
void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts,
const LangOptions &LOpts, const llvm::DataLayout &TDesc,
Module *M, BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
+ if (!CGOpts.ThinLTOIndexFile.empty()) {
+ runThinLTOBackend(CGOpts, M, std::move(OS));
+ return;
+ }
+
EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
AsmHelper.EmitAssembly(Action, std::move(OS));