[PATCH] Add support for optimization reports.
Diego Novillo
dnovillo at google.com
Mon Mar 31 09:27:14 PDT 2014
+richardsmith +tobias
I could not convince phabricator to add Richard and Tobias to the
reviewers line. I looked in its list of users and neither of you seem
to be registered. Maybe I was looking for the wrong IDs?
Thanks. Diego.
On Mon, Mar 31, 2014 at 12:26 PM, Diego Novillo <dnovillo at google.com> wrote:
> This patch adds a new flag -Rpass=. The flag indicates the name
> of the optimization pass that should emit remarks stating when it
> made a transformation to the code.
>
> This implements the design I proposed in:
>
> https://docs.google.com/document/d/1FYUatSjZZO-zmFBxjOiuOzAy9mhHA8hqdvklZv68WuQ/edit?usp=sharing
>
> The patch is still WIP:
>
> 1- I still need to add tests. Both in the front and middle end.
>
> 2- The diagnostic is emitted with a confusing [-WRpass] suffix. I'm
> not quite sure how to remove that. I think it's related to diagnostic
> groups?
>
> http://llvm-reviews.chandlerc.com/D3226
>
> Files:
> include/clang/Basic/DiagnosticDriverKinds.td
> include/clang/Basic/DiagnosticFrontendKinds.td
> include/clang/Basic/DiagnosticGroups.td
> include/clang/Driver/Options.td
> include/clang/Frontend/CodeGenOptions.h
> lib/CodeGen/CodeGenAction.cpp
> lib/Driver/Tools.cpp
> lib/Frontend/CompilerInvocation.cpp
>
> Index: include/clang/Basic/DiagnosticDriverKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticDriverKinds.td
> +++ include/clang/Basic/DiagnosticDriverKinds.td
> @@ -111,6 +111,8 @@
> "unknown or ill-formed Objective-C runtime '%0'">;
> def err_drv_emit_llvm_link : Error<
> "-emit-llvm cannot be used when linking">;
> +def err_drv_optimization_report_pattern : Error<
> + "%0 in '%1'">;
>
> def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
> def warn_drv_optimization_value : Warning<"optimization level '%0' is unsupported; using '%1%2' instead">,
> Index: include/clang/Basic/DiagnosticFrontendKinds.td
> ===================================================================
> --- include/clang/Basic/DiagnosticFrontendKinds.td
> +++ include/clang/Basic/DiagnosticFrontendKinds.td
> @@ -32,6 +32,9 @@
> def remark_fe_backend_plugin: Remark<"%0">, CatBackend, InGroup<RemarkBackendPlugin>;
> def note_fe_backend_plugin: Note<"%0">, CatBackend;
>
> +def remark_fe_backend_optimization_report: Remark<"%0">, CatBackend,
> + InGroup<BackendOptimizationReport>;
> +
> def err_fe_invalid_code_complete_file : Error<
> "cannot locate code-completion file %0">, DefaultFatal;
> def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
> Index: include/clang/Basic/DiagnosticGroups.td
> ===================================================================
> --- include/clang/Basic/DiagnosticGroups.td
> +++ include/clang/Basic/DiagnosticGroups.td
> @@ -662,3 +662,4 @@
> def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
> def BackendPlugin : DiagGroup<"backend-plugin">;
> def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
> +def BackendOptimizationReport : DiagGroup<"Rpass">;
> Index: include/clang/Driver/Options.td
> ===================================================================
> --- include/clang/Driver/Options.td
> +++ include/clang/Driver/Options.td
> @@ -60,6 +60,7 @@
> def M_Group : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
> def T_Group : OptionGroup<"<T group>">;
> def O_Group : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
> +def R_Group : OptionGroup<"<R group>">, Group<CompileOnly_Group>;
> def W_Group : OptionGroup<"<W group>">, Group<CompileOnly_Group>;
> def d_Group : OptionGroup<"<d group>">;
> def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>;
> @@ -253,7 +254,8 @@
> def Qunused_arguments : Flag<["-"], "Qunused-arguments">, Flags<[DriverOption, CoreOption]>,
> HelpText<"Don't emit warning for unused driver arguments">;
> def Q : Flag<["-"], "Q">;
> -def R : Flag<["-"], "R">;
> +def Rpass_EQ : Joined<["-"], "Rpass=">, Group<R_Group>, Flags<[CC1Option]>,
> + HelpText<"Report transformations performed by optimization passes">;
> def S : Flag<["-"], "S">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
> HelpText<"Only run preprocess and compilation steps">;
> def Tbss : JoinedOrSeparate<["-"], "Tbss">, Group<T_Group>;
> Index: include/clang/Frontend/CodeGenOptions.h
> ===================================================================
> --- include/clang/Frontend/CodeGenOptions.h
> +++ include/clang/Frontend/CodeGenOptions.h
> @@ -16,6 +16,7 @@
>
> #include <string>
> #include <vector>
> +#include "llvm/Support/Regex.h"
>
> namespace clang {
>
> @@ -145,6 +146,13 @@
> /// Name of the profile file to use as input for -fprofile-instr-use
> std::string InstrProfileInput;
>
> + /// Regular expression to select optimizations for which we should enable
> + /// optimization reports. Transformation passes whose name matches this
> + /// expression (and support this feature), will emit a diagnostic
> + /// whenever they perform a transformation. This is enabled by the
> + /// -Rpass=regexp flag.
> + llvm::Regex *OptimizationReportPattern;
> +
> public:
> // Define accessors/mutators for code generation options of enumeration type.
> #define CODEGENOPT(Name, Bits, Default)
> Index: lib/CodeGen/CodeGenAction.cpp
> ===================================================================
> --- lib/CodeGen/CodeGenAction.cpp
> +++ lib/CodeGen/CodeGenAction.cpp
> @@ -20,6 +20,7 @@
> #include "clang/Frontend/FrontendDiagnostic.h"
> #include "llvm/ADT/SmallString.h"
> #include "llvm/Bitcode/ReaderWriter.h"
> +#include "llvm/IR/DebugInfo.h"
> #include "llvm/IR/DiagnosticInfo.h"
> #include "llvm/IR/DiagnosticPrinter.h"
> #include "llvm/IR/LLVMContext.h"
> @@ -220,6 +221,11 @@
> /// \return True if the diagnostic has been successfully reported, false
> /// otherwise.
> bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
> + /// \brief Specialized handler for the optimization report diagnostic.
> + /// \return True if the diagnostic has been successfully reported, false
> + /// otherwise.
> + bool
> + OptimizationReportHandler(const llvm::DiagnosticInfoOptimizationReport &D);
> };
>
> void BackendConsumer::anchor() {}
> @@ -374,6 +380,27 @@
> return true;
> }
>
> +bool BackendConsumer::OptimizationReportHandler(
> + const llvm::DiagnosticInfoOptimizationReport &D) {
> + if (CodeGenOpts.OptimizationReportPattern->match(D.getPassName())) {
> + SourceLocation Loc;
> + // FIXME: This should be done earlier.
> + Diags.setDiagnosticMapping(diag::remark_fe_backend_optimization_report,
> + diag::Mapping::MAP_REMARK, Loc);
> + // FIXME: There should be a way of transferring the DILocation
> + // content into a SourceLocation. We are building the location string
> + // unnecessarily.
> + DILocation DIL(D.getDebugLoc().getAsMDNode(D.getFunction().getContext()));
> + StringRef FileName = DIL.getFilename();
> + unsigned LineNum = DIL.getLineNumber();
> + unsigned ColumnNum = DIL.getColumnNumber();
> + Diags.Report(Loc, diag::remark_fe_backend_optimization_report)
> + << Twine(FileName + ":" + Twine(LineNum) + ":" + Twine(ColumnNum) +
> + ": " + D.getMsg()).str();
> + }
> + return true;
> +}
> +
> /// \brief This function is invoked when the backend needs
> /// to report something to the user.
> void BackendConsumer::DiagnosticHandlerImpl(const DiagnosticInfo &DI) {
> @@ -391,6 +418,10 @@
> return;
> ComputeDiagID(Severity, backend_frame_larger_than, DiagID);
> break;
> + case llvm::DK_OptimizationReport:
> + if (CodeGenOpts.OptimizationReportPattern)
> + OptimizationReportHandler(cast<DiagnosticInfoOptimizationReport>(DI));
> + return;
> default:
> // Plugin IDs are not bound to any value as they are set dynamically.
> ComputeDiagRemarkID(Severity, backend_plugin, DiagID);
> Index: lib/Driver/Tools.cpp
> ===================================================================
> --- lib/Driver/Tools.cpp
> +++ lib/Driver/Tools.cpp
> @@ -3293,6 +3293,10 @@
> A->render(Args, CmdArgs);
> }
>
> + if (Arg *A = Args.getLastArg(options::OPT_Rpass_EQ)) {
> + A->render(Args, CmdArgs);
> + }
> +
> if (Args.hasArg(options::OPT_mkernel)) {
> if (!Args.hasArg(options::OPT_fapple_kext) && types::isCXX(InputType))
> CmdArgs.push_back("-fapple-kext");
> Index: lib/Frontend/CompilerInvocation.cpp
> ===================================================================
> --- lib/Frontend/CompilerInvocation.cpp
> +++ lib/Frontend/CompilerInvocation.cpp
> @@ -520,6 +520,23 @@
>
> Opts.DependentLibraries = Args.getAllArgValues(OPT_dependent_lib);
>
> + if (Arg *A = Args.getLastArg(OPT_Rpass_EQ)) {
> + StringRef Val = A->getValue();
> + std::string RegexError;
> + Opts.OptimizationReportPattern = new llvm::Regex(Val);
> + if (!Opts.OptimizationReportPattern->isValid(RegexError)) {
> + Diags.Report(diag::err_drv_optimization_report_pattern)
> + << RegexError << A->getAsString(Args);
> + delete Opts.OptimizationReportPattern;
> + Opts.OptimizationReportPattern = 0;
> + } else {
> + // Optimization report diagnostics need to extract location information
> + // from the instructions they are emitted on. When -Rpass is used,
> + // enable line table generation.
> + Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly);
> + }
> + }
> +
> return Success;
> }
More information about the llvm-commits
mailing list