OSDN Git Service

PR bootstrap/41241
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Sep 2009 21:15:45 +0000 (21:15 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 6 Sep 2009 21:15:45 +0000 (21:15 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151463 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/combine-stack-adj.c

index 9824c28..9c08f47 100644 (file)
@@ -1,3 +1,11 @@
+2009-09-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       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.
+
 2009-09-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR bootstrap/41241
index babd6d2..8849697 100644 (file)
@@ -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);