Commit 2e2255ff by Jason Merrill Committed by Jason Merrill

re PR rtl-optimization/10171 (wrong code for inlined function)

        PR optimization/10171
        * unroll.c (unroll_loop): Don't delete the jump at the end unless
        we also delete a jump at the beginning.

From-SVN: r64863
parent 8725a499
2003-03-21 Jason Merrill <jason@redhat.com>
PR optimization/10171
* unroll.c (unroll_loop): Don't delete the jump at the end unless
we also delete a jump at the beginning.
2003-03-25 Stephane Carrez <stcarrez@nerim.fr> 2003-03-25 Stephane Carrez <stcarrez@nerim.fr>
* doc/contrib.texi (Contributors): Mention self as 68HC11/68HC12 * doc/contrib.texi (Contributors): Mention self as 68HC11/68HC12
......
/* PR optimization/10171 */
/* Bug: unroll_loop misoptimized the function so that we got
0 iterations of the loop rather than the correct 1. */
/* { dg-do run } */
inline int tag() { return 0; }
void f ();
int main() {
int i;
for (i = 0; i < (tag() ? 2 : 1); i++)
f();
abort ();
}
void f ()
{
exit (0);
}
...@@ -305,9 +305,11 @@ unroll_loop (loop, insn_count, strength_reduce_p) ...@@ -305,9 +305,11 @@ unroll_loop (loop, insn_count, strength_reduce_p)
jump to the loop condition. Make sure to delete the jump jump to the loop condition. Make sure to delete the jump
insn, otherwise the loop body will never execute. */ 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); 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 /* 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. 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) ...@@ -319,9 +321,10 @@ unroll_loop (loop, insn_count, strength_reduce_p)
if (GET_CODE (last_loop_insn) == BARRIER) if (GET_CODE (last_loop_insn) == BARRIER)
{ {
/* Delete the jump insn. This will delete the barrier also. */ /* 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 #ifdef HAVE_cc0
rtx prev = PREV_INSN (last_loop_insn); rtx prev = PREV_INSN (last_loop_insn);
...@@ -333,7 +336,8 @@ unroll_loop (loop, insn_count, strength_reduce_p) ...@@ -333,7 +336,8 @@ unroll_loop (loop, insn_count, strength_reduce_p)
if (only_sets_cc0_p (prev)) if (only_sets_cc0_p (prev))
delete_related_insns (prev); delete_related_insns (prev);
#endif #endif
}
delete_related_insns (ujump);
/* Remove the loop notes since this is no longer a loop. */ /* Remove the loop notes since this is no longer a loop. */
if (loop->vtop) if (loop->vtop)
...@@ -347,7 +351,9 @@ unroll_loop (loop, insn_count, strength_reduce_p) ...@@ -347,7 +351,9 @@ unroll_loop (loop, insn_count, strength_reduce_p)
return; return;
} }
else if (loop_info->n_iterations > 0 }
if (loop_info->n_iterations > 0
/* Avoid overflow in the next expression. */ /* Avoid overflow in the next expression. */
&& loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS && loop_info->n_iterations < (unsigned) MAX_UNROLLED_INSNS
&& loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS) && loop_info->n_iterations * insn_count < (unsigned) MAX_UNROLLED_INSNS)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment