calls.c (combine_pending_stack_adjustment_and_call): Return the adjustment; don't do the stack adjust.

* calls.c (combine_pending_stack_adjustment_and_call): Return the
        adjustment; don't do the stack adjust.
        (expand_call): Call compute_argument_block_size right before
        allocating the block; update comment; don't do alignment sanity
        checking for sibling call; use args_size instead of
        unadjusted_args_size before args_size is adjusted.  Use
        combine_pending_stack_adjustment_and_call to compute stack adjust
        for must_preallocate case.

        * expr.c (push_block): Remove shadow `temp' in inner scope.

Co-Authored-By: Jan Hubicka <jh@suse.cz>

From-SVN: r33516
This commit is contained in:
Richard Henderson 2000-04-28 11:25:23 -07:00 committed by Richard Henderson
parent f1f39752d6
commit ce48579b9a
3 changed files with 92 additions and 54 deletions

View File

@ -1,3 +1,17 @@
2000-04-28 Richard Henderson <rth@cygnus.com>
Jan Hubicka <jh@suse.cz>
* calls.c (combine_pending_stack_adjustment_and_call): Return the
adjustment; don't do the stack adjust.
(expand_call): Call compute_argument_block_size right before
allocating the block; update comment; don't do alignment sanity
checking for sibling call; use args_size instead of
unadjusted_args_size before args_size is adjusted. Use
combine_pending_stack_adjustment_and_call to compute stack adjust
for must_preallocate case.
* expr.c (push_block): Remove shadow `temp' in inner scope.
2000-04-28 Jason Merrill <jason@casey.cygnus.com> 2000-04-28 Jason Merrill <jason@casey.cygnus.com>
* toplev.c (rest_of_compilation): Call * toplev.c (rest_of_compilation): Call

View File

