diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp | 149 |
1 files changed, 103 insertions, 46 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp index 49738a2..5f74141 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenAction.cpp @@ -21,8 +21,7 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/DiagnosticPrinter.h" @@ -34,6 +33,8 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/Timer.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/YAMLTraits.h" #include <memory> using namespace clang; using namespace llvm; @@ -43,6 +44,7 @@ namespace clang { virtual void anchor(); DiagnosticsEngine &Diags; BackendAction Action; + const HeaderSearchOptions &HeaderSearchOpts; const CodeGenOptions &CodeGenOpts; const TargetOptions &TargetOpts; const LangOptions &LangOpts; @@ -50,6 +52,12 @@ namespace clang { ASTContext *Context; Timer LLVMIRGeneration; + unsigned LLVMIRGenerationRefCount; + + /// True if we've finished generating IR. This prevents us from generating + /// additional LLVM IR after emitting output in HandleTranslationUnit. This + /// can happen when Clang plugins trigger additional AST deserialization. + bool IRGenFinished = false; std::unique_ptr<CodeGenerator> Gen; @@ -70,10 +78,11 @@ namespace clang { const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules, std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, CoverageSourceInfo *CoverageInfo = nullptr) - : Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts), - TargetOpts(TargetOpts), LangOpts(LangOpts), + : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), + CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), AsmOutStream(std::move(OS)), Context(nullptr), - LLVMIRGeneration("LLVM IR Generation Time"), + LLVMIRGeneration("irgen", "LLVM IR Generation Time"), + LLVMIRGenerationRefCount(0), Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)) { llvm::TimePassesIsEnabled = TimePasses; @@ -113,13 +122,20 @@ namespace clang { Context->getSourceManager(), "LLVM IR generation of declaration"); - if (llvm::TimePassesIsEnabled) - LLVMIRGeneration.startTimer(); + // Recurse. + if (llvm::TimePassesIsEnabled) { + LLVMIRGenerationRefCount += 1; + if (LLVMIRGenerationRefCount == 1) + LLVMIRGeneration.startTimer(); + } Gen->HandleTopLevelDecl(D); - if (llvm::TimePassesIsEnabled) - LLVMIRGeneration.stopTimer(); + if (llvm::TimePassesIsEnabled) { + LLVMIRGenerationRefCount -= 1; + if (LLVMIRGenerationRefCount == 0) + LLVMIRGeneration.stopTimer(); + } return true; } @@ -137,16 +153,30 @@ namespace clang { LLVMIRGeneration.stopTimer(); } + void HandleInterestingDecl(DeclGroupRef D) override { + // Ignore interesting decls from the AST reader after IRGen is finished. + if (!IRGenFinished) + HandleTopLevelDecl(D); + } + void HandleTranslationUnit(ASTContext &C) override { { PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); - if (llvm::TimePassesIsEnabled) - LLVMIRGeneration.startTimer(); + if (llvm::TimePassesIsEnabled) { + LLVMIRGenerationRefCount += 1; + if (LLVMIRGenerationRefCount == 1) + LLVMIRGeneration.startTimer(); + } Gen->HandleTranslationUnit(C); - if (llvm::TimePassesIsEnabled) - LLVMIRGeneration.stopTimer(); + if (llvm::TimePassesIsEnabled) { + LLVMIRGenerationRefCount -= 1; + if (LLVMIRGenerationRefCount == 0) + LLVMIRGeneration.stopTimer(); + } + + IRGenFinished = true; } // Silently ignore if we weren't initialized for some reason. @@ -165,6 +195,26 @@ namespace clang { Ctx.getDiagnosticHandler(); void *OldDiagnosticContext = Ctx.getDiagnosticContext(); Ctx.setDiagnosticHandler(DiagnosticHandler, this); + Ctx.setDiagnosticHotnessRequested(CodeGenOpts.DiagnosticsWithHotness); + + std::unique_ptr<llvm::tool_output_file> OptRecordFile; + if (!CodeGenOpts.OptRecordFile.empty()) { + std::error_code EC; + OptRecordFile = + llvm::make_unique<llvm::tool_output_file>(CodeGenOpts.OptRecordFile, + EC, sys::fs::F_None); + if (EC) { + Diags.Report(diag::err_cannot_open_file) << + CodeGenOpts.OptRecordFile << EC.message(); + return; + } + + Ctx.setDiagnosticsOutputFile( + llvm::make_unique<yaml::Output>(OptRecordFile->os())); + + if (CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) + Ctx.setDiagnosticHotnessRequested(true); + } // Link LinkModule into this module if present, preserving its validity. for (auto &I : LinkModules) { @@ -176,13 +226,16 @@ namespace clang { EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef()); - EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, - C.getTargetInfo().getDataLayout(), + EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, + LangOpts, C.getTargetInfo().getDataLayout(), getModule(), Action, std::move(AsmOutStream)); Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext); Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext); + + if (OptRecordFile) + OptRecordFile->keep(); } void HandleTagDeclDefinition(TagDecl *D) override { @@ -245,16 +298,13 @@ namespace clang { /// them. void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID); - void - OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationRemark &D); - void OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkMissed &D); - void OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D); + void OptimizationRemarkHandler(const llvm::OptimizationRemark &D); + void OptimizationRemarkHandler(const llvm::OptimizationRemarkMissed &D); + void OptimizationRemarkHandler(const llvm::OptimizationRemarkAnalysis &D); void OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysisFPCommute &D); + const llvm::OptimizationRemarkAnalysisFPCommute &D); void OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysisAliasing &D); + const llvm::OptimizationRemarkAnalysisAliasing &D); void OptimizationFailureHandler( const llvm::DiagnosticInfoOptimizationFailure &D); }; @@ -497,9 +547,16 @@ void BackendConsumer::EmitOptimizationMessage( FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); + std::string Msg; + raw_string_ostream MsgStream(Msg); + MsgStream << D.getMsg(); + + if (D.getHotness()) + MsgStream << " (hotness: " << *D.getHotness() << ")"; + Diags.Report(Loc, DiagID) - << AddFlagValue(D.getPassName() ? D.getPassName() : "") - << D.getMsg().str(); + << AddFlagValue(D.getPassName()) + << MsgStream.str(); if (BadDebugInfo) // If we were not able to translate the file:line:col information @@ -511,7 +568,7 @@ void BackendConsumer::EmitOptimizationMessage( } void BackendConsumer::OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemark &D) { + const llvm::OptimizationRemark &D) { // Optimization remarks are active only if the -Rpass flag has a regular // expression that matches the name of the pass name in \p D. if (CodeGenOpts.OptimizationRemarkPattern && @@ -520,7 +577,7 @@ void BackendConsumer::OptimizationRemarkHandler( } void BackendConsumer::OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkMissed &D) { + const llvm::OptimizationRemarkMissed &D) { // Missed optimization remarks are active only if the -Rpass-missed // flag has a regular expression that matches the name of the pass // name in \p D. @@ -531,7 +588,7 @@ void BackendConsumer::OptimizationRemarkHandler( } void BackendConsumer::OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysis &D) { + const llvm::OptimizationRemarkAnalysis &D) { // Optimization analysis remarks are active if the pass name is set to // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a // regular expression that matches the name of the pass name in \p D. @@ -544,7 +601,7 @@ void BackendConsumer::OptimizationRemarkHandler( } void BackendConsumer::OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysisFPCommute &D) { + const llvm::OptimizationRemarkAnalysisFPCommute &D) { // Optimization analysis remarks are active if the pass name is set to // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a // regular expression that matches the name of the pass name in \p D. @@ -557,7 +614,7 @@ void BackendConsumer::OptimizationRemarkHandler( } void BackendConsumer::OptimizationRemarkHandler( - const llvm::DiagnosticInfoOptimizationRemarkAnalysisAliasing &D) { + const llvm::OptimizationRemarkAnalysisAliasing &D) { // Optimization analysis remarks are active if the pass name is set to // llvm::DiagnosticInfo::AlwasyPrint or if the -Rpass-analysis flag has a // regular expression that matches the name of the pass name in \p D. @@ -601,30 +658,27 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { case llvm::DK_OptimizationRemark: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. - OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemark>(DI)); + OptimizationRemarkHandler(cast<OptimizationRemark>(DI)); return; case llvm::DK_OptimizationRemarkMissed: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. - OptimizationRemarkHandler(cast<DiagnosticInfoOptimizationRemarkMissed>(DI)); + OptimizationRemarkHandler(cast<OptimizationRemarkMissed>(DI)); return; case llvm::DK_OptimizationRemarkAnalysis: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. - OptimizationRemarkHandler( - cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI)); + OptimizationRemarkHandler(cast<OptimizationRemarkAnalysis>(DI)); return; case llvm::DK_OptimizationRemarkAnalysisFPCommute: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. - OptimizationRemarkHandler( - cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI)); + OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisFPCommute>(DI)); return; case llvm::DK_OptimizationRemarkAnalysisAliasing: // Optimization remarks are always handled completely by this // handler. There is no generic way of emitting them. - OptimizationRemarkHandler( - cast<DiagnosticInfoOptimizationRemarkAnalysisAliasing>(DI)); + OptimizationRemarkHandler(cast<OptimizationRemarkAnalysisAliasing>(DI)); return; case llvm::DK_OptimizationFailure: // Optimization failures are always handled completely by this @@ -732,11 +786,13 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { return nullptr; } - ErrorOr<std::unique_ptr<llvm::Module>> ModuleOrErr = - getLazyBitcodeModule(std::move(*BCBuf), *VMContext); - if (std::error_code EC = ModuleOrErr.getError()) { - CI.getDiagnostics().Report(diag::err_cannot_open_file) << LinkBCFile - << EC.message(); + Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = + getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); + if (!ModuleOrErr) { + handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { + CI.getDiagnostics().Report(diag::err_cannot_open_file) + << LinkBCFile << EIB.message(); + }); LinkModules.clear(); return nullptr; } @@ -843,9 +899,10 @@ void CodeGenAction::ExecuteAction() { Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &CI.getDiagnostics()); - EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts, - CI.getLangOpts(), CI.getTarget().getDataLayout(), - TheModule.get(), BA, std::move(OS)); + EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(), + CI.getTarget().getDataLayout(), TheModule.get(), BA, + std::move(OS)); return; } |