Commit 4b1baac8 by Richard Sandiford Committed by Richard Sandiford

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
parent cc107acf
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> 2013-02-27 Aldy Hernandez <aldyh@redhat.com>
* trans-mem.c (expand_transaction): Do not set PR_INSTRUMENTEDCODE * trans-mem.c (expand_transaction): Do not set PR_INSTRUMENTEDCODE
......
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> 2013-03-05 Jakub Jelinek <jakub@redhat.com>
PR middle-end/56461 PR middle-end/56461
......
...@@ -8947,8 +8947,6 @@ handle_optimize_attribute (tree *node, tree name, tree args, ...@@ -8947,8 +8947,6 @@ handle_optimize_attribute (tree *node, tree name, tree args,
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node) DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node)
= build_optimization_node (); = build_optimization_node ();
save_optabs_if_changed (*node);
/* Restore current options. */ /* Restore current options. */
cl_optimization_restore (&global_options, &cur_opts); cl_optimization_restore (&global_options, &cur_opts);
} }
......
...@@ -4400,25 +4400,14 @@ invoke_set_current_function_hook (tree fndecl) ...@@ -4400,25 +4400,14 @@ invoke_set_current_function_hook (tree fndecl)
} }
targetm.set_current_function (fndecl); targetm.set_current_function (fndecl);
this_fn_optabs = this_target_optabs;
if (opts == optimization_default_node) if (opts != optimization_default_node)
this_fn_optabs = this_target_optabs;
else
{ {
struct function *fn = DECL_STRUCT_FUNCTION (fndecl); init_tree_optimization_optabs (opts);
if (fn->optabs == NULL) if (TREE_OPTIMIZATION_OPTABS (opts))
{ this_fn_optabs = (struct target_optabs *)
if (this_target_optabs == &default_target_optabs) TREE_OPTIMIZATION_OPTABS (opts);
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;
} }
} }
} }
......
...@@ -580,9 +580,6 @@ struct GTY(()) function { ...@@ -580,9 +580,6 @@ struct GTY(()) function {
a string describing the reason for failure. */ a string describing the reason for failure. */
const char * GTY((skip)) cannot_be_copied_reason; 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. */ /* Collected bit flags. */
/* Number of units of general registers that need saving in stdarg /* Number of units of general registers that need saving in stdarg
......
...@@ -6208,31 +6208,32 @@ init_optabs (void) ...@@ -6208,31 +6208,32 @@ init_optabs (void)
targetm.init_libfuncs (); 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 void
save_optabs_if_changed (tree fndecl) init_tree_optimization_optabs (tree optnode)
{ {
/* ?? If this fails, we should temporarily restore the default /* Quick exit if we have already computed optabs for this target. */
target first (set_cfun (NULL) ??), do the rest of this function, if (TREE_OPTIMIZATION_BASE_OPTABS (optnode) == this_target_optabs)
and then restore it. */ return;
gcc_assert (this_target_optabs == &default_target_optabs);
/* 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 *) struct target_optabs *tmp_optabs = (struct target_optabs *)
ggc_alloc_atomic (sizeof (struct target_optabs)); TREE_OPTIMIZATION_OPTABS (optnode);
tree optnode = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl); 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. */ /* Generate a new set of optabs into tmp_optabs. */
init_all_optabs (tmp_optabs); init_all_optabs (tmp_optabs);
/* If the optabs changed, record it. */ /* If the optabs changed, record it. */
if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs))) if (memcmp (tmp_optabs, this_target_optabs, sizeof (struct target_optabs)))
{ TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
if (TREE_OPTIMIZATION_OPTABS (optnode))
ggc_free (TREE_OPTIMIZATION_OPTABS (optnode));
TREE_OPTIMIZATION_OPTABS (optnode) = (unsigned char *) tmp_optabs;
}
else else
{ {
TREE_OPTIMIZATION_OPTABS (optnode) = NULL; TREE_OPTIMIZATION_OPTABS (optnode) = NULL;
......
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> 2013-03-08 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/56565 PR c++/56565
......
/* { dg-options "-mips16" } */
void bar (void) {}
void __attribute__((optimize("schedule-insns")))
foo (void)
{
}
...@@ -3589,21 +3589,26 @@ struct GTY(()) tree_optimization_option { ...@@ -3589,21 +3589,26 @@ struct GTY(()) tree_optimization_option {
/* Target optabs for this set of optimization options. This is of /* Target optabs for this set of optimization options. This is of
type `struct target_optabs *'. */ 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) \ #define TREE_OPTIMIZATION(NODE) \
(&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts) (&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
#define TREE_OPTIMIZATION_OPTABS(NODE) \ #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. */ /* Return a tree node that encapsulates the current optimization options. */
extern tree build_optimization_node (void); extern tree build_optimization_node (void);
/* Save a new set of target_optabs in a TREE_OPTIMIZATION node if the extern void init_tree_optimization_optabs (tree);
current set of optabs has changed. */
extern void save_optabs_if_changed (tree);
/* Target options used by a function. */ /* Target options used by a function. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment