Index: lib/CodeGen/BackendUtil.cpp =================================================================== --- lib/CodeGen/BackendUtil.cpp +++ lib/CodeGen/BackendUtil.cpp @@ -29,9 +29,11 @@ #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" @@ -74,8 +76,7 @@ /// 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. @@ -281,8 +282,7 @@ } void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM, - legacy::FunctionPassManager &FPM, - ModuleSummaryIndex *ModuleSummary) { + legacy::FunctionPassManager &FPM) { if (CodeGenOpts.DisableLLVMPasses) return; @@ -333,14 +333,6 @@ 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( @@ -659,26 +651,6 @@ 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 ModuleSummary; - if (!CodeGenOpts.ThinLTOIndexFile.empty()) { - ErrorOr> 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())); @@ -687,7 +659,7 @@ PerFunctionPasses.add( createTargetTransformInfoWrapperPass(getTargetIRAnalysis())); - CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get()); + CreatePasses(PerModulePasses, PerFunctionPasses); legacy::PassManager CodeGenPasses; CodeGenPasses.add( @@ -740,12 +712,69 @@ } } +static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M, + std::unique_ptr 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> 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 CombinedIndex = std::move(*IndexOrErr); + + auto AddStream = [&](size_t Task) { return std::move(OS); }; + + StringMap> + ModuleToDefinedGVSummaries; + CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries); + + FunctionImporter::ImportMapTy ImportList; + ComputeCrossModuleImportForModule(M->getModuleIdentifier(), *CombinedIndex, + ImportList); + + std::vector> OwnedImports; + MapVector ModuleMap; + + for (auto &I : ImportList) { + ErrorOr> 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 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)); Index: lib/CodeGen/CMakeLists.txt =================================================================== --- lib/CodeGen/CMakeLists.txt +++ lib/CodeGen/CMakeLists.txt @@ -8,6 +8,7 @@ IRReader InstCombine Instrumentation + LTO Linker MC ObjCARCOpts