From: Chad Rosier Date: Wed, 24 Apr 2013 18:09:54 +0000 (+0000) Subject: [driver] Improve the implementation of the -Ofast option. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b82e117e4af1062b9f0d1aab89abf4aa804558f1;p=clang [driver] Improve the implementation of the -Ofast option. Specifically, allow the flags that fall under this umbrella (i.e., -O3, -ffast-math, and -fstrict-aliasing) to be overridden/disabled with the individual -O[0|1|2|s|z]/-fno- flags. This also fixes the handling of various floating point optimization flags that are modified by -ffast-math (and thus -Ofast as well). Part of rdar://13622687 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180204 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 119b7c76a4..d93c5cb449 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1829,6 +1829,13 @@ static void SplitDebugInfo(const ToolChain &TC, Compilation &C, C.addCommand(new Command(JA, T, Exec, StripArgs)); } +static bool isOptimizationLevelFast(const ArgList &Args) { + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) + if (A->getOption().matches(options::OPT_Ofast)) + return true; + return false; +} + void Clang::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -2117,7 +2124,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_fzero_initialized_in_bss, options::OPT_fno_zero_initialized_in_bss)) CmdArgs.push_back("-mno-zero-initialized-in-bss"); - if (!Args.hasFlag(options::OPT_fstrict_aliasing, + + bool OFastEnabled = isOptimizationLevelFast(Args); + // If -Ofast is the optimization level, then -fstrict-aliasing should be + // enabled. This alias option is being used to simplify the hasFlag logic. + OptSpecifier StrictAliasingAliasOption = OFastEnabled ? options::OPT_Ofast : + options::OPT_fstrict_aliasing; + if (!Args.hasFlag(options::OPT_fstrict_aliasing, StrictAliasingAliasOption, options::OPT_fno_strict_aliasing, getToolChain().IsStrictAliasingDefault())) CmdArgs.push_back("-relaxed-aliasing"); @@ -2133,13 +2146,18 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Handle segmented stacks. if (Args.hasArg(options::OPT_fsplit_stack)) CmdArgs.push_back("-split-stacks"); + + // If -Ofast is the optimization level, then -ffast-math should be enabled. + // This alias option is being used to simplify the getLastArg logic. + OptSpecifier FastMathAliasOption = OFastEnabled ? options::OPT_Ofast : + options::OPT_ffast_math; // Handle various floating point optimization flags, mapping them to the // appropriate LLVM code generation flags. The pattern for all of these is to // default off the codegen optimizations, and if any flag enables them and no // flag disables them after the flag enabling them, enable the codegen // optimization. This is complicated by several "umbrella" flags. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, @@ -2149,7 +2167,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_finite_math_only && A->getOption().getID() != options::OPT_fhonor_infinities) CmdArgs.push_back("-menable-no-infs"); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffinite_math_only, options::OPT_fno_finite_math_only, @@ -2162,7 +2180,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // -fmath-errno is the default on some platforms, e.g. BSD-derived OSes. bool MathErrno = getToolChain().IsMathErrnoDefault(); - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_fmath_errno, options::OPT_fno_math_errno)) @@ -2175,7 +2193,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // entire set of LLVM optimizations, so collect them through all the flag // madness. bool AssociativeMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2186,7 +2204,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_associative_math) AssociativeMath = true; bool ReciprocalMath = false; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2197,7 +2215,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fno_reciprocal_math) ReciprocalMath = true; bool SignedZeros = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2208,7 +2226,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, A->getOption().getID() != options::OPT_fsigned_zeros) SignedZeros = false; bool TrappingMath = true; - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_funsafe_math_optimizations, options::OPT_fno_unsafe_math_optimizations, @@ -2224,7 +2242,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Validate and pass through -fp-contract option. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, options::OPT_fno_fast_math, options::OPT_ffp_contract)) { if (A->getOption().getID() == options::OPT_ffp_contract) { @@ -2235,7 +2253,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, D.Diag(diag::err_drv_unsupported_option_argument) << A->getOption().getName() << Val; } - } else if (A->getOption().getID() == options::OPT_ffast_math) { + } else if (A->getOption().matches(options::OPT_ffast_math) || + (OFastEnabled && A->getOption().matches(options::OPT_Ofast))) { // If fast-math is set then set the fp-contract mode to fast. CmdArgs.push_back(Args.MakeArgString("-ffp-contract=fast")); } @@ -2246,9 +2265,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // preprocessor macros. This is distinct from enabling any optimizations as // these options induce language changes which must survive serialization // and deserialization, etc. - if (Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math)) - if (A->getOption().matches(options::OPT_ffast_math)) - CmdArgs.push_back("-ffast-math"); + if (Arg *A = Args.getLastArg(options::OPT_ffast_math, FastMathAliasOption, + options::OPT_fno_fast_math)) + if (!A->getOption().matches(options::OPT_fno_fast_math)) + CmdArgs.push_back("-ffast-math"); if (Arg *A = Args.getLastArg(options::OPT_ffinite_math_only, options::OPT_fno_fast_math)) if (A->getOption().matches(options::OPT_ffinite_math_only)) CmdArgs.push_back("-ffinite-math-only"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index ba3809bba5..b5fb71e00f 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -100,13 +100,6 @@ static unsigned getOptimizationLevelSize(ArgList &Args) { return 0; } -static bool isOptimizationLevelFast(ArgList &Args) { - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) - if (A->getOption().matches(options::OPT_Ofast)) - return true; - return false; -} - static void addWarningArgs(ArgList &Args, std::vector &Warnings) { for (arg_iterator I = Args.filtered_begin(OPT_W_Group), E = Args.filtered_end(); I != E; ++I) { @@ -333,8 +326,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables); Opts.UseRegisterSizedBitfieldAccess = Args.hasArg( OPT_fuse_register_sized_bitfield_access); - Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing) || - isOptimizationLevelFast(Args); + Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing); Opts.StructPathTBAA = Args.hasArg(OPT_struct_path_tbaa); Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); @@ -1313,8 +1305,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // inlining enabled. Opts.NoInlineDefine = !Opt || Args.hasArg(OPT_fno_inline); - Opts.FastMath = Args.hasArg(OPT_ffast_math) || - isOptimizationLevelFast(Args); + Opts.FastMath = Args.hasArg(OPT_ffast_math); Opts.FiniteMathOnly = Args.hasArg(OPT_ffinite_math_only); Opts.RetainCommentsFromSystemHeaders = diff --git a/test/Driver/Ofast.c b/test/Driver/Ofast.c new file mode 100644 index 0000000000..bceeb8f5fe --- /dev/null +++ b/test/Driver/Ofast.c @@ -0,0 +1,20 @@ +// RUN: %clang -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -fno-fast-math -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -fno-strict-aliasing -Ofast -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST %s +// RUN: %clang -Ofast -fno-fast-math -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-FAST-MATH %s +// RUN: %clang -Ofast -fno-strict-aliasing -### %s 2>&1 | FileCheck -check-prefix=CHECK-OFAST-NO-STRICT-ALIASING %s + +// CHECK-OFAST: -cc1 +// CHECK-OFAST-NOT: -relaxed-aliasing +// CHECK-OFAST: -ffast-math +// CHECK-OFAST: -Ofast + +// CHECK-OFAST-NO-FAST-MATH: -cc1 +// CHECK-OFAST-NO-FAST-MATH-NOT: -relaxed-aliasing +// CHECK-OFAST-NO-FAST-MATH-NOT: -ffast-math +// CHECK-OFAST-NO-FAST-MATH: -Ofast + +// CHECK-OFAST-NO-STRICT-ALIASING: -cc1 +// CHECK-OFAST-NO-STRICT-ALIASING: -relaxed-aliasing +// CHECK-OFAST-NO-STRICT-ALIASING: -ffast-math +// CHECK-OFAST-NO-STRICT-ALIASING: -Ofast