aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatherine Moore <clm@redhat.com>2000-09-07 13:10:51 +0000
committerCatherine Moore <clm@gcc.gnu.org>2000-09-07 09:10:51 -0400
commit4598ffe97a481d553bf8888d794059e3f8cb5ec7 (patch)
tree2dcd5b408e11f22df2a0bbc750dd91e6b361bd55
parentf52c723967006d4c135e46bb3e2974e54657a5d8 (diff)
downloadgcc-4598ffe97a481d553bf8888d794059e3f8cb5ec7.zip
gcc-4598ffe97a481d553bf8888d794059e3f8cb5ec7.tar.gz
gcc-4598ffe97a481d553bf8888d794059e3f8cb5ec7.tar.bz2
unroll.c (unroll_loop): Check for unconditional jumps to loop continuation.
* unroll.c (unroll_loop): Check for unconditional jumps to loop continuation. Delete if n_iterations is 1. (ujump_to_loop_cont): New routine. From-SVN: r36235
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/unroll.c47
2 files changed, 53 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a477e6f..186abc4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2000-09-07 Catherine Moore <clm@redhat.com>
+
+ * unroll.c (unroll_loop): Check for unconditional jumps
+ to loop continuation. Delete if n_iterations is 1.
+ (ujump_to_loop_cont): New routine.
+
2000-09-07 Bernd Schmidt <bernds@redhat.co.uk>
* rtl.c (class_narrowest_mode): Add entries for MODE_VECTOR_INT and
diff --git a/gcc/unroll.c b/gcc/unroll.c
index c09f036..36e6c57 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -216,6 +216,7 @@ static rtx remap_split_bivs PARAMS ((rtx));
static rtx find_common_reg_term PARAMS ((rtx, rtx));
static rtx subtract_reg_term PARAMS ((rtx, rtx));
static rtx loop_find_equiv_value PARAMS ((const struct loop *, rtx));
+static rtx ujump_to_loop_cont PARAMS ((rtx, rtx));
/* Try to unroll one loop and split induction variables in the loop.
@@ -348,6 +349,14 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
if (loop_info->n_iterations == 1)
{
+ /* Handle the case where the loop begins with an unconditional
+ jump to the loop condition. Make sure to delete the jump
+ insn, otherwise the loop body will never execute. */
+
+ rtx ujump = ujump_to_loop_cont (loop->start, loop->cont);
+ if (ujump)
+ delete_insn (ujump);
+
/* If number of iterations is exactly 1, then eliminate the compare and
branch at the end of the loop since they will never be taken.
Then return, since no other action is needed here. */
@@ -4152,3 +4161,41 @@ set_dominates_use (regno, first_uid, last_uid, copy_start, copy_end)
/* FIRST_UID is always executed if LAST_UID is executed. */
return 1;
}
+
+/* This routine is called when the number of iterations for the unrolled
+ loop is one. The goal is to identify a loop that begins with an
+ unconditional branch to the loop continuation note (or a label just after).
+ In this case, the unconditional branch that starts the loop needs to be
+ deleted so that we execute the single iteration. */
+static rtx
+ujump_to_loop_cont (loop_start, loop_cont)
+ rtx loop_start;
+ rtx loop_cont;
+{
+ rtx x, label, label_ref;
+
+ /* See if loop start, or the next insn is an unconditional jump. */
+ loop_start = next_nonnote_insn (loop_start);
+
+ x = pc_set (loop_start);
+ if (!x)
+ return NULL_RTX;
+
+ label_ref = SET_SRC (x);
+ if (!label_ref)
+ return NULL_RTX;
+
+ /* Examine insn after loop continuation note. Return if not a label. */
+ label = next_nonnote_insn (loop_cont);
+ if (label == 0 || GET_CODE (label) != CODE_LABEL)
+ return NULL_RTX;
+
+ /* Return the loop start if the branch label matches the code label. */
+ if (CODE_LABEL_NUMBER (label) == CODE_LABEL_NUMBER (XEXP (label_ref,0)))
+ return loop_start;
+ else
+ return NULL_RTX;
+
+}
+
+