Commit 3b3f318a by Richard Guenther Committed by Richard Biener

re PR middle-end/42248 (compat test struct-by-value-17 fails execution with -O1 -fschedule-insns)

2010-01-17  Richard Guenther  <rguenther@suse.de>

	PR middle-end/42248
	* function.c (split_complex_args): Take a VEC to modify.
	(assign_parms_augmented_arg_list): Build a VEC instead of
	a chain of PARM_DECLs.
	(assign_parms_unsplit_complex): Take a VEC of arguments.
	Do not fixup unmodified parms.
	(assign_parms): Deal with the VEC.
	(gimplify_parameters): Likewise.

	* gcc.c-torture/execute/pr42248.c: New testcase.

From-SVN: r155984
parent 8eacd016
2010-01-17 Richard Guenther <rguenther@suse.de> 2010-01-17 Richard Guenther <rguenther@suse.de>
PR middle-end/42248
* function.c (split_complex_args): Take a VEC to modify.
(assign_parms_augmented_arg_list): Build a VEC instead of
a chain of PARM_DECLs.
(assign_parms_unsplit_complex): Take a VEC of arguments.
Do not fixup unmodified parms.
(assign_parms): Deal with the VEC.
(gimplify_parameters): Likewise.
2010-01-17 Richard Guenther <rguenther@suse.de>
* tree-ssa-uncprop.c (uncprop_into_successor_phis): Fix PHI * tree-ssa-uncprop.c (uncprop_into_successor_phis): Fix PHI
node existence check. node existence check.
* tree-vect-loop.c (vect_analyze_loop_form): Likewise. * tree-vect-loop.c (vect_analyze_loop_form): Likewise.
......
...@@ -2082,25 +2082,13 @@ assign_parms_initialize_all (struct assign_parm_data_all *all) ...@@ -2082,25 +2082,13 @@ assign_parms_initialize_all (struct assign_parm_data_all *all)
entries of the component type. Return a new list of substitutions are entries of the component type. Return a new list of substitutions are
needed, else the old list. */ needed, else the old list. */
static tree static void
split_complex_args (tree args) split_complex_args (VEC(tree, heap) **args)
{ {
unsigned i;
tree p; tree p;
/* Before allocating memory, check for the common case of no complex. */ for (i = 0; VEC_iterate (tree, *args, i, p); ++i)
for (p = args; p; p = TREE_CHAIN (p))
{
tree type = TREE_TYPE (p);
if (TREE_CODE (type) == COMPLEX_TYPE
&& targetm.calls.split_complex_arg (type))
goto found;
}
return args;
found:
args = copy_list (args);
for (p = args; p; p = TREE_CHAIN (p))
{ {
tree type = TREE_TYPE (p); tree type = TREE_TYPE (p);
if (TREE_CODE (type) == COMPLEX_TYPE if (TREE_CODE (type) == COMPLEX_TYPE
...@@ -2111,6 +2099,7 @@ split_complex_args (tree args) ...@@ -2111,6 +2099,7 @@ split_complex_args (tree args)
bool addressable = TREE_ADDRESSABLE (p); bool addressable = TREE_ADDRESSABLE (p);
/* Rewrite the PARM_DECL's type with its component. */ /* Rewrite the PARM_DECL's type with its component. */
p = copy_node (p);
TREE_TYPE (p) = subtype; TREE_TYPE (p) = subtype;
DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p)); DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p));
DECL_MODE (p) = VOIDmode; DECL_MODE (p) = VOIDmode;
...@@ -2124,6 +2113,7 @@ split_complex_args (tree args) ...@@ -2124,6 +2113,7 @@ split_complex_args (tree args)
DECL_IGNORED_P (p) = addressable; DECL_IGNORED_P (p) = addressable;
TREE_ADDRESSABLE (p) = 0; TREE_ADDRESSABLE (p) = 0;
layout_decl (p, 0); layout_decl (p, 0);
VEC_replace (tree, *args, i, p);
/* Build a second synthetic decl. */ /* Build a second synthetic decl. */
decl = build_decl (EXPR_LOCATION (p), decl = build_decl (EXPR_LOCATION (p),
...@@ -2132,27 +2122,27 @@ split_complex_args (tree args) ...@@ -2132,27 +2122,27 @@ split_complex_args (tree args)
DECL_ARTIFICIAL (decl) = addressable; DECL_ARTIFICIAL (decl) = addressable;
DECL_IGNORED_P (decl) = addressable; DECL_IGNORED_P (decl) = addressable;
layout_decl (decl, 0); layout_decl (decl, 0);
VEC_safe_insert (tree, heap, *args, ++i, decl);
/* Splice it in; skip the new decl. */
TREE_CHAIN (decl) = TREE_CHAIN (p);
TREE_CHAIN (p) = decl;
p = decl;
} }
} }
return args;
} }
/* A subroutine of assign_parms. Adjust the parameter list to incorporate /* A subroutine of assign_parms. Adjust the parameter list to incorporate
the hidden struct return argument, and (abi willing) complex args. the hidden struct return argument, and (abi willing) complex args.
Return the new parameter list. */ Return the new parameter list. */
static tree static VEC(tree, heap) *
assign_parms_augmented_arg_list (struct assign_parm_data_all *all) assign_parms_augmented_arg_list (struct assign_parm_data_all *all)
{ {
tree fndecl = current_function_decl; tree fndecl = current_function_decl;
tree fntype = TREE_TYPE (fndecl); tree fntype = TREE_TYPE (fndecl);
tree fnargs = DECL_ARGUMENTS (fndecl); VEC(tree, heap) *fnargs = NULL;
tree arg;
for (arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
VEC_safe_push (tree, heap, fnargs, arg);
all->orig_fnargs = DECL_ARGUMENTS (fndecl);
/* If struct value address is treated as the first argument, make it so. */ /* If struct value address is treated as the first argument, make it so. */
if (aggregate_value_p (DECL_RESULT (fndecl), fndecl) if (aggregate_value_p (DECL_RESULT (fndecl), fndecl)
...@@ -2168,16 +2158,16 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all) ...@@ -2168,16 +2158,16 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all)
DECL_ARTIFICIAL (decl) = 1; DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1; DECL_IGNORED_P (decl) = 1;
TREE_CHAIN (decl) = fnargs; TREE_CHAIN (decl) = all->orig_fnargs;
fnargs = decl; all->orig_fnargs = decl;
VEC_safe_insert (tree, heap, fnargs, 0, decl);
all->function_result_decl = decl; all->function_result_decl = decl;
} }
all->orig_fnargs = fnargs;
/* If the target wants to split complex arguments into scalars, do so. */ /* If the target wants to split complex arguments into scalars, do so. */
if (targetm.calls.split_complex_arg) if (targetm.calls.split_complex_arg)
fnargs = split_complex_args (fnargs); split_complex_args (&fnargs);
return fnargs; return fnargs;
} }
...@@ -3065,12 +3055,14 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm, ...@@ -3065,12 +3055,14 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
undo the frobbing that we did in assign_parms_augmented_arg_list. */ undo the frobbing that we did in assign_parms_augmented_arg_list. */
static void static void
assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) assign_parms_unsplit_complex (struct assign_parm_data_all *all,
VEC(tree, heap) *fnargs)
{ {
tree parm; tree parm;
tree orig_fnargs = all->orig_fnargs; tree orig_fnargs = all->orig_fnargs;
unsigned i = 0;
for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm)) for (parm = orig_fnargs; parm; parm = TREE_CHAIN (parm), ++i)
{ {
if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE if (TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE
&& targetm.calls.split_complex_arg (TREE_TYPE (parm))) && targetm.calls.split_complex_arg (TREE_TYPE (parm)))
...@@ -3078,8 +3070,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) ...@@ -3078,8 +3070,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs)
rtx tmp, real, imag; rtx tmp, real, imag;
enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm)); enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm));
real = DECL_RTL (fnargs); real = DECL_RTL (VEC_index (tree, fnargs, i));
imag = DECL_RTL (TREE_CHAIN (fnargs)); imag = DECL_RTL (VEC_index (tree, fnargs, i + 1));
if (inner != GET_MODE (real)) if (inner != GET_MODE (real))
{ {
real = gen_lowpart_SUBREG (inner, real); real = gen_lowpart_SUBREG (inner, real);
...@@ -3112,8 +3104,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) ...@@ -3112,8 +3104,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs)
tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag); tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
SET_DECL_RTL (parm, tmp); SET_DECL_RTL (parm, tmp);
real = DECL_INCOMING_RTL (fnargs); real = DECL_INCOMING_RTL (VEC_index (tree, fnargs, i));
imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs)); imag = DECL_INCOMING_RTL (VEC_index (tree, fnargs, i + 1));
if (inner != GET_MODE (real)) if (inner != GET_MODE (real))
{ {
real = gen_lowpart_SUBREG (inner, real); real = gen_lowpart_SUBREG (inner, real);
...@@ -3121,20 +3113,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) ...@@ -3121,20 +3113,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs)
} }
tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag); tmp = gen_rtx_CONCAT (DECL_MODE (parm), real, imag);
set_decl_incoming_rtl (parm, tmp, false); set_decl_incoming_rtl (parm, tmp, false);
fnargs = TREE_CHAIN (fnargs); i++;
}
else
{
SET_DECL_RTL (parm, DECL_RTL (fnargs));
set_decl_incoming_rtl (parm, DECL_INCOMING_RTL (fnargs), false);
/* Set MEM_EXPR to the original decl, i.e. to PARM,
instead of the copy of decl, i.e. FNARGS. */
if (DECL_INCOMING_RTL (parm) && MEM_P (DECL_INCOMING_RTL (parm)))
set_mem_expr (DECL_INCOMING_RTL (parm), parm);
} }
fnargs = TREE_CHAIN (fnargs);
} }
} }
...@@ -3145,7 +3125,9 @@ static void ...@@ -3145,7 +3125,9 @@ static void
assign_parms (tree fndecl) assign_parms (tree fndecl)
{ {
struct assign_parm_data_all all; struct assign_parm_data_all all;
tree fnargs, parm; tree parm;
VEC(tree, heap) *fnargs;
unsigned i;
crtl->args.internal_arg_pointer crtl->args.internal_arg_pointer
= targetm.calls.internal_arg_pointer (); = targetm.calls.internal_arg_pointer ();
...@@ -3153,7 +3135,7 @@ assign_parms (tree fndecl) ...@@ -3153,7 +3135,7 @@ assign_parms (tree fndecl)
assign_parms_initialize_all (&all); assign_parms_initialize_all (&all);
fnargs = assign_parms_augmented_arg_list (&all); fnargs = assign_parms_augmented_arg_list (&all);
for (parm = fnargs; parm; parm = TREE_CHAIN (parm)) for (i = 0; VEC_iterate (tree, fnargs, i, parm); ++i)
{ {
struct assign_parm_data_one data; struct assign_parm_data_one data;
...@@ -3216,9 +3198,11 @@ assign_parms (tree fndecl) ...@@ -3216,9 +3198,11 @@ assign_parms (tree fndecl)
assign_parm_setup_stack (&all, parm, &data); assign_parm_setup_stack (&all, parm, &data);
} }
if (targetm.calls.split_complex_arg && fnargs != all.orig_fnargs) if (targetm.calls.split_complex_arg)
assign_parms_unsplit_complex (&all, fnargs); assign_parms_unsplit_complex (&all, fnargs);
VEC_free (tree, heap, fnargs);
/* Output all parameter conversion instructions (possibly including calls) /* Output all parameter conversion instructions (possibly including calls)
now that all parameters have been copied out of hard registers. */ now that all parameters have been copied out of hard registers. */
emit_insn (all.first_conversion_insn); emit_insn (all.first_conversion_insn);
...@@ -3370,13 +3354,15 @@ gimple_seq ...@@ -3370,13 +3354,15 @@ gimple_seq
gimplify_parameters (void) gimplify_parameters (void)
{ {
struct assign_parm_data_all all; struct assign_parm_data_all all;
tree fnargs, parm; tree parm;
gimple_seq stmts = NULL; gimple_seq stmts = NULL;
VEC(tree, heap) *fnargs;
unsigned i;
assign_parms_initialize_all (&all); assign_parms_initialize_all (&all);
fnargs = assign_parms_augmented_arg_list (&all); fnargs = assign_parms_augmented_arg_list (&all);
for (parm = fnargs; parm; parm = TREE_CHAIN (parm)) for (i = 0; VEC_iterate (tree, fnargs, i, parm); ++i)
{ {
struct assign_parm_data_one data; struct assign_parm_data_one data;
...@@ -3454,6 +3440,8 @@ gimplify_parameters (void) ...@@ -3454,6 +3440,8 @@ gimplify_parameters (void)
} }
} }
VEC_free (tree, heap, fnargs);
return stmts; return stmts;
} }
......
2010-01-17 Richard Guenther <rguenther@suse.de> 2010-01-17 Richard Guenther <rguenther@suse.de>
PR middle-end/42248
* gcc.c-torture/execute/pr42248.c: New testcase.
2010-01-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42773 PR tree-optimization/42773
* g++.dg/torture/pr42773.C: New testcase. * g++.dg/torture/pr42773.C: New testcase.
......
typedef struct {
_Complex double a;
_Complex double b;
} Scf10;
Scf10 g1s;
void
check (Scf10 x, _Complex double y)
{
if (x.a != y) __builtin_abort ();
}
void
init (Scf10 *p, _Complex double y)
{
p->a = y;
}
int
main ()
{
init (&g1s, (_Complex double)1);
check (g1s, (_Complex double)1);
return 0;
}
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