OSDN Git Service

2008-12-01 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2008 19:31:41 +0000 (19:31 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Dec 2008 19:31:41 +0000 (19:31 +0000)
PR rtl-optimization/37514
* reload1.c (reload_as_needed): Invalidate reg_last_reload
from previous insns.

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

gcc/ChangeLog
gcc/reload1.c

index 5d7f4f0..ec4530c 100644 (file)
@@ -1,3 +1,9 @@
+2008-12-01  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/37514
+       * reload1.c (reload_as_needed): Invalidate reg_last_reload
+       from previous insns.
+
 2008-12-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/38348
index e9ac148..2f95fa5 100644 (file)
@@ -4164,6 +4164,9 @@ reload_as_needed (int live_known)
       rtx prev = 0;
       rtx insn = chain->insn;
       rtx old_next = NEXT_INSN (insn);
+#ifdef AUTO_INC_DEC
+      rtx old_prev = PREV_INSN (insn);
+#endif
 
       /* If we pass a label, copy the offsets from the label information
         into the current offsets of each elimination.  */
@@ -4388,6 +4391,33 @@ reload_as_needed (int live_known)
                      SET_REGNO_REG_SET (&reg_has_output_reload,
                                         REGNO (XEXP (in_reg, 0)));
                    }
+                 else if ((code == PRE_INC || code == PRE_DEC
+                           || code == POST_INC || code == POST_DEC))
+                   {
+                     int in_hard_regno;
+                     int in_regno = REGNO (XEXP (in_reg, 0));
+
+                     if (reg_last_reload_reg[in_regno] != NULL_RTX)
+                       {
+                         in_hard_regno = REGNO (reg_last_reload_reg[in_regno]);
+                         gcc_assert (TEST_HARD_REG_BIT (reg_reloaded_valid,
+                                                        in_hard_regno));
+                         for (x = old_prev ? NEXT_INSN (old_prev) : insn;
+                              x != old_next;
+                              x = NEXT_INSN (x))
+                           if (x == reg_reloaded_insn[in_hard_regno])
+                             break;
+                         /* If for some reasons, we didn't set up
+                            reg_last_reload_reg in this insn,
+                            invalidate inheritance from previous
+                            insns for the incremented/decremented
+                            register.  Such registers will be not in
+                            reg_has_output_reload.  */
+                         if (x == old_next)
+                           forget_old_reloads_1 (XEXP (in_reg, 0),
+                                                 NULL_RTX, NULL);
+                       }
+                   }
                }
            }
          /* If a pseudo that got a hard register is auto-incremented,