@ -210,7 +210,7 @@ static int special_function_p PARAMS ((tree, int));
static int flags_from_decl_or_type PARAMS ((tree)); static int flags_from_decl_or_type PARAMS ((tree));
static rtx try_to_integrate PARAMS ((tree, tree, rtx, static rtx try_to_integrate PARAMS ((tree, tree, rtx,
int, tree, rtx)); int, tree, rtx));
static void combine_pending_stack_adjustment_and_call static int combine_pending_stack_adjustment_and_call
PARAMS ((int, struct args_size *, int)); PARAMS ((int, struct args_size *, int));
#ifdef REG_PARM_STACK_SPACE #ifdef REG_PARM_STACK_SPACE
@ -1860,13 +1860,13 @@ try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
/* We need to pop PENDING_STACK_ADJUST bytes. But, if the arguments /* We need to pop PENDING_STACK_ADJUST bytes. But, if the arguments
wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY wouldn't fill up an even multiple of PREFERRED_UNIT_STACK_BOUNDARY
bytes, then we would need to push some additional bytes to pad the bytes, then we would need to push some additional bytes to pad the
arguments. So, we adjust the stack pointer by an amount that will arguments. So, we compute an adjust to the stack pointer for an
leave the stack under-aligned by UNADJUSTED_ARGS_SIZE bytes. Then, amount that will leave the stack under-aligned by UNADJUSTED_ARGS_SIZE
when the arguments are pushed the stack will be perfectly aligned. bytes. Then, when the arguments are pushed the stack will be perfectly
ARGS_SIZE->CONSTANT is set to the number of bytes that should be aligned. ARGS_SIZE->CONSTANT is set to the number of bytes that should
popped after the call. */ be popped after the call. Returns the adjustment. */
static void static int
combine_pending_stack_adjustment_and_call (unadjusted_args_size, combine_pending_stack_adjustment_and_call (unadjusted_args_size,
args_size, args_size,
preferred_unit_stack_boundary) preferred_unit_stack_boundary)
@ -1910,9 +1910,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
args_size->constant args_size->constant
= pending_stack_adjust - adjustment + unadjusted_args_size; = pending_stack_adjust - adjustment + unadjusted_args_size;
/* Push the right number of bytes. */ return adjustment;
pending_stack_adjust = adjustment;
do_pending_stack_adjust ();
} }
/* Generate all the code for a function call /* Generate all the code for a function call
@ -2504,19 +2502,9 @@ expand_call (exp, target, ignore)
sibcall_failure = 1; sibcall_failure = 1;
} }
/* Compute the actual size of the argument block required. The variable
and constant sizes must be combined, the size may have to be rounded,
and there may be a minimum required size. When generating a sibcall
pattern, do not round up, since we'll be re-using whatever space our
caller provided. */
unadjusted_args_size
= compute_argument_block_size (reg_parm_stack_space, &args_size,
(pass == 0 ? 0
: preferred_stack_boundary));
/* If the callee pops its own arguments, then it must pop exactly /* If the callee pops its own arguments, then it must pop exactly
the same number of arguments as the current function. */ the same number of arguments as the current function. */
if (RETURN_POPS_ARGS (fndecl, funtype, unadjusted_args_size) if (RETURN_POPS_ARGS (fndecl, funtype, args_size.constant)
!= RETURN_POPS_ARGS (current_function_decl, != RETURN_POPS_ARGS (current_function_decl,
TREE_TYPE (current_function_decl), TREE_TYPE (current_function_decl),
current_function_args_size)) current_function_args_size))
@ -2548,14 +2536,25 @@ expand_call (exp, target, ignore)
if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC)) if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC))
start_sequence (); start_sequence ();
/* Compute the actual size of the argument block required. The variable
and constant sizes must be combined, the size may have to be rounded,
and there may be a minimum required size. When generating a sibcall
pattern, do not round up, since we'll be re-using whatever space our
caller provided. */
unadjusted_args_size
= compute_argument_block_size (reg_parm_stack_space, &args_size,
(pass == 0 ? 0
: preferred_stack_boundary));
old_stack_allocated = stack_pointer_delta - pending_stack_adjust; old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
/* The argument block when performing a sibling call is the /* The argument block when performing a sibling call is the
incoming argument block. */ incoming argument block. */
if (pass == 0) if (pass == 0)
argblock = virtual_incoming_args_rtx; argblock = virtual_incoming_args_rtx;
/* If we have no actual push instructions, or shouldn't use them, /* If we have no actual push instructions, or shouldn't use them,
make space for all args right now. */ make space for all args right now. */
else if (args_size.var != 0) else if (args_size.var != 0)
{ {
if (old_stack_level == 0) if (old_stack_level == 0)
@ -2644,20 +2643,36 @@ expand_call (exp, target, ignore)
if (inhibit_defer_pop == 0) if (inhibit_defer_pop == 0)
{ {
/* Try to reuse some or all of the pending_stack_adjust /* Try to reuse some or all of the pending_stack_adjust
to get this space. Maybe we can avoid any pushing. */ to get this space. */
if (needed > pending_stack_adjust) needed
= (combine_pending_stack_adjustment_and_call
(unadjusted_args_size,
&args_size,
preferred_unit_stack_boundary));
/* combine_pending_stack_adjustment_and_call computes
an adjustment before the arguments are allocated.
Account for them and see whether or not the stack
needs to go up or down. */
needed = unadjusted_args_size - needed;
if (needed < 0)
{ {
needed -= pending_stack_adjust; /* We're releasing stack space. */
pending_stack_adjust = 0; /* ??? We can avoid any adjustment at all if we're
} already aligned. FIXME. */
else pending_stack_adjust = -needed;
{ do_pending_stack_adjust ();
pending_stack_adjust -= needed;
needed = 0; needed = 0;
} }
else
/* We need to allocate space. We'll do that in
push_block below. */
pending_stack_adjust = 0;
} }
/* Special case this because overhead of `push_block' in this
case is non-trivial. */ /* Special case this because overhead of `push_block' in
this case is non-trivial. */
if (needed == 0) if (needed == 0)
argblock = virtual_outgoing_args_rtx; argblock = virtual_outgoing_args_rtx;
else else
@ -2673,35 +2688,41 @@ expand_call (exp, target, ignore)
argblock = copy_to_reg (argblock); argblock = copy_to_reg (argblock);
/* The save/restore code in store_one_arg handles all /* The save/restore code in store_one_arg handles all
cases except one: cases except one: a constructor call (including a C
a constructor call (including a C function returning function returning a BLKmode struct) to initialize
a BLKmode struct) to initialize an argument. */ an argument. */
if (stack_arg_under_construction) if (stack_arg_under_construction)
{ {
#ifndef OUTGOING_REG_PARM_STACK_SPACE #ifndef OUTGOING_REG_PARM_STACK_SPACE
rtx push_size = GEN_INT (reg_parm_stack_space + args_size.constant); rtx push_size = GEN_INT (reg_parm_stack_space
+ args_size.constant);
#else #else
rtx push_size = GEN_INT (args_size.constant); rtx push_size = GEN_INT (args_size.constant);
#endif #endif
if (old_stack_level == 0) if (old_stack_level == 0)
{ {
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); emit_stack_save (SAVE_BLOCK, &old_stack_level,
NULL_RTX);
old_pending_adj = pending_stack_adjust; old_pending_adj = pending_stack_adjust;
pending_stack_adjust = 0; pending_stack_adjust = 0;
/* stack_arg_under_construction says whether a stack arg is /* stack_arg_under_construction says whether a stack
being constructed at the old stack level. Pushing the stack arg is being constructed at the old stack level.
gets a clean outgoing argument block. */ Pushing the stack gets a clean outgoing argument
old_stack_arg_under_construction = stack_arg_under_construction; block. */
old_stack_arg_under_construction
= stack_arg_under_construction;
stack_arg_under_construction = 0; stack_arg_under_construction = 0;
/* Make a new map for the new argument list. */ /* Make a new map for the new argument list. */
stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use); stack_usage_map = (char *)
alloca (highest_outgoing_arg_in_use);
bzero (stack_usage_map, highest_outgoing_arg_in_use); bzero (stack_usage_map, highest_outgoing_arg_in_use);
highest_outgoing_arg_in_use = 0; highest_outgoing_arg_in_use = 0;
} }
allocate_dynamic_stack_space (push_size, NULL_RTX, BITS_PER_UNIT); allocate_dynamic_stack_space (push_size, NULL_RTX,
BITS_PER_UNIT);
} }
/* If argument evaluation might modify the stack pointer, copy the /* If argument evaluation might modify the stack pointer,
address of the argument list to a register. */ copy the address of the argument list to a register. */
for (i = 0; i < num_actuals; i++) for (i = 0; i < num_actuals; i++)
if (args[i].pass_on_stack) if (args[i].pass_on_stack)
{ {
@ -2725,10 +2746,14 @@ expand_call (exp, target, ignore)
if (pending_stack_adjust if (pending_stack_adjust
&& ! (flags & (ECF_CONST | ECF_PURE)) && ! (flags & (ECF_CONST | ECF_PURE))
&& ! inhibit_defer_pop) && ! inhibit_defer_pop)
combine_pending_stack_adjustment_and_call {
(unadjusted_args_size, pending_stack_adjust
&args_size, = (combine_pending_stack_adjustment_and_call
preferred_unit_stack_boundary); (unadjusted_args_size,
&args_size,
preferred_unit_stack_boundary));
do_pending_stack_adjust ();
}
else if (argblock == 0) else if (argblock == 0)
anti_adjust_stack (GEN_INT (args_size.constant anti_adjust_stack (GEN_INT (args_size.constant
- unadjusted_args_size)); - unadjusted_args_size));
@ -2862,8 +2887,8 @@ expand_call (exp, target, ignore)
now! */ now! */
#ifdef PREFERRED_STACK_BOUNDARY #ifdef PREFERRED_STACK_BOUNDARY
/* Stack must to be properly aligned now. */ /* Stack must be properly aligned now. */
if (stack_pointer_delta & (preferred_stack_boundary / BITS_PER_UNIT - 1)) if (pass && stack_pointer_delta % preferred_unit_stack_boundary)
abort(); abort();
#endif #endif
@ -3767,7 +3792,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
? hard_libcall_value (outmode) : NULL_RTX); ? hard_libcall_value (outmode) : NULL_RTX);
#ifdef PREFERRED_STACK_BOUNDARY #ifdef PREFERRED_STACK_BOUNDARY
/* Stack must to be properly aligned now. */ /* Stack must be properly aligned now. */
if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1)) if (stack_pointer_delta & (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT - 1))
abort(); abort();
#endif #endif

View File

@ -2840,7 +2840,7 @@ push_block (size, extra, below)
anti_adjust_stack (size); anti_adjust_stack (size);
else else
{ {
rtx temp = copy_to_mode_reg (Pmode, size); temp = copy_to_mode_reg (Pmode, size);
if (extra != 0) if (extra != 0)
temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra), temp = expand_binop (Pmode, add_optab, temp, GEN_INT (extra),
temp, 0, OPTAB_LIB_WIDEN); temp, 0, OPTAB_LIB_WIDEN);
@ -2857,7 +2857,6 @@ push_block (size, extra, below)
if (1) if (1)
#endif #endif
{ {
/* Return the lowest stack address when STACK or ARGS grow downward and /* Return the lowest stack address when STACK or ARGS grow downward and
we are not aaccumulating outgoing arguments (the c4x port uses such we are not aaccumulating outgoing arguments (the c4x port uses such
conventions). */ conventions). */