Index: clang/lib/CodeGen/CodeGenAction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenAction.cpp +++ clang/lib/CodeGen/CodeGenAction.cpp @@ -82,6 +82,40 @@ BackendConsumer *BackendCon; }; + // setOptRecordFile returns true if there is a record file. The record file can + // be an empty file. If it returns false, then there is an error. + static bool setOptRecordFile(const CodeGenOptions CGOpts, DiagnosticsEngine &Diags, + LLVMContext &Ctx, + std::unique_ptr &OptRecordFile) + { + Expected> OptRecordFileOrErr = + llvm::setupOptimizationRemarks(Ctx, CGOpts.OptRecordFile, + CGOpts.OptRecordPasses, + CGOpts.OptRecordFormat, + CGOpts.DiagnosticsWithHotness, + CGOpts.DiagnosticsHotnessThreshold); + if (Error E = OptRecordFileOrErr.takeError()) { + handleAllErrors( + std::move(E), + [&](const RemarkSetupFileError &E) { + Diags.Report(diag::err_cannot_open_file) + << CGOpts.OptRecordFile << E.message(); + }, + [&](const RemarkSetupPatternError &E) { + Diags.Report(diag::err_drv_optimization_remark_pattern) + << E.message() << CGOpts.OptRecordPasses; + }, + [&](const RemarkSetupFormatError &E) { + Diags.Report(diag::err_drv_optimization_remark_format) + << CGOpts.OptRecordFormat; + }); + return false; + } + OptRecordFile = std::move(*OptRecordFileOrErr); + + return true; + } + class BackendConsumer : public ASTConsumer { using LinkModule = CodeGenAction::LinkModule; @@ -267,33 +301,14 @@ Ctx.setDiagnosticHandler(std::make_unique( CodeGenOpts, this)); - Expected> OptRecordFileOrErr = - setupOptimizationRemarks(Ctx, CodeGenOpts.OptRecordFile, - CodeGenOpts.OptRecordPasses, - CodeGenOpts.OptRecordFormat, - CodeGenOpts.DiagnosticsWithHotness, - CodeGenOpts.DiagnosticsHotnessThreshold); - - if (Error E = OptRecordFileOrErr.takeError()) { - handleAllErrors( - std::move(E), - [&](const RemarkSetupFileError &E) { - Diags.Report(diag::err_cannot_open_file) - << CodeGenOpts.OptRecordFile << E.message(); - }, - [&](const RemarkSetupPatternError &E) { - Diags.Report(diag::err_drv_optimization_remark_pattern) - << E.message() << CodeGenOpts.OptRecordPasses; - }, - [&](const RemarkSetupFormatError &E) { - Diags.Report(diag::err_drv_optimization_remark_format) - << CodeGenOpts.OptRecordFormat; - }); + std::unique_ptr OptRecordFile; + bool isSet = setOptRecordFile(CodeGenOpts, Diags, Ctx, OptRecordFile); + + // Error: the record file is erroneous. + if (!isSet) return; - } - std::unique_ptr OptRecordFile = - std::move(*OptRecordFileOrErr); + // There is a record file and it is not empty. if (OptRecordFile && CodeGenOpts.getProfileUse() != CodeGenOptions::ProfileNone) Ctx.setDiagnosticsHotnessRequested(true); @@ -1046,6 +1061,7 @@ if (getCurrentFileKind().getLanguage() == Language::LLVM_IR) { BackendAction BA = static_cast(Act); CompilerInstance &CI = getCompilerInstance(); + auto &CodeGenOpts = CI.getCodeGenOpts(); std::unique_ptr OS = GetOutputStream(CI, getCurrentFile(), BA); if (BA != Backend_EmitNothing && !OS) @@ -1070,17 +1086,29 @@ TheModule->setTargetTriple(TargetOpts.Triple); } - EmbedBitcode(TheModule.get(), CI.getCodeGenOpts(), + EmbedBitcode(TheModule.get(), CodeGenOpts, MainFile->getMemBufferRef()); LLVMContext &Ctx = TheModule->getContext(); Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler, &CI.getDiagnostics()); + std::unique_ptr OptRecordFile; + bool isSet = setOptRecordFile(CodeGenOpts, CI.getDiagnostics(), + Ctx, OptRecordFile); + + // Error: the record file is erroneous. + if (!isSet) + return; + EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(), - CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(), + CodeGenOpts, TargetOpts, CI.getLangOpts(), CI.getTarget().getDataLayout(), TheModule.get(), BA, std::move(OS)); + + if (OptRecordFile) + OptRecordFile->keep(); + return; } Index: clang/test/CodeGen/opt-record-1.c =================================================================== --- /dev/null +++ clang/test/CodeGen/opt-record-1.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -opt-record-file=t1.opt -fopenmp -emit-llvm-bc -o %t.bc +// RUN: %clang_cc1 -x ir %t.bc -opt-record-file %t.opt -fopenmp -emit-obj +// RUN: cat %t.opt | FileCheck -check-prefix=CHECK -check-prefix=CHECK-PASSES %s + + +void foo(int *a, int *b, int *c) { +#pragma omp parallel for + for (int i = 0; i < 100; i++) { + a[i] = b[i] + c[i]; + } +} + +// CHECK: --- !Missed +// CHECK: Pass: inline +// CHECK: Name: NoDefinition +// CHECK: Function: foo +// CHECK-PASSES: Pass: inline +