aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Smith <peter.smith@linaro.org>2018-10-26 11:24:35 +0100
committerPeter Smith <peter.smith@linaro.org>2018-10-26 15:05:20 +0100
commit16835b68285b46208f4327a1a9f79ec07aecd9a4 (patch)
tree85acd2a56d68486962a2e6be6d290ed436f4983d
parentc78ee91a68fbbba3541355889b260a3ede7107aa (diff)
Add command line options for marking cold functions for size optimisationlinaro-local/peter.smith/rebased-pgo
There are 3 command line options To switch on the pass that marks functions for size optimisation use one of: -fprofile-opt-cold-for-size (after inlining) -fprofile-opt-cold-for-size-early (before inlining). To make the pass mark functions that are neither hot or cold for size optimisation but not minimum size optimisation use: -fmark-neutral-cold
-rw-r--r--include/clang/Driver/Options.td15
-rw-r--r--include/clang/Frontend/CodeGenOptions.def3
-rw-r--r--lib/CodeGen/BackendUtil.cpp26
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp3
-rw-r--r--lib/Driver/ToolChains/Clang.cpp12
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
6 files changed, 61 insertions, 1 deletions
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index ef6e47237c..ed9dd61815 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -718,6 +718,21 @@ def fauto_profile_accurate : Flag<["-"], "fauto-profile-accurate">,
Group<f_Group>, Alias<fprofile_sample_accurate>;
def fno_auto_profile_accurate : Flag<["-"], "fno-auto-profile-accurate">,
Group<f_Group>, Alias<fno_profile_sample_accurate>;
+def fprofile_opt_cold_for_size : Flag<["-"], "fprofile-opt-cold-for-size">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Use profile to optimise cold functions for size.">;
+def fprofile_opt_cold_for_size_early : Flag<["-"], "fprofile-opt-cold-for-size-early">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Use profile to optimise cold functions for size before inlining.">;
+def fno_profile_opt_cold_for_size : Flag<["-"], "fno-profile-opt-cold-for-size">, Group<f_Group>;
+def fno_profile_opt_cold_for_size_early : Flag<["-"], "fno-profile-opt-cold-for-size-early">, Group<f_Group>;
+def fmark_neutral_cold : Flag<["-"], "fmark-neutral-cold">,
+ Group<f_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Mark neither hot nor cold functions for size optimization">,
+ DocBrief<[{When using profile information to mark functions for size optimization, mark functions that are neither hot nor cold
+ for size optimization. Cold functions get minimum size.}]>;
+def fno_mark_neutral_cold : Flag<["-"], "fno-mark-neutral-cold">,
+ Group<f_Group>, Flags<[DriverOption]>;
def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Emit extra debug info to make sample profile more accurate.">;
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index cb6cc0a846..a67080b56a 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -119,6 +119,9 @@ CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
///< be used with an incremental
///< linker.
+CODEGENOPT(MarkCold, 1, 0) ///< Mark cold functions for size optimization.
+CODEGENOPT(MarkColdEarly, 1, 0) ///< As Mark cold but before inlining.
+CODEGENOPT(MarkNeutralCold, 1, 0) ///< Mark neither hot nor cold functions for size
CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants.
CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled.
CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled.
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 698386c062..79ac49c82a 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -58,6 +58,7 @@
#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Scalar/GVN.h"
+#include "llvm/Transforms/Scalar/MarkCold.h"
#include "llvm/Transforms/Utils.h"
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
#include "llvm/Transforms/Utils/SymbolRewriter.h"
@@ -693,6 +694,15 @@ void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
if (!CodeGenOpts.SampleProfileFile.empty())
PMBuilder.PGOSampleUse = CodeGenOpts.SampleProfileFile;
+ if (CodeGenOpts.hasProfileClangUse() || CodeGenOpts.hasProfileIRUse() ||
+ !CodeGenOpts.SampleProfileFile.empty()) {
+ if (CodeGenOpts.MarkCold) {
+ PMBuilder.EnableMarkColdAfterInline = true;
+ }
+ if (CodeGenOpts.MarkColdEarly)
+ PMBuilder.EnableMarkColdBeforeInline = true;
+ }
+
PMBuilder.populateFunctionPassManager(FPM);
PMBuilder.populateModulePassManager(MPM);
}
@@ -938,7 +948,12 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
// -fprofile-use.
PGOOpt = PGOOptions("", CodeGenOpts.ProfileInstrumentUsePath, "",
CodeGenOpts.ProfileRemappingFile, false,
- CodeGenOpts.DebugInfoForProfiling);
+ CodeGenOpts.DebugInfoForProfiling, false);
+ else if (CodeGenOpts.hasProfileClangUse())
+ // -fprofile-use.
+ PGOOpt = PGOOptions("", CodeGenOpts.ProfileInstrumentUsePath, "",
+ CodeGenOpts.ProfileRemappingFile, false,
+ CodeGenOpts.DebugInfoForProfiling, true);
else if (!CodeGenOpts.SampleProfileFile.empty())
// -fprofile-sample-use
PGOOpt = PGOOptions("", "", CodeGenOpts.SampleProfileFile,
@@ -948,6 +963,15 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
// -fdebug-info-for-profiling
PGOOpt = PGOOptions("", "", "", "", false, true);
+ if (PGOOpt &&
+ (CodeGenOpts.hasProfileIRUse() || CodeGenOpts.hasProfileClangUse() ||
+ !CodeGenOpts.SampleProfileFile.empty())) {
+ if (CodeGenOpts.MarkCold)
+ PGOOpt->MarkColdAfterInline = true;
+ if (CodeGenOpts.MarkColdEarly)
+ PGOOpt->MarkColdBeforeInline = true;
+ }
+
PassBuilder PB(TM.get(), PGOOpt);
LoopAnalysisManager LAM(CodeGenOpts.DebugPassManager);
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 84d7b9e611..05c936e221 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -945,6 +945,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
if (CGM.getCodeGenOpts().ProfileSampleAccurate)
Fn->addFnAttr("profile-sample-accurate");
+ if (CGM.getCodeGenOpts().MarkNeutralCold)
+ Fn->addFnAttr("mark-neutral-cold");
+
if (getLangOpts().OpenCL) {
// Add metadata for a kernel function.
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index a8ddd8adc3..c2b951a58a 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -3706,6 +3706,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
true))
CmdArgs.push_back("-fno-jump-tables");
+ if (Args.hasFlag(options::OPT_fprofile_opt_cold_for_size,
+ options::OPT_fno_profile_opt_cold_for_size, false))
+ CmdArgs.push_back("-fprofile-opt-cold-for-size");
+
+ if (Args.hasFlag(options::OPT_fprofile_opt_cold_for_size_early,
+ options::OPT_fno_profile_opt_cold_for_size_early, false))
+ CmdArgs.push_back("-fprofile-opt-cold-for-size-early");
+
+ if (Args.hasFlag(options::OPT_fmark_neutral_cold,
+ options::OPT_fno_mark_neutral_cold, false))
+ CmdArgs.push_back("-fmark-neutral-cold");
+
if (Args.hasFlag(options::OPT_fprofile_sample_accurate,
options::OPT_fno_profile_sample_accurate, false))
CmdArgs.push_back("-fprofile-sample-accurate");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 52c8109818..1288d4c2b3 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -763,7 +763,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks);
+ Opts.MarkCold = Args.hasArg(OPT_fprofile_opt_cold_for_size);
+ Opts.MarkColdEarly = Args.hasArg(OPT_fprofile_opt_cold_for_size_early);
Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate);
+ Opts.MarkNeutralCold = Args.hasArg(OPT_fmark_neutral_cold);
Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
Opts.PrepareForThinLTO = false;