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:
parent
f1f39752d6
commit
ce48579b9a
@ -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
|
||||||
|
129
gcc/calls.c
129
gcc/calls.c
@ -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
|
||||||
|
@ -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). */
|
||||||
|
Loading…
Reference in New Issue
Block a user