diff options
author | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-03 13:07:31 +0000 |
---|---|---|
committer | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-08-03 13:07:31 +0000 |
commit | 136305f40bec39c518bec801bcb454cf483005f3 (patch) | |
tree | d1aef2b428dd98d35f2e112642326ee2c613aac1 /gcc | |
parent | e7eb7e2193bd96631a02de88b263e05f040a4c7b (diff) | |
download | gcc-136305f40bec39c518bec801bcb454cf483005f3.tar.gz |
2005-08-03 Paul Brook <paul@codesourcery.com>
* combine.c (can_change_dest_mode): New function.
(try_combine, simplify_set): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@102686 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/combine.c | 62 |
2 files changed, 43 insertions, 24 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6656cad3a86..fb1cf3fd7cc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/combine.c b/gcc/combine.c index bbd6c0953c3..d5be605751a 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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); |