> 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 <jakub@redhat.com>
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.
/* 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. */
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. */
}
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);
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);
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);
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);
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;
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
/* 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. */
/* 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
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);
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);
}
}
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
= 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);
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)
{
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;
}
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
&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;
}
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 *);
/* 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;
/* 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. */
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);
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);
/* 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 ();
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);
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.
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);
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));
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;
/* 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),
/* 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
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));
}
}
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);
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)
{
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;
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
&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;
}
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;
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;
/* 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;
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;
&& 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);
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;
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
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)
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)
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,
/* 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);
}
\f
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++)
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;
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"))). */
{
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;
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;
}
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 ();
}
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 ();
}
}
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
/* 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
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 ();
}
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 ();
}
}
else
fprintf (stderr, DEBUG_FMT_S, "tune", "<none>");
- 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);
/* 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). */
&& 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);
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;
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;
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;
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
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)
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)
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;
static void
rs6000_function_specific_restore (struct gcc_options *opts,
+ struct gcc_options */* opts_set */,
struct cl_target_option *ptr)
{
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);
}
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)
&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;
}
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;
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))
/* 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
/* 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
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;
}
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;
&& 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);
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)
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)
@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.
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);
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);
}
}
&& 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;
}
!= 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
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;
}
}
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") {
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;
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 *$")
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++) {
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 "}";
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;
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 *$")
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++) {
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++) {
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 "}";
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 "}";
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 "}";
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 "";
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 */";
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 "}";
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 "}";
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 "";
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";
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";
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;
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 "";
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 "]+$")
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;
}
} else {
var_target_int[n_target_int++] = "int x_target_flags";
+ n_target_explicit++;
}
for (i = 0; i < n_target_other; 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 *);";
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 *);";
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;
}
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. */
"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. */
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)
{
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;
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;
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;
}
}
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;
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;
#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)
#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);