From ba948b37768c99cd8eb9f5b6fbd45fcf4bd15b78 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 14 Sep 2020 09:04:45 +0200 Subject: [PATCH] options: Save and restore opts_set for Optimization and Target options > Seems a latent issue. > Neither cl_optimization_{save,restore} nor cl_target_option_{save,restore} > (nor any of the target hooks they call) saves or restores any opts_set > values, so I think opts_set can be trusted only during option processing (if > at all), but not later. > So, short term a fix would be IMHO just stop using opts_set altogether in > arm_configure_build_target, it doesn't make much sense to me, it should test > if those strings are non-NULL instead, or at least do that when it is > invoked from arm_option_restore (e.g. could be done by calling it with > opts instead of &global_options_set ). > Longer term, the question is if cl_optimization_{save,restore} and > cl_target_option_{save,restore} shouldn't be changed not to only > save/restore the options, but also save the opts_set flags. > It could be done e.g. by adding a bool array or set of bool members > to struct cl_optimization and struct cl_target_option , or even more compact > by using bitmasks, pack each 64 adjacent option flags into a UHWI element > of an array. So, I've tried under debugger how it behaves and seems global_options_set is really an or of whether an option has been ever seen as explicit, either on the command line or in any of the option pragmas or optimize/target attributes seen so far, so it isn't something that can be relied on. The following patch implements the saving/restoring of the opts_set bits (though only for the options/variables saved by the generic options-save.c code, for the target specific stuff that isn't handled by the generic code the opts_set argument is now passed to the hook and the backends can choose e.g. to use a TargetSave variable to save the flags either individually or together in some bitmask (or ignore it if they never need opts_set for the options). This patch itself doesn't fix the testcase failing on arm, but a follow up patch will. 2020-09-14 Jakub Jelinek gcc/ * opt-read.awk: Also initialize extra_target_var_types array. * opth-gen.awk: Emit explicit_mask arrays to struct cl_optimization and cl_target_option. Adjust cl_optimization_save, cl_optimization_restore, cl_target_option_save and cl_target_option_restore declarations. * optc-save-gen.awk: Add opts_set argument to cl_optimization_save, cl_optimization_restore, cl_target_option_save and cl_target_option_restore functions and save or restore opts_set next to the opts values into or from explicit_mask arrays. In cl_target_option_eq and cl_optimization_option_eq compare explicit_mask arrays, in cl_target_option_hash and cl_optimization_hash hash them and in cl_target_option_stream_out, cl_target_option_stream_in, cl_optimization_stream_out and cl_optimization_stream_in stream them. * tree.h (build_optimization_node, build_target_option_node): Add opts_set argument. * tree.c (build_optimization_node): Add opts_set argument, pass it to cl_optimization_save. (build_target_option_node): Add opts_set argument, pass it to cl_target_option_save. * function.c (invoke_set_current_function_hook): Adjust cl_optimization_restore caller. * ipa-inline-transform.c (inline_call): Adjust cl_optimization_restore and build_optimization_node callers. * target.def (TARGET_OPTION_SAVE, TARGET_OPTION_RESTORE): Add opts_set argument. * target-globals.c (save_target_globals_default_opts): Adjust cl_optimization_restore callers. * toplev.c (process_options): Adjust build_optimization_node and cl_optimization_restore callers. (target_reinit): Adjust cl_optimization_restore caller. * tree-streamer-in.c (lto_input_ts_function_decl_tree_pointers): Adjust build_optimization_node and cl_optimization_restore callers. * doc/tm.texi: Updated. * config/aarch64/aarch64.c (aarch64_override_options): Adjust build_target_option_node caller. (aarch64_option_save, aarch64_option_restore): Add opts_set argument. (aarch64_set_current_function): Adjust cl_target_option_restore caller. (aarch64_option_valid_attribute_p): Adjust cl_target_option_save, cl_target_option_restore, cl_optimization_restore, build_optimization_node and build_target_option_node callers. * config/aarch64/aarch64-c.c (aarch64_pragma_target_parse): Adjust cl_target_option_restore and build_target_option_node callers. * config/arm/arm.c (arm_option_save, arm_option_restore): Add opts_set argument. (arm_option_override): Adjust cl_target_option_save, build_optimization_node and build_target_option_node callers. (arm_set_current_function): Adjust cl_target_option_restore caller. (arm_valid_target_attribute_tree): Adjust build_target_option_node caller. (add_attribute): Formatting fix. (arm_valid_target_attribute_p): Adjust cl_optimization_restore, cl_target_option_restore, arm_valid_target_attribute_tree and build_optimization_node callers. * config/arm/arm-c.c (arm_pragma_target_parse): Adjust cl_target_option_restore callers. * config/csky/csky.c (csky_option_override): Adjust build_target_option_node and cl_target_option_save callers. * config/gcn/gcn.c (gcn_fixup_accel_lto_options): Adjust build_optimization_node and cl_optimization_restore callers. * config/i386/i386-builtins.c (get_builtin_code_for_version): Adjust cl_target_option_save and cl_target_option_restore callers. * config/i386/i386-c.c (ix86_pragma_target_parse): Adjust build_target_option_node and cl_target_option_restore callers. * config/i386/i386-options.c (ix86_function_specific_save, ix86_function_specific_restore): Add opts_set arguments. (ix86_valid_target_attribute_tree): Adjust build_target_option_node caller. (ix86_valid_target_attribute_p): Adjust build_optimization_node, cl_optimization_restore, cl_target_option_restore, ix86_valid_target_attribute_tree and build_optimization_node callers. (ix86_option_override_internal): Adjust build_target_option_node caller. (ix86_reset_previous_fndecl, ix86_set_current_function): Adjust cl_target_option_restore callers. * config/i386/i386-options.h (ix86_function_specific_save, ix86_function_specific_restore): Add opts_set argument. * config/nios2/nios2.c (nios2_option_override): Adjust build_target_option_node caller. (nios2_option_save, nios2_option_restore): Add opts_set argument. (nios2_valid_target_attribute_tree): Adjust build_target_option_node caller. (nios2_valid_target_attribute_p): Adjust build_optimization_node, cl_optimization_restore, cl_target_option_save and cl_target_option_restore callers. (nios2_set_current_function, nios2_pragma_target_parse): Adjust cl_target_option_restore callers. * config/pru/pru.c (pru_option_override): Adjust build_target_option_node caller. (pru_set_current_function): Adjust cl_target_option_restore callers. * config/rs6000/rs6000.c (rs6000_debug_reg_global): Adjust cl_target_option_save caller. (rs6000_option_override_internal): Adjust build_target_option_node caller. (rs6000_valid_attribute_p): Adjust build_optimization_node, cl_optimization_restore, cl_target_option_save, cl_target_option_restore and build_target_option_node callers. (rs6000_pragma_target_parse): Adjust cl_target_option_restore and build_target_option_node callers. (rs6000_activate_target_options): Adjust cl_target_option_restore callers. (rs6000_function_specific_save, rs6000_function_specific_restore): Add opts_set argument. * config/s390/s390.c (s390_function_specific_restore): Likewise. (s390_option_override_internal): Adjust s390_function_specific_restore caller. (s390_option_override, s390_valid_target_attribute_tree): Adjust build_target_option_node caller. (s390_valid_target_attribute_p): Adjust build_optimization_node, cl_optimization_restore and cl_target_option_restore callers. (s390_activate_target_options): Adjust cl_target_option_restore caller. * config/s390/s390-c.c (s390_cpu_cpp_builtins): Adjust cl_target_option_save caller. (s390_pragma_target_parse): Adjust build_target_option_node and cl_target_option_restore callers. gcc/c-family/ * c-attribs.c (handle_optimize_attribute): Adjust cl_optimization_save, cl_optimization_restore and build_optimization_node callers. * c-pragma.c (handle_pragma_optimize): Adjust build_optimization_node caller. (handle_pragma_push_options): Adjust build_optimization_node and build_target_option_node callers. (handle_pragma_pop_options, handle_pragma_reset_options): Adjust cl_optimization_restore callers. gcc/go/ * go-gcc.cc (Gcc_backend::function): Adjust cl_optimization_save, cl_optimization_restore and build_optimization_node callers. gcc/ada/ * gcc-interface/trans.c (gigi): Adjust build_optimization_node caller. --- gcc/ada/gcc-interface/trans.c | 3 +- gcc/c-family/c-attribs.c | 9 +- gcc/c-family/c-pragma.c | 13 +- gcc/config/aarch64/aarch64-c.c | 4 +- gcc/config/aarch64/aarch64.c | 36 ++-- gcc/config/arm/arm-c.c | 4 +- gcc/config/arm/arm.c | 41 ++-- gcc/config/csky/csky.c | 4 +- gcc/config/gcn/gcn.c | 10 +- gcc/config/i386/i386-builtins.c | 6 +- gcc/config/i386/i386-c.c | 7 +- gcc/config/i386/i386-options.c | 30 +-- gcc/config/i386/i386-options.h | 4 +- gcc/config/nios2/nios2.c | 27 +-- gcc/config/pru/pru.c | 6 +- gcc/config/rs6000/rs6000.c | 36 ++-- gcc/config/s390/s390-c.c | 7 +- gcc/config/s390/s390.c | 26 ++- gcc/doc/tm.texi | 4 +- gcc/function.c | 3 +- gcc/go/go-gcc.cc | 8 +- gcc/ipa-inline-transform.c | 10 +- gcc/opt-read.awk | 1 + gcc/optc-save-gen.awk | 370 +++++++++++++++++++++++++++++++- gcc/opth-gen.awk | 19 +- gcc/target-globals.c | 4 +- gcc/target.def | 6 +- gcc/toplev.c | 7 +- gcc/tree-streamer-in.c | 9 +- gcc/tree.c | 14 +- gcc/tree.h | 12 +- 31 files changed, 583 insertions(+), 157 deletions(-) diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c index 9be12952c5b..3491451cc3d 100644 --- a/gcc/ada/gcc-interface/trans.c +++ b/gcc/ada/gcc-interface/trans.c @@ -691,7 +691,8 @@ gigi (Node_Id gnat_root, /* Save the current optimization options again after the above possible global_options changes. */ - optimization_default_node = build_optimization_node (&global_options); + optimization_default_node + = build_optimization_node (&global_options, &global_options_set); optimization_current_node = optimization_default_node; /* Now translate the compilation unit proper. */ diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 37214831538..4920725ca2d 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -4448,7 +4448,7 @@ handle_optimize_attribute (tree *node, tree name, tree args, tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node); /* Save current options. */ - cl_optimization_save (&cur_opts, &global_options); + cl_optimization_save (&cur_opts, &global_options, &global_options_set); /* If we previously had some optimization options, use them as the default. */ @@ -4460,16 +4460,17 @@ handle_optimize_attribute (tree *node, tree name, tree args, } if (old_opts) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (old_opts)); /* Parse options, and update the vector. */ parse_optimize_options (args, true); DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) - = build_optimization_node (&global_options); + = build_optimization_node (&global_options, &global_options_set); /* Restore current options. */ - cl_optimization_restore (&global_options, &cur_opts); + cl_optimization_restore (&global_options, &global_options_set, + &cur_opts); if (saved_global_options != NULL) { cl_optimization_compare (saved_global_options, &global_options); diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index e3169e68fb6..dc52ee8b003 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -987,7 +987,8 @@ handle_pragma_optimize (cpp_reader *ARG_UNUSED(dummy)) parse_optimize_options (args, false); current_optimize_pragma = chainon (current_optimize_pragma, args); - optimization_current_node = build_optimization_node (&global_options); + optimization_current_node + = build_optimization_node (&global_options, &global_options_set); c_cpp_builtins_optimize_pragma (parse_in, optimization_previous_node, optimization_current_node); @@ -1034,8 +1035,10 @@ handle_pragma_push_options (cpp_reader *ARG_UNUSED(dummy)) p->saved_global_options = XNEW (gcc_options); *p->saved_global_options = global_options; } - p->optimize_binary = build_optimization_node (&global_options); - p->target_binary = build_target_option_node (&global_options); + p->optimize_binary = build_optimization_node (&global_options, + &global_options_set); + p->target_binary = build_target_option_node (&global_options, + &global_options_set); /* Save optimization and target flags in string list format. */ p->optimize_strings = copy_list (current_optimize_pragma); @@ -1079,7 +1082,7 @@ handle_pragma_pop_options (cpp_reader *ARG_UNUSED(dummy)) if (p->optimize_binary != optimization_current_node) { tree old_optimize = optimization_current_node; - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (p->optimize_binary)); c_cpp_builtins_optimize_pragma (parse_in, old_optimize, p->optimize_binary); @@ -1122,7 +1125,7 @@ handle_pragma_reset_options (cpp_reader *ARG_UNUSED(dummy)) if (new_optimize != optimization_current_node) { tree old_optimize = optimization_current_node; - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (new_optimize)); c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize); optimization_current_node = new_optimize; diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c index 69691b3ad72..5e23328608b 100644 --- a/gcc/config/aarch64/aarch64-c.c +++ b/gcc/config/aarch64/aarch64-c.c @@ -242,12 +242,12 @@ aarch64_pragma_target_parse (tree args, tree pop_target) else { pop_target = pop_target ? pop_target : target_option_default_node; - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (pop_target)); } target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); aarch64_reset_previous_fndecl (); /* For the definitions, ensure all newly defined macros are considered diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b6d74496cd0..b251f3947e2 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -15034,7 +15034,7 @@ aarch64_override_options (void) /* Save these options as the default ones in case we push and pop them later while processing functions with potential target attributes. */ target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); } /* Implement targetm.override_options_after_change. */ @@ -15109,7 +15109,8 @@ initialize_aarch64_code_model (struct gcc_options *opts) /* Implement TARGET_OPTION_SAVE. */ static void -aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts) +aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts, + struct gcc_options */* opts_set */) { ptr->x_aarch64_override_tune_string = opts->x_aarch64_override_tune_string; ptr->x_aarch64_branch_protection_string @@ -15120,7 +15121,9 @@ aarch64_option_save (struct cl_target_option *ptr, struct gcc_options *opts) using the information saved in PTR. */ static void -aarch64_option_restore (struct gcc_options *opts, struct cl_target_option *ptr) +aarch64_option_restore (struct gcc_options *opts, + struct gcc_options */* opts_set */, + struct cl_target_option *ptr) { opts->x_explicit_tune_core = ptr->x_explicit_tune_core; selected_tune = aarch64_get_tune_cpu (ptr->x_explicit_tune_core); @@ -15210,7 +15213,8 @@ aarch64_set_current_function (tree fndecl) aarch64_previous_fndecl = fndecl; /* First set the target options. */ - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); aarch64_save_restore_target_globals (new_tree); } @@ -15709,17 +15713,18 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) } tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); - old_optimize = build_optimization_node (&global_options); + old_optimize + = build_optimization_node (&global_options, &global_options_set); func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); /* If the function changed the optimization levels as well as setting target options, start with the optimizations specified. */ if (func_optimize && func_optimize != old_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (func_optimize)); /* Save the current target options to restore at the end. */ - cl_target_option_save (&cur_target, &global_options); + cl_target_option_save (&cur_target, &global_options, &global_options_set); /* If fndecl already has some target attributes applied to it, unpack them so that we add this attribute on top of them, rather than @@ -15730,11 +15735,12 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) = TREE_TARGET_OPTION (existing_target); if (existing_options) - cl_target_option_restore (&global_options, existing_options); + cl_target_option_restore (&global_options, &global_options_set, + existing_options); } else - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (target_option_current_node)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (target_option_current_node)); ret = aarch64_process_target_attr (args); @@ -15754,12 +15760,14 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) aarch64_init_simd_builtins (); current_target_pragma = saved_current_target_pragma; } - new_target = build_target_option_node (&global_options); + new_target = build_target_option_node (&global_options, + &global_options_set); } else new_target = NULL; - new_optimize = build_optimization_node (&global_options); + new_optimize = build_optimization_node (&global_options, + &global_options_set); if (fndecl && ret) { @@ -15769,10 +15777,10 @@ aarch64_option_valid_attribute_p (tree fndecl, tree, tree args, int) DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; } - cl_target_option_restore (&global_options, &cur_target); + cl_target_option_restore (&global_options, &global_options_set, &cur_target); if (old_optimize != new_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (old_optimize)); return ret; } diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 7468a20bd98..899b890d7a3 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -390,7 +390,7 @@ arm_pragma_target_parse (tree args, tree pop_target) if (! args) { cur_tree = ((pop_target) ? pop_target : target_option_default_node); - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (cur_tree)); } else @@ -399,7 +399,7 @@ arm_pragma_target_parse (tree args, tree pop_target) &global_options_set); if (cur_tree == NULL_TREE) { - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (prev_tree)); return false; } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index bae8791dd9a..f4f32b66a3b 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -247,8 +247,9 @@ static tree arm_build_builtin_va_list (void); static void arm_expand_builtin_va_start (tree, rtx); static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *); static void arm_option_override (void); -static void arm_option_save (struct cl_target_option *, struct gcc_options *); -static void arm_option_restore (struct gcc_options *, +static void arm_option_save (struct cl_target_option *, struct gcc_options *, + struct gcc_options *); +static void arm_option_restore (struct gcc_options *, struct gcc_options *, struct cl_target_option *); static void arm_override_options_after_change (void); static void arm_option_print (FILE *, int, struct cl_target_option *); @@ -3043,7 +3044,8 @@ arm_override_options_after_change (void) /* Implement TARGET_OPTION_SAVE. */ static void -arm_option_save (struct cl_target_option *ptr, struct gcc_options *opts) +arm_option_save (struct cl_target_option *ptr, struct gcc_options *opts, + struct gcc_options */* opts_set */) { ptr->x_arm_arch_string = opts->x_arm_arch_string; ptr->x_arm_cpu_string = opts->x_arm_cpu_string; @@ -3052,13 +3054,13 @@ arm_option_save (struct cl_target_option *ptr, struct gcc_options *opts) /* Implement TARGET_OPTION_RESTORE. */ static void -arm_option_restore (struct gcc_options *opts, struct cl_target_option *ptr) +arm_option_restore (struct gcc_options *opts, struct gcc_options *opts_set, + struct cl_target_option *ptr) { opts->x_arm_arch_string = ptr->x_arm_arch_string; opts->x_arm_cpu_string = ptr->x_arm_cpu_string; opts->x_arm_tune_string = ptr->x_arm_tune_string; - arm_configure_build_target (&arm_active_target, ptr, &global_options_set, - false); + arm_configure_build_target (&arm_active_target, ptr, opts_set, false); } /* Reset options between modes that the user has specified. */ @@ -3457,7 +3459,7 @@ arm_option_override (void) arm_fpu_index = (enum fpu_type) fpu_index; } - cl_target_option_save (&opts, &global_options); + cl_target_option_save (&opts, &global_options, &global_options_set); arm_configure_build_target (&arm_active_target, &opts, &global_options_set, true); @@ -3682,7 +3684,8 @@ arm_option_override (void) flag_schedule_fusion = 0; /* Need to remember initial options before they are overriden. */ - init_optimize = build_optimization_node (&global_options); + init_optimize = build_optimization_node (&global_options, + &global_options_set); arm_options_perform_arch_sanity_checks (); arm_option_override_internal (&global_options, &global_options_set); @@ -3691,7 +3694,7 @@ arm_option_override (void) /* Create the default target_options structure. */ target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); /* Register global variables with the garbage collector. */ arm_add_gc_roots (); @@ -32332,7 +32335,8 @@ arm_set_current_function (tree fndecl) arm_previous_fndecl = fndecl; /* First set the target options. */ - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); save_restore_target_globals (new_tree); @@ -32534,7 +32538,7 @@ arm_valid_target_attribute_tree (tree args, struct gcc_options *opts, if (!arm_valid_target_attribute_rec (args, opts)) return NULL_TREE; - cl_target_option_save (&cl_opts, opts); + cl_target_option_save (&cl_opts, opts, opts_set); arm_configure_build_target (&arm_active_target, &cl_opts, opts_set, false); arm_option_check_internal (opts); /* Do any overrides, such as global options arch=xxx. @@ -32543,11 +32547,11 @@ arm_valid_target_attribute_tree (tree args, struct gcc_options *opts, arm_options_perform_arch_sanity_checks (); arm_option_override_internal (opts, opts_set); - return build_target_option_node (opts); + return build_target_option_node (opts, opts_set); } static void -add_attribute (const char * mode, tree *attributes) +add_attribute (const char * mode, tree *attributes) { size_t len = strlen (mode); tree value = build_string (len, mode); @@ -32599,7 +32603,7 @@ arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name), tree args, int ARG_UNUSED (flags)) { bool ret = true; - struct gcc_options func_options; + struct gcc_options func_options, func_options_set; tree cur_tree, new_optimize; gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE)); @@ -32615,22 +32619,23 @@ arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name), memset (&func_options, 0, sizeof (func_options)); init_options_struct (&func_options, NULL); lang_hooks.init_options_struct (&func_options); + memset (&func_options_set, 0, sizeof (func_options_set)); /* Initialize func_options to the defaults. */ - cl_optimization_restore (&func_options, + cl_optimization_restore (&func_options, &func_options_set, TREE_OPTIMIZATION (func_optimize)); - cl_target_option_restore (&func_options, + cl_target_option_restore (&func_options, &func_options_set, TREE_TARGET_OPTION (target_option_default_node)); /* Set func_options flags with new target mode. */ cur_tree = arm_valid_target_attribute_tree (args, &func_options, - &global_options_set); + &func_options_set); if (cur_tree == NULL_TREE) ret = false; - new_optimize = build_optimization_node (&func_options); + new_optimize = build_optimization_node (&func_options, &func_options_set); DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree; diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c index 7ba3ed3e74e..aa05365162a 100644 --- a/gcc/config/csky/csky.c +++ b/gcc/config/csky/csky.c @@ -2435,7 +2435,7 @@ csky_option_override (void) /* Create the default target_options structure. We need this early to configure the overall build target. */ target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); csky_configure_build_target (&csky_active_target, TREE_TARGET_OPTION (target_option_default_node), @@ -2600,7 +2600,7 @@ csky_option_override (void) /* Resynchronize the saved target options. */ cl_target_option_save (TREE_TARGET_OPTION (target_option_default_node), - &global_options); + &global_options, &global_options_set); #ifdef ENABLE_TPF_DEBUG /* Don't emit DWARF4 unless specifically selected. The TPF diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c index 84d1fd9a354..e868a8d9ae4 100644 --- a/gcc/config/gcn/gcn.c +++ b/gcc/config/gcn/gcn.c @@ -4975,26 +4975,28 @@ gcn_fixup_accel_lto_options (tree fndecl) if (!func_optimize) return; - tree old_optimize = build_optimization_node (&global_options); + tree old_optimize + = build_optimization_node (&global_options, &global_options_set); tree new_optimize; /* If the function changed the optimization levels as well as setting target options, start with the optimizations specified. */ if (func_optimize != old_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (func_optimize)); gcn_option_override (); /* The target attributes may also change some optimization flags, so update the optimization options if necessary. */ - new_optimize = build_optimization_node (&global_options); + new_optimize = build_optimization_node (&global_options, + &global_options_set); if (old_optimize != new_optimize) { DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (old_optimize)); } } diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c index 834438a6666..ca7a870896b 100644 --- a/gcc/config/i386/i386-builtins.c +++ b/gcc/config/i386/i386-builtins.c @@ -1866,7 +1866,8 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) before the ssse3 version. */ if (strstr (attrs_str, "arch=") != NULL) { - cl_target_option_save (&cur_target, &global_options); + cl_target_option_save (&cur_target, &global_options, + &global_options_set); target_node = ix86_valid_target_attribute_tree (decl, attrs, &global_options, &global_options_set, 0); @@ -1935,7 +1936,8 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) break; } - cl_target_option_restore (&global_options, &cur_target); + cl_target_option_restore (&global_options, &global_options_set, + &cur_target); if (predicate_list && arg_str == NULL) { diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index 2d61a0ce70a..3553a372427 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -603,7 +603,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, static bool ix86_pragma_target_parse (tree args, tree pop_target) { - tree prev_tree = build_target_option_node (&global_options); + tree prev_tree + = build_target_option_node (&global_options, &global_options_set); tree cur_tree; struct cl_target_option *prev_opt; struct cl_target_option *cur_opt; @@ -621,7 +622,7 @@ ix86_pragma_target_parse (tree args, tree pop_target) if (! args) { cur_tree = (pop_target ? pop_target : target_option_default_node); - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (cur_tree)); } else @@ -631,7 +632,7 @@ ix86_pragma_target_parse (tree args, tree pop_target) &global_options_set, 0); if (!cur_tree || cur_tree == error_mark_node) { - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (prev_tree)); return false; } diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index b93c338346f..2fabd200298 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -627,7 +627,8 @@ ix86_debug_options (void) void ix86_function_specific_save (struct cl_target_option *ptr, - struct gcc_options *opts) + struct gcc_options *opts, + struct gcc_options */* opts_set */) { ptr->arch = ix86_arch; ptr->schedule = ix86_schedule; @@ -754,6 +755,7 @@ set_ix86_tune_features (struct gcc_options *opts, void ix86_function_specific_restore (struct gcc_options *opts, + struct gcc_options */* opts_set */, struct cl_target_option *ptr) { enum processor_type old_tune = ix86_tune; @@ -1356,7 +1358,7 @@ ix86_valid_target_attribute_tree (tree fndecl, tree args, /* Save the current options unless we are validating options for #pragma. */ - t = build_target_option_node (opts); + t = build_target_option_node (opts, opts_set); opts->x_ix86_arch_string = orig_arch_string; opts->x_ix86_tune_string = orig_tune_string; @@ -1377,7 +1379,7 @@ ix86_valid_target_attribute_p (tree fndecl, tree args, int flags) { - struct gcc_options func_options; + struct gcc_options func_options, func_options_set; tree new_target, new_optimize; bool ret = true; @@ -1389,7 +1391,8 @@ ix86_valid_target_attribute_p (tree fndecl, && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0) return true; - tree old_optimize = build_optimization_node (&global_options); + tree old_optimize = build_optimization_node (&global_options, + &global_options_set); /* Get the optimization options of the current function. */ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); @@ -1401,21 +1404,22 @@ ix86_valid_target_attribute_p (tree fndecl, memset (&func_options, 0, sizeof (func_options)); init_options_struct (&func_options, NULL); lang_hooks.init_options_struct (&func_options); - - cl_optimization_restore (&func_options, + memset (&func_options_set, 0, sizeof (func_options_set)); + + cl_optimization_restore (&func_options, &func_options_set, TREE_OPTIMIZATION (func_optimize)); /* Initialize func_options to the default before its target options can be set. */ - cl_target_option_restore (&func_options, + cl_target_option_restore (&func_options, &func_options_set, TREE_TARGET_OPTION (target_option_default_node)); /* FLAGS == 1 is used for target_clones attribute. */ new_target = ix86_valid_target_attribute_tree (fndecl, args, &func_options, - &global_options_set, flags == 1); + &func_options_set, flags == 1); - new_optimize = build_optimization_node (&func_options); + new_optimize = build_optimization_node (&func_options, &func_options_set); if (new_target == error_mark_node) ret = false; @@ -2954,7 +2958,7 @@ ix86_option_override_internal (bool main_args_p, options. */ if (main_args_p) target_option_default_node = target_option_current_node - = build_target_option_node (opts); + = build_target_option_node (opts, opts_set); if (opts->x_flag_cf_protection != CF_NONE) opts->x_flag_cf_protection @@ -2991,7 +2995,8 @@ void ix86_reset_previous_fndecl (void) { tree new_tree = target_option_current_node; - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); if (TREE_TARGET_GLOBALS (new_tree)) restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); else if (new_tree == target_option_default_node) @@ -3250,7 +3255,8 @@ ix86_set_current_function (tree fndecl) if (old_tree != new_tree) { - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); if (TREE_TARGET_GLOBALS (new_tree)) restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); else if (new_tree == target_option_default_node) diff --git a/gcc/config/i386/i386-options.h b/gcc/config/i386/i386-options.h index 646d3d55515..9172936bbea 100644 --- a/gcc/config/i386/i386-options.h +++ b/gcc/config/i386/i386-options.h @@ -70,8 +70,10 @@ extern const char *stringop_alg_names[]; void ix86_add_new_builtins (HOST_WIDE_INT isa, HOST_WIDE_INT isa2); void ix86_function_specific_save (struct cl_target_option *, - struct gcc_options *opts); + struct gcc_options *opts, + struct gcc_options *opts_set); void ix86_function_specific_restore (struct gcc_options *opts, + struct gcc_options *opts_set, struct cl_target_option *); void ix86_function_specific_post_stream_in (struct cl_target_option *); void ix86_function_specific_print (FILE *, int, diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c index ba0a0a9ba43..55664358ba4 100644 --- a/gcc/config/nios2/nios2.c +++ b/gcc/config/nios2/nios2.c @@ -1448,7 +1448,7 @@ nios2_option_override (void) /* Save the initial options in case the user does function specific options. */ target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); } @@ -4137,7 +4137,8 @@ nios2_deregister_custom_code (unsigned int N) static void nios2_option_save (struct cl_target_option *ptr, - struct gcc_options *opts ATTRIBUTE_UNUSED) + struct gcc_options *opts ATTRIBUTE_UNUSED, + struct gcc_options *opts_set ATTRIBUTE_UNUSED) { unsigned int i; for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++) @@ -4150,6 +4151,7 @@ nios2_option_save (struct cl_target_option *ptr, static void nios2_option_restore (struct gcc_options *opts ATTRIBUTE_UNUSED, + struct gcc_options *opts_set ATTRIBUTE_UNUSED, struct cl_target_option *ptr) { unsigned int i; @@ -4310,7 +4312,7 @@ nios2_valid_target_attribute_tree (tree args) if (!nios2_valid_target_attribute_rec (args)) return NULL_TREE; nios2_custom_check_insns (); - return build_target_option_node (&global_options); + return build_target_option_node (&global_options, &global_options_set); } /* Hook to validate attribute((target("string"))). */ @@ -4321,21 +4323,22 @@ nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name), { struct cl_target_option cur_target; bool ret = true; - tree old_optimize = build_optimization_node (&global_options); + tree old_optimize + = build_optimization_node (&global_options, &global_options_set); tree new_target, new_optimize; tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); /* If the function changed the optimization levels as well as setting target options, start with the optimizations specified. */ if (func_optimize && func_optimize != old_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (func_optimize)); /* The target attributes may also change some optimization flags, so update the optimization options if necessary. */ - cl_target_option_save (&cur_target, &global_options); + cl_target_option_save (&cur_target, &global_options, &global_options_set); new_target = nios2_valid_target_attribute_tree (args); - new_optimize = build_optimization_node (&global_options); + new_optimize = build_optimization_node (&global_options, &global_options_set); if (!new_target) ret = false; @@ -4348,10 +4351,10 @@ nios2_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name), DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; } - cl_target_option_restore (&global_options, &cur_target); + cl_target_option_restore (&global_options, &global_options_set, &cur_target); if (old_optimize != new_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (old_optimize)); return ret; } @@ -4381,7 +4384,7 @@ nios2_set_current_function (tree fndecl) else if (new_tree) { - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (new_tree)); target_reinit (); } @@ -4391,7 +4394,7 @@ nios2_set_current_function (tree fndecl) struct cl_target_option *def = TREE_TARGET_OPTION (target_option_current_node); - cl_target_option_restore (&global_options, def); + cl_target_option_restore (&global_options, &global_options_set, def); target_reinit (); } } @@ -4409,7 +4412,7 @@ nios2_pragma_target_parse (tree args, tree pop_target) cur_tree = ((pop_target) ? pop_target : target_option_default_node); - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (cur_tree)); } else diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c index a715f6b07ce..39104e5f9cd 100644 --- a/gcc/config/pru/pru.c +++ b/gcc/config/pru/pru.c @@ -621,7 +621,7 @@ pru_option_override (void) /* Save the initial options in case the user does function specific options. */ target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); /* Due to difficulties in implementing the TI ABI with GCC, at least check and error-out if GCC cannot compile a @@ -2848,7 +2848,7 @@ pru_set_current_function (tree fndecl) else if (new_tree) { - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (new_tree)); target_reinit (); } @@ -2858,7 +2858,7 @@ pru_set_current_function (tree fndecl) struct cl_target_option *def = TREE_TARGET_OPTION (target_option_current_node); - cl_target_option_restore (&global_options, def); + cl_target_option_restore (&global_options, &global_options_set, def); target_reinit (); } } diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 20a4ba382bc..abbcc50e104 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2393,7 +2393,7 @@ rs6000_debug_reg_global (void) else fprintf (stderr, DEBUG_FMT_S, "tune", ""); - cl_target_option_save (&cl_opts, &global_options); + cl_target_option_save (&cl_opts, &global_options, &global_options_set); rs6000_print_isa_options (stderr, 0, "rs6000_isa_flags", rs6000_isa_flags); @@ -4769,7 +4769,7 @@ rs6000_option_override_internal (bool global_init_p) /* Save the initial options in case the user does function specific options */ if (global_init_p) target_option_default_node = target_option_current_node - = build_target_option_node (&global_options); + = build_target_option_node (&global_options, &global_options_set); /* If not explicitly specified via option, decide whether to generate the extra blr's required to preserve the link stack on some cpus (eg, 476). */ @@ -23662,18 +23662,19 @@ rs6000_valid_attribute_p (tree fndecl, && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0) return true; - old_optimize = build_optimization_node (&global_options); + old_optimize = build_optimization_node (&global_options, + &global_options_set); func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); /* If the function changed the optimization levels as well as setting target options, start with the optimizations specified. */ if (func_optimize && func_optimize != old_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (func_optimize)); /* The target attributes may also change some optimization flags, so update the optimization options if necessary. */ - cl_target_option_save (&cur_target, &global_options); + cl_target_option_save (&cur_target, &global_options, &global_options_set); rs6000_cpu_index = rs6000_tune_index = -1; ret = rs6000_inner_target_options (args, true); @@ -23681,12 +23682,14 @@ rs6000_valid_attribute_p (tree fndecl, if (ret) { ret = rs6000_option_override_internal (false); - new_target = build_target_option_node (&global_options); + new_target = build_target_option_node (&global_options, + &global_options_set); } else new_target = NULL; - new_optimize = build_optimization_node (&global_options); + new_optimize = build_optimization_node (&global_options, + &global_options_set); if (!new_target) ret = false; @@ -23699,10 +23702,10 @@ rs6000_valid_attribute_p (tree fndecl, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize; } - cl_target_option_restore (&global_options, &cur_target); + cl_target_option_restore (&global_options, &global_options_set, &cur_target); if (old_optimize != new_optimize) - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (old_optimize)); return ret; @@ -23716,7 +23719,8 @@ rs6000_valid_attribute_p (tree fndecl, bool rs6000_pragma_target_parse (tree args, tree pop_target) { - tree prev_tree = build_target_option_node (&global_options); + tree prev_tree = build_target_option_node (&global_options, + &global_options_set); tree cur_tree; struct cl_target_option *prev_opt, *cur_opt; HOST_WIDE_INT prev_flags, cur_flags, diff_flags; @@ -23745,7 +23749,7 @@ rs6000_pragma_target_parse (tree args, tree pop_target) cur_tree = ((pop_target) ? pop_target : target_option_default_node); - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (cur_tree)); } else @@ -23753,7 +23757,8 @@ rs6000_pragma_target_parse (tree args, tree pop_target) rs6000_cpu_index = rs6000_tune_index = -1; if (!rs6000_inner_target_options (args, false) || !rs6000_option_override_internal (false) - || (cur_tree = build_target_option_node (&global_options)) + || (cur_tree = build_target_option_node (&global_options, + &global_options_set)) == NULL_TREE) { if (TARGET_DEBUG_BUILTIN || TARGET_DEBUG_TARGET) @@ -23808,7 +23813,8 @@ static GTY(()) tree rs6000_previous_fndecl; void rs6000_activate_target_options (tree new_tree) { - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); if (TREE_TARGET_GLOBALS (new_tree)) restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); else if (new_tree == target_option_default_node) @@ -23899,7 +23905,8 @@ rs6000_set_current_function (tree fndecl) static void rs6000_function_specific_save (struct cl_target_option *ptr, - struct gcc_options *opts) + struct gcc_options *opts, + struct gcc_options */* opts_set */) { ptr->x_rs6000_isa_flags = opts->x_rs6000_isa_flags; ptr->x_rs6000_isa_flags_explicit = opts->x_rs6000_isa_flags_explicit; @@ -23909,6 +23916,7 @@ rs6000_function_specific_save (struct cl_target_option *ptr, static void rs6000_function_specific_restore (struct gcc_options *opts, + struct gcc_options */* opts_set */, struct cl_target_option *ptr) { diff --git a/gcc/config/s390/s390-c.c b/gcc/config/s390/s390-c.c index f236c55e006..8e5f2c9a394 100644 --- a/gcc/config/s390/s390-c.c +++ b/gcc/config/s390/s390-c.c @@ -388,7 +388,7 @@ s390_cpu_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__s390x__"); if (TARGET_LONG_DOUBLE_128) cpp_define (pfile, "__LONG_DOUBLE_128__"); - cl_target_option_save (&opts, &global_options); + cl_target_option_save (&opts, &global_options, &global_options_set); s390_cpu_cpp_builtins_internal (pfile, &opts, NULL); } @@ -400,7 +400,8 @@ s390_cpu_cpp_builtins (cpp_reader *pfile) static bool s390_pragma_target_parse (tree args, tree pop_target) { - tree prev_tree = build_target_option_node (&global_options); + tree prev_tree = build_target_option_node (&global_options, + &global_options_set); tree cur_tree; if (! args) @@ -411,7 +412,7 @@ s390_pragma_target_parse (tree args, tree pop_target) &global_options_set, true); if (!cur_tree || cur_tree == error_mark_node) { - cl_target_option_restore (&global_options, + cl_target_option_restore (&global_options, &global_options_set, TREE_TARGET_OPTION (prev_tree)); return false; } diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 5488a5dc5e8..c762840c7e0 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -15207,6 +15207,7 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop) static void s390_function_specific_restore (struct gcc_options *opts, + struct gcc_options */* opts_set */, struct cl_target_option *ptr ATTRIBUTE_UNUSED) { opts->x_s390_cost_pointer = (long)processor_table[opts->x_s390_tune].cost; @@ -15230,7 +15231,7 @@ s390_override_options_after_change (void) static void s390_option_override_internal (struct gcc_options *opts, - const struct gcc_options *opts_set) + struct gcc_options *opts_set) { /* Architecture mode defaults according to ABI. */ if (!(opts_set->x_target_flags & MASK_ZARCH)) @@ -15444,7 +15445,7 @@ s390_option_override_internal (struct gcc_options *opts, /* Call target specific restore function to do post-init work. At the moment, this just sets opts->x_s390_cost_pointer. */ - s390_function_specific_restore (opts, NULL); + s390_function_specific_restore (opts, opts_set, NULL); /* Check whether -mfentry is supported. It cannot be used in 31-bit mode, because 31-bit PLT stubs assume that %r12 contains GOT address, which is @@ -15513,7 +15514,8 @@ s390_option_override (void) /* Save the initial options in case the user does function specific options. */ - target_option_default_node = build_target_option_node (&global_options); + target_option_default_node + = build_target_option_node (&global_options, &global_options_set); target_option_current_node = target_option_default_node; /* This cannot reside in s390_option_optimization_table since HAVE_prefetch @@ -15803,7 +15805,7 @@ s390_valid_target_attribute_tree (tree args, s390_option_override_internal (opts, &new_opts_set); /* Save the current options unless we are validating options for #pragma. */ - t = build_target_option_node (opts); + t = build_target_option_node (opts, &new_opts_set); } return t; } @@ -15816,7 +15818,7 @@ s390_valid_target_attribute_p (tree fndecl, tree args, int ARG_UNUSED (flags)) { - struct gcc_options func_options; + struct gcc_options func_options, func_options_set; tree new_target, new_optimize; bool ret = true; @@ -15828,7 +15830,8 @@ s390_valid_target_attribute_p (tree fndecl, && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "default") == 0) return true; - tree old_optimize = build_optimization_node (&global_options); + tree old_optimize + = build_optimization_node (&global_options, &global_options_set); /* Get the optimization options of the current function. */ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); @@ -15840,19 +15843,21 @@ s390_valid_target_attribute_p (tree fndecl, memset (&func_options, 0, sizeof (func_options)); init_options_struct (&func_options, NULL); lang_hooks.init_options_struct (&func_options); + memset (&func_options_set, 0, sizeof (func_options_set)); - cl_optimization_restore (&func_options, TREE_OPTIMIZATION (func_optimize)); + cl_optimization_restore (&func_options, &func_options_set, + TREE_OPTIMIZATION (func_optimize)); /* Initialize func_options to the default before its target options can be set. */ - cl_target_option_restore (&func_options, + cl_target_option_restore (&func_options, &func_options_set, TREE_TARGET_OPTION (target_option_default_node)); new_target = s390_valid_target_attribute_tree (args, &func_options, &global_options_set, (args == current_target_pragma)); - new_optimize = build_optimization_node (&func_options); + new_optimize = build_optimization_node (&func_options, &func_options_set); if (new_target == error_mark_node) ret = false; else if (fndecl && new_target) @@ -15990,7 +15995,8 @@ s390_indirect_branch_settings (tree fndecl) void s390_activate_target_options (tree new_tree) { - cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + cl_target_option_restore (&global_options, &global_options_set, + TREE_TARGET_OPTION (new_tree)); if (TREE_TARGET_GLOBALS (new_tree)) restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); else if (new_tree == target_option_default_node) diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index fb902b36d99..8e9e7701531 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -10493,14 +10493,14 @@ the function declaration to hold a pointer to a target-specific @code{struct cl_target_option} structure. @end deftypefn -@deftypefn {Target Hook} void TARGET_OPTION_SAVE (struct cl_target_option *@var{ptr}, struct gcc_options *@var{opts}) +@deftypefn {Target Hook} void TARGET_OPTION_SAVE (struct cl_target_option *@var{ptr}, struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set}) This hook is called to save any additional target-specific information in the @code{struct cl_target_option} structure for function-specific options from the @code{struct gcc_options} structure. @xref{Option file format}. @end deftypefn -@deftypefn {Target Hook} void TARGET_OPTION_RESTORE (struct gcc_options *@var{opts}, struct cl_target_option *@var{ptr}) +@deftypefn {Target Hook} void TARGET_OPTION_RESTORE (struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set}, struct cl_target_option *@var{ptr}) This hook is called to restore any additional target-specific information in the @code{struct cl_target_option} structure for function-specific options to the @code{struct gcc_options} structure. diff --git a/gcc/function.c b/gcc/function.c index 2c8fa217f1f..de5947937eb 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4664,7 +4664,8 @@ invoke_set_current_function_hook (tree fndecl) if (optimization_current_node != opts) { optimization_current_node = opts; - cl_optimization_restore (&global_options, TREE_OPTIMIZATION (opts)); + cl_optimization_restore (&global_options, &global_options_set, + TREE_OPTIMIZATION (opts)); } targetm.set_current_function (fndecl); diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index fd96481b12d..505fb1528fa 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -3281,13 +3281,15 @@ Gcc_backend::function(Btype* fntype, const std::string& name, if (pos == name.length()) { struct cl_optimization cur_opts; - cl_optimization_save(&cur_opts, &global_options); + cl_optimization_save(&cur_opts, &global_options, + &global_options_set); global_options.x_optimize_size = 1; global_options.x_optimize_fast = 0; global_options.x_optimize_debug = 0; DECL_FUNCTION_SPECIFIC_OPTIMIZATION(decl) = - build_optimization_node(&global_options); - cl_optimization_restore(&global_options, &cur_opts); + build_optimization_node(&global_options, &global_options_set); + cl_optimization_restore(&global_options, &global_options_set, + &cur_opts); } } diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index e9e21cc0296..5e37e612bfd 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -380,14 +380,15 @@ inline_call (struct cgraph_edge *e, bool update_original, && opt_for_fn (to->decl, flag_strict_aliasing)) { struct gcc_options opts = global_options; + struct gcc_options opts_set = global_options_set; - cl_optimization_restore (&opts, opts_for_fn (to->decl)); + cl_optimization_restore (&opts, &opts_set, opts_for_fn (to->decl)); opts.x_flag_strict_aliasing = false; if (dump_file) fprintf (dump_file, "Dropping flag_strict_aliasing on %s\n", to->dump_name ()); DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl) - = build_optimization_node (&opts); + = build_optimization_node (&opts, &opts_set); reload_optimization_node = true; } @@ -420,8 +421,9 @@ inline_call (struct cgraph_edge *e, bool update_original, != opt_for_fn (to->decl, flag_errno_math)) { struct gcc_options opts = global_options; + struct gcc_options opts_set = global_options_set; - cl_optimization_restore (&opts, opts_for_fn (to->decl)); + cl_optimization_restore (&opts, &opts_set, opts_for_fn (to->decl)); opts.x_flag_rounding_math = opt_for_fn (callee->decl, flag_rounding_math); opts.x_flag_trapping_math @@ -448,7 +450,7 @@ inline_call (struct cgraph_edge *e, bool update_original, fprintf (dump_file, "Copying FP flags from %s to %s\n", callee->dump_name (), to->dump_name ()); DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl) - = build_optimization_node (&opts); + = build_optimization_node (&opts, &opts_set); reload_optimization_node = true; } } diff --git a/gcc/opt-read.awk b/gcc/opt-read.awk index 9bb9dfcf6ca..b113291f9a4 100644 --- a/gcc/opt-read.awk +++ b/gcc/opt-read.awk @@ -71,6 +71,7 @@ BEGIN { n_target_save++ extra_target_vars[n_extra_target_vars] = name + extra_target_var_types[n_extra_target_vars] = type n_extra_target_vars++ } else if ($1 == "HeaderInclude") { diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index ff173fee404..2e4787ec57e 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -78,7 +78,8 @@ for (i = 0; i < n_opts; i++) { print "/* Save optimization variables into a structure. */" print "void"; -print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts)"; +print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts,"; +print " struct gcc_options *opts_set)"; print "{"; n_opt_char = 4; @@ -116,9 +117,10 @@ for (i = 0; i < n_opts; i++) { else if (otype ~ "^((un)?signed +)?short *$") var_opt_short[n_opt_short++] = name; - else if (otype ~ ("^enum +[_" alnum "]+ *")) + else if (otype ~ ("^enum +[_" alnum "]+ *")) { + var_opt_enum_type[n_opt_enum] = otype; var_opt_enum[n_opt_enum++] = name; - + } else if (otype ~ "^((un)?signed +)?char *$") { var_opt_char[n_opt_char++] = name; if (otype ~ "^unsigned +char *$") @@ -166,12 +168,88 @@ for (i = 0; i < n_opt_string; i++) { print " ptr->x_" var_opt_string[i] " = opts->x_" var_opt_string[i] ";"; } +print ""; +print " unsigned HOST_WIDE_INT mask = 0;"; + +j = 0; +k = 0; +for (i = 0; i < n_opt_other; i++) { + print " if (opts_set->x_" var_opt_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_opt_int; i++) { + print " if (opts_set->x_" var_opt_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_opt_enum; i++) { + print " if (opts_set->x_" var_opt_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_opt_short; i++) { + print " if (opts_set->x_" var_opt_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_opt_char; i++) { + print " if (opts_set->x_" var_opt_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_opt_string; i++) { + print " if (opts_set->x_" var_opt_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +if (j != 0) { + print " ptr->explicit_mask[" k "] = mask;"; +} + print "}"; print ""; print "/* Restore optimization options from a structure. */"; print "void"; -print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)"; +print "cl_optimization_restore (struct gcc_options *opts, struct gcc_options *opts_set,"; +print " struct cl_optimization *ptr)"; print "{"; for (i = 0; i < n_opt_other; i++) { @@ -198,6 +276,77 @@ for (i = 0; i < n_opt_string; i++) { print " opts->x_" var_opt_string[i] " = ptr->x_" var_opt_string[i] ";"; } +print ""; +print " unsigned HOST_WIDE_INT mask;"; + +j = 64; +k = 0; +for (i = 0; i < n_opt_other; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_other[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_opt_int; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_int[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_opt_enum; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_enum[i] " = static_cast<" var_opt_enum_type[i] ">((mask & 1) != 0);"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_opt_short; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_short[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_opt_char; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_char[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_opt_string; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_opt_string[i] " = (mask & 1) ? \"\" : nullptr;"; + print " mask >>= 1;" + j++; +} + print " targetm.override_options_after_change ();"; print "}"; @@ -344,7 +493,8 @@ print "}"; print ""; print "/* Save selected option variables into a structure. */" print "void"; -print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts)"; +print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts,"; +print " struct gcc_options *opts_set)"; print "{"; n_target_char = 0; @@ -372,9 +522,10 @@ if (have_save) { else if (otype ~ "^((un)?signed +)?short *$") var_target_short[n_target_short++] = name; - else if (otype ~ ("^enum +[_" alnum "]+ *$")) + else if (otype ~ ("^enum +[_" alnum "]+ *$")) { + var_target_enum_type[n_target_enum] = otype; var_target_enum[n_target_enum++] = name; - + } else if (otype ~ "^((un)?signed +)?char *$") { var_target_char[n_target_char++] = name; if (otype ~ "^unsigned +char *$") @@ -409,7 +560,7 @@ if (have_assert) print ""; print " if (targetm.target_option.save)"; -print " targetm.target_option.save (ptr, opts);"; +print " targetm.target_option.save (ptr, opts, opts_set);"; print ""; for (i = 0; i < n_extra_target_vars; i++) { @@ -440,12 +591,99 @@ for (i = 0; i < n_target_string; i++) { print " ptr->x_" var_target_string[i] " = opts->x_" var_target_string[i] ";"; } +print ""; +print " unsigned HOST_WIDE_INT mask = 0;"; + +j = 0; +k = 0; +for (i = 0; i < n_extra_target_vars; i++) { + print " if (opts_set->x_" extra_target_vars[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_other; i++) { + print " if (opts_set->x_" var_target_other[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_enum; i++) { + print " if (opts_set->x_" var_target_enum[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_int; i++) { + print " if (opts_set->x_" var_target_int[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_short; i++) { + print " if (opts_set->x_" var_target_short[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_char; i++) { + print " if (opts_set->x_" var_target_char[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +for (i = 0; i < n_target_string; i++) { + print " if (opts_set->x_" var_target_string[i] ") mask |= HOST_WIDE_INT_1U << " j ";"; + j++; + if (j == 64) { + print " ptr->explicit_mask[" k "] = mask;"; + print " mask = 0;"; + j = 0; + k++; + } +} + +if (j != 0) { + print " ptr->explicit_mask[" k "] = mask;"; +} + print "}"; print ""; print "/* Restore selected current options from a structure. */"; print "void"; -print "cl_target_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)"; +print "cl_target_option_restore (struct gcc_options *opts, struct gcc_options *opts_set,"; +print " struct cl_target_option *ptr)"; print "{"; for (i = 0; i < n_extra_target_vars; i++) { @@ -476,11 +714,101 @@ for (i = 0; i < n_target_string; i++) { print " opts->x_" var_target_string[i] " = ptr->x_" var_target_string[i] ";"; } +print ""; +print " unsigned HOST_WIDE_INT mask;"; + +j = 64; +k = 0; +for (i = 0; i < n_extra_target_vars; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + if (extra_target_var_types[i] ~ ("^enum +[_" alnum "]+ *$")) { + print " opts_set->x_" extra_target_vars[i] " = static_cast<" extra_target_var_types[i] ">((mask & 1) != 0);"; + } + else if (extra_target_var_types[i] ~ "^const char \\**$") { + print " opts_set->x_" extra_target_vars[i] " = (mask & 1) ? \"\" : nullptr;"; + } + else { + print " opts_set->x_" extra_target_vars[i] " = (mask & 1) != 0;"; + } + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_other; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_other[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_enum; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_enum[i] " = static_cast<" var_target_enum_type[i] ">((mask & 1) != 0);"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_int; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_int[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_short; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_short[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_char; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_char[i] " = (mask & 1) != 0;"; + print " mask >>= 1;" + j++; +} + +for (i = 0; i < n_target_string; i++) { + if (j == 64) { + print " mask = ptr->explicit_mask[" k "];"; + k++; + j = 0; + } + print " opts_set->x_" var_target_string[i] " = (mask & 1) ? \"\" : nullptr;"; + print " mask >>= 1;" + j++; +} + # This must occur after the normal variables in case the code depends on those # variables. print ""; print " if (targetm.target_option.restore)"; -print " targetm.target_option.restore (opts, ptr);"; +print " targetm.target_option.restore (opts, opts_set, ptr);"; print "}"; @@ -726,6 +1054,10 @@ for (i = 0; i < n_target_val; i++) { print " return false;"; } +print " for (size_t i = 0; i < sizeof (ptr1->explicit_mask) / sizeof (ptr1->explicit_mask[0]); i++)"; +print " if (ptr1->explicit_mask[i] != ptr2->explicit_mask[i])"; +print " return false;" + print " return true;"; print "}"; @@ -754,6 +1086,8 @@ for (i = 0; i < n_target_val; i++) { name = var_target_val[i] print " hstate.add_hwi (ptr->" name");"; } +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " hstate.add_hwi (ptr->explicit_mask[i]);"; print " return hstate.end ();"; print "}"; @@ -778,6 +1112,10 @@ for (i = 0; i < n_target_val; i++) { name = var_target_val[i] print " bp_pack_value (bp, ptr->" name", 64);"; } + +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " bp_pack_value (bp, ptr->explicit_mask[i], 64);"; + print "}"; print ""; @@ -804,6 +1142,9 @@ for (i = 0; i < n_target_val; i++) { print " ptr->" name" = (" var_target_val_type[i] ") bp_unpack_value (bp, 64);"; } +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " ptr->explicit_mask[i] = bp_unpack_value (bp, 64);"; + print "}"; print "/* free heap memory used by target options */"; @@ -869,6 +1210,8 @@ for (i = 0; i < n_opt_val; i++) { else print " hstate.add_hwi (ptr->" name");"; } +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " hstate.add_hwi (ptr->explicit_mask[i]);"; print " return hstate.end ();"; print "}"; @@ -896,6 +1239,9 @@ for (i = 0; i < n_opt_val; i++) { print " return false;"; } } +print " for (size_t i = 0; i < sizeof (ptr1->explicit_mask) / sizeof (ptr1->explicit_mask[0]); i++)"; +print " if (ptr1->explicit_mask[i] != ptr2->explicit_mask[i])"; +print " return false;" print " return true;"; print "}"; @@ -914,6 +1260,8 @@ for (i = 0; i < n_opt_val; i++) { else print " bp_pack_value (bp, ptr->" name", 64);"; } +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " bp_pack_value (bp, ptr->explicit_mask[i], 64);"; print "}"; print ""; @@ -935,6 +1283,8 @@ for (i = 0; i < n_opt_val; i++) { else print " ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_value (bp, 64);"; } +print " for (size_t i = 0; i < sizeof (ptr->explicit_mask) / sizeof (ptr->explicit_mask[0]); i++)"; +print " ptr->explicit_mask[i] = bp_unpack_value (bp, 64);"; print "}"; print "/* Free heap memory used by optimization options */"; print "void"; diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index 472fd591413..8fec607041e 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -137,6 +137,7 @@ n_opt_short = 0; n_opt_int = 0; n_opt_enum = 0; n_opt_other = 0; +n_opt_explicit = 4; var_opt_char[0] = "unsigned char x_optimize"; var_opt_char[1] = "unsigned char x_optimize_size"; var_opt_char[2] = "unsigned char x_optimize_debug"; @@ -152,6 +153,7 @@ for (i = 0; i < n_opts; i++) { continue; var_opt_seen[name]++; + n_opt_explicit++; otype = var_type_struct(flags[i]); if (otype ~ "^((un)?signed +)?int *$") var_opt_int[n_opt_int++] = otype "x_" name; @@ -190,6 +192,9 @@ for (i = 0; i < n_opt_char; i++) { print " " var_opt_char[i] ";"; } +print " /* " n_opt_explicit " members */"; +print " unsigned HOST_WIDE_INT explicit_mask[" int ((n_opt_explicit + 63) / 64) "];"; + print "};"; print ""; @@ -203,6 +208,7 @@ n_target_short = 0; n_target_int = 0; n_target_enum = 0; n_target_other = 0; +n_target_explicit = n_extra_target_vars; for (i = 0; i < n_target_save; i++) { if (target_save_decl[i] ~ "^((un)?signed +)?int +[_" alnum "]+$") @@ -232,6 +238,7 @@ if (have_save) { continue; var_save_seen[name]++; + n_target_explicit++; otype = var_type_struct(flags[i]) if (otype ~ "^((un)?signed +)?int *$") var_target_int[n_target_int++] = otype "x_" name; @@ -251,6 +258,7 @@ if (have_save) { } } else { var_target_int[n_target_int++] = "int x_target_flags"; + n_target_explicit++; } for (i = 0; i < n_target_other; i++) { @@ -273,14 +281,17 @@ for (i = 0; i < n_target_char; i++) { print " " var_target_char[i] ";"; } +print " /* " n_target_explicit " members */"; +print " unsigned HOST_WIDE_INT explicit_mask[" int ((n_target_explicit + 63) / 64) "];"; + print "};"; print ""; print ""; print "/* Save optimization variables into a structure. */" -print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);"; +print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *, struct gcc_options *);"; print ""; print "/* Restore optimization variables from a structure. */"; -print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);"; +print "extern void cl_optimization_restore (struct gcc_options *, struct gcc_options *, struct cl_optimization *);"; print ""; print "/* Print optimization variables from a structure. */"; print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);"; @@ -289,10 +300,10 @@ print "/* Print different optimization variables from structures provided as arg print "extern void cl_optimization_print_diff (FILE *, int, cl_optimization *ptr1, cl_optimization *ptr2);"; print ""; print "/* Save selected option variables into a structure. */" -print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);"; +print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *, struct gcc_options *);"; print ""; print "/* Restore selected option variables from a structure. */" -print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);"; +print "extern void cl_target_option_restore (struct gcc_options *, struct gcc_options *, struct cl_target_option *);"; print ""; print "/* Print target option variables from a structure. */"; print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);"; diff --git a/gcc/target-globals.c b/gcc/target-globals.c index 3d8e8a4ae9a..c7fcd70f776 100644 --- a/gcc/target-globals.c +++ b/gcc/target-globals.c @@ -108,11 +108,11 @@ save_target_globals_default_opts () attribute. */ optimization_current_node = optimization_default_node; cl_optimization_restore - (&global_options, + (&global_options, &global_options_set, TREE_OPTIMIZATION (optimization_default_node)); globals = save_target_globals (); optimization_current_node = opts; - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (opts)); return globals; } diff --git a/gcc/target.def b/gcc/target.def index c11cab8891f..fc4563d144c 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6376,7 +6376,8 @@ DEFHOOK in the @code{struct cl_target_option} structure for function-specific\n\ options from the @code{struct gcc_options} structure.\n\ @xref{Option file format}.", - void, (struct cl_target_option *ptr, struct gcc_options *opts), NULL) + void, (struct cl_target_option *ptr, struct gcc_options *opts, + struct gcc_options *opts_set), NULL) /* Function to restore any extra target state from the target options structure. */ @@ -6385,7 +6386,8 @@ DEFHOOK "This hook is called to restore any additional target-specific\n\ information in the @code{struct cl_target_option} structure for\n\ function-specific options to the @code{struct gcc_options} structure.", - void, (struct gcc_options *opts, struct cl_target_option *ptr), NULL) + void, (struct gcc_options *opts, struct gcc_options *opts_set, + struct cl_target_option *ptr), NULL) /* Function to update target-specific option information after being streamed in. */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 07457d08c3a..cdd4b5b4f92 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1867,7 +1867,8 @@ process_options (void) DK_ERROR, UNKNOWN_LOCATION); /* Save the current optimization options. */ - optimization_default_node = build_optimization_node (&global_options); + optimization_default_node + = build_optimization_node (&global_options, &global_options_set); optimization_current_node = optimization_default_node; if (flag_checking >= 2) @@ -2075,7 +2076,7 @@ target_reinit (void) { optimization_current_node = optimization_default_node; cl_optimization_restore - (&global_options, + (&global_options, &global_options_set, TREE_OPTIMIZATION (optimization_default_node)); } this_fn_optabs = this_target_optabs; @@ -2107,7 +2108,7 @@ target_reinit (void) if (saved_optimization_current_node != optimization_default_node) { optimization_current_node = saved_optimization_current_node; - cl_optimization_restore (&global_options, + cl_optimization_restore (&global_options, &global_options_set, TREE_OPTIMIZATION (optimization_current_node)); } this_fn_optabs = saved_this_fn_optabs; diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index a456709ffd8..2a8817bd282 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -800,11 +800,12 @@ lto_input_ts_function_decl_tree_pointers (class lto_input_block *ib, tree opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr); if (opts) { - struct gcc_options tmp; + struct gcc_options tmp, tmp_set; init_options_struct (&tmp, NULL); - cl_optimization_restore (&tmp, TREE_OPTIMIZATION (opts)); - finish_options (&tmp, &global_options_set, UNKNOWN_LOCATION); - opts = build_optimization_node (&tmp); + memset (&tmp_set, 0, sizeof (tmp_set)); + cl_optimization_restore (&tmp, &tmp_set, TREE_OPTIMIZATION (opts)); + finish_options (&tmp, &tmp_set, UNKNOWN_LOCATION); + opts = build_optimization_node (&tmp, &tmp_set); DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = opts; } } diff --git a/gcc/tree.c b/gcc/tree.c index 45aacadbe2d..4046debb72f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12574,17 +12574,18 @@ cl_option_hasher::equal (tree x, tree y) gcc_unreachable (); } -/* Build an OPTIMIZATION_NODE based on the options in OPTS. */ +/* Build an OPTIMIZATION_NODE based on the options in OPTS and OPTS_SET. */ tree -build_optimization_node (struct gcc_options *opts) +build_optimization_node (struct gcc_options *opts, + struct gcc_options *opts_set) { tree t; /* Use the cache of optimization nodes. */ cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node), - opts); + opts, opts_set); tree *slot = cl_option_hash_table->find_slot (cl_optimization_node, INSERT); t = *slot; @@ -12601,17 +12602,18 @@ build_optimization_node (struct gcc_options *opts) return t; } -/* Build a TARGET_OPTION_NODE based on the options in OPTS. */ +/* Build a TARGET_OPTION_NODE based on the options in OPTS and OPTS_SET. */ tree -build_target_option_node (struct gcc_options *opts) +build_target_option_node (struct gcc_options *opts, + struct gcc_options *opts_set) { tree t; /* Use the cache of optimization nodes. */ cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node), - opts); + opts, opts_set); tree *slot = cl_option_hash_table->find_slot (cl_target_option_node, INSERT); t = *slot; diff --git a/gcc/tree.h b/gcc/tree.h index 9ec24a3008b..8c65f7ca0a9 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3272,8 +3272,10 @@ extern vec **decl_debug_args_insert (tree); #define TREE_OPTIMIZATION_BASE_OPTABS(NODE) \ (OPTIMIZATION_NODE_CHECK (NODE)->optimization.base_optabs) -/* Return a tree node that encapsulates the optimization options in OPTS. */ -extern tree build_optimization_node (struct gcc_options *opts); +/* Return a tree node that encapsulates the optimization options in OPTS + and OPTS_SET. */ +extern tree build_optimization_node (struct gcc_options *opts, + struct gcc_options *opts_set); #define TREE_TARGET_OPTION(NODE) \ (TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts) @@ -3281,8 +3283,10 @@ extern tree build_optimization_node (struct gcc_options *opts); #define TREE_TARGET_GLOBALS(NODE) \ (TARGET_OPTION_NODE_CHECK (NODE)->target_option.globals) -/* Return a tree node that encapsulates the target options in OPTS. */ -extern tree build_target_option_node (struct gcc_options *opts); +/* Return a tree node that encapsulates the target options in OPTS and + OPTS_SET. */ +extern tree build_target_option_node (struct gcc_options *opts, + struct gcc_options *opts_set); extern void prepare_target_option_nodes_for_pch (void); -- 2.30.2