summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1999-10-25 06:44:53 +0000
committerJeff Law <law@gcc.gnu.org>1999-10-25 00:44:53 -0600
commit44430e4b6563358215a15a26c9f606ef5fd30296 (patch)
tree727cc3bbcd380311a1474c37fd908a0c26f61a8b
parentcb642a0dd6c448a511dab2f0083ecfbbe8726c32 (diff)
downloadgcc-44430e4b6563358215a15a26c9f606ef5fd30296.tar.gz
loop.c (note_set_pseudo_multiple_uses_retval): New variable.
* 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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/loop.c54
2 files changed, 57 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d4debbd84da..11c7922546a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/loop.c b/gcc/loop.c
index 7acd727042e..7ee92e143a6 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -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;
+}
/* 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;