target.h (struct gcc_target): Change gimplify_va_arg_expr hook signature.
authorJason Merrill <jason@gcc.gnu.org>
Thu, 10 Jun 2004 15:49:49 +0000 (11:49 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 10 Jun 2004 15:49:49 +0000 (11:49 -0400)
        * 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
gcc/builtins.c
gcc/config/alpha/alpha.c
gcc/config/i386/i386.c
gcc/config/ia64/ia64.c
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/target.h
gcc/tree-gimple.h

index dc7b3026d4ff40a6c6dd3fd9f1a0b85f3d5d1a14..48af490674e8b1269cedba4a095df9f0f97ac3d8 100644 (file)
@@ -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.
        (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.
 
 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.
        * 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>
 
index 793d7bc9208f08f573cd1bbef11be0e8aee97baa..384173f2bd20914254d519746055ab442f4cbd71 100644 (file)
@@ -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;
     }
 }
index b8bf569a51242adad424499566ddc5aadbae91e6..7c9d67d66f9813f10e3a8f2fc49d5745262acc96 100644 (file)
@@ -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;
 }
 \f
 /* Builtins.  */
index 75e80a651b23732f23b9e59265cc0ba22099266b..cffbadff6e997aceb15a8456e136c5bd90a374d0 100644 (file)
@@ -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);
 }
 \f
 /* Return nonzero if OP is either a i387 or SSE fp register.  */
index 14fdfe25a1c48a9830360d206a513044e601a46a..519dc0570b3d6aeeb1d4e512e51d642b2cfdbb99 100644 (file)
@@ -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 *);
 
 \f
 /* 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);
 }
 \f
 /* Return 1 if function return value returned in memory.  Return 0 if it is
index d0bc91d40d6bcde5d651a115f2dab3f59a6934ce..315cd50eda779064f399e67c52231be06d3283ee 100644 (file)
@@ -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.  */
index 082de59446cb831a127b811c2869a0a249d5c396..0d4d647cf7701688cba83dbcadeb56cbbbf6bc44 100644 (file)
@@ -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
index a2a564619fae1d29df1ff2eac941c899510a7e0e..3b9af5da4f23647990887043ed70b4029fb3175e 100644 (file)
@@ -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;
 
index eb3dea86e85037c967379d76fc19a4f2ff855fc0..c433c1eec5fc485f4dc024b2d43e6057e3f52ea5 100644 (file)
@@ -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);