]> gcc.gnu.org Git - gcc.git/commitdiff
combine.c (can_change_dest_mode): New function.
authorPaul Brook <paul@codesourcery.com>
Wed, 3 Aug 2005 13:07:31 +0000 (13:07 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Wed, 3 Aug 2005 13:07:31 +0000 (13:07 +0000)
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

gcc/ChangeLog
gcc/combine.c

index 6656cad3a86aa24740d969661fc0d0db0a51785e..fb1cf3fd7cc5d32ce0a237eba2685504746a2d07 100644 (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
index bbd6c0953c3aec1d424adfe9a2bdc0ea9124411c..d5be605751ae4e69d84b49e24bcff6e473b2d141 100644 (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);
 
This page took 0.079108 seconds and 5 git commands to generate.