Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
9 changes: 9 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2668,6 +2668,15 @@ def fsanitize_skip_hot_cutoff_EQ

} // end -f[no-]sanitize* flags

def fallow_runtime_check_skip_hot_cutoff_EQ
Copy link
Contributor

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.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks?

: Joined<["-"], "fallow-runtime-check-skip-hot-cutoff=">,
Copy link
Contributor

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

Copy link
Contributor Author

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 __builtin_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">,
Expand Down
12 changes: 8 additions & 4 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
});
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions clang/test/CodeGen/fallow-runtime-check-skip-hot-cutoff.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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
// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=6.0 -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=SIX %s
// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=-1.0 -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=MINUSONE %s
// RUN: not %clang -fallow-runtime-check-skip-hot-cutoff=string -S -emit-llvm %s -o - -O2 2>&1 | FileCheck --check-prefix=STRING %s

// ONE: ret i32 0
// ZERO: ret i32 1
// SIX: invalid value '6.0' in '-fallow-runtime-check-skip-hot-cutoff='
// MINUSONE: invalid value '-1.0' in '-fallow-runtime-check-skip-hot-cutoff='
// STRING: invalid value 'string' in '-fallow-runtime-check-skip-hot-cutoff='

int main(int argc, char** argv) {
return __builtin_allow_runtime_check("foo");
}
6 changes: 6 additions & 0 deletions clang/test/Driver/fallow-runtime-check-skip-hot-cutoff.c
Original file line number Diff line number Diff line change
@@ -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");
}
Loading