-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[clang] Add flag fallow-runtime-check-skip-hot-cutoff #145999
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Add flag fallow-runtime-check-skip-hot-cutoff #145999
Conversation
Created using spr 1.3.4
Created using spr 1.3.4 [skip ci]
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Florian Mayer (fmayer) ChangesFull diff: https://github.com/llvm/llvm-project/pull/145999.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 77a0c559f7689..1b99d56fc68e1 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -399,6 +399,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// with extra debug info.
SanitizerSet SanitizeAnnotateDebugInfo;
+ std::optional<double> AllowRuntimeCheckSkipHotCutoff;
+
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0822df2640d23..c36daa2c3afea 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2668,6 +2668,16 @@ def fsanitize_skip_hot_cutoff_EQ
} // end -f[no-]sanitize* flags
+def fallow_runtime_check_skip_hot_cutoff_EQ
+ : Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
+ Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Exclude __allow_runtime_check for the top hottest code "
+ "responsible for "
+ "the given fraction of PGO counters "
+ "(0.0 [default] = skip none; 1/.0 = skip all). "
+ "Argument format: <value>">;
+
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 97bc063ad34e5..1c92ea45c7458 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -805,17 +805,21 @@ static void addSanitizers(const Triple &TargetTriple,
// SanitizeSkipHotCutoffs: doubles with range [0, 1]
// Opts.cutoffs: unsigned ints with range [0, 1000000]
auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000);
-
+ uint64_t AllowRuntimeCheckSkipHotCutoff =
+ CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.value_or(0.0) * 1000000;
// TODO: remove IsRequested()
- if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) {
+ if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value() ||
+ CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.has_value()) {
// We want to call it after inline, which is about OptimizerEarlyEPCallback.
PB.registerOptimizerEarlyEPCallback(
- [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level,
- ThinOrFullLTOPhase Phase) {
+ [ScaledCutoffs, AllowRuntimeCheckSkipHotCutoff](
+ ModulePassManager &MPM, OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase) {
LowerAllowCheckPass::Options Opts;
// TODO: after removing IsRequested(), make this unconditional
if (ScaledCutoffs.has_value())
Opts.cutoffs = ScaledCutoffs.value();
+ Opts.runtime_check = AllowRuntimeCheckSkipHotCutoff;
MPM.addPass(
createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));
});
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 8a18865b899d2..ceb592d1548f5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6028,7 +6028,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
// complicated ways.
auto SanitizeArgs = TC.getSanitizerArgs(Args);
-
+ Args.AddLastArg(CmdArgs,
+ options::OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
bool IsAsyncUnwindTablesDefault =
TC.getDefaultUnwindTableLevel(Args) == ToolChain::UnwindTableLevel::Asynchronous;
bool IsSyncUnwindTablesDefault =
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 9e269ab244d4c..f366e90945dac 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1820,6 +1820,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
for (std::string Sanitizer : Values)
GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
+ if (Opts.AllowRuntimeCheckSkipHotCutoff) {
+ GenerateArg(Consumer, OPT_fallow_runtime_check_skip_hot_cutoff_EQ,
+ std::to_string(*Opts.AllowRuntimeCheckSkipHotCutoff));
+ }
+
for (StringRef Sanitizer :
serializeSanitizerKinds(Opts.SanitizeAnnotateDebugInfo))
GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer);
@@ -2322,6 +2327,18 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags,
Opts.SanitizeAnnotateDebugInfo);
+ if (StringRef V =
+ Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
+ !V.empty()) {
+ double A;
+ if (V.getAsDouble(A) || A < 0.0 || A > 1.0) {
+ Diags.Report(diag::err_drv_invalid_value)
+ << "-fallow-runtime-check-skip-hot-cutoff=" << V;
+ } else {
+ Opts.AllowRuntimeCheckSkipHotCutoff = A;
+ }
+ }
+
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
if (!LangOpts->CUDAIsDevice)
diff --git a/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c
new file mode 100644
index 0000000000000..cede7530d2a22
--- /dev/null
+++ b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c
@@ -0,0 +1,9 @@
+// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=1.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ONE %s
+// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=0.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ZERO %s
+
+// ONE: ret i32 0
+// ZERO: ret i32 1
+
+int main(int argc, char** argv) {
+ return __builtin_allow_runtime_check("foo");
+}
diff --git a/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c
new file mode 100644
index 0000000000000..b186e6e74f162
--- /dev/null
+++ b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c
@@ -0,0 +1,6 @@
+// RUN: %clang -### -fallow-runtime-check-skip-hot-cutoff=1.0 %s 2>&1 | FileCheck %s
+// CHECK: -fallow-runtime-check-skip-hot-cutoff=1.0
+
+int main(int argc, char** argv) {
+ return __builtin_allow_runtime_check("foo");
+}
|
@llvm/pr-subscribers-clang-codegen Author: Florian Mayer (fmayer) ChangesFull diff: https://github.com/llvm/llvm-project/pull/145999.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index 77a0c559f7689..1b99d56fc68e1 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -399,6 +399,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// with extra debug info.
SanitizerSet SanitizeAnnotateDebugInfo;
+ std::optional<double> AllowRuntimeCheckSkipHotCutoff;
+
/// List of backend command-line options for -fembed-bitcode.
std::vector<uint8_t> CmdArgs;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0822df2640d23..c36daa2c3afea 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2668,6 +2668,16 @@ def fsanitize_skip_hot_cutoff_EQ
} // end -f[no-]sanitize* flags
+def fallow_runtime_check_skip_hot_cutoff_EQ
+ : Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
+ Group<f_clang_Group>,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"Exclude __allow_runtime_check for the top hottest code "
+ "responsible for "
+ "the given fraction of PGO counters "
+ "(0.0 [default] = skip none; 1/.0 = skip all). "
+ "Argument format: <value>">;
+
def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">,
Group<f_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Allow unsafe floating-point math optimizations which may decrease precision">,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 97bc063ad34e5..1c92ea45c7458 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -805,17 +805,21 @@ static void addSanitizers(const Triple &TargetTriple,
// SanitizeSkipHotCutoffs: doubles with range [0, 1]
// Opts.cutoffs: unsigned ints with range [0, 1000000]
auto ScaledCutoffs = CodeGenOpts.SanitizeSkipHotCutoffs.getAllScaled(1000000);
-
+ uint64_t AllowRuntimeCheckSkipHotCutoff =
+ CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.value_or(0.0) * 1000000;
// TODO: remove IsRequested()
- if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value()) {
+ if (LowerAllowCheckPass::IsRequested() || ScaledCutoffs.has_value() ||
+ CodeGenOpts.AllowRuntimeCheckSkipHotCutoff.has_value()) {
// We want to call it after inline, which is about OptimizerEarlyEPCallback.
PB.registerOptimizerEarlyEPCallback(
- [ScaledCutoffs](ModulePassManager &MPM, OptimizationLevel Level,
- ThinOrFullLTOPhase Phase) {
+ [ScaledCutoffs, AllowRuntimeCheckSkipHotCutoff](
+ ModulePassManager &MPM, OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase) {
LowerAllowCheckPass::Options Opts;
// TODO: after removing IsRequested(), make this unconditional
if (ScaledCutoffs.has_value())
Opts.cutoffs = ScaledCutoffs.value();
+ Opts.runtime_check = AllowRuntimeCheckSkipHotCutoff;
MPM.addPass(
createModuleToFunctionPassAdaptor(LowerAllowCheckPass(Opts)));
});
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 8a18865b899d2..ceb592d1548f5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -6028,7 +6028,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
// complicated ways.
auto SanitizeArgs = TC.getSanitizerArgs(Args);
-
+ Args.AddLastArg(CmdArgs,
+ options::OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
bool IsAsyncUnwindTablesDefault =
TC.getDefaultUnwindTableLevel(Args) == ToolChain::UnwindTableLevel::Asynchronous;
bool IsSyncUnwindTablesDefault =
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 9e269ab244d4c..f366e90945dac 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1820,6 +1820,11 @@ void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
for (std::string Sanitizer : Values)
GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
+ if (Opts.AllowRuntimeCheckSkipHotCutoff) {
+ GenerateArg(Consumer, OPT_fallow_runtime_check_skip_hot_cutoff_EQ,
+ std::to_string(*Opts.AllowRuntimeCheckSkipHotCutoff));
+ }
+
for (StringRef Sanitizer :
serializeSanitizerKinds(Opts.SanitizeAnnotateDebugInfo))
GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer);
@@ -2322,6 +2327,18 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags,
Opts.SanitizeAnnotateDebugInfo);
+ if (StringRef V =
+ Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
+ !V.empty()) {
+ double A;
+ if (V.getAsDouble(A) || A < 0.0 || A > 1.0) {
+ Diags.Report(diag::err_drv_invalid_value)
+ << "-fallow-runtime-check-skip-hot-cutoff=" << V;
+ } else {
+ Opts.AllowRuntimeCheckSkipHotCutoff = A;
+ }
+ }
+
Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
if (!LangOpts->CUDAIsDevice)
diff --git a/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c
new file mode 100644
index 0000000000000..cede7530d2a22
--- /dev/null
+++ b/clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c
@@ -0,0 +1,9 @@
+// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=1.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ONE %s
+// RUN: %clang -fallow-runtime-check-skip-hot-cutoff=0.0 -S -emit-llvm %s -o - -O2 | FileCheck --check-prefix=ZERO %s
+
+// ONE: ret i32 0
+// ZERO: ret i32 1
+
+int main(int argc, char** argv) {
+ return __builtin_allow_runtime_check("foo");
+}
diff --git a/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c
new file mode 100644
index 0000000000000..b186e6e74f162
--- /dev/null
+++ b/clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c
@@ -0,0 +1,6 @@
+// RUN: %clang -### -fallow-runtime-check-skip-hot-cutoff=1.0 %s 2>&1 | FileCheck %s
+// CHECK: -fallow-runtime-check-skip-hot-cutoff=1.0
+
+int main(int argc, char** argv) {
+ return __builtin_allow_runtime_check("foo");
+}
|
Created using spr 1.3.4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[this page intentionally left blank]
HelpText<"Exclude __allow_runtime_check for the top hottest code " | ||
"responsible for " | ||
"the given fraction of PGO counters " | ||
"(0.0 [default] = skip none; 1/.0 = skip all). " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: "1/.0"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -2668,6 +2668,16 @@ def fsanitize_skip_hot_cutoff_EQ | |||
|
|||
} // end -f[no-]sanitize* flags | |||
|
|||
def fallow_runtime_check_skip_hot_cutoff_EQ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"fallow" is either unfortunate or brilliant naming, similar to fun safe math. (I'm looking forward to the "fallow_fields" flag.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks?
@@ -2668,6 +2668,16 @@ def fsanitize_skip_hot_cutoff_EQ | |||
|
|||
} // end -f[no-]sanitize* flags | |||
|
|||
def fallow_runtime_check_skip_hot_cutoff_EQ | |||
: Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more user-friendly (and possibly less code duplication) to add "allow_runtime_check" as one of the options for the existing -fsanitize-skip-hot-cutoff
(possibly renaming the flag since it would no longer be entirely sanitizers)? e.g., allow -fsanitize-skip-hot-cutoff=undefined=0.999999,allow_runtime_check=1.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not really about sanitizers though. Also if we want to teach this flag about kind=blah, that would become very messy.
Group<f_clang_Group>, | ||
Visibility<[ClangOption, CC1Option]>, | ||
HelpText<"Exclude __allow_runtime_check for the top hottest code " | ||
"responsible for " |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: string split is awkward
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Created using spr 1.3.4 [skip ci]
Co-authored-by: Kazu Hirata <kazu@google.com>
No description provided.