diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-10-25 06:44:53 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-10-25 06:44:53 +0000 |
commit | b692647d547ef6b7931b6bc9157833754e096427 (patch) | |
tree | 727cc3bbcd380311a1474c37fd908a0c26f61a8b /gcc | |
parent | 7a7461aedb71cb84bffd82718325f9162ecebd82 (diff) |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-2_95-branch@30156 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/loop.c | 54 |
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; |