Index: docs/UsersManual.rst =================================================================== --- docs/UsersManual.rst +++ docs/UsersManual.rst @@ -322,18 +322,27 @@ by category, so it should be a high level category. We want dozens of these, not hundreds or thousands of them. +.. _opt_fsave-optimization-record: + +**-fsave-optimization-record** + Write optimization remarks to a YAML file. + + This option, which defaults to off, controls whether Clang writes + optimization reports to a YAML file. By recording diagnostics in a file, + using a structured YAML format, users can parse or sort the remarks in a + convenient way. + .. _opt_fdiagnostics-show-hotness: **-f[no-]diagnostics-show-hotness** Enable profile hotness information in diagnostic line. - This option, which defaults to off, controls whether Clang prints the - profile hotness associated with a diagnostics in the presence of - profile-guided optimization information. This is currently supported with - optimization remarks (see :ref:`Options to Emit Optimization Reports - `). The hotness information allows users to focus on the hot - optimization remarks that are likely to be more relevant for run-time - performance. + This option controls whether Clang prints the profile hotness associated + with diagnostics in the presence of profile-guided optimization information. + This is currently supported with optimization remarks (see + :ref:`Options to Emit Optimization Reports `). The hotness information + allows users to focus on the hot optimization remarks that are likely to be + more relevant for run-time performance. For example, in this output, the block containing the callsite of `foo` was executed 3000 times according to the profile data: @@ -344,6 +353,23 @@ sum += foo(x, x - 2); ^ + This option is implied when + :ref:`-fsave-optimization-record ` is used. + Otherwise, it defaults to off. + +.. _opt_fdiagnostics-hotness-threshold + +**-fdiagnostics-hotness-threshold** + Prevent optimization remarks from being output if they do not have at least + this hotness value. + + This option, which defaults to zero, controls the minimum hotness an + optimization remark would need in order to be output by Clang. This is + currently supported with optimization remarks (see :ref:`Options to Emit + Optimization Reports `) when profile hotness information in + diagnostics is enabled (see + :ref:`-fdiagnostics-show-hotness `). + .. _opt_fdiagnostics-fixit-info: **-f[no-]diagnostics-fixit-info** Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -195,8 +195,8 @@ def warn_drv_empty_joined_argument : Warning< "joined argument expects additional value: '%0'">, InGroup; -def warn_drv_fdiagnostics_show_hotness_requires_pgo : Warning< - "argument '-fdiagnostics-show-hotness' requires profile-guided optimization information">, +def warn_drv_diagnostics_hotness_requires_pgo : Warning< + "argument '%0' requires profile-guided optimization information">, InGroup; def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -723,6 +723,9 @@ HelpText<"Print source range spans in numeric form">; def fdiagnostics_show_hotness : Flag<["-"], "fdiagnostics-show-hotness">, Group, Flags<[CC1Option]>, HelpText<"Enable profile hotness information in diagnostic line">; +def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-threshold=">, + Group, Flags<[CC1Option]>, MetaVarName<"">, + HelpText<"Prevent optimization remarks from being output if they do not have at least this profile count">; def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group, Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">; def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -260,6 +260,10 @@ /// Whether to report the hotness of the code region for optimization remarks. CODEGENOPT(DiagnosticsWithHotness, 1, 0) +/// The minimum hotness value a diagnostic needs in order to be included in +/// optimization diagnostics. +VALUE_CODEGENOPT(DiagnosticsHotnessThreshold, 32, 0) + /// Whether copy relocations support is available when building as PIE. CODEGENOPT(PIECopyRelocations, 1, 0) Index: lib/CodeGen/CodeGenAction.cpp =================================================================== --- lib/CodeGen/CodeGenAction.cpp +++ lib/CodeGen/CodeGenAction.cpp @@ -229,6 +229,9 @@ void *OldDiagnosticContext = Ctx.getDiagnosticContext(); Ctx.setDiagnosticHandler(DiagnosticHandler, this); Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness); + if (CodeGenOpts.DiagnosticsHotnessThreshold != 0) + Ctx.setDiagnosticsHotnessThreshold( + CodeGenOpts.DiagnosticsHotnessThreshold); std::unique_ptr OptRecordFile; if (!CodeGenOpts.OptRecordFile.empty()) { Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -4072,6 +4072,12 @@ options::OPT_fno_diagnostics_show_hotness, false)) CmdArgs.push_back("-fdiagnostics-show-hotness"); + if (const Arg *A = + Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) { + std::string Opt = std::string("-fdiagnostics-hotness-threshold=") + A->getValue(); + CmdArgs.push_back(Args.MakeArgString(Opt)); + } + if (const Arg *A = Args.getLastArg(options::OPT_fdiagnostics_format_EQ)) { CmdArgs.push_back("-fdiagnostics-format"); CmdArgs.push_back(A->getValue()); Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -906,12 +906,18 @@ Opts.DiagnosticsWithHotness = Args.hasArg(options::OPT_fdiagnostics_show_hotness); bool UsingSampleProfile = !Opts.SampleProfileFile.empty(); - - if (Opts.DiagnosticsWithHotness && - Opts.getProfileUse() == CodeGenOptions::ProfileNone && - !UsingSampleProfile) { - Diags.Report(diag::warn_drv_fdiagnostics_show_hotness_requires_pgo); - } + bool UsingProfile = UsingSampleProfile || + (Opts.getProfileUse() != CodeGenOptions::ProfileNone); + + if (Opts.DiagnosticsWithHotness && !UsingProfile) + Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo) + << "-fdiagnostics-show-hotness"; + + Opts.DiagnosticsHotnessThreshold = getLastArgUInt64Value( + Args, options::OPT_fdiagnostics_hotness_threshold_EQ, 0); + if (Opts.DiagnosticsHotnessThreshold > 0 && !UsingProfile) + Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo) + << "-fdiagnostics-hotness-threshold="; // If the user requested to use a sample profile for PGO, then the // backend will need to track source location information so the profile Index: test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext =================================================================== --- test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext +++ test/Frontend/Inputs/optimization-remark-with-hotness-sample.proftext @@ -1,7 +1,7 @@ foo:0:0 0: 0 bar:29:29 - 6: foo:0 + 9: foo:0 main:0:0 0: 0 bar:0 Index: test/Frontend/optimization-remark-with-hotness.c =================================================================== --- test/Frontend/optimization-remark-with-hotness.c +++ test/Frontend/optimization-remark-with-hotness.c @@ -15,12 +15,14 @@ // RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \ // RUN: -fprofile-sample-use=%t-sample.profdata -Rpass=inline \ // RUN: -Rpass-analysis=inline -Rpass-missed=inline \ -// RUN: -fdiagnostics-show-hotness -verify +// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 \ +// RUN: -verify // The clang version of the previous test. // RUN: %clang -target x86_64-apple-macosx10.9 %s -c -emit-llvm -o /dev/null \ // RUN: -fprofile-instr-use=%t.profdata -Rpass=inline \ // RUN: -Rpass-analysis=inline -Rpass-missed=inline \ -// RUN: -fdiagnostics-show-hotness -Xclang -verify +// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 \ +// RUN: -Xclang -verify // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \ // RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \ // RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \ @@ -28,11 +30,18 @@ // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \ // RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \ // RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \ -// RUN: -Rpass-analysis=inline -Rno-pass-with-hotness 2>&1 | FileCheck \ +// RUN: -Rpass-analysis=inline -Rno-pass-with-hotness 2>&1 | FileCheck \ // RUN: -check-prefix=HOTNESS_OFF %s // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \ // RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \ -// RUN: -Rpass=inline -Rpass-analysis=inline -fdiagnostics-show-hotness 2>&1 \ +// RUN: -fprofile-instrument-use-path=%t.profdata -Rpass=inline \ +// RUN: -Rpass-analysis=inline -fdiagnostics-show-hotness \ +// RUN: -fdiagnostics-hotness-threshold=100 2>&1 \ +// RUN: | FileCheck -allow-empty -check-prefix=THRESHOLD %s +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name \ +// RUN: optimization-remark-with-hotness.c %s -emit-llvm-only \ +// RUN: -Rpass=inline -Rpass-analysis=inline \ +// RUN: -fdiagnostics-show-hotness -fdiagnostics-hotness-threshold=10 2>&1 \ // RUN: | FileCheck -check-prefix=NO_PGO %s int foo(int x, int y) __attribute__((always_inline)); @@ -43,7 +52,10 @@ void bar(int x) { // HOTNESS_OFF: foo inlined into bar // HOTNESS_OFF-NOT: hotness: + // THRESHOLD-NOT: inlined + // THRESHOLD-NOT: hotness // NO_PGO: '-fdiagnostics-show-hotness' requires profile-guided optimization information + // NO_PGO: '-fdiagnostics-hotness-threshold=' requires profile-guided optimization information // expected-remark@+2 {{foo should always be inlined (cost=always) (hotness: 30)}} // expected-remark@+1 {{foo inlined into bar (hotness: 30)}} sum += foo(x, x - 2);