builtins.c (std_gimplify_va_arg_expr): Hoist valist into a temporary.
authorRichard Henderson <rth@redhat.com>
Fri, 9 Jul 2004 03:36:31 +0000 (20:36 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 9 Jul 2004 03:36:31 +0000 (20:36 -0700)
        * builtins.c (std_gimplify_va_arg_expr): Hoist valist into a
        temporary.  Use bit arithmetic to align.

From-SVN: r84342

gcc/ChangeLog
gcc/builtins.c

index e49ec16147e2563a37b8e80c0c543870fba8909d..bfeb09aeab33693313dead431f4f070b2e32971e 100644 (file)
@@ -1,3 +1,8 @@
+2004-07-08  Richard Henderson  <rth@redhat.com>
+
+       * builtins.c (std_gimplify_va_arg_expr): Hoist valist into a
+       temporary.  Use bit arithmetic to align.
+
 2004-07-08  Jerry Quinn  <jlquinn@optonline.net>
 
        * alias.c (nonlocal_mentioned_p, nonlocal_referenced_p,
index 26d4867e389d0a9bc972dea29eab10fc901edf1d..ecb7841ec6d8848963f6831860a6718a0f09a1fc 100644 (file)
@@ -4474,15 +4474,19 @@ 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 align, alignm1, malign;
   tree rounded_size;
+  tree valist_tmp;
   HOST_WIDE_INT boundary;
 
   /* Compute the rounded size of the type.  */
   align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
   alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1);
+  malign = size_int (-(PARM_BOUNDARY / BITS_PER_UNIT));
   boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
 
+  valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+
   /* va_list pointer is aligned to PARM_BOUNDARY.  If argument actually
      requires greater alignment, we must perform dynamic alignment.  */
 
@@ -4490,17 +4494,15 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
     {
       if (!PAD_VARARGS_DOWN)
        {
-         t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
-                     build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
+         t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+                     build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp,
                              build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
-         gimplify_stmt (&t);
-         append_to_statement_list (t, pre_p);
+         gimplify_and_add (t, pre_p);
        }
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
-                 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist,
+      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+                 build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp,
                          build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
-      gimplify_stmt (&t);
-      append_to_statement_list (t, pre_p);
+      gimplify_and_add (t, pre_p);
     }
   if (type == error_mark_node
       || (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL
@@ -4509,17 +4511,15 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
   else
     {
       rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
-      rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype,
-                                  rounded_size, align));
-      rounded_size = fold (build2 (MULT_EXPR, sizetype,
-                                  rounded_size, align));
+      rounded_size = fold (build2 (BIT_AND_EXPR, sizetype,
+                                  rounded_size, malign));
     }
 
   /* Reduce rounded_size so it's sharable with the postqueue.  */
   gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
 
   /* Get AP.  */
-  addr = valist;
+  addr = valist_tmp;
   if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
     {
       /* Small args are padded downward.  */
@@ -4536,14 +4536,10 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
     }
 
   /* Compute new value for AP.  */
-  if (! integer_zerop (rounded_size))
-    {
-      t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
-                 build2 (PLUS_EXPR, TREE_TYPE (valist), valist,
-                         rounded_size));
-      gimplify_stmt (&t);
-      append_to_statement_list (t, post_p);
-    }
+  t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
+             fold (build2 (PLUS_EXPR, TREE_TYPE (valist),
+                           valist_tmp, rounded_size)));
+  gimplify_and_add (t, pre_p);
 
   addr = fold_convert (build_pointer_type (type), addr);
   return build_fold_indirect_ref (addr);