OSDN Git Service

More efficient version of Jul 10 bugfix of mine, as
authordavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Jul 1998 03:34:12 +0000 (03:34 +0000)
committerdavem <davem@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 13 Jul 1998 03:34:12 +0000 (03:34 +0000)
discussed on egcs-patches.
* regclass.c (reg_scan_mark_refs): New arg min_regno.  Only update
regscan information for REGs with numbers greater than or equal to
this.  All callers changed.
(reg_scan_update): New function to efficiently update regscan
information on the fly.
* rtl.h: Add prototype.
* jump.c (jump_optimize): Call it when we make a transformation
which generates new pseudo-REGs.

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

gcc/ChangeLog
gcc/jump.c
gcc/regclass.c
gcc/rtl.h

index be1ed8b..2ea1526 100644 (file)
@@ -1,3 +1,14 @@
+Mon Jul 13 02:24:08 1998  David S. Miller  <davem@pierdol.cobaltmicro.com>
+
+       * regclass.c (reg_scan_mark_refs): New arg min_regno.  Only update
+       regscan information for REGs with numbers greater than or equal to
+       this.  All callers changed.
+       (reg_scan_update): New function to efficiently update regscan
+       information on the fly.
+       * rtl.h: Add prototype.
+       * jump.c (jump_optimize): Call it when we make a transformation
+       which generates new pseudo-REGs.
+
 Sun Jul 12 13:08:14 1998  Jeffrey A Law  (law@cygnus.com)
 
        * collect2.c (main): Use "-x c" instead of "-lang-c" for force the
index 9956789..fce3dc0 100644 (file)
@@ -605,15 +605,6 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
          int this_is_simplejump, this_is_condjump, reversep = 0;
          int this_is_condjump_in_parallel;
 
-         /* If one of our transformations has created more REGs we
-            must rerun reg_scan or else we risk missed optimizations,
-            erroneous optimizations, or even worse a crash.  */
-         if (after_regscan &&
-             old_max_reg < max_reg_num ())
-           {
-             reg_scan (f, max_reg_num (), 0);
-             old_max_reg = max_reg_num ();
-           }
 #if 0
          /* If NOT the first iteration, if this is the last jump pass
             (just before final), do the special peephole optimizations.
@@ -987,7 +978,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
             We set:
 
             TEMP to the "x = exp;" insn.
-            TEMP1 to the single set in the "x = exp; insn.
+            TEMP1 to the single set in the "x = exp;" insn.
             TEMP2 to "x".  */
 
          if (! reload_completed
@@ -1021,6 +1012,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                                                   PREV_INSN (temp3), temp);
                  delete_insn (temp);
                  reallabelprev = prev_active_insn (JUMP_LABEL (insn));
+
+                 if (after_regscan)
+                   {
+                     reg_scan_update (temp3, NEXT_INSN (next), old_max_reg);
+                     old_max_reg = max_reg_num ();
+                   }
                }
            }
 
@@ -1073,6 +1070,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                  delete_insn (temp);
                  delete_insn (temp3);
                  reallabelprev = prev_active_insn (JUMP_LABEL (insn));
+
+                 if (after_regscan)
+                   {
+                     reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
+                     old_max_reg = max_reg_num ();
+                   }
                }
            }
 
@@ -1133,6 +1136,12 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                  delete_insn (temp);
                  delete_insn (temp3);
                  reallabelprev = prev_active_insn (JUMP_LABEL (insn));
+
+                 if (after_regscan)
+                   {
+                     reg_scan_update (temp6, NEXT_INSN (next), old_max_reg);
+                     old_max_reg = max_reg_num ();
+                   }
                }
            }
 #endif /* HAVE_cc0 */
