rtlanal.c (auto_inc_p): New function.
authorMichael Hayes <m.hayes@elec.canterbury.ac.nz>
Mon, 15 Mar 1999 01:52:49 +0000 (01:52 +0000)
committerMichael Hayes <m.hayes@gcc.gnu.org>
Mon, 15 Mar 1999 01:52:49 +0000 (01:52 +0000)
* rtlanal.c (auto_inc_p): New function.
        * rtl.h (auto_inc_p): Prototype it.
* reload1.c (add_auto_inc_notes): New function.
(reload): Strip REG_INC notes and call add_auto_inc_notes
for each insn to restore them correctly.

From-SVN: r25774

gcc/ChangeLog
gcc/reload1.c
gcc/rtl.h
gcc/rtlanal.c

index ac346d163e91befd7f8035c89ee2d3a093569b7a..cbf81e5dbb2653e04e9b685eeae7ba33fe43e03f 100644 (file)
@@ -1,3 +1,11 @@
+Mon Mar 15 22:50:18 1999  Michael Hayes  <m.hayes@elec.canterbury.ac.nz>
+
+       * rtlanal.c (auto_inc_p): New function.
+        * rtl.h (auto_inc_p): Prototype it.
+       * reload1.c (add_auto_inc_notes): New function.
+       (reload): Strip REG_INC notes and call add_auto_inc_notes
+       for each insn to restore them correctly.
+
 1999-03-15  Manfred Hollstein  <manfred@s-direktnet.de>
 
        * fixinc/Makefile.in (procopen.o): List the actual
index 440283195df457009c5c8a80cac28c72f30c7abe..1e83d5fe4be18e327274ce3bc68253ad46db66f7 100644 (file)
@@ -443,6 +443,9 @@ static void reload_combine_note_use PROTO((rtx *, rtx));
 static void reload_combine_note_store PROTO((rtx, rtx));
 static void reload_cse_move2add PROTO((rtx));
 static void move2add_note_store PROTO((rtx, rtx));
+#ifdef AUTO_INC_DEC
+static void add_auto_inc_notes PROTO((rtx, rtx));
+#endif
 \f
 /* Initialize the reload pass once per compilation.  */
 
@@ -1124,11 +1127,13 @@ reload (first, global, dumpfile)
      which are only valid during and after reload.  */
   reload_completed = 1;
 
-  /* Make a pass over all the insns and delete all USEs which we inserted
-     only to tag a REG_EQUAL note on them.  Remove all REG_DEAD and REG_UNUSED
-     notes.  Delete all CLOBBER insns and simplify (subreg (reg)) operands.
-     Also remove all REG_RETVAL and REG_LIBCALL notes since they are no longer
-     useful or accurate.  */
+  /* Make a pass over all the insns and delete all USEs which we
+     inserted only to tag a REG_EQUAL note on them.  Remove all
+     REG_DEAD and REG_UNUSED notes.  Delete all CLOBBER insns and
+     simplify (subreg (reg)) operands.  Also remove all REG_RETVAL and
+     REG_LIBCALL notes since they are no longer useful or accurate.
+     Strip and regenerate REG_INC notes that may have been moved
+     around.  */
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
@@ -1150,6 +1155,7 @@ reload (first, global, dumpfile)
          {
            if (REG_NOTE_KIND (*pnote) == REG_DEAD
                || REG_NOTE_KIND (*pnote) == REG_UNUSED
+               || REG_NOTE_KIND (*pnote) == REG_INC
                || REG_NOTE_KIND (*pnote) == REG_RETVAL
                || REG_NOTE_KIND (*pnote) == REG_LIBCALL)
              *pnote = XEXP (*pnote, 1);
@@ -1157,6 +1163,10 @@ reload (first, global, dumpfile)
              pnote = &XEXP (*pnote, 1);
          }
 
+#ifdef AUTO_INC_DEC
+       add_auto_inc_notes (insn, PATTERN (insn));
+#endif
+
        /* And simplify (subreg (reg)) if it appears as an operand.  */
        cleanup_subreg_operands (insn);
       }
@@ -10131,3 +10141,33 @@ move2add_note_store (dst, set)
        }
     }
 }
+
+#ifdef AUTO_INC_DEC
+static void
+add_auto_inc_notes (insn, x)
+     rtx insn;
+     rtx x;
+{
+  enum rtx_code code = GET_CODE (x);
+  char *fmt;
+  int i, j;
+
+  if (code == MEM && auto_inc_p (XEXP (x, 0)))
+    {
+      REG_NOTES (insn)
+       = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
+      return;
+    }
+
+  /* Scan all the operand sub-expressions.  */
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'e')
+       add_auto_inc_notes (insn, XEXP (x, i));
+      else if (fmt[i] == 'E')
+       for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+         add_auto_inc_notes (insn, XVECEXP (x, i, j));
+    }
+}
+#endif
index 7f4460f19346051fba8544b6611be38fc081f715..18489d372b468ad71b85fd5d9b195dd47a260b0d 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1041,6 +1041,7 @@ extern int computed_jump_p                PROTO((rtx));
 typedef int (*rtx_function)             PROTO((rtx *, void *));
 extern int for_each_rtx                 PROTO((rtx *, rtx_function, void *));
 extern rtx regno_use_in                        PROTO((int, rtx));
+extern int auto_inc_p                  PROTO((rtx));
 
 /* flow.c */
 
index d061273a172135b67cd8c0895820d05216f6ffb3..8347849c6e197c7f307948bb717b5b992fad633c 100644 (file)
@@ -2235,3 +2235,27 @@ regno_use_in (regno, x)
 
   return NULL_RTX;
 }
+
+
+/* Return 1 if X is an autoincrement side effect and the register is
+   not the stack pointer.  */
+int
+auto_inc_p (x)
+     rtx x;
+{
+  switch (GET_CODE (x))
+    {
+    case PRE_INC:
+    case POST_INC:
+    case PRE_DEC:
+    case POST_DEC:
+    case PRE_MODIFY:
+    case POST_MODIFY:
+      /* There are no REG_INC notes for SP.  */
+      if (XEXP (x, 0) != stack_pointer_rtx)
+       return 1;
+    default:
+      break;
+    }
+  return 0;
+}