summaryrefslogtreecommitdiff
path: root/gcc/config/aarch64
diff options
context:
space:
mode:
authorktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-11 15:27:24 +0000
committerktkachov <ktkachov@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-11 15:27:24 +0000
commit1f5ef87e8259bf842c0e064b0b32432c99405040 (patch)
tree355eb89d0b763eda4169d93361d3c9320699c13b /gcc/config/aarch64
parentf9c352a12457b1ae7b23911acf27ee4d29b20377 (diff)
downloadgcc-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.c5
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64.c80
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.