diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp | 220 |
1 files changed, 92 insertions, 128 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp index 55925110708e..778d4df3c2e9 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp @@ -35,6 +35,7 @@ #include "llvm/IR/LLVMRemarkStreamer.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/LTO/LTOBackend.h" #include "llvm/Linker/Linker.h" #include "llvm/Pass.h" #include "llvm/Support/MemoryBuffer.h" @@ -121,6 +122,8 @@ namespace clang { /// can happen when Clang plugins trigger additional AST deserialization. bool IRGenFinished = false; + bool TimerIsEnabled = false; + std::unique_ptr<CodeGenerator> Gen; SmallVector<LinkModule, 4> LinkModules; @@ -135,8 +138,7 @@ namespace clang { const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, const TargetOptions &TargetOpts, - const LangOptions &LangOpts, bool TimePasses, - const std::string &InFile, + const LangOptions &LangOpts, const std::string &InFile, SmallVector<LinkModule, 4> LinkModules, std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C, CoverageSourceInfo *CoverageInfo = nullptr) @@ -148,8 +150,9 @@ namespace clang { Gen(CreateLLVMCodeGen(Diags, InFile, HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)), LinkModules(std::move(LinkModules)) { - FrontendTimesIsEnabled = TimePasses; - llvm::TimePassesIsEnabled = TimePasses; + TimerIsEnabled = CodeGenOpts.TimePasses; + llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; + llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; } // This constructor is used in installing an empty BackendConsumer @@ -160,7 +163,7 @@ namespace clang { const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, const TargetOptions &TargetOpts, - const LangOptions &LangOpts, bool TimePasses, + const LangOptions &LangOpts, SmallVector<LinkModule, 4> LinkModules, LLVMContext &C, CoverageSourceInfo *CoverageInfo = nullptr) : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), @@ -171,8 +174,9 @@ namespace clang { Gen(CreateLLVMCodeGen(Diags, "", HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)), LinkModules(std::move(LinkModules)) { - FrontendTimesIsEnabled = TimePasses; - llvm::TimePassesIsEnabled = TimePasses; + TimerIsEnabled = CodeGenOpts.TimePasses; + llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses; + llvm::TimePassesPerRun = CodeGenOpts.TimePassesPerRun; } llvm::Module *getModule() const { return Gen->GetModule(); } std::unique_ptr<llvm::Module> takeModule() { @@ -190,12 +194,12 @@ namespace clang { Context = &Ctx; - if (FrontendTimesIsEnabled) + if (TimerIsEnabled) LLVMIRGeneration.startTimer(); Gen->Initialize(Ctx); - if (FrontendTimesIsEnabled) + if (TimerIsEnabled) LLVMIRGeneration.stopTimer(); } @@ -205,7 +209,7 @@ namespace clang { "LLVM IR generation of declaration"); // Recurse. - if (FrontendTimesIsEnabled) { + if (TimerIsEnabled) { LLVMIRGenerationRefCount += 1; if (LLVMIRGenerationRefCount == 1) LLVMIRGeneration.startTimer(); @@ -213,7 +217,7 @@ namespace clang { Gen->HandleTopLevelDecl(D); - if (FrontendTimesIsEnabled) { + if (TimerIsEnabled) { LLVMIRGenerationRefCount -= 1; if (LLVMIRGenerationRefCount == 0) LLVMIRGeneration.stopTimer(); @@ -226,12 +230,12 @@ namespace clang { PrettyStackTraceDecl CrashInfo(D, SourceLocation(), Context->getSourceManager(), "LLVM IR generation of inline function"); - if (FrontendTimesIsEnabled) + if (TimerIsEnabled) LLVMIRGeneration.startTimer(); Gen->HandleInlineFunctionDefinition(D); - if (FrontendTimesIsEnabled) + if (TimerIsEnabled) LLVMIRGeneration.stopTimer(); } @@ -245,8 +249,13 @@ namespace clang { bool LinkInModules() { for (auto &LM : LinkModules) { if (LM.PropagateAttrs) - for (Function &F : *LM.Module) + for (Function &F : *LM.Module) { + // Skip intrinsics. Keep consistent with how intrinsics are created + // in LLVM IR. + if (F.isIntrinsic()) + continue; Gen->CGM().addDefaultFunctionDefinitionAttributes(F); + } CurLinkModule = LM.Module.get(); @@ -274,7 +283,7 @@ namespace clang { { llvm::TimeTraceScope TimeScope("Frontend"); PrettyStackTraceString CrashInfo("Per-file LLVM IR generation"); - if (FrontendTimesIsEnabled) { + if (TimerIsEnabled) { LLVMIRGenerationRefCount += 1; if (LLVMIRGenerationRefCount == 1) LLVMIRGeneration.startTimer(); @@ -282,7 +291,7 @@ namespace clang { Gen->HandleTranslationUnit(C); - if (FrontendTimesIsEnabled) { + if (TimerIsEnabled) { LLVMIRGenerationRefCount -= 1; if (LLVMIRGenerationRefCount == 0) LLVMIRGeneration.stopTimer(); @@ -398,9 +407,6 @@ namespace clang { bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); /// Specialized handler for unsupported backend feature diagnostic. void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); - /// Specialized handler for misexpect warnings. - /// Note that misexpect remarks are emitted through ORE - void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D); /// Specialized handlers for optimization remarks. /// Note that these handlers only accept remarks and they always handle /// them. @@ -668,36 +674,6 @@ void BackendConsumer::UnsupportedDiagHandler( << Filename << Line << Column; } -void BackendConsumer::MisExpectDiagHandler( - const llvm::DiagnosticInfoMisExpect &D) { - StringRef Filename; - unsigned Line, Column; - bool BadDebugInfo = false; - FullSourceLoc Loc; - std::string Msg; - raw_string_ostream MsgStream(Msg); - DiagnosticPrinterRawOStream DP(MsgStream); - - // Context will be nullptr for IR input files, we will construct the diag - // message from llvm::DiagnosticInfoMisExpect. - if (Context != nullptr) { - Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column); - MsgStream << D.getMsg(); - } else { - DiagnosticPrinterRawOStream DP(MsgStream); - D.print(DP); - } - Diags.Report(Loc, diag::warn_profile_data_misexpect) << MsgStream.str(); - - if (BadDebugInfo) - // If we were not able to translate the file:line:col information - // back to a SourceLocation, at least emit a note stating that - // we could not translate this location. This can happen in the - // case of #line directives. - Diags.Report(Loc, diag::note_fe_backend_invalid_loc) - << Filename << Line << Column; -} - void BackendConsumer::EmitOptimizationMessage( const llvm::DiagnosticInfoOptimizationBase &D, unsigned DiagID) { // We only support warnings and remarks. @@ -875,9 +851,6 @@ void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) { case llvm::DK_Unsupported: UnsupportedDiagHandler(cast<DiagnosticInfoUnsupported>(DI)); return; - case llvm::DK_MisExpect: - MisExpectDiagHandler(cast<DiagnosticInfoMisExpect>(DI)); - return; default: // Plugin IDs are not bound to any value as they are set dynamically. ComputeDiagRemarkID(Severity, backend_plugin, DiagID); @@ -990,17 +963,15 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { CoverageSourceInfo *CoverageInfo = nullptr; // Add the preprocessor callback only when the coverage mapping is generated. - if (CI.getCodeGenOpts().CoverageMapping) { - CoverageInfo = new CoverageSourceInfo; - CI.getPreprocessor().addPPCallbacks( - std::unique_ptr<PPCallbacks>(CoverageInfo)); - } + if (CI.getCodeGenOpts().CoverageMapping) + CoverageInfo = CodeGen::CoverageMappingModuleGen::setUpCoverageCallbacks( + CI.getPreprocessor()); std::unique_ptr<BackendConsumer> Result(new BackendConsumer( BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), - CI.getLangOpts(), CI.getFrontendOpts().ShowTimers, std::string(InFile), - std::move(LinkModules), std::move(OS), *VMContext, CoverageInfo)); + CI.getLangOpts(), std::string(InFile), std::move(LinkModules), + std::move(OS), *VMContext, CoverageInfo)); BEConsumer = Result.get(); // Enable generating macro debug info only when debug info is not disabled and @@ -1063,7 +1034,7 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); if (!BMsOrErr) return DiagErrors(BMsOrErr.takeError()); - BitcodeModule *Bm = FindThinLTOModule(*BMsOrErr); + BitcodeModule *Bm = llvm::lto::findThinLTOModule(*BMsOrErr); // We have nothing to do if the file contains no ThinLTO module. This is // possible if ThinLTO compilation was not able to split module. Content of // the file was already processed by indexing and will be passed to the @@ -1107,81 +1078,74 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { } void CodeGenAction::ExecuteAction() { - // If this is an IR file, we have to treat it specially. - if (getCurrentFileKind().getLanguage() == Language::LLVM_IR) { - BackendAction BA = static_cast<BackendAction>(Act); - CompilerInstance &CI = getCompilerInstance(); - auto &CodeGenOpts = CI.getCodeGenOpts(); - auto &Diagnostics = CI.getDiagnostics(); - std::unique_ptr<raw_pwrite_stream> OS = - GetOutputStream(CI, getCurrentFile(), BA); - if (BA != Backend_EmitNothing && !OS) - return; - - bool Invalid; - SourceManager &SM = CI.getSourceManager(); - FileID FID = SM.getMainFileID(); - const llvm::MemoryBuffer *MainFile = SM.getBuffer(FID, &Invalid); - if (Invalid) - return; + if (getCurrentFileKind().getLanguage() != Language::LLVM_IR) { + this->ASTFrontendAction::ExecuteAction(); + return; + } - TheModule = loadModule(*MainFile); - if (!TheModule) - return; + // If this is an IR file, we have to treat it specially. + BackendAction BA = static_cast<BackendAction>(Act); + CompilerInstance &CI = getCompilerInstance(); + auto &CodeGenOpts = CI.getCodeGenOpts(); + auto &Diagnostics = CI.getDiagnostics(); + std::unique_ptr<raw_pwrite_stream> OS = + GetOutputStream(CI, getCurrentFile(), BA); + if (BA != Backend_EmitNothing && !OS) + return; - const TargetOptions &TargetOpts = CI.getTargetOpts(); - if (TheModule->getTargetTriple() != TargetOpts.Triple) { - Diagnostics.Report(SourceLocation(), - diag::warn_fe_override_module) - << TargetOpts.Triple; - TheModule->setTargetTriple(TargetOpts.Triple); - } + SourceManager &SM = CI.getSourceManager(); + FileID FID = SM.getMainFileID(); + Optional<MemoryBufferRef> MainFile = SM.getBufferOrNone(FID); + if (!MainFile) + return; - EmbedBitcode(TheModule.get(), CodeGenOpts, - MainFile->getMemBufferRef()); - - LLVMContext &Ctx = TheModule->getContext(); - Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, - &Diagnostics); - - // Set clang diagnostic handler. To do this we need to create a fake - // BackendConsumer. - BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), - CI.getPreprocessorOpts(), CI.getCodeGenOpts(), - CI.getTargetOpts(), CI.getLangOpts(), - CI.getFrontendOpts().ShowTimers, - std::move(LinkModules), *VMContext, nullptr); - // PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be - // true here because the valued names are needed for reading textual IR. - Ctx.setDiscardValueNames(false); - Ctx.setDiagnosticHandler( - std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result)); - - Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr = - setupLLVMOptimizationRemarks( - Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, - CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, - CodeGenOpts.DiagnosticsHotnessThreshold); - - if (Error E = OptRecordFileOrErr.takeError()) { - reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts); - return; - } - std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = - std::move(*OptRecordFileOrErr); + TheModule = loadModule(*MainFile); + if (!TheModule) + return; - EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, - TargetOpts, CI.getLangOpts(), - CI.getTarget().getDataLayout(), TheModule.get(), BA, - std::move(OS)); + const TargetOptions &TargetOpts = CI.getTargetOpts(); + if (TheModule->getTargetTriple() != TargetOpts.Triple) { + Diagnostics.Report(SourceLocation(), diag::warn_fe_override_module) + << TargetOpts.Triple; + TheModule->setTargetTriple(TargetOpts.Triple); + } - if (OptRecordFile) - OptRecordFile->keep(); + EmbedBitcode(TheModule.get(), CodeGenOpts, *MainFile); + + LLVMContext &Ctx = TheModule->getContext(); + Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &Diagnostics); + + // Set clang diagnostic handler. To do this we need to create a fake + // BackendConsumer. + BackendConsumer Result(BA, CI.getDiagnostics(), CI.getHeaderSearchOpts(), + CI.getPreprocessorOpts(), CI.getCodeGenOpts(), + CI.getTargetOpts(), CI.getLangOpts(), + std::move(LinkModules), *VMContext, nullptr); + // PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be + // true here because the valued names are needed for reading textual IR. + Ctx.setDiscardValueNames(false); + Ctx.setDiagnosticHandler( + std::make_unique<ClangDiagnosticHandler>(CodeGenOpts, &Result)); + + Expected<std::unique_ptr<llvm::ToolOutputFile>> OptRecordFileOrErr = + setupLLVMOptimizationRemarks( + Ctx, CodeGenOpts.OptRecordFile, CodeGenOpts.OptRecordPasses, + CodeGenOpts.OptRecordFormat, CodeGenOpts.DiagnosticsWithHotness, + CodeGenOpts.DiagnosticsHotnessThreshold); + + if (Error E = OptRecordFileOrErr.takeError()) { + reportOptRecordError(std::move(E), Diagnostics, CodeGenOpts); return; } - - // Otherwise follow the normal AST path. - this->ASTFrontendAction::ExecuteAction(); + std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = + std::move(*OptRecordFileOrErr); + + EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, + TargetOpts, CI.getLangOpts(), + CI.getTarget().getDataLayout(), TheModule.get(), BA, + std::move(OS)); + if (OptRecordFile) + OptRecordFile->keep(); } // |