From fe9458c280dbd6e8b892db4ca3b64185049c376b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 12 Aug 2020 17:00:41 +0200 Subject: [PATCH] Fix up flag_cunroll_grow_size handling in presence of optimize attr [PR96535] As the testcase in the PR shows (not included in the patch, as it seems quite fragile to observe unrolling in the IL), the introduction of flag_cunroll_grow_size broke optimize attribute related to loop unrolling. The problem is that the new option flag is set (if not set explicitly) only in process_options and in rs6000_option_override_internal (and there only if global_init_p). So, this means that while it is Optimization option, it will only be set based on the command line -funroll-loops/-O3/-fpeel-loops or -funroll-all-loops, which means that if command line does include any of those, it is enabled even for functions that will through optimize attribute have all of those disabled, and if command line does not include those, it will not be enabled for functions that will through optimize attribute have any of those enabled. process_options is called just once, so IMHO it should be handling only non-Optimization option adjustments (various other options suffer from that too, but as this is a regression from 10.1 on the 10 branch, changing those is not appropriate). Similarly, rs6000_option_override_internal is called only once (with global_init_p) and then for target attribute handling, but not for optimize attribute handling. This patch moves the unrolling related handling from process_options into finish_options which is invoked whenever the options are being finalized, and the rs6000 specific parts into the override_options_after_change hook which is called for optimize attribute handling (and unfortunately also th cfun changes, but what the hook does is cheap) and I've added a call to that from rs6000_override_options_internal, so it is also called on cmdline processing and for target attribute. Furthermore, it stops using AUTODETECT_VALUE, which can work only once, and instead uses the global_options_set.x_... flags. 2020-08-12 Jakub Jelinek PR tree-optimization/96535 * toplev.c (process_options): Move flag_unroll_loops and flag_cunroll_grow_size handling from here to ... * opts.c (finish_options): ... here. For flag_cunroll_grow_size, don't check for AUTODETECT_VALUE, but instead check opts_set->x_flag_cunroll_grow_size. * common.opt (funroll-completely-grow-size): Default to 0. * config/rs6000/rs6000.c (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): Redefine. (rs6000_override_options_after_change): New function. (rs6000_option_override_internal): Call it. Move there the flag_cunroll_grow_size, unroll_only_small_loops and flag_rename_registers handling. --- gcc/common.opt | 2 +- gcc/config/rs6000/rs6000.c | 50 +++++++++++++++++++++++++------------- gcc/opts.c | 20 +++++++++++---- gcc/toplev.c | 10 -------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/gcc/common.opt b/gcc/common.opt index c16d1faff88..084e28ee617 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2884,7 +2884,7 @@ Common Report Var(flag_unroll_all_loops) Optimization Perform loop unrolling for all loops. funroll-completely-grow-size -Undocumented Var(flag_cunroll_grow_size) Init(2) Optimization +Undocumented Var(flag_cunroll_grow_size) Optimization ; Internal undocumented flag, allow size growth during complete unrolling ; Nonzero means that loop optimizer may assume that the induction variables diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 40ee0a695f1..fe93cf6ff2b 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -1493,6 +1493,9 @@ static const struct attribute_spec rs6000_attribute_table[] = #undef TARGET_PROMOTE_FUNCTION_MODE #define TARGET_PROMOTE_FUNCTION_MODE rs6000_promote_function_mode +#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE +#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rs6000_override_options_after_change + #undef TARGET_RETURN_IN_MEMORY #define TARGET_RETURN_IN_MEMORY rs6000_return_in_memory @@ -3420,6 +3423,34 @@ rs6000_md_asm_adjust (vec &/*outputs*/, vec &/*inputs*/, return NULL; } +/* This target function is similar to the hook TARGET_OPTION_OVERRIDE + but is called when the optimize level is changed via an attribute or + pragma or when it is reset at the end of the code affected by the + attribute or pragma. It is not called at the beginning of compilation + when TARGET_OPTION_OVERRIDE is called so if you want to perform these + actions then, you should have TARGET_OPTION_OVERRIDE call + TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */ + +static void +rs6000_override_options_after_change (void) +{ + /* Explicit -funroll-loops turns -munroll-only-small-loops off, and + turns -frename-registers on. */ + if ((global_options_set.x_flag_unroll_loops && flag_unroll_loops) + || (global_options_set.x_flag_unroll_all_loops + && flag_unroll_all_loops)) + { + if (!global_options_set.x_unroll_only_small_loops) + unroll_only_small_loops = 0; + if (!global_options_set.x_flag_rename_registers) + flag_rename_registers = 1; + if (!global_options_set.x_flag_cunroll_grow_size) + flag_cunroll_grow_size = 1; + } + else if (!global_options_set.x_flag_cunroll_grow_size) + flag_cunroll_grow_size = flag_peel_loops || optimize >= 3; +} + /* Override command line options. Combine build-specific configuration information with options @@ -4647,23 +4678,6 @@ rs6000_option_override_internal (bool global_init_p) param_sched_pressure_algorithm, SCHED_PRESSURE_MODEL); - /* Explicit -funroll-loops turns -munroll-only-small-loops off, and - turns -frename-registers on. */ - if ((global_options_set.x_flag_unroll_loops && flag_unroll_loops) - || (global_options_set.x_flag_unroll_all_loops - && flag_unroll_all_loops)) - { - if (!global_options_set.x_unroll_only_small_loops) - unroll_only_small_loops = 0; - if (!global_options_set.x_flag_rename_registers) - flag_rename_registers = 1; - if (!global_options_set.x_flag_cunroll_grow_size) - flag_cunroll_grow_size = 1; - } - else - if (!global_options_set.x_flag_cunroll_grow_size) - flag_cunroll_grow_size = flag_peel_loops || optimize >= 3; - /* If using typedef char *va_list, signal that __builtin_va_start (&ap, 0) can be optimized to ap = __builtin_next_arg (0). */ @@ -4671,6 +4685,8 @@ rs6000_option_override_internal (bool global_init_p) targetm.expand_builtin_va_start = NULL; } + rs6000_override_options_after_change (); + /* If not explicitly specified via option, decide whether to generate indexed load/store instructions. A value of -1 indicates that the initial value of this variable has not been overwritten. During diff --git a/gcc/opts.c b/gcc/opts.c index 63c995ddde9..c5c60581f70 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1142,11 +1142,21 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* Control IPA optimizations based on different -flive-patching level. */ if (opts->x_flag_live_patching) - { - control_options_for_live_patching (opts, opts_set, - opts->x_flag_live_patching, - loc); - } + control_options_for_live_patching (opts, opts_set, + opts->x_flag_live_patching, + loc); + + /* Unrolling all loops implies that standard loop unrolling must also + be done. */ + if (opts->x_flag_unroll_all_loops) + opts->x_flag_unroll_loops = 1; + + /* Allow cunroll to grow size accordingly. */ + if (!opts_set->x_flag_cunroll_grow_size) + opts->x_flag_cunroll_grow_size + = (opts->x_flag_unroll_loops + || opts->x_flag_peel_loops + || opts->x_optimize >= 3); } #define LEFT_COLUMN 27 diff --git a/gcc/toplev.c b/gcc/toplev.c index 9a78af1e1cf..07457d08c3a 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1474,16 +1474,6 @@ process_options (void) flag_abi_version = 2; } - /* Unrolling all loops implies that standard loop unrolling must also - be done. */ - if (flag_unroll_all_loops) - flag_unroll_loops = 1; - - /* Allow cunroll to grow size accordingly. */ - if (flag_cunroll_grow_size == AUTODETECT_VALUE) - flag_cunroll_grow_size - = flag_unroll_loops || flag_peel_loops || optimize >= 3; - /* web and rename-registers help when run after loop unrolling. */ if (flag_web == AUTODETECT_VALUE) flag_web = flag_unroll_loops; -- 2.30.2