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>
* 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 rtx try_to_integrate PARAMS ((tree, 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));
#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
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
arguments. So, we adjust the stack pointer by an amount that will
leave the stack under-aligned by UNADJUSTED_ARGS_SIZE bytes. Then,
when the arguments are pushed the stack will be perfectly aligned.
ARGS_SIZE->CONSTANT is set to the number of bytes that should be
popped after the call. */
arguments. So, we compute an adjust to the stack pointer for an
amount that will leave the stack under-aligned by UNADJUSTED_ARGS_SIZE
bytes. Then, when the arguments are pushed the stack will be perfectly
aligned. ARGS_SIZE->CONSTANT is set to the number of bytes that should
be popped after the call. Returns the adjustment. */
static void
static int
combine_pending_stack_adjustment_and_call (unadjusted_args_size,
args_size,
preferred_unit_stack_boundary)
@ -1910,9 +1910,7 @@ combine_pending_stack_adjustment_and_call (unadjusted_args_size,
args_size->constant
= pending_stack_adjust - adjustment + unadjusted_args_size;
/* Push the right number of bytes. */
pending_stack_adjust = adjustment;
do_pending_stack_adjust ();
return adjustment;
}
/* Generate all the code for a function call
@ -2504,19 +2502,9 @@ expand_call (exp, target, ignore)
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
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,
TREE_TYPE (current_function_decl),
current_function_args_size))
@ -2548,14 +2536,25 @@ expand_call (exp, target, ignore)
if (flags & (ECF_CONST | ECF_PURE | ECF_MALLOC))
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;
/* The argument block when performing a sibling call is the
incoming argument block. */
if (pass == 0)
argblock = virtual_incoming_args_rtx;
/* If we have no actual push instructions, or shouldn't use them,
make space for all args right now. */
else if (args_size.var != 0)
{
if (old_stack_level == 0)
@ -2644,20 +2643,36 @@ expand_call (exp, target, ignore)
if (inhibit_defer_pop == 0)
{
/* Try to reuse some or all of the pending_stack_adjust
to get this space. Maybe we can avoid any pushing. */
if (needed > pending_stack_adjust)
to get this space. */
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;
pending_stack_adjust = 0;
}
else
{
pending_stack_adjust -= needed;
/* We're releasing stack space. */
/* ??? We can avoid any adjustment at all if we're
already aligned. FIXME. */
pending_stack_adjust = -needed;
do_pending_stack_adjust ();
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)
argblock = virtual_outgoing_args_rtx;
else
@ -2673,35 +2688,41 @@ expand_call (exp, target, ignore)
argblock = copy_to_reg (argblock);
/* The save/restore code in store_one_arg handles all
cases except one:
a constructor call (including a C function returning
a BLKmode struct) to initialize an argument. */
cases except one: a constructor call (including a C
function returning a BLKmode struct) to initialize
an argument. */
if (stack_arg_under_construction)
{
#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
rtx push_size = GEN_INT (args_size.constant);
#endif
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;
pending_stack_adjust = 0;
/* stack_arg_under_construction says whether a stack arg is
being constructed at the old stack level. Pushing the stack
gets a clean outgoing argument block. */
old_stack_arg_under_construction = stack_arg_under_construction;
/* stack_arg_under_construction says whether a stack
arg is being constructed at the old stack level.
Pushing the stack gets a clean outgoing argument
block. */
old_stack_arg_under_construction
= stack_arg_under_construction;
stack_arg_under_construction = 0;
/* 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);
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
address of the argument list to a register. */
/* If argument evaluation might modify the stack pointer,
copy the address of the argument list to a register. */
for (i = 0; i < num_actuals; i++)
if (args[i].pass_on_stack)
{
@ -2725,10 +2746,14 @@ expand_call (exp, target, ignore)
if (pending_stack_adjust
&& ! (flags & (ECF_CONST | ECF_PURE))
&& ! inhibit_defer_pop)
combine_pending_stack_adjustment_and_call
(unadjusted_args_size,
&args_size,
preferred_unit_stack_boundary);
{
pending_stack_adjust
= (combine_pending_stack_adjustment_and_call
(unadjusted_args_size,
&args_size,
preferred_unit_stack_boundary));
do_pending_stack_adjust ();
}
else if (argblock == 0)
anti_adjust_stack (GEN_INT (args_size.constant
- unadjusted_args_size));
@ -2862,8 +2887,8 @@ expand_call (exp, target, ignore)
now! */
#ifdef PREFERRED_STACK_BOUNDARY
/* Stack must to be properly aligned now. */
if (stack_pointer_delta & (preferred_stack_boundary / BITS_PER_UNIT - 1))
/* Stack must be properly aligned now. */
if (pass && stack_pointer_delta % preferred_unit_stack_boundary)
abort();
#endif
@ -3767,7 +3792,7 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p)
? hard_libcall_value (outmode) : NULL_RTX);
#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))
abort();
#endif

View File

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