Commit 37369edc by Richard Henderson Committed by Richard Henderson

builtins.c (std_gimplify_va_arg_expr): Hoist valist into a temporary.

        * builtins.c (std_gimplify_va_arg_expr): Hoist valist into a
        temporary.  Use bit arithmetic to align.

From-SVN: r84342
parent 4b4bf941
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> 2004-07-08 Jerry Quinn <jlquinn@optonline.net>
* alias.c (nonlocal_mentioned_p, nonlocal_referenced_p, * alias.c (nonlocal_mentioned_p, nonlocal_referenced_p,
......
...@@ -4474,15 +4474,19 @@ tree ...@@ -4474,15 +4474,19 @@ tree
std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
{ {
tree addr, t, type_size = NULL; tree addr, t, type_size = NULL;
tree align, alignm1; tree align, alignm1, malign;
tree rounded_size; tree rounded_size;
tree valist_tmp;
HOST_WIDE_INT boundary; HOST_WIDE_INT boundary;
/* Compute the rounded size of the type. */ /* Compute the rounded size of the type. */
align = size_int (PARM_BOUNDARY / BITS_PER_UNIT); align = size_int (PARM_BOUNDARY / BITS_PER_UNIT);
alignm1 = size_int (PARM_BOUNDARY / BITS_PER_UNIT - 1); 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); 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 /* va_list pointer is aligned to PARM_BOUNDARY. If argument actually
requires greater alignment, we must perform dynamic alignment. */ 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) ...@@ -4490,17 +4494,15 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
{ {
if (!PAD_VARARGS_DOWN) if (!PAD_VARARGS_DOWN)
{ {
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
build2 (PLUS_EXPR, TREE_TYPE (valist), valist, build2 (PLUS_EXPR, TREE_TYPE (valist), valist_tmp,
build_int_2 (boundary / BITS_PER_UNIT - 1, 0))); build_int_2 (boundary / BITS_PER_UNIT - 1, 0)));
gimplify_stmt (&t); gimplify_and_add (t, pre_p);
append_to_statement_list (t, pre_p);
} }
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist, build2 (BIT_AND_EXPR, TREE_TYPE (valist), valist_tmp,
build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1))); build_int_2 (~(boundary / BITS_PER_UNIT - 1), -1)));
gimplify_stmt (&t); gimplify_and_add (t, pre_p);
append_to_statement_list (t, pre_p);
} }
if (type == error_mark_node if (type == error_mark_node
|| (type_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type))) == NULL || (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) ...@@ -4509,17 +4511,15 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
else else
{ {
rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1)); rounded_size = fold (build2 (PLUS_EXPR, sizetype, type_size, alignm1));
rounded_size = fold (build2 (TRUNC_DIV_EXPR, sizetype, rounded_size = fold (build2 (BIT_AND_EXPR, sizetype,
rounded_size, align)); rounded_size, malign));
rounded_size = fold (build2 (MULT_EXPR, sizetype,
rounded_size, align));
} }
/* Reduce rounded_size so it's sharable with the postqueue. */ /* Reduce rounded_size so it's sharable with the postqueue. */
gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue); gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
/* Get AP. */ /* Get AP. */
addr = valist; addr = valist_tmp;
if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size)) if (PAD_VARARGS_DOWN && ! integer_zerop (rounded_size))
{ {
/* Small args are padded downward. */ /* Small args are padded downward. */
...@@ -4536,14 +4536,10 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p) ...@@ -4536,14 +4536,10 @@ std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
} }
/* Compute new value for AP. */ /* Compute new value for AP. */
if (! integer_zerop (rounded_size)) t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist,
{ fold (build2 (PLUS_EXPR, TREE_TYPE (valist),
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, valist_tmp, rounded_size)));
build2 (PLUS_EXPR, TREE_TYPE (valist), valist, gimplify_and_add (t, pre_p);
rounded_size));
gimplify_stmt (&t);
append_to_statement_list (t, post_p);
}
addr = fold_convert (build_pointer_type (type), addr); addr = fold_convert (build_pointer_type (type), addr);
return build_fold_indirect_ref (addr); return build_fold_indirect_ref (addr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment