diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2009-09-06 21:15:45 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2009-09-06 21:15:45 +0000 |
commit | 1362aa31311322ad03b604cf8a6ad646f84232be (patch) | |
tree | 2b564bf489c100b7874e0af4630bfa7154bc5fa2 /gcc/combine-stack-adj.c | |
parent | 90588a106ef2e2fe5d524ef138652f68bce5f72c (diff) | |
download | gcc-1362aa31311322ad03b604cf8a6ad646f84232be.tar.gz |
re PR bootstrap/41241 (bootstrap comparison failure)
PR bootstrap/41241
* combine-stack-adj.c (try_apply_stack_adjustment): Handle stores.
(combine_stack_adjustments_for_block): Allow insns between stack
adjustments and stores with corresponding with pre-(dec|inc)rement
or pre-modify.
From-SVN: r151463
Diffstat (limited to 'gcc/combine-stack-adj.c')
-rw-r--r-- | gcc/combine-stack-adj.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c index babd6d27e93..8849697bfce 100644 --- a/gcc/combine-stack-adj.c +++ b/gcc/combine-stack-adj.c @@ -206,7 +206,12 @@ try_apply_stack_adjustment (rtx insn, struct csa_reflist *reflist, rtx set; set = single_set_for_csa (insn); - validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1); + if (MEM_P (SET_DEST (set))) + validate_change (insn, &SET_DEST (set), + replace_equiv_address (SET_DEST (set), stack_pointer_rtx), + 1); + else + validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1); for (ml = reflist; ml ; ml = ml->next) { @@ -468,28 +473,33 @@ combine_stack_adjustments_for_block (basic_block bb) continue; } - /* Find a predecrement of exactly the previous adjustment and - turn it into a direct store. Obviously we can't do this if - there were any intervening uses of the stack pointer. */ - if (reflist == NULL - && MEM_P (dest) - && ((GET_CODE (XEXP (dest, 0)) == PRE_DEC - && (last_sp_adjust - == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest)))) - || (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY + /* Find a store with pre-(dec|inc)rement or pre-modify of exactly + the previous adjustment and turn it into a simple store. This + is equivalent to anticipating the stack adjustment so this must + be an allocation. */ + if (MEM_P (dest) + && ((STACK_GROWS_DOWNWARD + ? (GET_CODE (XEXP (dest, 0)) == PRE_DEC + && last_sp_adjust + == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))) + : (GET_CODE (XEXP (dest, 0)) == PRE_INC + && last_sp_adjust + == -(HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest)))) + || ((STACK_GROWS_DOWNWARD + ? last_sp_adjust >= 0 : last_sp_adjust <= 0) + && GET_CODE (XEXP (dest, 0)) == PRE_MODIFY && GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS - && XEXP (XEXP (XEXP (dest, 0), 1), 0) == stack_pointer_rtx - && (GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1)) - == CONST_INT) - && (INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1)) - == -last_sp_adjust))) + && XEXP (XEXP (XEXP (dest, 0), 1), 0) + == stack_pointer_rtx + && GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1)) + == CONST_INT + && INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1)) + == -last_sp_adjust)) && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx - && ! reg_mentioned_p (stack_pointer_rtx, src) + && !reg_mentioned_p (stack_pointer_rtx, src) && memory_address_p (GET_MODE (dest), stack_pointer_rtx) - && validate_change (insn, &SET_DEST (set), - replace_equiv_address (dest, - stack_pointer_rtx), - 0)) + && try_apply_stack_adjustment (insn, reflist, 0, + -last_sp_adjust)) { delete_insn (last_sp_set); free_csa_reflist (reflist); |