diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 79 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 76 |
2 files changed, 102 insertions, 53 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 37e62f8ddcd..784e9c7ba5f 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -22,6 +22,7 @@ #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/FunctionInfo.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" @@ -53,6 +54,7 @@ class EmitAssemblyHelper { const clang::TargetOptions &TargetOpts; const LangOptions &LangOpts; Module *TheModule; + std::unique_ptr<FunctionInfoIndex> FunctionIndex; Timer CodeGenerationTime; @@ -113,15 +115,14 @@ private: bool AddEmitPasses(BackendAction Action, raw_pwrite_stream &OS); public: - EmitAssemblyHelper(DiagnosticsEngine &_Diags, - const CodeGenOptions &CGOpts, + EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, - const LangOptions &LOpts, - Module *M) - : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), - TheModule(M), CodeGenerationTime("Code Generation Time"), - CodeGenPasses(nullptr), PerModulePasses(nullptr), - PerFunctionPasses(nullptr) {} + const LangOptions &LOpts, Module *M, + std::unique_ptr<FunctionInfoIndex> Index) + : Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts), + TheModule(M), FunctionIndex(std::move(Index)), + CodeGenerationTime("Code Generation Time"), CodeGenPasses(nullptr), + PerModulePasses(nullptr), PerFunctionPasses(nullptr) {} ~EmitAssemblyHelper() { delete CodeGenPasses; @@ -285,6 +286,29 @@ void EmitAssemblyHelper::CreatePasses() { } PassManagerBuilderWrapper PMBuilder(CodeGenOpts, LangOpts); + + // Figure out TargetLibraryInfo. + Triple TargetTriple(TheModule->getTargetTriple()); + PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); + + switch (Inlining) { + case CodeGenOptions::NoInlining: + break; + case CodeGenOptions::NormalInlining: { + PMBuilder.Inliner = + createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); + break; + } + case CodeGenOptions::OnlyAlwaysInlining: + // Respect always_inline. + if (OptLevel == 0) + // Do not insert lifetime intrinsics at -O0. + PMBuilder.Inliner = createAlwaysInlinerPass(false); + else + PMBuilder.Inliner = createAlwaysInlinerPass(); + break; + } + PMBuilder.OptLevel = OptLevel; PMBuilder.SizeLevel = CodeGenOpts.OptimizeSize; PMBuilder.BBVectorize = CodeGenOpts.VectorizeBB; @@ -297,6 +321,17 @@ void EmitAssemblyHelper::CreatePasses() { PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO; PMBuilder.RerollLoops = CodeGenOpts.RerollLoops; + legacy::PassManager *MPM = getPerModulePasses(); + + // If we are performing a ThinLTO importing compile, invoke the LTO + // pipeline and pass down the in-memory function index. + if (!CodeGenOpts.ThinLTOIndexFile.empty()) { + assert(FunctionIndex && "Expected non-empty function index"); + PMBuilder.FunctionIndex = FunctionIndex.get(); + PMBuilder.populateLTOPassManager(*MPM); + return; + } + PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible, addAddDiscriminatorsPass); @@ -361,27 +396,6 @@ void EmitAssemblyHelper::CreatePasses() { addDataFlowSanitizerPass); } - // Figure out TargetLibraryInfo. - Triple TargetTriple(TheModule->getTargetTriple()); - PMBuilder.LibraryInfo = createTLII(TargetTriple, CodeGenOpts); - - switch (Inlining) { - case CodeGenOptions::NoInlining: break; - case CodeGenOptions::NormalInlining: { - PMBuilder.Inliner = - createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize); - break; - } - case CodeGenOptions::OnlyAlwaysInlining: - // Respect always_inline. - if (OptLevel == 0) - // Do not insert lifetime intrinsics at -O0. - PMBuilder.Inliner = createAlwaysInlinerPass(false); - else - PMBuilder.Inliner = createAlwaysInlinerPass(); - break; - } - // Set up the per-function pass manager. legacy::FunctionPassManager *FPM = getPerFunctionPasses(); if (CodeGenOpts.VerifyModule) @@ -389,7 +403,6 @@ void EmitAssemblyHelper::CreatePasses() { PMBuilder.populateFunctionPassManager(*FPM); // Set up the per-module pass manager. - legacy::PassManager *MPM = getPerModulePasses(); if (!CodeGenOpts.RewriteMapFiles.empty()) addSymbolRewriterPass(CodeGenOpts, MPM); @@ -660,8 +673,10 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags, const clang::TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, Module *M, BackendAction Action, - raw_pwrite_stream *OS) { - EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M); + raw_pwrite_stream *OS, + std::unique_ptr<FunctionInfoIndex> Index) { + EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M, + std::move(Index)); AsmHelper.EmitAssembly(Action, OS); diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index da48dbdefbe..9c0ae9ed991 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -26,10 +26,12 @@ #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/FunctionInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Linker/Linker.h" +#include "llvm/Object/FunctionIndexObjectFile.h" #include "llvm/Pass.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -39,6 +41,24 @@ using namespace clang; using namespace llvm; namespace clang { +/// Diagnostic handler used by invocations of Linker::LinkModules +static void linkerDiagnosticHandler(const DiagnosticInfo &DI, + const llvm::Module *LinkModule, + DiagnosticsEngine &Diags) { + if (DI.getSeverity() != DS_Error) + return; + + std::string MsgStorage; + { + raw_string_ostream Stream(MsgStorage); + DiagnosticPrinterRawOStream DP(Stream); + DI.print(DP); + } + + Diags.Report(diag::err_fe_cannot_link_module) + << LinkModule->getModuleIdentifier() << MsgStorage; +} + class BackendConsumer : public ASTConsumer { virtual void anchor(); DiagnosticsEngine &Diags; @@ -167,7 +187,7 @@ namespace clang { llvm::Module *LinkModule = I.second.get(); if (Linker::linkModules(*M, *LinkModule, [=](const DiagnosticInfo &DI) { - linkerDiagnosticHandler(DI, LinkModule); + linkerDiagnosticHandler(DI, LinkModule, Diags); }, LinkFlags)) return; @@ -233,9 +253,6 @@ namespace clang { ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc); } - void linkerDiagnosticHandler(const llvm::DiagnosticInfo &DI, - const llvm::Module *LinkModule); - static void DiagnosticHandler(const llvm::DiagnosticInfo &DI, void *Context) { ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI); @@ -545,22 +562,6 @@ void BackendConsumer::OptimizationFailureHandler( EmitOptimizationMessage(D, diag::warn_fe_backend_optimization_failure); } -void BackendConsumer::linkerDiagnosticHandler(const DiagnosticInfo &DI, - const llvm::Module *LinkModule) { - if (DI.getSeverity() != DS_Error) - return; - - std::string MsgStorage; - { - raw_string_ostream Stream(MsgStorage); - DiagnosticPrinterRawOStream DP(Stream); - DI.print(DP); - } - - Diags.Report(diag::err_fe_cannot_link_module) - << LinkModule->getModuleIdentifier() << MsgStorage; -} - /// \brief This function is invoked when the backend needs /// to report something to the user. void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { @@ -785,11 +786,44 @@ void CodeGenAction::ExecuteAction() { TheModule->setTargetTriple(TargetOpts.Triple); } + auto DiagHandler = [&](const DiagnosticInfo &DI) { + linkerDiagnosticHandler(DI, TheModule.get(), + getCompilerInstance().getDiagnostics()); + }; + + // If we are performing ThinLTO importing compilation (indicated by + // a non-empty index file option), then we need promote to global scope + // and rename any local values that are potentially exported to other + // modules. Do this early so that the rest of the compilation sees the + // promoted symbols. + std::unique_ptr<FunctionInfoIndex> Index; + if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) { + ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = + llvm::getFunctionIndexForFile(CI.getCodeGenOpts().ThinLTOIndexFile, + DiagHandler); + if (std::error_code EC = IndexOrErr.getError()) { + std::string Error = EC.message(); + errs() << "Error loading index file '" + << CI.getCodeGenOpts().ThinLTOIndexFile << "': " << Error + << "\n"; + return; + } + Index = std::move(IndexOrErr.get()); + assert(Index); + // Currently this requires creating a new Module object. + std::unique_ptr<llvm::Module> RenamedModule = + renameModuleForThinLTO(TheModule, Index.get(), DiagHandler); + if (!RenamedModule) + return; + + TheModule = std::move(RenamedModule); + } + LLVMContext &Ctx = TheModule->getContext(); Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler); EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(), CI.getTarget().getDataLayoutString(), - TheModule.get(), BA, OS); + TheModule.get(), BA, OS, std::move(Index)); return; } |