Commit b72bdd84 by J"orn Rennecke Committed by Joern Rennecke

loop.c (strength_reduce): Check for intervening jumps when converting biv increment to giv.

	* loop.c (strength_reduce): Check for intervening jumps when
	converting biv increment to giv.

From-SVN: r25310
parent 4e03cf86
Fri Feb 19 19:55:06 1999 J"orn Rennecke <amylaar@cygnus.co.uk>
* loop.c (strength_reduce): Check for intervening jumps when
converting biv increment to giv.
Thu Feb 18 16:36:58 1999 Per Bothner <bothner@cygnus.com> Thu Feb 18 16:36:58 1999 Per Bothner <bothner@cygnus.com>
* tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes, * tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes,
......
...@@ -4136,6 +4136,7 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4136,6 +4136,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
for (bl = loop_iv_list; bl; bl = bl->next) for (bl = loop_iv_list; bl; bl = bl->next)
{ {
struct induction **vp, *v, *next; struct induction **vp, *v, *next;
int biv_dead_after_loop = 0;
/* The biv increments lists are in reverse order. Fix this first. */ /* The biv increments lists are in reverse order. Fix this first. */
for (v = bl->biv, bl->biv = 0; v; v = next) for (v = bl->biv, bl->biv = 0; v; v = next)
...@@ -4145,6 +4146,31 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4145,6 +4146,31 @@ strength_reduce (scan_start, end, loop_top, insn_count,
bl->biv = v; bl->biv = v;
} }
/* We must guard against the case that an early exit between v->insn
and next->insn leaves the biv live after the loop, since that
would mean that we'd be missing an increment for the final
value. The following test to set biv_dead_after_loop is like
the first part of the test to set bl->eliminable.
We don't check here if we can calculate the final value, since
this can't succeed if we already know that there is a jump
between v->insn and next->insn, yet next->always_executed is
set and next->maybe_multiple is cleared. Such a combination
implies that the jump destination is outseide the loop.
If we want to make this check more sophisticated, we should
check each branch between v->insn and next->insn individually
to see if it the biv is dead at its destination. */
if (uid_luid[REGNO_LAST_UID (bl->regno)] < INSN_LUID (loop_end)
&& bl->init_insn
&& INSN_UID (bl->init_insn) < max_uid_for_loop
&& (uid_luid[REGNO_FIRST_UID (bl->regno)]
>= INSN_LUID (bl->init_insn))
#ifdef HAVE_decrement_and_branch_until_zero
&& ! bl->nonneg
#endif
&& ! reg_mentioned_p (bl->biv->dest_reg, SET_SRC (bl->init_set)))
biv_dead_after_loop = 1;
for (vp = &bl->biv, next = *vp; v = next, next = v->next_iv;) for (vp = &bl->biv, next = *vp; v = next, next = v->next_iv;)
{ {
HOST_WIDE_INT offset; HOST_WIDE_INT offset;
...@@ -4156,7 +4182,9 @@ strength_reduce (scan_start, end, loop_top, insn_count, ...@@ -4156,7 +4182,9 @@ strength_reduce (scan_start, end, loop_top, insn_count,
|| GET_CODE (v->add_val) != CONST_INT || GET_CODE (v->add_val) != CONST_INT
|| ! next->always_executed || ! next->always_executed
|| next->maybe_multiple || next->maybe_multiple
|| ! CONSTANT_P (next->add_val)) || ! CONSTANT_P (next->add_val)
|| ! (biv_dead_after_loop
|| no_jumps_between_p (v->insn, next->insn)))
{ {
vp = &v->next_iv; vp = &v->next_iv;
continue; continue;
......
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