]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
loop.c (note_set_pseudo_multiple_uses_retval): New variable.
authorJeffrey A Law <law@cygnus.com>
Mon, 25 Oct 1999 06:44:53 +0000 (06:44 +0000)
committerJeff Law <law@gcc.gnu.org>
Mon, 25 Oct 1999 06:44:53 +0000 (00:44 -0600)
        * loop.c (note_set_pseudo_multiple_uses_retval): New variable.
        (note_set_pseudo_multiple_uses): New function.
        (check_dbra_loop): Use not_set_pseudo_multiple_uses to determine
        if a pseudo set in the loop exit is used elsewhere.

From-SVN: r30156

gcc/ChangeLog
gcc/loop.c

index d4debbd84da6b20073f49fd4553c14ad7a408634..11c7922546a9075d1423dd8e3623cbf06a8edc15 100644 (file)
@@ -1,3 +1,10 @@
+Mon Oct 25 00:43:05 1999  Jeffrey A Law  (law@cygnus.com)
+
+       * loop.c (note_set_pseudo_multiple_uses_retval): New variable.
+       (note_set_pseudo_multiple_uses): New function.
+       (check_dbra_loop): Use not_set_pseudo_multiple_uses to determine
+       if a pseudo set in the loop exit is used elsewhere.
+
 Wed Oct 20 10:46:41 1999  Richard Earnshaw (rearnsha@arm.com)
 
        * jump.c (jump_optimize_1): More accurately detect casesi insns.
index 7acd727042efa2783d794314de2800859d2e68f9..7ee92e143a695f3673cdb6f8f44f22189164bf92 100644 (file)
@@ -283,6 +283,9 @@ static struct movable *the_movables;
 
 FILE *loop_dump_stream;
 
+/* For communicating return values from note_set_pseudo_multiple_uses.  */
+static int note_set_pseudo_multiple_uses_retval;
+
 /* Forward declarations.  */
 
 static void verify_dominator PROTO((int));
@@ -297,6 +300,7 @@ static void count_one_set PROTO((rtx, rtx, varray_type, rtx *));
 static void count_loop_regs_set PROTO((rtx, rtx, varray_type, varray_type,
                                       int *, int)); 
 static void note_addr_stored PROTO((rtx, rtx));
+static void note_set_pseudo_multiple_uses PROTO((rtx, rtx));
 static int loop_reg_used_before_p PROTO((rtx, rtx, rtx, rtx, rtx));
 static void scan_loop PROTO((rtx, rtx, rtx, int, int));
 #if 0
@@ -3140,6 +3144,36 @@ note_addr_stored (x, y)
 
   loop_store_mems = gen_rtx_EXPR_LIST (VOIDmode, x, loop_store_mems);
 }
+
+/* X is a value modified by an INSN that references a biv inside a loop
+   exit test (ie, X is somehow related to the value of the biv).  If X
+   is a pseudo that is used more than once, then the biv is (effectively)
+   used more than once.  */
+
+static void
+note_set_pseudo_multiple_uses (x, y)
+     rtx x;
+     rtx y ATTRIBUTE_UNUSED;
+{
+  if (x == 0)
+    return;
+
+  while (GET_CODE (x) == STRICT_LOW_PART
+        || GET_CODE (x) == SIGN_EXTRACT
+        || GET_CODE (x) == ZERO_EXTRACT
+        || GET_CODE (x) == SUBREG)
+    x = XEXP (x, 0);
+
+  if (GET_CODE (x) != REG || REGNO (x) < FIRST_PSEUDO_REGISTER)
+    return;
+
+  /* If we do not have usage information, or if we know the register
+     is used more than once, note that fact for check_dbra_loop.  */
+  if (REGNO (x) >= max_reg_before_loop
+      || ! VARRAY_RTX (reg_single_usage, REGNO (x))
+      || VARRAY_RTX (reg_single_usage, REGNO (x)) == const0_rtx)
+    note_set_pseudo_multiple_uses_retval = 1;
+}
 \f
 /* Return nonzero if the rtx X is invariant over the current loop.
 
@@ -7765,10 +7799,22 @@ check_dbra_loop (loop_end, insn_count, loop_start, loop_info)
                    && REGNO (SET_DEST (set)) == bl->regno)
                  /* An insn that sets the biv is okay.  */
                  ;
-               else if (p == prev_nonnote_insn (prev_nonnote_insn (loop_end))
-                        || p == prev_nonnote_insn (loop_end))
-                 /* Don't bother about the end test.  */
-                 ;
+               else if ((p == prev_nonnote_insn (prev_nonnote_insn (loop_end))
+                         || p == prev_nonnote_insn (loop_end))
+                        && reg_mentioned_p (bivreg, PATTERN (p)))
+                 {
+                   /* If either of these insns uses the biv and sets a pseudo
+                      that has more than one usage, then the biv has uses
+                      other than counting since it's used to derive a value
+                      that is used more than one time.  */
+                   note_set_pseudo_multiple_uses_retval = 0;
+                   note_stores (PATTERN (p), note_set_pseudo_multiple_uses);
+                   if (note_set_pseudo_multiple_uses_retval)
+                     {
+                       no_use_except_counting = 0;
+                       break;
+                     }
+                 }
                else if (reg_mentioned_p (bivreg, PATTERN (p)))
                  {
                    no_use_except_counting = 0;