aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2013-03-09 07:54:02 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2013-03-09 07:54:02 +0000
commit4b1baac81ff353bf0e3cea5c972a864db361355c (patch)
tree6f0f3cdaa7c97b4ffb3074c195483271e15c9cc5 /gcc/optabs.c
parentcc107acf8d31160a54c0ba669fc3db0aec6548aa (diff)
downloadgcc-4b1baac81ff353bf0e3cea5c972a864db361355c.zip
gcc-4b1baac81ff353bf0e3cea5c972a864db361355c.tar.gz
gcc-4b1baac81ff353bf0e3cea5c972a864db361355c.tar.bz2
re PR middle-end/56524 (Compiler ICE when compiling with -mips16)
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. From-SVN: r196570
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index c5778d1..a3051ad 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;