diff options
author | Richard Guenther <rguenther@suse.de> | 2010-01-17 17:00:47 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-01-17 17:00:47 +0000 |
commit | 3b3f318a47b4a45b30d9d239f031ecfcf85ab0d3 (patch) | |
tree | 477137746dbd5d42ffd5c3297e597dd501ed2d46 | |
parent | 8eacd0162e5d13cd77de8c85aa2759519a1cd5ec (diff) | |
download | gcc-3b3f318a47b4a45b30d9d239f031ecfcf85ab0d3.zip gcc-3b3f318a47b4a45b30d9d239f031ecfcf85ab0d3.tar.gz gcc-3b3f318a47b4a45b30d9d239f031ecfcf85ab0d3.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/function.c | 96 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr42248.c | 27 |
4 files changed, 85 insertions, 54 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 212381f..66b9b0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,16 @@ 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 node existence check. * tree-vect-loop.c (vect_analyze_loop_form): Likewise. diff --git a/gcc/function.c b/gcc/function.c index ac5ba94..6314ae0 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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 needed, else the old list. */ -static tree -split_complex_args (tree args) +static void +split_complex_args (VEC(tree, heap) **args) { + unsigned i; tree p; - /* Before allocating memory, check for the common case of no complex. */ - 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)) + for (i = 0; VEC_iterate (tree, *args, i, p); ++i) { tree type = TREE_TYPE (p); if (TREE_CODE (type) == COMPLEX_TYPE @@ -2111,6 +2099,7 @@ split_complex_args (tree args) bool addressable = TREE_ADDRESSABLE (p); /* Rewrite the PARM_DECL's type with its component. */ + p = copy_node (p); TREE_TYPE (p) = subtype; DECL_ARG_TYPE (p) = TREE_TYPE (DECL_ARG_TYPE (p)); DECL_MODE (p) = VOIDmode; @@ -2124,6 +2113,7 @@ split_complex_args (tree args) DECL_IGNORED_P (p) = addressable; TREE_ADDRESSABLE (p) = 0; layout_decl (p, 0); + VEC_replace (tree, *args, i, p); /* Build a second synthetic decl. */ decl = build_decl (EXPR_LOCATION (p), @@ -2132,27 +2122,27 @@ split_complex_args (tree args) DECL_ARTIFICIAL (decl) = addressable; DECL_IGNORED_P (decl) = addressable; layout_decl (decl, 0); - - /* Splice it in; skip the new decl. */ - TREE_CHAIN (decl) = TREE_CHAIN (p); - TREE_CHAIN (p) = decl; - p = decl; + VEC_safe_insert (tree, heap, *args, ++i, decl); } } - - return args; } /* A subroutine of assign_parms. Adjust the parameter list to incorporate the hidden struct return argument, and (abi willing) complex args. Return the new parameter list. */ -static tree +static VEC(tree, heap) * assign_parms_augmented_arg_list (struct assign_parm_data_all *all) { tree fndecl = current_function_decl; 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 (aggregate_value_p (DECL_RESULT (fndecl), fndecl) @@ -2168,16 +2158,16 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all) DECL_ARTIFICIAL (decl) = 1; DECL_IGNORED_P (decl) = 1; - TREE_CHAIN (decl) = fnargs; - fnargs = decl; + TREE_CHAIN (decl) = all->orig_fnargs; + all->orig_fnargs = decl; + VEC_safe_insert (tree, heap, fnargs, 0, decl); + all->function_result_decl = decl; } - all->orig_fnargs = fnargs; - /* If the target wants to split complex arguments into scalars, do so. */ if (targetm.calls.split_complex_arg) - fnargs = split_complex_args (fnargs); + split_complex_args (&fnargs); return fnargs; } @@ -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. */ 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 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 && targetm.calls.split_complex_arg (TREE_TYPE (parm))) @@ -3078,8 +3070,8 @@ assign_parms_unsplit_complex (struct assign_parm_data_all *all, tree fnargs) rtx tmp, real, imag; enum machine_mode inner = GET_MODE_INNER (DECL_MODE (parm)); - real = DECL_RTL (fnargs); - imag = DECL_RTL (TREE_CHAIN (fnargs)); + real = DECL_RTL (VEC_index (tree, fnargs, i)); + imag = DECL_RTL (VEC_index (tree, fnargs, i + 1)); if (inner != GET_MODE (real)) { real = gen_lowpart_SUBREG (inner, real); @@ -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); SET_DECL_RTL (parm, tmp); - real = DECL_INCOMING_RTL (fnargs); - imag = DECL_INCOMING_RTL (TREE_CHAIN (fnargs)); + real = DECL_INCOMING_RTL (VEC_index (tree, fnargs, i)); + imag = DECL_INCOMING_RTL (VEC_index (tree, fnargs, i + 1)); if (inner != GET_MODE (real)) { real = gen_lowpart_SUBREG (inner, real); @@ -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); set_decl_incoming_rtl (parm, tmp, false); - fnargs = TREE_CHAIN (fnargs); - } - 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); + i++; } - - fnargs = TREE_CHAIN (fnargs); } } @@ -3145,7 +3125,9 @@ static void assign_parms (tree fndecl) { struct assign_parm_data_all all; - tree fnargs, parm; + tree parm; + VEC(tree, heap) *fnargs; + unsigned i; crtl->args.internal_arg_pointer = targetm.calls.internal_arg_pointer (); @@ -3153,7 +3135,7 @@ assign_parms (tree fndecl) assign_parms_initialize_all (&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; @@ -3216,9 +3198,11 @@ assign_parms (tree fndecl) 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); + VEC_free (tree, heap, fnargs); + /* Output all parameter conversion instructions (possibly including calls) now that all parameters have been copied out of hard registers. */ emit_insn (all.first_conversion_insn); @@ -3370,13 +3354,15 @@ gimple_seq gimplify_parameters (void) { struct assign_parm_data_all all; - tree fnargs, parm; + tree parm; gimple_seq stmts = NULL; + VEC(tree, heap) *fnargs; + unsigned i; assign_parms_initialize_all (&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; @@ -3454,6 +3440,8 @@ gimplify_parameters (void) } } + VEC_free (tree, heap, fnargs); + return stmts; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d5249fd..f494a09 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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 * g++.dg/torture/pr42773.C: New testcase. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr42248.c b/gcc/testsuite/gcc.c-torture/execute/pr42248.c new file mode 100644 index 0000000..bbb91b34 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr42248.c @@ -0,0 +1,27 @@ +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; +} |