more radical fix for the last problem, from the egcs/gcc mailing list

(http://egcs.cygnus.com/ml/gcc/1999-10/msg00400.html).
Log message:
          * combine.c (get_last_value): If the last set of a register
        is after subst_low_cuid, then we can not use it to determine
        the register's last value.
This commit is contained in:
drochner 1999-10-25 19:30:19 +00:00
parent 87568e8d82
commit 16dcb3a8fd

View File

@ -10813,62 +10813,10 @@ get_last_value (x)
return 0; return 0;
/* If the value was set in a later insn than the ones we are processing, /* If the value was set in a later insn than the ones we are processing,
we can't use it even if the register was only set once, but make a quick we can't use it even if the register was only set once. */
check to see if the previous insn set it to something. This is commonly
the case when the same pseudo is used by repeated insns.
This does not work if there exists an instruction which is temporarily
not on the insn chain. */
if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid) if (INSN_CUID (reg_last_set[regno]) >= subst_low_cuid)
{
rtx insn, set;
/* We can't do anything if the value is set in between the insns we are
processing. */
if (INSN_CUID (reg_last_set[regno]) <= INSN_CUID (subst_insn))
return 0;
/* We can not do anything useful in this case, because there is
an instruction which is not on the insn chain. */
if (subst_prev_insn)
return 0; return 0;
/* Skip over USE insns. They are not useful here, and they may have
been made by combine, in which case they do not have a INSN_CUID
value. We can't use prev_real_insn, because that would incorrectly
take us backwards across labels. Skip over BARRIERs also, since
they could have been made by combine. If we see one, we must be
optimizing dead code, so it doesn't matter what we do. */
for (insn = prev_nonnote_insn (subst_insn);
insn && ((GET_CODE (insn) == INSN
&& GET_CODE (PATTERN (insn)) == USE)
|| GET_CODE (insn) == BARRIER
|| INSN_CUID (insn) >= subst_low_cuid);
insn = prev_nonnote_insn (insn))
;
if (insn
&& (set = single_set (insn)) != 0
&& rtx_equal_p (SET_DEST (set), x))
{
value = SET_SRC (set);
/* Make sure that VALUE doesn't reference X. Replace any
explicit references with a CLOBBER. If there are any remaining
references (rare), don't use the value. */
if (reg_mentioned_p (x, value))
value = replace_rtx (copy_rtx (value), x,
gen_rtx_CLOBBER (GET_MODE (x), const0_rtx));
if (reg_overlap_mentioned_p (x, value))
return 0;
}
else
return 0;
}
/* If the value has all its registers valid, return it. */ /* If the value has all its registers valid, return it. */
if (get_last_value_validate (&value, reg_last_set[regno], if (get_last_value_validate (&value, reg_last_set[regno],
reg_last_set_label[regno], 0)) reg_last_set_label[regno], 0))