combine.c (can_change_dest_mode): New function.

2005-08-03  Paul Brook  <paul@codesourcery.com>

	* combine.c (can_change_dest_mode): New function.
	(try_combine, simplify_set): Use it.

From-SVN: r102686
This commit is contained in:
Paul Brook 2005-08-03 13:07:31 +00:00 committed by Paul Brook
parent 4e2b3c877d
commit 4164b2fb16
2 changed files with 43 additions and 24 deletions

View file

@ -1,3 +1,8 @@
2005-08-03 Paul Brook <paul@codesourcery.com>
* combine.c (can_change_dest_mode): New function.
(try_combine, simplify_set): Use it.
2005-08-03 Eric Botcazou <ebotcazou@adacore.com>
* config/ia64/hpux.h (MEMBER_TYPE_FORCES_BLK): Only force

View file

@ -1666,6 +1666,29 @@ adjust_for_new_dest (rtx insn)
distribute_links (gen_rtx_INSN_LIST (VOIDmode, insn, NULL_RTX));
}
/* Return TRUE if combine can reuse reg X in mode MODE.
ADDED_SETS is nonzero if the original set is still required. */
static bool
can_change_dest_mode (rtx x, int added_sets, enum machine_mode mode)
{
unsigned int regno;
if (!REG_P(x))
return false;
regno = REGNO (x);
/* Allow hard registers if the new mode is legal, and occupies no more
registers than the old mode. */
if (regno < FIRST_PSEUDO_REGISTER)
return (HARD_REGNO_MODE_OK (regno, mode)
&& (hard_regno_nregs[regno][GET_MODE (x)]
>= hard_regno_nregs[regno][mode]));
/* Or a pseudo that is only used once. */
return (REG_N_SETS (regno) == 1 && !added_sets
&& !REG_USERVAR_P (x));
}
/* Try to combine the insns I1 and I2 into I3.
Here I1 and I2 appear earlier than I3.
I1 can be zero; then we combine just I2 into I3.
@ -2117,13 +2140,12 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
i2src, const0_rtx))
!= GET_MODE (SET_DEST (newpat))))
{
unsigned int regno = REGNO (SET_DEST (newpat));
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno < FIRST_PSEUDO_REGISTER
|| (REG_N_SETS (regno) == 1 && ! added_sets_2
&& ! REG_USERVAR_P (SET_DEST (newpat))))
if (can_change_dest_mode(SET_DEST (newpat), added_sets_2,
compare_mode))
{
unsigned int regno = REGNO (SET_DEST (newpat));
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno >= FIRST_PSEUDO_REGISTER)
SUBST (regno_reg_rtx[regno], new_dest);
@ -2356,14 +2378,12 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
if (m_split == 0 && ! reg_overlap_mentioned_p (ni2dest, newpat))
{
enum machine_mode new_mode = GET_MODE (SET_DEST (newpat));
/* If I2DEST is a hard register or the only use of a pseudo,
we can change its mode. */
if (GET_MODE (SET_DEST (newpat)) != GET_MODE (i2dest)
&& GET_MODE (SET_DEST (newpat)) != VOIDmode
&& REG_P (i2dest)
&& (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
|| (REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
&& ! REG_USERVAR_P (i2dest))))
if (new_mode != GET_MODE (i2dest)
&& new_mode != VOIDmode
&& can_change_dest_mode (i2dest, added_sets_2, new_mode))
ni2dest = gen_rtx_REG (GET_MODE (SET_DEST (newpat)),
REGNO (i2dest));
@ -2471,13 +2491,8 @@ try_combine (rtx i3, rtx i2, rtx i1, int *new_direct_jump_p)
isn't valid for it, or change the number of registers. */
&& (GET_MODE (*split) == GET_MODE (i2dest)
|| GET_MODE (*split) == VOIDmode
|| (REGNO (i2dest) < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_MODE_OK (REGNO (i2dest), GET_MODE (*split))
&& (hard_regno_nregs[REGNO (i2dest)][GET_MODE (i2dest)]
== hard_regno_nregs[REGNO (i2dest)][GET_MODE (*split)]))
|| (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (REGNO (i2dest)) == 1 && ! added_sets_2
&& ! REG_USERVAR_P (i2dest)))
|| can_change_dest_mode (i2dest, added_sets_2,
GET_MODE (*split)))
&& (next_real_insn (i2) == i3
|| ! use_crosses_set_p (*split, INSN_CUID (i2)))
/* We can't overwrite I2DEST if its value is still used by
@ -5282,12 +5297,11 @@ simplify_set (rtx x)
which case we can safely change its mode. */
if (compare_mode != GET_MODE (dest))
{
unsigned int regno = REGNO (dest);
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno < FIRST_PSEUDO_REGISTER
|| (REG_N_SETS (regno) == 1 && ! REG_USERVAR_P (dest)))
if (can_change_dest_mode (dest, 0, compare_mode))
{
unsigned int regno = REGNO (dest);
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno >= FIRST_PSEUDO_REGISTER)
SUBST (regno_reg_rtx[regno], new_dest);