OSDN Git Service

* regrename.c (rr_replace_reg): Rewrite to use recog_data to
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 20 Oct 2000 17:54:49 +0000 (17:54 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 20 Oct 2000 17:54:49 +0000 (17:54 +0000)
        perform substitutions, and apply_change_group to see if it worked.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36971 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/regrename.c

index eab6238..6414aec 100644 (file)
@@ -7,6 +7,9 @@ Fri Oct 20 13:33:16 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * function.c (locate_and_pad_parm): Zero alignment_pad.
 
+       * regrename.c (rr_replace_reg): Rewrite to use recog_data to
+       perform substitutions, and apply_change_group to see if it worked.
+
 Fri Oct 20 13:33:16 2000  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * dwarf2out.c (add_bound_info): Also ignore COND_EXPR.
index fb0a3be..968b8b9 100644 (file)
@@ -83,8 +83,7 @@ static int replace_reg_in_block               PARAMS ((def_uses *, varray_type *,
 static int consider_def                        PARAMS ((rtx, int, def_uses *, int));
 static int consider_available          PARAMS ((rtx, int, HARD_REG_SET *,
                                                 int, def_uses *, int));
-static rtx rr_replace_reg              PARAMS ((rtx, rtx, rtx, int, rtx,
-                                                int *));
+static void rr_replace_reg             PARAMS ((rtx, rtx, int, rtx, int *));
 static int consider_use                        PARAMS ((rtx, int, int, int));
 static int condmove_p                  PARAMS ((rtx));
 static void dump_def_use_chain         PARAMS ((HARD_REG_SET *, def_uses *,
@@ -527,8 +526,8 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
   rtx reg_use = 0;
   rtx new_reg = gen_rtx_REG (GET_MODE (reg_def), avail_reg);
 
-  rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, def)), reg_def, new_reg,
-                 DESTINATION, VARRAY_RTX (*uid_ruid, def), &status);
+  rr_replace_reg (reg_def, new_reg, DESTINATION,
+                 VARRAY_RTX (*uid_ruid, def), &status);
 
   if (!status)
     return status;
@@ -568,9 +567,8 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
        {
          new_reg = gen_rtx_REG (GET_MODE (reg_use), avail_reg);
          
-         rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, du_idx)), reg_use,
-                         new_reg, SOURCE, VARRAY_RTX (*uid_ruid, du_idx),
-                         &status);
+         rr_replace_reg (reg_use, new_reg, SOURCE,
+                         VARRAY_RTX (*uid_ruid, du_idx), &status);
          death_note = find_reg_note (VARRAY_RTX (*uid_ruid, du_idx),
                                      REG_DEAD, reg_use);
          if (death_note)
@@ -628,134 +626,82 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg)
 /* Try to replace REG_USE in X with REG_SUB if INSN has a REPLACE_TYPE.
    STATUS is zero if the resulting pattern is not valid. */
 