@@ -1244,7 +1253,7 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
 
                if (target)
                  {
-                   rtx seq1,seq2;
+                   rtx seq1,seq2,last;
 
                    /* Save the conditional move sequence but don't emit it
                       yet.  On some machines, like the alpha, it is possible
@@ -1266,13 +1275,20 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                    emit_insns_before (seq1, temp5);
                    /* Insert conditional move after insn, to be sure that
                       the jump and a possible compare won't be separated */
-                   emit_insns_after (seq2, insn);
+                   last = emit_insns_after (seq2, insn);
 
                    /* ??? We can also delete the insn that sets X to A.
                       Flow will do it too though.  */
                    delete_insn (temp);
                    next = NEXT_INSN (insn);
                    delete_jump (insn);
+
+                   if (after_regscan)
+                     {
+                       reg_scan_update (seq1, NEXT_INSN (last), old_max_reg);
+                       old_max_reg = max_reg_num ();
+                     }
+
                    changed = 1;
                    continue;
                  }
@@ -1455,6 +1471,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                      delete_insn (temp);
                      next = NEXT_INSN (insn);
                      delete_jump (insn);
+
+                     if (after_regscan)
+                       {
+                         reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
+                         old_max_reg = max_reg_num ();
+                       }
+
                      changed = 1;
                      continue;
                    }
@@ -1574,6 +1597,13 @@ jump_optimize (f, cross_jump, noop_moves, after_regscan)
                  delete_insn (prev_nonnote_insn (insn));
 #endif
                  delete_insn (insn);
+
+                 if (after_regscan)
+                   {
+                     reg_scan_update (seq, NEXT_INSN (next), old_max_reg);
+                     old_max_reg = max_reg_num ();
+                   }
+
                  changed = 1;
                  continue;
                }
index 2bb6b42..256d92b 100644 (file)
@@ -673,7 +673,7 @@ static void record_address_regs     PROTO((rtx, enum reg_class, int));
 #ifdef FORBIDDEN_INC_DEC_CLASSES
 static int auto_inc_dec_reg_p  PROTO((rtx, enum machine_mode));
 #endif
-static void reg_scan_mark_refs PROTO((rtx, rtx, int));
+static void reg_scan_mark_refs PROTO((rtx, rtx, int, int));
 
 /* Return the reg_class in which pseudo reg number REGNO is best allocated.
    This function is sometimes called before the info has been computed.
@@ -1939,21 +1939,54 @@ reg_scan (f, nregs, repeat)
        if (GET_CODE (PATTERN (insn)) == PARALLEL
            && XVECLEN (PATTERN (insn), 0) > max_parallel)
          max_parallel = XVECLEN (PATTERN (insn), 0);
-       reg_scan_mark_refs (PATTERN (insn), insn, 0);
+       reg_scan_mark_refs (PATTERN (insn), insn, 0, 0);
 
        if (REG_NOTES (insn))
-         reg_scan_mark_refs (REG_NOTES (insn), insn, 1);
+         reg_scan_mark_refs (REG_NOTES (insn), insn, 1, 0);
+      }
+}
+
+/* Update 'regscan' information by looking at the insns
+   from FIRST to LAST.  Some new REGs have been created,
+   and any REG with number greater than OLD_MAX_REGNO is
+   such a REG.  We only update information for those.  */
+
+void
+reg_scan_update(first, last, old_max_regno)
+     rtx first;
+     rtx last;
+     int old_max_regno;
+{
+  register rtx insn;
+
+  allocate_reg_info (max_reg_num (), FALSE, FALSE);
+
+  for (insn = first; insn != last; insn = NEXT_INSN (insn))
+    if (GET_CODE (insn) == INSN
+       || GET_CODE (insn) == CALL_INSN
+       || GET_CODE (insn) == JUMP_INSN)
+      {
+       if (GET_CODE (PATTERN (insn)) == PARALLEL
+           && XVECLEN (PATTERN (insn), 0) > max_parallel)
+         max_parallel = XVECLEN (PATTERN (insn), 0);
+       reg_scan_mark_refs (PATTERN (insn), insn, 0, old_max_regno);
+
+       if (REG_NOTES (insn))
+         reg_scan_mark_refs (REG_NOTES (insn), insn, 1, old_max_regno);
       }
 }
 
 /* X is the expression to scan.  INSN is the insn it appears in.
-   NOTE_FLAG is nonzero if X is from INSN's notes rather than its body.  */
+   NOTE_FLAG is nonzero if X is from INSN's notes rather than its body.
+   We should only record information for REGs with numbers
+   greater than or equal to MIN_REGNO.  */
 
 static void
