diff options
author | Olivier Hainque <hainque@act-europe.fr> | 2003-04-19 00:20:55 +0200 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2003-04-18 18:20:55 -0400 |
commit | 38afb23f55aae5e04bcc5e401ae0fb1d26b0ee22 (patch) | |
tree | 704b899798a4f8f6d32c2d5504f9f23b2f2cb366 /gcc | |
parent | e59baa1f83fd053979c637f12f89cdf04d1d5ed5 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/calls.c | 113 |
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. */ |