aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorOlivier Hainque <hainque@act-europe.fr>2003-04-19 00:20:55 +0200
committerRichard Kenner <kenner@gcc.gnu.org>2003-04-18 18:20:55 -0400
commit38afb23f55aae5e04bcc5e401ae0fb1d26b0ee22 (patch)
tree704b899798a4f8f6d32c2d5504f9f23b2f2cb366 /gcc
parente59baa1f83fd053979c637f12f89cdf04d1d5ed5 (diff)
downloadgcc-38afb23f55aae5e04bcc5e401ae0fb1d26b0ee22.zip
gcc-38afb23f55aae5e04bcc5e401ae0fb1d26b0ee22.tar.gz
gcc-38afb23f55aae5e04bcc5e401ae0fb1d26b0ee22.tar.bz2
calls.c (expand_call): Move special case for constructor calls to right place.
* calls.c (expand_call): Move special case for constructor calls to right place. Ensures constructor calls used to initialize arguments get a clean outgoing argument block for themselves. Move check for stack deallocation completeness until after last deallocation. Add stack_pointer_delta to set of state variables saved and restored along with current stack_level. From-SVN: r65795
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/calls.c113
2 files changed, 72 insertions, 48 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a9d5e2..0847ad9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2003-04-18 Olivier Hainque <hainque@act-europe.fr>
+ * calls.c (expand_call): Move special case for constructor calls
+ to right place. Ensures constructor calls used to initialize
+ arguments get a clean outgoing argument block for themselves.
+ Move check for stack deallocation completeness until after last
+ deallocation. Add stack_pointer_delta to set of state
+ variables saved and restored along with current stack_level.
+
* integrate.c (expand_inline_function): Ensure non-const actuals
don't end up const in the caller's flow after conversion to possibly
const formal type.
diff --git a/gcc/calls.c b/gcc/calls.c
index 1dc5fc5..42e2bf7 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2200,12 +2200,20 @@ expand_call (exp, target, ignore)
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
char *initial_stack_usage_map = stack_usage_map;
- int old_stack_arg_under_construction = 0;
+ int old_stack_allocated;
+
+ /* State variables to track stack modifications. */
rtx old_stack_level = 0;
+ int old_stack_arg_under_construction = 0;
int old_pending_adj = 0;
int old_inhibit_defer_pop = inhibit_defer_pop;
- int old_stack_allocated;
+
+ /* Some stack pointer alterations we make are performed via
+ allocate_dynamic_stack_space. This modifies the stack_pointer_delta,
+ which we then also need to save/restore along the way. */
+ int old_stack_pointer_delta;
+
rtx call_fusage;
tree p = TREE_OPERAND (exp, 0);
tree addr = TREE_OPERAND (exp, 0);
@@ -2751,6 +2759,7 @@ expand_call (exp, target, ignore)
if (old_stack_level == 0)
{
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+ old_stack_pointer_delta = stack_pointer_delta;
old_pending_adj = pending_stack_adjust;
pending_stack_adjust = 0;
/* stack_arg_under_construction says whether a stack arg is
@@ -2877,53 +2886,58 @@ expand_call (exp, target, ignore)
VIRTUAL_OUTGOING_ARGS_RTX changes as well. But might
as well always do it. */
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. */
- if (stack_arg_under_construction)
- {
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* 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. */
+ if (stack_arg_under_construction)
+ {
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- rtx push_size = GEN_INT (reg_parm_stack_space
- + adjusted_args_size.constant);
+ rtx push_size = GEN_INT (reg_parm_stack_space
+ + adjusted_args_size.constant);
#else
- rtx push_size = GEN_INT (adjusted_args_size.constant);
+ rtx push_size = GEN_INT (adjusted_args_size.constant);
#endif
- if (old_stack_level == 0)
- {
- 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 = 0;
- /* Make a new map for the new argument list. */
- stack_usage_map = (char *)
- alloca (highest_outgoing_arg_in_use);
- memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
- highest_outgoing_arg_in_use = 0;
- }
- 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. */
- for (i = 0; i < num_actuals; i++)
- if (args[i].pass_on_stack)
- {
- argblock = copy_addr_to_reg (argblock);
- break;
- }
+ if (old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, &old_stack_level,
+ NULL_RTX);
+ old_stack_pointer_delta = stack_pointer_delta;
+ 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 = 0;
+ /* Make a new map for the new argument list. */
+ stack_usage_map = (char *)
+ alloca (highest_outgoing_arg_in_use);
+ memset (stack_usage_map, 0, highest_outgoing_arg_in_use);
+ highest_outgoing_arg_in_use = 0;
}
+ 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. */
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].pass_on_stack)
+ {
+ argblock = copy_addr_to_reg (argblock);
+ break;
+ }
+ }
+
compute_argument_addresses (args, argblock, num_actuals);
/* If we push args individually in reverse order, perform stack alignment
@@ -3087,11 +3101,6 @@ expand_call (exp, target, ignore)
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
flags, & args_so_far);
- /* Verify that we've deallocated all the stack we used. */
- if (pass
- && old_stack_allocated != stack_pointer_delta - pending_stack_adjust)
- abort ();
-
/* If call is cse'able, make appropriate pair of reg-notes around it.
Test valreg so we don't crash; may safely ignore `const'
if return type is void. Disable for PARALLEL return values, because
@@ -3313,6 +3322,7 @@ expand_call (exp, target, ignore)
if (old_stack_level && ! (flags & ECF_SP_DEPRESSED))
{
emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
+ stack_pointer_delta = old_stack_pointer_delta;
pending_stack_adjust = old_pending_adj;
stack_arg_under_construction = old_stack_arg_under_construction;
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
@@ -3393,7 +3403,14 @@ expand_call (exp, target, ignore)
sbitmap_free (stored_args_map);
}
else
- normal_call_insns = insns;
+ {
+ normal_call_insns = insns;
+
+ /* Verify that we've deallocated all the stack we used. */
+ if (old_stack_allocated !=
+ stack_pointer_delta - pending_stack_adjust)
+ abort ();
+ }
/* If something prevents making this a sibling call,
zero out the sequence. */