aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Driver/ArgList.cpp18
-rw-r--r--lib/Driver/Tools.cpp102
-rw-r--r--lib/Frontend/CompilerInvocation.cpp7
3 files changed, 108 insertions, 19 deletions
diff --git a/lib/Driver/ArgList.cpp b/lib/Driver/ArgList.cpp
index ca9b944950..3c9e71d6f8 100644
--- a/lib/Driver/ArgList.cpp
+++ b/lib/Driver/ArgList.cpp
@@ -122,6 +122,24 @@ Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
return Res;
}
+Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2, OptSpecifier Id3,
+ OptSpecifier Id4) const {
+ Arg *Res = 0;
+ for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
+ if ((*it)->getOption().matches(Id0) ||
+ (*it)->getOption().matches(Id1) ||
+ (*it)->getOption().matches(Id2) ||
+ (*it)->getOption().matches(Id3) ||
+ (*it)->getOption().matches(Id4)) {
+ Res = *it;
+ Res->claim();
+ }
+ }
+
+ return Res;
+}
+
bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
if (Arg *A = getLastArg(Pos, Neg))
return A->getOption().matches(Pos);
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 41ff1102bf..f678667c33 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1435,18 +1435,90 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
getToolChain().IsStrictAliasingDefault()))
CmdArgs.push_back("-relaxed-aliasing");
- // Handle -f{no-}honor-infinities, -f{no-}honor-nans, and -ffinite-math-only.
- bool HonorInfinities = Args.hasFlag(options::OPT_fhonor_infinities,
- options::OPT_fno_honor_infinities);
- bool HonorNaNs = Args.hasFlag(options::OPT_fhonor_nans,
- options::OPT_fno_honor_nans);
- if (Args.hasArg(options::OPT_ffinite_math_only))
- HonorInfinities = HonorNaNs = false;
- if (!HonorInfinities)
- CmdArgs.push_back("-menable-no-infs");
- if (!HonorNaNs)
- CmdArgs.push_back("-menable-no-nans");
-
+ // 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,
+ options::OPT_ffinite_math_only,
+ options::OPT_fno_finite_math_only,
+ options::OPT_fhonor_infinities,
+ options::OPT_fno_honor_infinities))
+ if (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,
+ options::OPT_ffinite_math_only,
+ options::OPT_fno_finite_math_only,
+ options::OPT_fhonor_nans,
+ options::OPT_fno_honor_nans))
+ if (A->getOption().getID() != options::OPT_fno_finite_math_only &&
+ A->getOption().getID() != options::OPT_fhonor_nans)
+ CmdArgs.push_back("-menable-no-nans");
+
+ // -fno-math-errno is default.
+ bool MathErrno = false;
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_fmath_errno,
+ options::OPT_fno_math_errno)) {
+ if (A->getOption().getID() == options::OPT_fmath_errno) {
+ CmdArgs.push_back("-fmath-errno");
+ MathErrno = true;
+ }
+ }
+
+ // There are several flags which require disabling very specific
+ // optimizations. Any of these being disabled forces us to turn off the
+ // 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,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations,
+ options::OPT_fassociative_math,
+ options::OPT_fno_associative_math))
+ if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ A->getOption().getID() != options::OPT_fno_associative_math)
+ AssociativeMath = true;
+ bool ReciprocalMath = false;
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations,
+ options::OPT_freciprocal_math,
+ options::OPT_fno_reciprocal_math))
+ if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ A->getOption().getID() != options::OPT_fno_reciprocal_math)
+ ReciprocalMath = true;
+ bool SignedZeros = true;
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations,
+ options::OPT_fsigned_zeros,
+ options::OPT_fno_signed_zeros))
+ if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ A->getOption().getID() != options::OPT_fsigned_zeros)
+ SignedZeros = false;
+ bool TrappingMath = true;
+ if (Arg *A = Args.getLastArg(options::OPT_ffast_math,
+ options::OPT_funsafe_math_optimizations,
+ options::OPT_fno_unsafe_math_optimizations,
+ options::OPT_ftrapping_math,
+ options::OPT_fno_trapping_math))
+ if (A->getOption().getID() != options::OPT_fno_unsafe_math_optimizations &&
+ A->getOption().getID() != options::OPT_ftrapping_math)
+ TrappingMath = false;
+ if (!MathErrno && AssociativeMath && ReciprocalMath && !SignedZeros &&
+ !TrappingMath)
+ CmdArgs.push_back("-menable-unsafe-fp-math");
+
+ // We separately look for the '-ffast-math' flag, and if we find it, tell the
+ // frontend to provide the appropriate preprocessor macros. This is distinct
+ // from enabling any optimizations as it induces a language change which must
+ // survive serialization and deserialization, etc.
+ if (Args.hasArg(options::OPT_ffast_math))
+ CmdArgs.push_back("-ffast-math");
+
// Decide whether to use verbose asm. Verbose assembly is the default on
// toolchains which have the integrated assembler on by default.
bool IsVerboseAsmDefault = getToolChain().IsIntegratedAssemblerDefault();
@@ -1548,12 +1620,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
!getToolChain().getTriple().isOSDarwin()))
CmdArgs.push_back("-momit-leaf-frame-pointer");
- // -fno-math-errno is default.
- if (Args.hasFlag(options::OPT_fmath_errno,
- options::OPT_fno_math_errno,
- false))
- CmdArgs.push_back("-fmath-errno");
-
// Explicitly error on some things we know we don't support and can't just
// ignore.
types::ID InputType = Inputs[0].getType();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index caeb416a59..0137774cf1 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -735,6 +735,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
Res.push_back("-fheinous-gnu-extensions");
// Optimize is implicit.
// OptimizeSize is implicit.
+ if (Opts.FastMath)
+ Res.push_back("-ffast-math");
if (Opts.Static)
Res.push_back("-static-define");
if (Opts.DumpRecordLayouts)
@@ -1117,7 +1119,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.NoDwarf2CFIAsm = Args.hasArg(OPT_fno_dwarf2_cfi_asm);
Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm);
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
- Opts.UnsafeFPMath = Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
+ Opts.UnsafeFPMath = Args.hasArg(OPT_menable_unsafe_fp_math) ||
+ Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
Args.hasArg(OPT_cl_fast_relaxed_math);
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
@@ -1874,6 +1877,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// FIXME: This is affected by other options (-fno-inline).
Opts.NoInline = !Opt;
+ Opts.FastMath = Args.hasArg(OPT_ffast_math);
+
unsigned SSP = Args.getLastArgIntValue(OPT_stack_protector, 0, Diags);
switch (SSP) {
default: