(move_deaths): New parameter maybe_kill_insn.
authorRichard Kenner <kenner@gcc.gnu.org>
Wed, 19 Jun 1996 21:50:05 +0000 (17:50 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Wed, 19 Jun 1996 21:50:05 +0000 (17:50 -0400)
Don't move note if reg killed by maybe_kill_insn.
(try_combine): Pass new arg to move_deaths.

From-SVN: r12311

gcc/combine.c

index 3dbdb183e5dbc651303e5d264513e9fdd2278c2a..25e872928611bd253ba8ad4f1a326fcc6763693b 100644 (file)
@@ -440,7 +440,7 @@ static rtx get_last_value   PROTO((rtx));
 static int use_crosses_set_p   PROTO((rtx, int));
 static void reg_dead_at_p_1    PROTO((rtx, rtx));
 static int reg_dead_at_p       PROTO((rtx, rtx));
-static void move_deaths                PROTO((rtx, int, rtx, rtx *));
+static void move_deaths                PROTO((rtx, rtx, int, rtx, rtx *));
 static int reg_bitfield_target_p  PROTO((rtx, rtx));
 static void distribute_notes   PROTO((rtx, rtx, rtx, rtx, rtx, rtx));
 static void distribute_links   PROTO((rtx));
@@ -2204,11 +2204,18 @@ try_combine (i3, i2, i1)
       }
 
     /* Get death notes for everything that is now used in either I3 or
-       I2 and used to die in a previous insn.  */
+       I2 and used to die in a previous insn.  If we built two new 
+       patterns, move from I1 to I2 then I2 to I3 so that we get the
+       proper movement on registers that I2 modifies.  */
 
-    move_deaths (newpat, i1 ? INSN_CUID (i1) : INSN_CUID (i2), i3, &midnotes);
     if (newi2pat)
-      move_deaths (newi2pat, INSN_CUID (i1), i2, &midnotes);
+      {
+       move_deaths (newi2pat, NULL_RTX, INSN_CUID (i1), i2, &midnotes);
+       move_deaths (newpat, newi2pat, INSN_CUID (i1), i3, &midnotes);
+      }
+    else
+      move_deaths (newpat, NULL_RTX, i1 ? INSN_CUID (i1) : INSN_CUID (i2),
+                  i3, &midnotes);
 
     /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3.  */
     if (i3notes)
@@ -10489,12 +10496,15 @@ remove_death (regno, insn)
    TO_INSN (exclusive), put a REG_DEAD note for that register in the
    list headed by PNOTES. 
 
+   That said, don't move registers killed by maybe_kill_insn.
+
    This is done when X is being merged by combination into TO_INSN.  These
    notes will then be distributed as needed.  */
 
 static void
-move_deaths (x, from_cuid, to_insn, pnotes)
+move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
      rtx x;
+     rtx maybe_kill_insn;
      int from_cuid;
      rtx to_insn;
      rtx *pnotes;
@@ -10509,6 +10519,11 @@ move_deaths (x, from_cuid, to_insn, pnotes)
       register rtx where_dead = reg_last_death[regno];
       register rtx before_dead, after_dead;
 
+      /* Don't move the register if it gets killed in between from and to */
+      if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
+         && !reg_referenced_p (x, maybe_kill_insn))
+       return;
+
       /* WHERE_DEAD could be a USE insn made by combine, so first we
         make sure that we have insns with valid INSN_CUID values.  */
       before_dead = where_dead;
@@ -10566,7 +10581,7 @@ move_deaths (x, from_cuid, to_insn, pnotes)
 
              for (i = regno + 1; i < ourend; i++)
                move_deaths (gen_rtx (REG, reg_raw_mode[i], i),
-                            from_cuid, to_insn, &oldnotes);
+                            maybe_kill_insn, from_cuid, to_insn, &oldnotes);
            }
 
          if (note != 0 && GET_MODE (XEXP (note, 0)) == GET_MODE (x))
@@ -10587,7 +10602,7 @@ move_deaths (x, from_cuid, to_insn, pnotes)
     {
       rtx dest = SET_DEST (x);
 
-      move_deaths (SET_SRC (x), from_cuid, to_insn, pnotes);
+      move_deaths (SET_SRC (x), maybe_kill_insn, from_cuid, to_insn, pnotes);
 
       /* In the case of a ZERO_EXTRACT, a STRICT_LOW_PART, or a SUBREG
         that accesses one word of a multi-word item, some
@@ -10602,7 +10617,7 @@ move_deaths (x, from_cuid, to_insn, pnotes)
                  == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
                       + UNITS_PER_WORD - 1) / UNITS_PER_WORD))))
        {
-         move_deaths (dest, from_cuid, to_insn, pnotes);
+         move_deaths (dest, maybe_kill_insn, from_cuid, to_insn, pnotes);
          return;
        }
 
@@ -10616,7 +10631,8 @@ move_deaths (x, from_cuid, to_insn, pnotes)
         being replaced so the old value is not used in this insn.  */
 
       if (GET_CODE (dest) == MEM)
-       move_deaths (XEXP (dest, 0), from_cuid, to_insn, pnotes);
+       move_deaths (XEXP (dest, 0), maybe_kill_insn, from_cuid,
+                    to_insn, pnotes);
       return;
     }
 
@@ -10632,10 +10648,11 @@ move_deaths (x, from_cuid, to_insn, pnotes)
        {
          register int j;
          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-           move_deaths (XVECEXP (x, i, j), from_cuid, to_insn, pnotes);
+           move_deaths (XVECEXP (x, i, j), maybe_kill_insn, from_cuid,
+                        to_insn, pnotes);
        }
       else if (fmt[i] == 'e')
-       move_deaths (XEXP (x, i), from_cuid, to_insn, pnotes);
+       move_deaths (XEXP (x, i), maybe_kill_insn, from_cuid, to_insn, pnotes);
     }
 }
 \f