-static rtx
-rr_replace_reg (x, reg_use, reg_sub, replace_type, insn, status)
-     rtx x;
+static void
+rr_replace_reg (reg_use, reg_sub, replace_type, insn, status)
      rtx reg_use;
      rtx reg_sub;
      int replace_type;
      rtx insn;
      int *status;
 {
-  enum rtx_code code;
   int i;
-  const char *fmt;
-  int n;
+  int changed = 0;
 
-  if (x == 0)
-    return x;
+  /* We only perform replacements on operands, since everything else
+     is by definition hard-coded.  Begin by extracting insn information
+     so that we know where the operands and dups exist.  */
+  extract_insn (insn);
 
-  code = GET_CODE (x);
-  switch (code)
+  for (i = recog_data.n_operands - 1; i >= 0; --i)
     {
-    case REG:
-      if (REGNO (x) == REGNO (reg_use))
-       {
-         if (GET_MODE (x) == GET_MODE (reg_use))
-           return reg_sub;
-         else
-           return gen_rtx_REG (GET_MODE (x), REGNO (reg_sub));
-       }
+      rtx op;
 
-      return x;
+      /* Match replace_type with operand_type and skip those we aren't
+        supposed to touch.  Note that OP_INOUT does _not_ match either
+        replace_type.  */
+      if (replace_type == DESTINATION && recog_data.operand_type[i] != OP_OUT)
+       continue;
+      if (replace_type == SOURCE && recog_data.operand_type[i] != OP_IN)
+       continue;
 
-    case SET:
-      if (replace_type == DESTINATION)
-       SET_DEST (x) = rr_replace_reg (SET_DEST (x), reg_use, reg_sub,
-                                      replace_type, insn, status);
-      else if (replace_type == SOURCE)
-       {
-         unsigned int dest_subregno = 0;
-         int had_subreg = GET_CODE (SET_DEST (x)) == SUBREG;
-
-         if (had_subreg)
-           dest_subregno = REGNO (XEXP (SET_DEST (x), 0));
-
-         SET_SRC (x) = rr_replace_reg (SET_SRC (x), reg_use, reg_sub,
-                                       replace_type, insn, status);
-
-         /* If the replacement register is not part of the source
-            then it may be part of a source mem operand. */
-         if (GET_CODE (SET_DEST (x)) == MEM
-             || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT
-             || GET_CODE (SET_DEST (x)) == SIGN_EXTRACT
-             || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
-           SET_DEST (x) = rr_replace_reg (SET_DEST (x), reg_use, reg_sub,
-                                          replace_type, insn, status);
-         /* Shared rtl sanity check. */
-         if (had_subreg && dest_subregno != REGNO (XEXP (SET_DEST (x), 0)))
-           {
-             *status = 0;
-             return x;
-           }
-       }
+      op = recog_data.operand[i];
+      if (GET_CODE (op) != REG)
+       continue;
 
-      n = recog_memoized (insn);
-      if (n >= 0)
+      if (REGNO (op) == REGNO (reg_use))
        {
-         int id;
-
-         extract_insn (insn);
-
-         /* Any MATCH_DUP's which are REGs must still match */
-         for (id = insn_data[n].n_dups - 1; id >= 0; id--)
-           {
-             int opno = recog_data.dup_num[id];
+         rtx new = reg_sub;
+         if (GET_MODE (op) != GET_MODE (reg_use))
+           new = gen_rtx_REG (GET_MODE (op), REGNO (reg_sub));
 
-             if (GET_CODE (*recog_data.dup_loc[id]) == REG
-                 && GET_CODE (*recog_data.operand_loc[opno]) == REG
-                 && (REGNO (*recog_data.dup_loc[id])
-                     != REGNO (*recog_data.operand_loc[opno])))
-               *status = 0;
-           }
+         validate_change (insn, recog_data.operand_loc[i], new, 1);
+         recog_data.operand[i] = new;
 
-         if (!constrain_operands (1))
-           {
-             *status = 0;
-             validate_replace_rtx (reg_sub, reg_use, insn);
-           }
+         changed |= 1 << i;
        }
-      else
-       *status = 0;
-
-      return x;
-
-    default:
-      break;
     }
 
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+  /* Any MATCH_DUP's for changed operands must also be changed.  */
+  /* ??? This more or less assumes that operand_type is correct, in
+     that the dup will be of the appropriate replace_type.  */
+  for (i = recog_data.n_dups - 1; i >= 0; i--)
     {
-      if (fmt[i] == 'e')
-       XEXP (x, i) = rr_replace_reg (XEXP (x, i), reg_use, reg_sub,
-                                     replace_type, insn, status);
-      if (fmt[i] == 'E')
-       {
-         register int xv;
+      int opno = recog_data.dup_num[i];
+      if ((changed >> opno) & 1)
+       validate_change (insn, recog_data.dup_loc[i],
+                        recog_data.operand[i], 1);
+    }
 
-         for (xv = 0; xv < XVECLEN (x, i); xv++)
-           {
-             XVECEXP (x, i, xv) = rr_replace_reg (XVECEXP (x, i, xv), reg_use,
-                                               reg_sub, replace_type, insn,
-                                                  status);
-             n = recog_memoized (insn);
-             if (n >= 0)
-               {
-                 extract_insn (insn);
-                 if (!constrain_operands (1))
-                   {
-                     *status = 0;
-                     validate_replace_rtx (reg_sub, reg_use, insn);
-                   }
-               }
-             else
-               *status = 0;
-           }
-       }
+  /* Verify that the changes applied so far result in a recognizable insn.  */
+  if (! apply_change_group ())
+    {
+      *status = 0;
+      return;
     }
 
-  return x;
+  /* Verify that there are no other references of the given type to the
+     register in question.  That is, there are no hard-coded references
+     to this hard register left in the insn.  */
+  if (replace_type == DESTINATION)
+    {
+      if (reg_set_p (reg_use, insn))
+       *status = 0;
+    }
+  else
+    {
+      if (reg_referenced_p (reg_use, PATTERN (insn)))
+       *status = 0;
+    }
 }
 
 /* Can REGNO in INSN be considered for renaming, given def INUM in d/u