Projects
openEuler:24.03:SP1:Everything:64G
gcc
_service:tar_scm:0019-fp-model-Enable-fp-model-...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0019-fp-model-Enable-fp-model-on-kunpeng.patch of Package gcc
From 8cdb316a3fe205a3089b9c17aec0442f4d5f75be Mon Sep 17 00:00:00 2001 From: bule <bule1@huawei.com> Date: Sun, 27 Aug 2023 16:49:04 +0800 Subject: [PATCH 19/22] [fp-model] Enable fp-model on kunpeng Enable fp-model options on kunpeng for precision control. --- gcc/common.opt | 26 +++++ gcc/config/aarch64/aarch64-linux.h | 3 +- gcc/flag-types.h | 9 ++ gcc/fortran/options.cc | 8 ++ gcc/opts-common.cc | 146 ++++++++++++++++++++++++++++- gcc/opts.cc | 68 ++++++++++++++ 6 files changed, 256 insertions(+), 4 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index 8a0dafc52..f5eef8a45 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1642,6 +1642,32 @@ ffp-int-builtin-inexact Common Var(flag_fp_int_builtin_inexact) Init(1) Optimization Allow built-in functions ceil, floor, round, trunc to raise \"inexact\" exceptions. +fftz +Common Var(flag_ftz) Optimization +Control fpcr register for flush to zero. + +fp-model= +Common Joined RejectNegative Enum(fp_model) Var(flag_fp_model) Init(FP_MODEL_NORMAL) Optimization +-fp-model=[normal|fast|precise|except|strict] Perform floating-point precision control. + +Enum +Name(fp_model) Type(enum fp_model) UnknownError(unknown floating point precision model %qs) + +EnumValue +Enum(fp_model) String(normal) Value(FP_MODEL_NORMAL) + +EnumValue +Enum(fp_model) String(fast) Value(FP_MODEL_FAST) + +EnumValue +Enum(fp_model) String(precise) Value(FP_MODEL_PRECISE) + +EnumValue +Enum(fp_model) String(except) Value(FP_MODEL_EXCEPT) + +EnumValue +Enum(fp_model) String(strict) Value(FP_MODEL_STRICT) + ; Nonzero means don't put addresses of constant functions in registers. ; Used for compiling the Unix kernel, where strange substitutions are ; done on the assembly output. diff --git a/gcc/config/aarch64/aarch64-linux.h b/gcc/config/aarch64/aarch64-linux.h index 5e4553d79..a5cba6391 100644 --- a/gcc/config/aarch64/aarch64-linux.h +++ b/gcc/config/aarch64/aarch64-linux.h @@ -50,7 +50,8 @@ #define LINK_SPEC LINUX_TARGET_LINK_SPEC AARCH64_ERRATA_LINK_SPEC #define GNU_USER_TARGET_MATHFILE_SPEC \ - "%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s}" + "%{Ofast|ffast-math|funsafe-math-optimizations|fp-model=fast|fftz:\ + %{!fno-ftz:crtfastmath.o%s}}" #undef ENDFILE_SPEC #define ENDFILE_SPEC \ diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 2c8498169..64c64eb32 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -260,6 +260,15 @@ enum fp_contract_mode { FP_CONTRACT_FAST = 2 }; +/* Floating-point precision mode. */ +enum fp_model { + FP_MODEL_NORMAL = 0, + FP_MODEL_FAST = 1, + FP_MODEL_PRECISE = 2, + FP_MODEL_EXCEPT = 3, + FP_MODEL_STRICT = 4 +}; + /* Scalar storage order kind. */ enum scalar_storage_order_kind { SSO_NATIVE = 0, diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc index d0fa634f1..3eb99a84a 100644 --- a/gcc/fortran/options.cc +++ b/gcc/fortran/options.cc @@ -243,6 +243,7 @@ form_from_filename (const char *filename) return f_form; } +static void gfc_handle_fpe_option (const char *arg, bool trap); /* Finalize commandline options. */ @@ -286,6 +287,13 @@ gfc_post_options (const char **pfilename) if (flag_protect_parens == -1) flag_protect_parens = !optimize_fast; + /* If fp-model=precise/strict, turn on all ffpe-trap and ffpe-summary. */ + if (flag_fp_model == FP_MODEL_EXCEPT || flag_fp_model == FP_MODEL_STRICT) + { + gfc_handle_fpe_option ("all", false); + gfc_handle_fpe_option ("invalid,zero,overflow,underflow", true); + } + /* -Ofast sets implies -fstack-arrays unless an explicit size is set for stack arrays. */ if (flag_stack_arrays == -1 && flag_max_stack_var_size == -2) diff --git a/gcc/opts-common.cc b/gcc/opts-common.cc index 7c07d5046..489a6e02a 100644 --- a/gcc/opts-common.cc +++ b/gcc/opts-common.cc @@ -28,7 +28,8 @@ along with GCC; see the file COPYING3. If not see #include "spellcheck.h" #include "opts-jobserver.h" -static void prune_options (struct cl_decoded_option **, unsigned int *); +static void prune_options (struct cl_decoded_option **, unsigned int *, + unsigned int); /* An option that is undocumented, that takes a joined argument, and that doesn't fit any of the classes of uses (language/common, @@ -1091,7 +1092,7 @@ decode_cmdline_options_to_array (unsigned int argc, const char **argv, *decoded_options = opt_array; *decoded_options_count = num_decoded_options; - prune_options (decoded_options, decoded_options_count); + prune_options (decoded_options, decoded_options_count, lang_mask); } /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the @@ -1112,11 +1113,109 @@ cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx) return false; } +/* Check whether opt_idx exists in decoded_options array between index + start and end. If found, return its index in decoded_options, + else return end. */ +static unsigned int +find_opt_idx (const struct cl_decoded_option *decoded_options, + unsigned int decoded_options_count, + unsigned int start, unsigned int end, unsigned int opt_idx) +{ + gcc_assert (end <= decoded_options_count); + gcc_assert (opt_idx < cl_options_count); + unsigned int k; + for (k = start; k < end; k++) + { + if (decoded_options[k].opt_index == opt_idx) + { + return k; + } + } + return k; +} + +/* remove the opt_index element from decoded_options array. */ +static unsigned int +remove_option (struct cl_decoded_option *decoded_options, + unsigned int decoded_options_count, + unsigned int opt_index) +{ + gcc_assert (opt_index < decoded_options_count); + unsigned int i; + for (i = opt_index; i < decoded_options_count - 1; i++) + { + decoded_options[i] = decoded_options[i + 1]; + } + return decoded_options_count - 1; +} + +/* Handle the priority between fp-model, Ofast, and + ffast-math. */ +static unsigned int +handle_fp_model_driver (struct cl_decoded_option *decoded_options, + unsigned int decoded_options_count, + unsigned int fp_model_index, + unsigned int lang_mask) +{ + struct cl_decoded_option fp_model_opt = decoded_options[fp_model_index]; + enum fp_model model = (enum fp_model) fp_model_opt.value; + if (model == FP_MODEL_PRECISE || model == FP_MODEL_STRICT) + { + /* If found Ofast, override Ofast with O3. */ + unsigned int Ofast_index; + Ofast_index = find_opt_idx (decoded_options, decoded_options_count, + 0, decoded_options_count, OPT_Ofast); + while (Ofast_index != decoded_options_count) + { + const char *tmp_argv = "-O3"; + decode_cmdline_option (&tmp_argv, lang_mask, + &decoded_options[Ofast_index]); + warning (0, "%<-Ofast%> is degraded to %<-O3%> due to %qs", + fp_model_opt.orig_option_with_args_text); + Ofast_index = find_opt_idx (decoded_options, decoded_options_count, + 0, decoded_options_count, OPT_Ofast); + } + /* If found ffast-math before fp-model=precise/strict + it, cancel it. */ + unsigned int ffast_math_index; + ffast_math_index + = find_opt_idx (decoded_options, decoded_options_count, 0, + fp_model_index, OPT_ffast_math); + if (ffast_math_index != fp_model_index) + { + decoded_options_count + = remove_option (decoded_options, decoded_options_count, + ffast_math_index); + warning (0, "%<-ffast-math%> before %qs is canceled", + fp_model_opt.orig_option_with_args_text); + } + } + if (model == FP_MODEL_FAST) + { + /* If found -fno-fast-math after fp-model=fast, cancel this one. */ + unsigned int fno_fast_math_index; + fno_fast_math_index + = find_opt_idx (decoded_options, decoded_options_count, fp_model_index, + decoded_options_count, OPT_ffast_math); + if (fno_fast_math_index != decoded_options_count + && decoded_options[fno_fast_math_index].value == 0) + { + decoded_options_count + = remove_option (decoded_options, decoded_options_count, + fp_model_index); + warning (0, + "%<-fp-model=fast%> before %<-fno-fast-math%> is canceled"); + } + } + return decoded_options_count; +} + /* Filter out options canceled by the ones after them. */ static void prune_options (struct cl_decoded_option **decoded_options, - unsigned int *decoded_options_count) + unsigned int *decoded_options_count, + unsigned int lang_mask) { unsigned int old_decoded_options_count = *decoded_options_count; struct cl_decoded_option *old_decoded_options = *decoded_options; @@ -1127,7 +1226,12 @@ prune_options (struct cl_decoded_option **decoded_options, const struct cl_option *option; unsigned int fdiagnostics_color_idx = 0; + if (!diagnostic_ready_p ()) + diagnostic_initialize (global_dc, 0); + /* Remove arguments which are negated by others after them. */ + + unsigned int fp_model_index = old_decoded_options_count; new_decoded_options_count = 0; for (i = 0; i < old_decoded_options_count; i++) { @@ -1151,6 +1255,34 @@ prune_options (struct cl_decoded_option **decoded_options, fdiagnostics_color_idx = i; continue; + case OPT_fp_model_: + /* Only the last fp-model option will take effect. */ + unsigned int next_fp_model_idx; + next_fp_model_idx = find_opt_idx (old_decoded_options, + old_decoded_options_count, + i + 1, + old_decoded_options_count, + OPT_fp_model_); + if (next_fp_model_idx != old_decoded_options_count) + { + /* Found more than one fp-model, cancel this one. */ + if (old_decoded_options[i].value + != old_decoded_options[next_fp_model_idx].value) + { + warning (0, "%qs is overrided by %qs", + old_decoded_options[i]. + orig_option_with_args_text, + old_decoded_options[next_fp_model_idx]. + orig_option_with_args_text); + } + break; + } + else + { + /* Found the last fp-model option. */ + fp_model_index = new_decoded_options_count; + } + /* FALLTHRU. */ default: gcc_assert (opt_idx < cl_options_count); option = &cl_options[opt_idx]; @@ -1190,6 +1322,14 @@ keep: break; } } + if (fp_model_index < new_decoded_options_count) + { + new_decoded_options_count + = handle_fp_model_driver (new_decoded_options, + new_decoded_options_count, + fp_model_index, + lang_mask); + } if (fdiagnostics_color_idx >= 1) { diff --git a/gcc/opts.cc b/gcc/opts.cc index a97630d1c..b522ed7e2 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -328,6 +328,7 @@ static void set_debug_level (uint32_t dinfo, int extended, struct gcc_options *opts_set, location_t loc); static void set_fast_math_flags (struct gcc_options *opts, int set); +static void set_fp_model_flags (struct gcc_options *opts, int set); static void decode_d_option (const char *arg, struct gcc_options *opts, location_t loc, diagnostic_context *dc); static void set_unsafe_math_optimizations_flags (struct gcc_options *opts, @@ -2857,6 +2858,10 @@ common_handle_option (struct gcc_options *opts, set_fast_math_flags (opts, value); break; + case OPT_fp_model_: + set_fp_model_flags (opts, value); + break; + case OPT_funsafe_math_optimizations: set_unsafe_math_optimizations_flags (opts, value); break; @@ -3266,6 +3271,69 @@ set_fast_math_flags (struct gcc_options *opts, int set) } } +/* Handle fp-model options. */ +static void +set_fp_model_flags (struct gcc_options *opts, int set) +{ + enum fp_model model = (enum fp_model) set; + switch (model) + { + case FP_MODEL_FAST: + /* Equivalent to open ffast-math. */ + set_fast_math_flags (opts, 1); + break; + + case FP_MODEL_PRECISE: + /* Equivalent to close ffast-math. */ + set_fast_math_flags (opts, 0); + /* Turn on -frounding-math -fsignaling-nans. */ + if (!opts->frontend_set_flag_signaling_nans) + opts->x_flag_signaling_nans = 1; + if (!opts->frontend_set_flag_rounding_math) + opts->x_flag_rounding_math = 1; + opts->x_flag_expensive_optimizations = 0; + opts->x_flag_code_hoisting = 0; + opts->x_flag_predictive_commoning = 0; + opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF; + break; + + case FP_MODEL_EXCEPT: + if (!opts->frontend_set_flag_signaling_nans) + opts->x_flag_signaling_nans = 1; + if (!opts->frontend_set_flag_errno_math) + opts->x_flag_errno_math = 1; + if (!opts->frontend_set_flag_trapping_math) + opts->x_flag_trapping_math = 1; + opts->x_flag_fp_int_builtin_inexact = 1; + /* Also turn on ffpe-trap in fortran. */ + break; + + case FP_MODEL_STRICT: + /* Turn on both precise and except. */ + if (!opts->frontend_set_flag_signaling_nans) + opts->x_flag_signaling_nans = 1; + if (!opts->frontend_set_flag_rounding_math) + opts->x_flag_rounding_math = 1; + opts->x_flag_expensive_optimizations = 0; + opts->x_flag_code_hoisting = 0; + opts->x_flag_predictive_commoning = 0; + if (!opts->frontend_set_flag_errno_math) + opts->x_flag_errno_math = 1; + if (!opts->frontend_set_flag_trapping_math) + opts->x_flag_trapping_math = 1; + opts->x_flag_fp_int_builtin_inexact = 1; + opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF; + break; + + case FP_MODEL_NORMAL: + /* Do nothing. */ + break; + + default: + gcc_unreachable (); + } +} + /* When -funsafe-math-optimizations is set the following flags are set as well. */ static void -- 2.33.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2