diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -73,11 +73,12 @@ // has // TODO: Share with clang instead of re-implementing here enum class RemarkKind { - RK_Missing, // Remark argument not present on the command line. - RK_Enabled, // Remark enabled via '-Rgroup', i.e. -Rpass, -Rpass-missed, - // -Rpass-analysis - RK_Disabled, // Remark disabled via '-Rno-group', i.e. -Rno-pass, - // -Rno-pass-missed, -Rno-pass-analysis. + RK_Missing, // Remark argument not present on the command line. + RK_Enabled, // Remark enabled via '-Rgroup', i.e. -Rpass, -Rpass-missed, + // -Rpass-analysis + RK_Disabled, // Remark disabled via '-Rno-group', i.e. -Rno-pass, + // -Rno-pass-missed, -Rno-pass-analysis. + RK_WithPattern, // Remark pattern specified via '-Rgroup=regexp'. }; /// Optimization remark with an optional regular expression pattern. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -156,7 +156,8 @@ // Generate an OptRemark object containing info on if the -Rgroup // specified is enabled or not. static CodeGenOptions::OptRemark -parseOptimizationRemark(llvm::opt::ArgList &args, +parseOptimizationRemark(clang::DiagnosticsEngine &diags, + llvm::opt::ArgList &args, llvm::opt::OptSpecifier optEq, llvm::StringRef remarkOptName) { assert((remarkOptName == "pass" || remarkOptName == "pass-missed" || remarkOptName == "pass-analysis") && @@ -180,6 +181,17 @@ result.Pattern = ""; result.Regex = nullptr; } + } else if (a->getOption().matches(optEq)) { + result.Kind = CodeGenOptions::RemarkKind::RK_WithPattern; + result.Pattern = a->getValue(); + result.Regex = std::make_shared(result.Pattern); + std::string regexError; + + if (!result.Regex->isValid(regexError)) { + diags.Report(clang::diag::err_drv_optimization_remark_pattern) + << regexError << a->getAsString(args); + return CodeGenOptions::OptRemark(); + } } } return result; @@ -240,15 +252,18 @@ // Create OptRemark that allows printing of all successful optimization // passes applied. - opts.OptimizationRemark = parseOptimizationRemark(args, "pass"); + opts.OptimizationRemark = parseOptimizationRemark( + diags, args, clang::driver::options::OPT_Rpass_EQ, "pass"); // Create OptRemark that allows all missed optimization passes to be printed. - opts.OptimizationRemarkMissed = parseOptimizationRemark(args, "pass-missed"); + opts.OptimizationRemarkMissed = parseOptimizationRemark( + diags, args, clang::driver::options::OPT_Rpass_missed_EQ, "pass-missed"); // Create OptRemark that allows all optimization decisions made by LLVM // to be printed. - opts.OptimizationRemarkAnalysis = - parseOptimizationRemark(args, "pass-analysis"); + opts.OptimizationRemarkAnalysis = parseOptimizationRemark( + diags, args, clang::driver::options::OPT_Rpass_analysis_EQ, + "pass-analysis"); if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ)) opts.SaveTempsDir = a->getValue(); @@ -746,6 +761,9 @@ res.getFrontendOpts().showColors = parseShowColorsArgs(args, /*defaultDiagColor=*/false); + // Honor color diagnostics. + res.getDiagnosticOpts().ShowColors = res.getFrontendOpts().showColors; + return diags.getNumErrors() == numErrorsBefore; } @@ -1010,8 +1028,15 @@ // Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or // -Rpass-analysis. This will be used later when processing and outputting the // remarks generated by LLVM in ExecuteCompilerInvocation.cpp. - for (auto *a : args.filtered(clang::driver::options::OPT_R_Group)) - res.getDiagnosticOpts().Remarks.push_back(a->getValue()); + for (auto *a : args.filtered(clang::driver::options::OPT_R_Group)) { + if (a->getOption().matches(clang::driver::options::OPT_R_value_Group)) + // This is -Rfoo=, where foo is the name of the diagnostic + // group. Add only the group name to the diagnostics. + res.getDiagnosticOpts().Remarks.push_back( + std::string(a->getOption().getName().drop_front(1).rtrim("=-"))); + else + res.getDiagnosticOpts().Remarks.push_back(a->getValue()); + } success &= parseFrontendArgs(res.getFrontendOpts(), args, diags); parseTargetArgs(res.getTargetOpts(), args); diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp --- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -191,9 +191,6 @@ return false; } - // Honor color diagnostics. - flang->getDiagnosticOpts().ShowColors = flang->getFrontendOpts().showColors; - updateDiagEngineForOptRemarks(flang->getDiagnostics(), flang->getDiagnosticOpts()); diff --git a/flang/test/Driver/optimization-remark.f90 b/flang/test/Driver/optimization-remark.f90 --- a/flang/test/Driver/optimization-remark.f90 +++ b/flang/test/Driver/optimization-remark.f90 @@ -11,6 +11,18 @@ ! RUN: %flang %s -O1 -Rno-pass-missed 2>&1 | FileCheck %s --allow-empty --check-prefix=NO-REMARKS ! RUN: %flang %s -O1 -Rno-pass-analysis 2>&1 | FileCheck %s --allow-empty --check-prefix=NO-REMARKS +! Check error on invalid regex -Rpass message is emitted +! RUN: not %flang %s -O1 -Rpass=[ 2>&1 | FileCheck %s --check-prefix=REGEX-INVALID + +! Check valid -Rpass regex +! RUN: %flang %s -O1 -Rpass=loop 2>&1 | FileCheck %s + +! Check valid -Rpass-missed regex +! RUN: %flang %s -O1 -Rpass-missed=loop 2>&1 | FileCheck %s --check-prefix=REMARKS-MISSED + +! Check valid -Rpass-analysis regex +! RUN: %flang %s -O1 -Rpass-analysis=loop 2>&1 | FileCheck %s --check-prefix=REMARKS-ANALYSIS + ! Check full -Rpass message is emitted ! RUN: %flang %s -O1 -Rpass 2>&1 | FileCheck %s @@ -20,6 +32,7 @@ ! Check full -Rpass-analysis message is emitted ! RUN: %flang %s -O1 -Rpass-analysis 2>&1 | FileCheck %s --check-prefix=REMARKS-ANALYSIS +! REGEX-INVALID: error: in pattern '-Rpass=[': brackets ([ ]) not balanced ! CHECK: remark: Loop deleted because it is invariant ! REMARKS-MISSED: remark: loop not vectorized ! REMARKS-ANALYSIS: remark: loop not vectorized: instruction cannot be vectorized