summaryrefslogtreecommitdiff
path: root/gcc/unroll.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-25 20:24:42 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-03-25 20:24:42 +0000
commita82119e49ef3ab1cca3e6b472878d8ffc4b7b724 (patch)
treec48ce8d00c0de5784247bb6050aa914358fd8591 /gcc/unroll.c
parent91bee29ee2fe5ec100e78cb677747756e5b3c0bd (diff)
downloadgcc-a82119e49ef3ab1cca3e6b472878d8ffc4b7b724.tar.gz
PR optimization/10171
* unroll.c (unroll_loop): Don't delete the jump at the end unless we also delete a jump at the beginning. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@64863 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r--gcc/unroll.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 3b5dd7c91f8..9db997512c1 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -305,9 +305,11 @@ unroll_loop (loop, insn_count, strength_reduce_p)
jump to the loop condition. Make sure to delete the jump
insn, otherwise the loop body will never execute. */
+ /* FIXME this actually checks for a jump to the continue point, which
+ is not the same as the condition in a for loop. As a result, this
+ optimization fails for most for loops. We should really use flow
+ information rather than instruction pattern matching. */
rtx ujump = ujump_to_loop_cont (loop->start, loop->cont);
- if (ujump)
- delete_related_insns (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.
@@ -319,9 +321,10 @@ unroll_loop (loop, insn_count, strength_reduce_p)
if (GET_CODE (last_loop_insn) == BARRIER)
{
/* Delete the jump insn. This will delete the barrier also. */
- delete_related_insns (PREV_INSN (last_loop_insn));
+ last_loop_insn = PREV_INSN (last_loop_insn);
}
- else if (GET_CODE (last_loop_insn) == JUMP_INSN)
+
+ if (ujump && GET_CODE (last_loop_insn) == JUMP_INSN)
{
#ifdef HAVE_cc0
rtx prev = PREV_INSN (last_loop_insn);
@@ -333,24 +336,27 @@ unroll_loop (loop, insn_count, strength_reduce_p)
if (only_sets_cc0_p (prev))
delete_related_insns (prev);
#endif
- }
- /* Remove the loop notes since this is no longer a loop. */
- if (loop->vtop)
- delete_related_insns (loop->vtop);
- if (loop->cont)
- delete_related_insns (loop->cont);
- if (loop_start)
- delete_related_insns (loop_start);
- if (loop_end)
- delete_related_insns (loop_end);
+ delete_related_insns (ujump);
- return;
+ /* Remove the loop notes since this is no longer a loop. */
+ if (loop->vtop)
+ delete_related_insns (loop->vtop);
+ if (loop->cont)
+ delete_related_insns (loop->cont);
+ if (loop_start)
+ delete_related_insns (loop_start);
+ if (loop_end)
+ delete_related_insns (loop_end);
+
+ return;
+ }
}
- else if (loop_info->n_iterations > 0
- /* Avoid overflow in the next expression. */
- && loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS
- && loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS)
+
+ if (loop_info->n_iterations > 0
+ /* Avoid overflow in the next expression. */
+ && loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS
+ && loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS)
{
unroll_number = loop_info->n_iterations;
unroll_type = UNROLL_COMPLETELY;