-reg_scan_mark_refs (x, insn, note_flag)
+reg_scan_mark_refs (x, insn, note_flag, min_regno)
      rtx x;
      rtx insn;
      int note_flag;
+     int min_regno;
 {
   register enum rtx_code code = GET_CODE (x);
   register rtx dest;
@@ -1976,24 +2009,27 @@ reg_scan_mark_refs (x, insn, note_flag)
       {
        register int regno = REGNO (x);
 
-       REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn);
-       if (!note_flag)
-         REGNO_LAST_UID (regno) = INSN_UID (insn);
-       if (REGNO_FIRST_UID (regno) == 0)
-         REGNO_FIRST_UID (regno) = INSN_UID (insn);
+       if (regno >= min_regno)
+         {
+           REGNO_LAST_NOTE_UID (regno) = INSN_UID (insn);
+           if (!note_flag)
+             REGNO_LAST_UID (regno) = INSN_UID (insn);
+           if (REGNO_FIRST_UID (regno) == 0)
+             REGNO_FIRST_UID (regno) = INSN_UID (insn);
+         }
       }
       break;
 
     case EXPR_LIST:
       if (XEXP (x, 0))
-       reg_scan_mark_refs (XEXP (x, 0), insn, note_flag);
+       reg_scan_mark_refs (XEXP (x, 0), insn, note_flag, min_regno);
       if (XEXP (x, 1))
-       reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
+       reg_scan_mark_refs (XEXP (x, 1), insn, note_flag, min_regno);
       break;
 
     case INSN_LIST:
       if (XEXP (x, 1))
-       reg_scan_mark_refs (XEXP (x, 1), insn, note_flag);
+       reg_scan_mark_refs (XEXP (x, 1), insn, note_flag, min_regno);
       break;
 
     case SET:
@@ -2004,7 +2040,8 @@ reg_scan_mark_refs (x, insn, note_flag)
           dest = XEXP (dest, 0))
        ;
 
-      if (GET_CODE (dest) == REG)
+      if (GET_CODE (dest) == REG
+         && REGNO (dest) >= min_regno)
        REG_N_SETS (REGNO (dest))++;
 
       /* If this is setting a pseudo from another pseudo or the sum of a
@@ -2021,6 +2058,7 @@ reg_scan_mark_refs (x, insn, note_flag)
 
       if (GET_CODE (SET_DEST (x)) == REG
          && REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER
+         && REGNO (SET_DEST (x)) >= min_regno
          /* If the destination pseudo is set more than once, then other
             sets might not be to a pointer value (consider access to a
             union in two threads of control in the presense of global
@@ -2063,12 +2101,12 @@ reg_scan_mark_refs (x, insn, note_flag)
        for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
          {
            if (fmt[i] == 'e')
-             reg_scan_mark_refs (XEXP (x, i), insn, note_flag);
+             reg_scan_mark_refs (XEXP (x, i), insn, note_flag, min_regno);
            else if (fmt[i] == 'E' && XVEC (x, i) != 0)
              {
                register int j;
                for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-                 reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag);
+                 reg_scan_mark_refs (XVECEXP (x, i, j), insn, note_flag, min_regno);
              }
          }
       }
index 7515dcf..4aa25b2 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1449,6 +1449,7 @@ extern void regset_release_memory PROTO ((void));
 extern void regclass_init              PROTO ((void));
 extern void regclass                   PROTO ((rtx, int));
 extern void reg_scan                   PROTO ((rtx, int, int));
+extern void reg_scan_update            PROTO ((rtx, rtx, int));
 extern void fix_register               PROTO ((char *, int, int));
 
 /* In regmove.c */