From 4b1baac81ff353bf0e3cea5c972a864db361355c Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 9 Mar 2013 07:54:02 +0000 Subject: 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 --- gcc/optabs.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'gcc/optabs.c') 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; -- cgit v1.1