From 23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 10 Jun 2004 11:49:49 -0400 Subject: [PATCH] target.h (struct gcc_target): Change gimplify_va_arg_expr hook signature. * target.h (struct gcc_target): Change gimplify_va_arg_expr hook signature. * tree-gimple.h: Adjust. * config/alpha/alpha.c (alpha_gimplify_va_arg): Adjust. * config/i386/i386.c (ix86_gimplify_va_arg): Adjust. Use fold_convert. * config/ia64/ia64.c (ia64_gimplify_va_arg): Adjust. * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust. Use COMPLEX_EXPR for complex numbers. Use fold_convert. * builtins.c (std_gimplify_va_arg_expr): Adjust. Use fold_convert. (gimplify_va_arg_expr): Return GS_ERROR in error case. Gimplify valist rather than calling stabilize_va_list. From-SVN: r82925 --- gcc/ChangeLog | 28 ++++++++++++++++ gcc/builtins.c | 37 ++++++++++++--------- gcc/config/alpha/alpha.c | 29 +++++++---------- gcc/config/i386/i386.c | 21 +++++------- gcc/config/ia64/ia64.c | 18 ++++------ gcc/config/rs6000/rs6000.c | 67 ++++++++++---------------------------- gcc/doc/tm.texi | 13 ++++++++ gcc/target.h | 2 +- gcc/tree-gimple.h | 2 +- 9 files changed, 108 insertions(+), 109 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dc7b3026d4f..48af490674e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2004-06-10 Jason Merrill + + * target.h (struct gcc_target): Change gimplify_va_arg_expr + hook signature. + * tree-gimple.h: Adjust. + * config/alpha/alpha.c (alpha_gimplify_va_arg): Adjust. + * config/i386/i386.c (ix86_gimplify_va_arg): Adjust. + Use fold_convert. + * config/ia64/ia64.c (ia64_gimplify_va_arg): Adjust. + * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Adjust. + Use COMPLEX_EXPR for complex numbers. Use fold_convert. + * builtins.c (std_gimplify_va_arg_expr): Adjust. Use fold_convert. + (gimplify_va_arg_expr): Return GS_ERROR in error case. + Gimplify valist rather than calling stabilize_va_list. + 2004-06-10 Zdenek Dvorak * Makefile.in (df.o): Remove fibheap dependency. @@ -189,7 +204,10 @@ (ia64_gimplify_va_arg): New fn. * config/rs6000/rs6000.c (rs6000_gimplify_va_arg): New fn. (TARGET_GIMPLIFY_VA_ARG_EXPR): Define. +<<<<<<< ChangeLog +======= * config/sparc/sparc.c (sparc_gimplify_va_arg): New fn. +>>>>>>> 2.3910 * alias.c (get_varargs_alias_set): Just return 0 for now. * c-objc-common.c (c_tree_printer): Improve handling of %T. @@ -282,6 +300,15 @@ 2004-06-08 Richard Henderson +<<<<<<< ChangeLog + * gimple-low.c (struct lower_data): Replace the_return_label and + one_return_stmt with return_statements. + (lower_function_body): Process the entire list of return_statements. + (lower_return_expr): Check source value before unifying return_exprs. + * gimplify.c (gimplify_return_expr): Force the use of a temporary + for !aggregate_value_p. + * tree-gimple.c: Update RETURN_EXPR grammer. +======= * gimple-low.c (struct lower_data): Replace the_return_label and one_return_stmt with return_statements. (lower_function_body): Process the entire list of return_statements. @@ -289,6 +316,7 @@ * gimplify.c (gimplify_return_expr): Force the use of a temporary for !aggregate_value_p. * tree-gimple.c: Update RETURN_EXPR grammer. +>>>>>>> 2.3910 2004-06-08 Vladimir Makarov diff --git a/gcc/builtins.c b/gcc/builtins.c index 793d7bc9208..384173f2bd2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -4364,24 +4364,19 @@ expand_builtin_va_arg (tree valist, tree type) /* Like std_expand_builtin_va_arg, but gimplify instead of expanding. */ -void -std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) +tree +std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) { tree addr, t, type_size = NULL; tree align, alignm1; tree rounded_size; HOST_WIDE_INT boundary; - tree valist = TREE_OPERAND (*expr_p, 0); - tree type = TREE_TYPE (*expr_p); /* Compute the rounded size of the type. */ align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type); - /* Reduce valist it so it's sharable with the postqueue. */ - gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue); - /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually requires greater alignment, we must perform dynamic alignment. */ @@ -4434,9 +4429,6 @@ std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) type_size)))))); } - addr = convert (build_pointer_type (type), addr); - *expr_p = build1 (INDIRECT_REF, type, addr); - /* Compute new value for AP. */ if (! integer_zerop (rounded_size)) { @@ -4446,6 +4438,9 @@ std_gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) gimplify_stmt (&t); append_to_statement_list (t, post_p); } + + addr = fold_convert (build_pointer_type (type), addr); + return build_fold_indirect_ref (addr); } /* Return a dummy expression of type TYPE in order to keep going after an @@ -4489,8 +4484,7 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) if (TYPE_MAIN_VARIANT (want_va_type) != TYPE_MAIN_VARIANT (have_va_type)) { error ("first argument to `va_arg' not of type `va_list'"); - *expr_p = dummy_object (type); - return GS_ALL_DONE; + return GS_ERROR; } /* Generate a diagnostic for requesting data of a type that cannot @@ -4528,14 +4522,27 @@ gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p) { /* Make it easier for the backends by protecting the valist argument from multiple evaluations. */ - valist = stabilize_va_list (valist, 0); - TREE_OPERAND (*expr_p, 0) = valist; + if (TREE_CODE (va_list_type_node) == ARRAY_TYPE) + { + /* For this case, the backends will be expecting a pointer to + TREE_TYPE (va_list_type_node), but it's possible we've + actually been given an array (an actual va_list_type_node). + So fix it. */ + if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE) + { + tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node)); + valist = build_fold_addr_expr_with_type (valist, p1); + } + gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue); + } + else + gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue); if (!targetm.calls.gimplify_va_arg_expr) /* Once most targets are converted this should abort. */ return GS_ALL_DONE; - targetm.calls.gimplify_va_arg_expr (expr_p, pre_p, post_p); + *expr_p = targetm.calls.gimplify_va_arg_expr (valist, type, pre_p, post_p); return GS_OK; } } diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index b8bf569a512..7c9d67d66f9 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -6444,17 +6444,14 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, else if (TREE_CODE (type) == COMPLEX_TYPE) { tree real_part, imag_part, real_temp; + tree post = NULL_TREE; real_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base, offset, - pre_p, post_p); - append_to_statement_list (*post_p, pre_p); - *post_p = NULL; - + pre_p, &post); /* Copy the value into a temporary, lest the formal temporary be reused out from under us. */ - real_temp = create_tmp_var (TREE_TYPE (real_part), NULL); - t = build (MODIFY_EXPR, void_type_node, real_temp, real_part); - gimplify_and_add (t, pre_p); + real_temp = get_initialized_tmp_var (real_part, pre_p, &post); + append_to_statement_list (post, pre_p); imag_part = alpha_gimplify_va_arg_1 (TREE_TYPE (type), base, offset, pre_p, post_p); @@ -6491,19 +6488,13 @@ alpha_gimplify_va_arg_1 (tree type, tree base, tree offset, return build_fold_indirect_ref (addr); } -static void -alpha_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) +static tree +alpha_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { - tree valist, type, offset_field, base_field, offset, base, t; + tree offset_field, base_field, offset, base, t, r; if (TARGET_ABI_OPEN_VMS || TARGET_ABI_UNICOSMK) - { - std_gimplify_va_arg_expr (expr_p, pre_p, post_p); - return; - } - - valist = TREE_OPERAND (*expr_p, 0); - type = TREE_TYPE (*expr_p); + return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); base_field = TYPE_FIELDS (va_list_type_node); offset_field = TREE_CHAIN (base_field); @@ -6525,12 +6516,14 @@ alpha_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) /* Find the value. Note that this will be a stable indirection, or a composite of stable indirections in the case of complex. */ - *expr_p = alpha_gimplify_va_arg_1 (type, base, offset, pre_p, post_p); + r = alpha_gimplify_va_arg_1 (type, base, offset, pre_p, post_p); /* Stuff the offset temporary back into its field. */ t = build (MODIFY_EXPR, void_type_node, offset_field, fold_convert (TREE_TYPE (offset_field), offset)); gimplify_and_add (t, pre_p); + + return r; } /* Builtins. */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 75e80a651b2..cffbadff6e9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -878,7 +878,7 @@ static bool ix86_expand_carry_flag_compare (enum rtx_code, rtx, rtx, rtx*); static tree ix86_build_builtin_va_list (void); static void ix86_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); -static void ix86_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p); +static tree ix86_gimplify_va_arg (tree, tree, tree *, tree *); struct ix86_address { @@ -3418,11 +3418,9 @@ ix86_va_arg (tree valist, tree type) /* Lower VA_ARG_EXPR at gimplification time. */ -void -ix86_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) +tree +ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { - tree valist = TREE_OPERAND (*expr_p, 0); - tree type = TREE_TYPE (*expr_p); static const int intreg[6] = { 0, 1, 2, 3, 4, 5 }; tree f_gpr, f_fpr, f_ovf, f_sav; tree gpr, fpr, ovf, sav, t; @@ -3435,10 +3433,7 @@ ix86_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) /* Only 64bit target needs something special. */ if (!TARGET_64BIT) - { - std_gimplify_va_arg_expr (expr_p, pre_p, post_p); - return; - } + return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); f_fpr = TREE_CHAIN (f_gpr); @@ -3595,12 +3590,12 @@ ix86_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) src_addr = int_addr; src_offset = REGNO (reg) * 8; } - src_addr = convert (addr_type, src_addr); + src_addr = fold_convert (addr_type, src_addr); src_addr = fold (build2 (PLUS_EXPR, addr_type, src_addr, size_int (src_offset))); src = build_fold_indirect_ref (src_addr); - dest_addr = convert (addr_type, addr); + dest_addr = fold_convert (addr_type, addr); dest_addr = fold (build2 (PLUS_EXPR, addr_type, dest_addr, size_int (INTVAL (XEXP (slot, 1))))); dest = build_fold_indirect_ref (dest_addr); @@ -3661,11 +3656,11 @@ ix86_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) } ptrtype = build_pointer_type (type); - addr = convert (ptrtype, addr); + addr = fold_convert (ptrtype, addr); if (indirect_p) addr = build_fold_indirect_ref (addr); - *expr_p = build_fold_indirect_ref (addr); + return build_fold_indirect_ref (addr); } /* Return nonzero if OP is either a i387 or SSE fp register. */ diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 14fdfe25a1c..519dc0570b3 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -274,7 +274,7 @@ static void ia64_vms_init_libfuncs (void) static tree ia64_handle_model_attribute (tree *, tree, tree, int, bool *); static void ia64_encode_section_info (tree, rtx, int); static rtx ia64_struct_value_rtx (tree, int); -static void ia64_gimplify_va_arg (tree *, tree *, tree *); +static tree ia64_gimplify_va_arg (tree, tree, tree *, tree *); /* Table of valid machine attributes. */ @@ -3993,19 +3993,15 @@ ia64_va_arg (tree valist, tree type) return std_expand_builtin_va_arg (valist, type); } -static void -ia64_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) +static tree +ia64_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { - tree valist = TREE_OPERAND (*expr_p, 0); - tree type = TREE_TYPE (*expr_p); - /* Variable sized types are passed by reference. */ if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { - TREE_TYPE (*expr_p) = build_pointer_type (type); - std_gimplify_va_arg_expr (expr_p, pre_p, post_p); - *expr_p = build_fold_indirect_ref (*expr_p); - return; + tree ptrtype = build_pointer_type (type); + tree addr = std_gimplify_va_arg_expr (valist, ptrtype, pre_p, post_p); + return build_fold_indirect_ref (addr); } /* Aggregate arguments with alignment larger than 8 bytes start at @@ -4023,7 +4019,7 @@ ia64_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) gimplify_and_add (t, pre_p); } - std_gimplify_va_arg_expr (expr_p, pre_p, post_p); + return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); } /* Return 1 if function return value returned in memory. Return 0 if it is diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d0bc91d40d6..315cd50eda7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -440,7 +440,7 @@ static tree get_prev_label (tree function_name); #endif static tree rs6000_build_builtin_va_list (void); -static void rs6000_gimplify_va_arg (tree *, tree *, tree *); +static tree rs6000_gimplify_va_arg (tree, tree, tree *, tree *); /* Hash table stuff for keeping track of TOC entries. */ @@ -5292,11 +5292,9 @@ rs6000_va_arg (tree valist, tree type) return addr_rtx; } -void -rs6000_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) +tree +rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) { - tree valist = TREE_OPERAND (*expr_p, 0); - tree type = TREE_TYPE (*expr_p); tree f_gpr, f_fpr, f_res, f_ovf, f_sav; tree gpr, fpr, ovf, sav, reg, t, u; int indirect_p, size, rsize, n_reg, sav_ofs, sav_scale; @@ -5318,10 +5316,7 @@ rs6000_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) build_int_2 (POINTER_SIZE / BITS_PER_UNIT, 0)); t = build1 (NOP_EXPR, build_pointer_type (ptrtype), t); t = build_fold_indirect_ref (t); - t = build_fold_indirect_ref (t); - - *expr_p = t; - return; + return build_fold_indirect_ref (t); } if (targetm.calls.split_complex_arg && TREE_CODE (type) == COMPLEX_TYPE) @@ -5332,52 +5327,24 @@ rs6000_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) if (elem_size < UNITS_PER_WORD) { - tree real_part, imag_addr, dest_real, rr; + tree real_part, imag_part; tree post = NULL_TREE; - /* This is a bit tricky because we can't just feed the - VA_ARG_EXPRs back into gimplify_expr; if we did, - gimplify_va_arg_expr would complain about trying to pass a - float. */ - real_part = build1 (VA_ARG_EXPR, elem_type, valist); - rs6000_gimplify_va_arg (&real_part, pre_p, &post); - gimplify_expr (&real_part, pre_p, &post, is_gimple_val, - fb_rvalue); + real_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, + &post); + /* Copy the value into a temporary, lest the formal temporary + be reused out from under us. */ + real_part = get_initialized_tmp_var (real_part, pre_p, &post); append_to_statement_list (post, pre_p); - imag_addr = build1 (VA_ARG_EXPR, elem_type, valist); - rs6000_gimplify_va_arg (&imag_addr, pre_p, post_p); - imag_addr = build_fold_addr_expr (imag_addr); - gimplify_expr (&imag_addr, pre_p, post_p, is_gimple_val, - fb_rvalue); - - /* We're not returning the value here, but the address. - real_part and imag_part are not contiguous, and we know - there is space available to pack real_part next to - imag_part. float _Complex is not promoted to - double _Complex by the default promotion rules that - promote float to double. */ - if (2 * elem_size > UNITS_PER_WORD) - abort (); - - dest_real = fold (build2 (MINUS_EXPR, TREE_TYPE (imag_addr), - imag_addr, ssize_int (elem_size))); - gimplify_expr (&dest_real, pre_p, post_p, is_gimple_val, - fb_rvalue); + imag_part = rs6000_gimplify_va_arg (valist, elem_type, pre_p, + post_p); - rr = build_fold_indirect_ref (dest_real); - rr = build2 (MODIFY_EXPR, void_type_node, rr, real_part); - gimplify_and_add (rr, pre_p); - - dest_real = convert (build_pointer_type (type), dest_real); - *expr_p = build_fold_indirect_ref (dest_real); - - return; + return build (COMPLEX_EXPR, type, real_part, imag_part); } } - std_gimplify_va_arg_expr (expr_p, pre_p, post_p); - return; + return std_gimplify_va_arg_expr (valist, type, pre_p, post_p); } f_gpr = TYPE_FIELDS (TREE_TYPE (va_list_type_node)); @@ -5520,13 +5487,13 @@ rs6000_gimplify_va_arg (tree *expr_p, tree *pre_p, tree *post_p) if (indirect_p) { - addr = convert (build_pointer_type (ptrtype), addr); + addr = fold_convert (build_pointer_type (ptrtype), addr); addr = build_fold_indirect_ref (addr); } else - addr = convert (ptrtype, addr); + addr = fold_convert (ptrtype, addr); - *expr_p = build_fold_indirect_ref (addr); + return build_fold_indirect_ref (addr); } /* Builtins. */ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 082de59446c..0d4d647cf77 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3864,6 +3864,19 @@ The default value of this hook is @code{NULL}, which is treated as always false. @end deftypefn +@deftypefn {Target Hook} tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree @var{valist}, tree @var{type}, tree *@var{pre_p}, tree *@var{post_p}) +This hook performs target-specific gimplification of +@code{VA_ARG_EXPR}. The first two parameters correspond to the +arguments to @code{va_arg}; the latter two are as in +@code{gimplify.c:gimplify_expr}. + +You only need to define this hook if you also define +@code{EXPAND_BUILTIN_VA_ARG}; it is pretty easy to reuse the same code +for both. One significant difference is that +@code{EXPAND_BUILTIN_VA_ARG} returns an address, whereas this hook +produces an expression of type @var{type}, usually an @code{INDIRECT_REF}. +@end deftypefn + @node Scalar Return @subsection How Scalar Function Values Are Returned @cindex return values in registers diff --git a/gcc/target.h b/gcc/target.h index a2a564619fa..3b9af5da4f2 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -472,7 +472,7 @@ struct gcc_target bool (* split_complex_arg) (tree type); /* Gimplifies a VA_ARG_EXPR. */ - void (* gimplify_va_arg_expr) (tree *expr_p, tree *pre_p, + tree (* gimplify_va_arg_expr) (tree valist, tree type, tree *pre_p, tree *post_p); } calls; diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h index eb3dea86e85..c433c1eec5f 100644 --- a/gcc/tree-gimple.h +++ b/gcc/tree-gimple.h @@ -123,7 +123,7 @@ tree alloc_stmt_list (void); void free_stmt_list (tree); tree force_labels_r (tree *, int *, void *); enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *); -void std_gimplify_va_arg_expr (tree *, tree *, tree *); +tree std_gimplify_va_arg_expr (tree, tree, tree *, tree *); /* In tree-nested.c. */ extern void lower_nested_functions (tree); -- 2.30.2