aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@linaro.org>2016-05-01 21:03:59 +0200
committerChristophe Lyon <christophe.lyon@linaro.org>2016-06-10 12:48:30 +0000
commitedceeffafc77f05f5e0c20e91cd5106da486a811 (patch)
tree3d051824d0cdba0941f5d9f85b4c3ec79edc55b7
parent5961cb80233dcfe9a83be08cb830616744e3872c (diff)
gcc/
Backport from trunk r233745. 2016-02-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR target/69245 * config/aarch64/aarch64.c (aarch64_set_current_function): Save/restore target globals when switching to target_option_default_node. gcc/testsuite/ Backport from trunk r233745. 2016-02-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR target/69245 * gcc.target/aarch64/pr69245_1.c: New test. gcc/ Backport from trunk r234141. 2016-03-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 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. gcc/testsuite/ Backport from trunk r234141. 2016-03-11 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR target/70002 PR target/69245 * gcc.target/aarch64/pr69245_2.c: New test. Change-Id: I130100debcacc28a39c6dcdfdf473c2774a621ed
-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.c67
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr69245_1.c18
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr69245_2.c17
5 files changed, 73 insertions, 35 deletions
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index ad95c78b989..8a2105f4ab3 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 9bf433594c5..9c9ba8f22d5 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -366,6 +366,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);
/* Initialize builtins for SIMD intrinsics. */
void init_aarch64_simd_builtins (void);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 108c6d16229..c1078820742 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8108,6 +8108,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
@@ -8117,49 +8132,30 @@ 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 && new_tree != target_option_default_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
- 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. */
@@ -8174,6 +8170,7 @@ aarch64_set_current_function (tree fndecl)
relayout_decl (parms);
}
}
+ aarch64_save_restore_target_globals (new_tree);
}
/* Enum describing the various ways we can handle attributes.
diff --git a/gcc/testsuite/gcc.target/aarch64/pr69245_1.c b/gcc/testsuite/gcc.target/aarch64/pr69245_1.c
new file mode 100644
index 00000000000..dcc542b2a86
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr69245_1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a+fp -fomit-frame-pointer" } */
+
+#pragma GCC target "arch=armv8-a+nofp"
+long a;
+static void
+fn1 ()
+{
+}
+
+#pragma GCC target "arch=armv8-a+fp"
+float
+fn2 (float a)
+{
+ return a + 2.0;
+}
+
+/* { dg-final { scan-assembler-not "__addsf3" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr69245_2.c b/gcc/testsuite/gcc.target/aarch64/pr69245_2.c
new file mode 100644
index 00000000000..6743f5d0ccc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr69245_2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8-a+fp" } */
+
+#pragma GCC push_options
+#pragma GCC target "arch=armv8-a+nofp"
+static void
+fn1 ()
+{
+}
+#pragma GCC pop_options
+float
+fn2 (float a)
+{
+ return a + 2.0;
+}
+
+/* { dg-final { scan-assembler-not "__addsf3" } } */