summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-09 07:54:02 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2013-03-09 07:54:02 +0000
commit9d3fa9375021ee8fbb9a5fddcb98fdf8750181ff (patch)
tree6f0f3cdaa7c97b4ffb3074c195483271e15c9cc5
parent6c587dc6423cefea4a221acea7f2dcab52af0d19 (diff)
downloadppe42-gcc-9d3fa9375021ee8fbb9a5fddcb98fdf8750181ff.tar.gz
ppe42-gcc-9d3fa9375021ee8fbb9a5fddcb98fdf8750181ff.zip
gcc/
PR middle-end/56524 * tree.h (tree_optimization_option): Rename target_optabs to optabs. Add base_optabs. (TREE_OPTIMIZATION_OPTABS): Update after previous field change. (TREE_OPTIMIZATION_BASE_OPTABS): New macro. (save_optabs_if_changed): Replace with... (init_tree_optimization_optabs): ...this. * optabs.c (save_optabs_if_changed): Rename to... (init_tree_optimization_optabs): ...this. Take the optimization node as argument. Do nothing if the base optabs are already correct. Reuse the existing TREE_OPTIMIZATION_OPTABS memory if we need to recompute optabs. * function.h (function): Remove optabs field. * function.c (invoke_set_current_function_hook): Call init_tree_optimization_optabs. Use the result to initialize this_fn_optabs. gcc/c-family/ PR middle-end/56524 * c-common.c (handle_optimize_attribute): Don't call save_optabs_if_changed. gcc/testsuite/ PR middle-end/56524 * gcc.target/mips/pr56524.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@196570 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c2
-rw-r--r--gcc/function.c23
-rw-r--r--gcc/function.h3
-rw-r--r--gcc/optabs.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/mips/pr56524.c8
-rw-r--r--gcc/tree.h15
9 files changed, 69 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7a4de2537e7..3ae6c4c84b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+2013-03-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR middle-end/56524
+ * tree.h (tree_optimization_option): Rename target_optabs to optabs.
+ Add base_optabs.
+ (TREE_OPTIMIZATION_OPTABS): Update after previous field change.
+ (TREE_OPTIMIZATION_BASE_OPTABS): New macro.
+ (save_optabs_if_changed): Replace with...
+ (init_tree_optimization_optabs): ...this.
+ * optabs.c (save_optabs_if_changed): Rename to...
+ (init_tree_optimization_optabs): ...this. Take the optimization node
+ as argument. Do nothing if the base optabs are already correct.
+ Reuse the existing TREE_OPTIMIZATION_OPTABS memory if we need
+ to recompute optabs.
+ * function.h (function): Remove optabs field.
+ * function.c (invoke_set_current_function_hook): Call
+ init_tree_optimization_optabs. Use the result to initialize
+ this_fn_optabs.
+
2013-02-27 Aldy Hernandez <aldyh@redhat.com>
* trans-mem.c (expand_transaction): Do not set PR_INSTRUMENTEDCODE
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 6d90bfb37d2..dd6cb296a44 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,9 @@
+2013-03-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR middle-end/56524
+ * c-common.c (handle_optimize_attribute): Don't call
+ save_optabs_if_changed.
+
2013-03-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56461
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d01de3e40d5..c7cdd0fc7a0 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -8947,8 +8947,6 @@ handle_optimize_attribute (tree *node, tree name, tree args,
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
= build_optimization_node ();
- save_optabs_if_changed (*node);
-
/* Restore current options. */
cl_optimization_restore (&global_options, &cur_opts);
}
diff --git a/gcc/function.c b/gcc/function.c
index 1b41cf2cb34..e673f21a57d 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -4400,25 +4400,14 @@ invoke_set_current_function_hook (tree fndecl)
}
targetm.set_current_function (fndecl);
+ this_fn_optabs = this_target_optabs;
- if (opts == optimization_default_node)
- this_fn_optabs = this_target_optabs;
- else
+ if (opts != optimization_default_node)
{
- struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
- if (fn->optabs == NULL)
- {
- if (this_target_optabs == &default_target_optabs)
- fn->optabs = TREE_OPTIMIZATION_OPTABS (opts);
- else
- {
- fn->optabs = (unsigned char *)
- ggc_alloc_atomic (sizeof (struct target_optabs));
- init_all_optabs ((struct target_optabs *) fn->optabs);
- }
- }
- this_fn_optabs = fn->optabs ? (struct target_optabs *) fn->optabs
- : this_target_optabs;
+ init_tree_optimization_optabs (opts);
+ if (TREE_OPTIMIZATION_OPTABS (opts))
+ this_fn_optabs = (struct target_optabs *)
+ TREE_OPTIMIZATION_OPTABS (opts);
}
}
}
diff --git a/gcc/function.h b/gcc/function.h
index 53e28b768c0..89d71e592dd 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -580,9 +580,6 @@ struct GTY(()) function {
a string describing the reason for failure. */
const char * GTY((skip)) cannot_be_copied_reason;
- /* Optabs for this function. This is of type `struct target_optabs *'. */
- unsigned char *GTY ((atomic)) optabs;
-
/* Collected bit flags. */
/* Number of units of general registers that need saving in stdarg
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c5778d1928b..a3051ad9d9a 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -6208,31 +6208,32 @@ init_optabs (void)
targetm.init_libfuncs ();
}
-/* Recompute the optabs and save them if they have changed. */
+/* Use the current target and options to initialize
+ TREE_OPTIMIZATION_OPTABS (OPTNODE). */
void
-save_optabs_if_changed (tree fndecl)
+init_tree_optimization_optabs (tree optnode)
{
- /* ?? If this fails, we should temporarily restore the default
- target first (set_cfun (NULL) ??), do the rest of this function,
- and then restore it. */
- gcc_assert (this_target_optabs == &default_target_optabs);
+ /* Quick exit if we have already computed optabs for this target. */
+ if (TREE_OPTIMIZATION_BASE_OPTABS (optnode) == this_target_optabs)
+ return;
+ /* Forget any previous information and set up for the current target. */
+ TREE_OPTIMIZATION_BASE_OPTABS (optnode) = this_target_optabs;
struct target_optabs *tmp_optabs = (struct target_optabs *)
- ggc_alloc_atomic (sizeof (struct target_optabs));
- tree optnode = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+ TREE_OPTIMIZATION_OPTABS (optnode);
+ if (tmp_optabs)
+ memset (tmp_optabs, 0, sizeof (struct target_optabs));
+ else
+ tmp_optabs = (struct target_optabs *)
+ ggc_alloc_atomic (sizeof (struct target_optabs));
/* Generate a new set of optabs into tmp_optabs. */
init_all_optabs (tmp_optabs);
/* If the optabs changed, record it. */
if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
- {
- if (TREE_OPTIMIZATION_OPTABS (optnode))
- ggc_free (TREE_OPTIMIZATION_OPTABS (optnode));
-
- TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
- }
+ TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
else
{
TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b1043301fa3..15156f7ae8c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR middle-end/56524
+ * gcc.target/mips/pr56524.c: New test.
+
2013-03-08 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/56565
diff --git a/gcc/testsuite/gcc.target/mips/pr56524.c b/gcc/testsuite/gcc.target/mips/pr56524.c
new file mode 100644
index 00000000000..7df021b6998
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/pr56524.c
@@ -0,0 +1,8 @@
+/* { dg-options "-mips16" } */
+
+void bar (void) {}
+
+void __attribute__((optimize("schedule-insns")))
+foo (void)
+{
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index 740d4382712..b852f1d9434 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -3589,21 +3589,26 @@ struct GTY(()) tree_optimization_option {
/* Target optabs for this set of optimization options. This is of
type `struct target_optabs *'. */
- unsigned char *GTY ((atomic)) target_optabs;
+ unsigned char *GTY ((atomic)) optabs;
+
+ /* The value of this_target_optabs against which the optabs above were
+ generated. */
+ struct target_optabs *GTY ((skip)) base_optabs;
};
#define TREE_OPTIMIZATION(NODE) \
(&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
#define TREE_OPTIMIZATION_OPTABS(NODE) \
- (OPTIMIZATION_NODE_CHECK (NODE)->optimization.target_optabs)
+ (OPTIMIZATION_NODE_CHECK (NODE)->optimization.optabs)
+
+#define TREE_OPTIMIZATION_BASE_OPTABS(NODE) \
+ (OPTIMIZATION_NODE_CHECK (NODE)->optimization.base_optabs)
/* Return a tree node that encapsulates the current optimization options. */
extern tree build_optimization_node (void);
-/* Save a new set of target_optabs in a TREE_OPTIMIZATION node if the
- current set of optabs has changed. */
-extern void save_optabs_if_changed (tree);
+extern void init_tree_optimization_optabs (tree);
/* Target options used by a function. */
OpenPOWER on IntegriCloud