diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 28a3177fd1f..d767472eedb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2004-10-18 Eric Botcazou + Roger Sayle + + PR middle-end/17813 + * dojump.c (discard_pending_stack_adjust): New function. + (clear_pending_stack_adjust): Call it. + * expr.h (discard_pending_stack_adjust): Declare it. + * explow.c (emit_stack_save): Emit pending stack adjustments + before saving the stack pointer. + (emit_stack_restore): Discard pending stack adjustments before + restoring the stack pointer. + 2004-10-18 Richard Henderson * c-common.c (handle_mode_attribute): Allow scalar->vector diff --git a/gcc/dojump.c b/gcc/dojump.c index 50fc093f72f..e506684f41d 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -50,6 +50,15 @@ init_pending_stack_adjust (void) pending_stack_adjust = 0; } +/* Discard any pending stack adjustment. This avoid relying on the + RTL optimizers to remove useless adjustments when we know the + stack pointer value is dead. */ +void discard_pending_stack_adjust (void) +{ + stack_pointer_delta -= pending_stack_adjust; + pending_stack_adjust = 0; +} + /* When exiting from function, if safe, clear out any pending stack adjust so the adjustment won't get done. @@ -64,10 +73,7 @@ clear_pending_stack_adjust (void) && EXIT_IGNORE_STACK && ! (DECL_INLINE (current_function_decl) && ! flag_no_inline) && ! flag_inline_functions) - { - stack_pointer_delta -= pending_stack_adjust, - pending_stack_adjust = 0; - } + discard_pending_stack_adjust (); } /* Pop any previously-pushed arguments that have not been popped yet. */ diff --git a/gcc/explow.c b/gcc/explow.c index 62ca87c3ca0..45126f6c420 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -965,6 +965,7 @@ emit_stack_save (enum save_level save_level, rtx *psave, rtx after) rtx seq; start_sequence (); + do_pending_stack_adjust (); /* We must validize inside the sequence, to ensure that any instructions created by the validize call also get moved to the right place. */ if (sa != 0) @@ -976,6 +977,7 @@ emit_stack_save (enum save_level save_level, rtx *psave, rtx after) } else { + do_pending_stack_adjust (); if (sa != 0) sa = validize_mem (sa); emit_insn (fcn (sa, stack_pointer_rtx)); @@ -1032,6 +1034,8 @@ emit_stack_restore (enum save_level save_level, rtx sa, rtx after) gen_rtx_MEM (BLKmode, stack_pointer_rtx))); } + discard_pending_stack_adjust (); + if (after) { rtx seq; diff --git a/gcc/expr.h b/gcc/expr.h index 2f693bb3daf..dc66239f240 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -499,6 +499,9 @@ extern void expand_var (tree); arguments waiting to be popped. */ extern void init_pending_stack_adjust (void); +/* Discard any pending stack adjustment. */ +extern void discard_pending_stack_adjust (void); + /* When exiting from function, if safe, clear out any pending stack adjust so the adjustment won't get done. */ extern void clear_pending_stack_adjust (void);