aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2004-06-10 11:49:49 -0400
committerJason Merrill <jason@gcc.gnu.org>2004-06-10 11:49:49 -0400
commit23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e (patch)
tree97aaa6402c26723b11a9196283dc0e2e9dd4e5dc
parent339586c817ea6e5481d1d10f604f50c81ead3645 (diff)
downloadgcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.zip
gcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.tar.gz
gcc-23a60a0436f48f1de4e5bf124f29f0e4a32e7d4e.tar.bz2
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
-rw-r--r--gcc/ChangeLog28
-rw-r--r--gcc/builtins.c37
-rw-r--r--gcc/config/alpha/alpha.c29
-rw-r--r--gcc/config/i386/i386.c21
-rw-r--r--gcc/config/ia64/ia64.c18
-rw-r--r--gcc/config/rs6000/rs6000.c67
-rw-r--r--gcc/doc/tm.texi13
-rw-r--r--gcc/target.h2
-rw-r--r--gcc/tree-gimple.h2
9 files changed, 108 insertions, 109 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dc7b302..48af490 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2004-06-10 Jason Merrill <jason@redhat.com>
+
+ * 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 <rakdver@atrey.karlin.mff.cuni.cz>
* 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 <rth@redhat.com>
+<<<<<<< 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 <vmakarov@redhat.com>
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 793d7bc..384173f 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 b8bf569..7c9d67d 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 75e80a6..cffbadf 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 14fdfe2..519dc05 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 d0bc91d..315cd50 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 082de59..0d4d647 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 a2a5646..3b9af5d 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 eb3dea8..c433c1e 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);