From 090651ad61e3a676420bcb82d53f58a6ca8755f8 Mon Sep 17 00:00:00 2001 From: law Date: Mon, 25 Oct 1999 06:44:04 +0000 Subject: [PATCH] * 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/trunk@30155 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 +++++++ gcc/loop.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a2713d9aa0c..d72d913bb40 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Mon Oct 25 00:42:35 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. + Sun Oct 24 20:52:40 1999 Mark Mitchell * i386.md (mulsi3): Tweak to work with SCO OSR5 COFF assembler. diff --git a/gcc/loop.c b/gcc/loop.c index ea815fff847..5ef10bd5b67 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -269,6 +269,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)); @@ -283,6 +286,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 @@ -3172,6 +3176,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. @@ -7932,10 +7966,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; -- 2.11.0