*** empty log message ***

From-SVN: r611
This commit is contained in:
Richard Kenner 1992-03-28 07:27:04 -05:00
parent e165f3f04d
commit 7dcd3836a3
1 changed files with 77 additions and 11 deletions

View File

@ -1467,7 +1467,7 @@ add_label_notes (x, insns)
rtx insns;
{
enum rtx_code code = GET_CODE (x);
int i;
int i, j;
char *fmt;
rtx insn;
@ -1482,8 +1482,13 @@ add_label_notes (x, insns)
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
if (fmt[i] == 'e')
add_label_notes (XEXP (x, i), insns);
{
if (fmt[i] == 'e')
add_label_notes (XEXP (x, i), insns);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
add_label_notes (XVECEXP (x, i, j), insns);
}
}
/* Scan MOVABLES, and move the insns that deserve to be moved.
@ -3067,6 +3072,9 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* This is 1 if current insn is not executed at least once for every loop
iteration. */
int not_every_iteration = 0;
/* This is 1 if current insn may be executed more than once for every
loop iteration. */
int maybe_multiple = 0;
/* Temporary list pointers for traversing loop_iv_list. */
struct iv_class *bl, **backbl;
/* Ratio of extra register life span we can justify
@ -3141,7 +3149,7 @@ strength_reduce (scan_start, end, loop_top, insn_count,
= (struct induction *) alloca (sizeof (struct induction));
record_biv (v, p, dest_reg, inc_val, mult_val,
not_every_iteration);
not_every_iteration, maybe_multiple);
reg_iv_type[REGNO (dest_reg)] = BASIC_INDUCT;
}
else if (REGNO (dest_reg) < max_reg_before_loop)
@ -3149,6 +3157,46 @@ strength_reduce (scan_start, end, loop_top, insn_count,
}
}
/* Past CODE_LABEL, we get to insns that may be executed multiple
times. The only way we can be sure that they can't is if every
every jump insn between here and the end of the loop either
returns, exits the loop, or is a forward jump. */
if (GET_CODE (p) == CODE_LABEL)
{
rtx insn = p;
maybe_multiple = 0;
while (1)
{
insn = NEXT_INSN (insn);
if (insn == scan_start)
break;
if (insn == end)
{
if (loop_top != 0)
insn = NEXT_INSN (loop_top);
else
break;
if (insn == scan_start)
break;
}
if (GET_CODE (insn) == JUMP_INSN
&& GET_CODE (PATTERN (insn)) != RETURN
&& (! condjump_p (insn)
|| (JUMP_LABEL (insn) != 0
&& (INSN_UID (JUMP_LABEL (insn)) > max_uid_for_loop
|| (INSN_LUID (JUMP_LABEL (insn))
< INSN_LUID (insn))))))
{
maybe_multiple = 1;
break;
}
}
}
/* Past a label or a jump, we get to insns for which we can't count
on whether or how many times they will be executed during each
iteration. */
@ -3415,7 +3463,8 @@ strength_reduce (scan_start, end, loop_top, insn_count,
/* Update the status of whether giv can derive other givs. This can
change when we pass a label or an insn that updates a biv. */
if (GET_CODE (p) == INSN || GET_CODE (p) == CODE_LABEL)
if (GET_CODE (p) == INSN || GET_CODE (p) == JUMP_INSN
|| GET_CODE (p) == CODE_LABEL)
update_giv_derive (p);
/* Past a label or a jump, we get to insns for which we can't count
@ -4000,16 +4049,24 @@ find_mem_givs (x, insn, not_every_iteration, loop_start, loop_end)
MULT_VAL is const1_rtx if the biv is being incremented here, in which case
INC_VAL is the increment. Otherwise, MULT_VAL is const0_rtx and the biv is
being set to INC_VAL. */
being set to INC_VAL.
NOT_EVERY_ITERATION is nonzero if this biv update is not know to be
executed every iteration; MAYBE_MULTIPLE is nonzero if this biv update
can be executed more than once per iteration. If MAYBE_MULTIPLE
and NOT_EVERY_ITERATION are both zero, we know that the biv update is
executed exactly once per iteration. */
static void
record_biv (v, insn, dest_reg, inc_val, mult_val, not_every_iteration)
record_biv (v, insn, dest_reg, inc_val, mult_val,
not_every_iteration, maybe_multiple)
struct induction *v;
rtx insn;
rtx dest_reg;
rtx inc_val;
rtx mult_val;
int not_every_iteration;
int maybe_multiple;
{
struct iv_class *bl;
@ -4020,6 +4077,7 @@ record_biv (v, insn, dest_reg, inc_val, mult_val, not_every_iteration)
v->add_val = inc_val;
v->mode = GET_MODE (dest_reg);
v->always_computable = ! not_every_iteration;
v->maybe_multiple = maybe_multiple;
/* Add this to the reg's iv_class, creating a class
if this is the first incrementation of the reg. */
@ -4122,6 +4180,7 @@ record_giv (v, insn, src_reg, dest_reg, mult_val, add_val, benefit,
v->location = location;
v->cant_derive = 0;
v->combined_with = 0;
v->maybe_multiple = 0;
v->maybe_dead = 0;
v->derive_adjustment = 0;
v->same = 0;
@ -4485,7 +4544,7 @@ update_giv_derive (p)
/* Search all IV classes, then all bivs, and finally all givs.
There are two cases we are concerned with. First we have the situation
There are three cases we are concerned with. First we have the situation
of a giv that is only updated conditionally. In that case, it may not
derive any givs after a label is passed.
@ -4501,13 +4560,19 @@ update_giv_derive (p)
a branch here (actually, we need to pass both a jump and a label, but
this extra tracking doesn't seem worth it).
If this is a giv update, we must adjust the giv status to show that a
If this is a jump, we are concerned about any biv update that may be
executed multiple times. We are actually only concerned about
backward jumps, but it is probably not worth performing the test
on the jump again here.
If this is a biv update, we must adjust the giv status to show that a
subsequent biv update was performed. If this adjustment cannot be done,
the giv cannot derive further givs. */
for (bl = loop_iv_list; bl; bl = bl->next)
for (biv = bl->biv; biv; biv = biv->next_iv)
if (GET_CODE (p) == CODE_LABEL || biv->insn == p)
if (GET_CODE (p) == CODE_LABEL || GET_CODE (p) == JUMP_INSN
|| biv->insn == p)
{
for (giv = bl->giv; giv; giv = giv->next_iv)
{
@ -4551,7 +4616,8 @@ update_giv_derive (p)
else
giv->cant_derive = 1;
}
else if (GET_CODE (p) == CODE_LABEL && ! biv->always_computable)
else if ((GET_CODE (p) == CODE_LABEL && ! biv->always_computable)
|| (GET_CODE (p) == JUMP_INSN && biv->maybe_multiple))
giv->cant_derive = 1;
}
}