diff options
author | ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-11 15:27:24 +0000 |
---|---|---|
committer | ktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-03-11 15:27:24 +0000 |
commit | 1f5ef87e8259bf842c0e064b0b32432c99405040 (patch) | |
tree | 355eb89d0b763eda4169d93361d3c9320699c13b /gcc/config/aarch64 | |
parent | f9c352a12457b1ae7b23911acf27ee4d29b20377 (diff) | |
download | gcc-1f5ef87e8259bf842c0e064b0b32432c99405040.tar.gz |
[AArch64] PR target/70002: Make aarch64_set_current_function play nice with pragma resetting
PR target/70002
* config/aarch64/aarch64-protos.h
(aarch64_save_restore_target_globals): New prototype.
* config/aarch64/aarch64-c.c (aarch64_pragma_target_parse):
Call the above when popping pragma.
* config/aarch64/aarch64.c (aarch64_save_restore_target_globals):
New function.
(aarch64_set_current_function): Rewrite using the above.
PR target/70002
PR target/69245
* gcc.target/aarch64/pr69245_2.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234141 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/aarch64')
-rw-r--r-- | gcc/config/aarch64/aarch64-c.c | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 80 |
3 files changed, 38 insertions, 48 deletions
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c index 3590ae0daa5..e64dc7676cc 100644 --- a/gcc/config/aarch64/aarch64-c.c +++ b/gcc/config/aarch64/aarch64-c.c @@ -178,6 +178,11 @@ aarch64_pragma_target_parse (tree args, tree pop_target) cpp_opts->warn_unused_macros = saved_warn_unused_macros; + /* If we're popping or reseting make sure to update the globals so that + the optab availability predicates get recomputed. */ + if (pop_target) + aarch64_save_restore_target_globals (pop_target); + /* Initialize SIMD builtins if we haven't already. Set current_target_pragma to NULL for the duration so that the builtin initialization code doesn't try to tag the functions diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index acf2062245f..dced2098918 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -360,6 +360,7 @@ void aarch64_emit_call_insn (rtx); void aarch64_register_pragmas (void); void aarch64_relayout_simd_types (void); void aarch64_reset_previous_fndecl (void); +void aarch64_save_restore_target_globals (tree); void aarch64_emit_approx_rsqrt (rtx, rtx); /* Initialize builtins for SIMD intrinsics. */ diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index d536aa0f1a3..cf1239dd69d 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -8577,6 +8577,21 @@ aarch64_reset_previous_fndecl (void) aarch64_previous_fndecl = NULL; } +/* Restore or save the TREE_TARGET_GLOBALS from or to NEW_TREE. + Used by aarch64_set_current_function and aarch64_pragma_target_parse to + make sure optab availability predicates are recomputed when necessary. */ + +void +aarch64_save_restore_target_globals (tree new_tree) +{ + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else if (new_tree == target_option_default_node) + restore_target_globals (&default_target_globals); + else + TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); +} + /* Implement TARGET_SET_CURRENT_FUNCTION. Unpack the codegen decisions like tuning and ISA features from the DECL_FUNCTION_SPECIFIC_TARGET of the function, if such exists. This function may be called multiple @@ -8586,63 +8601,32 @@ aarch64_reset_previous_fndecl (void) static void aarch64_set_current_function (tree fndecl) { + if (!fndecl || fndecl == aarch64_previous_fndecl) + return; + tree old_tree = (aarch64_previous_fndecl ? DECL_FUNCTION_SPECIFIC_TARGET (aarch64_previous_fndecl) : NULL_TREE); - tree new_tree = (fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl) - : NULL_TREE); - + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); - if (fndecl && fndecl != aarch64_previous_fndecl) - { - aarch64_previous_fndecl = fndecl; - if (old_tree == new_tree) - ; + /* If current function has no attributes but the previous one did, + use the default node. */ + if (!new_tree && old_tree) + new_tree = target_option_default_node; - else if (new_tree) - { - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } + /* If nothing to do, return. #pragma GCC reset or #pragma GCC pop to + the default have been handled by aarch64_save_restore_target_globals from + aarch64_pragma_target_parse. */ + if (old_tree == new_tree) + return; - else if (old_tree && old_tree != target_option_default_node) - { - new_tree = target_option_current_node; - cl_target_option_restore (&global_options, - 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) - restore_target_globals (&default_target_globals); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } - } + aarch64_previous_fndecl = fndecl; - if (!fndecl) - return; + /* First set the target options. */ + cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); - /* If we turned on SIMD make sure that any vector parameters are re-laid out - so that they use proper vector modes. */ - if (TARGET_SIMD) - { - tree parms = DECL_ARGUMENTS (fndecl); - for (; parms && parms != void_list_node; parms = TREE_CHAIN (parms)) - { - if (TREE_CODE (parms) == PARM_DECL - && VECTOR_TYPE_P (TREE_TYPE (parms)) - && DECL_MODE (parms) != TYPE_MODE (TREE_TYPE (parms))) - relayout_decl (parms); - } - } + aarch64_save_restore_target_globals (new_tree); } /* Enum describing the various ways we can handle attributes. |