re PR rtl-optimization/55055 (RTL check: expected code 'reg', have 'subreg' in rhs_re...
authorVladimir Makarov <vmakarov@redhat.com>
Wed, 24 Oct 2012 20:02:08 +0000 (20:02 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Wed, 24 Oct 2012 20:02:08 +0000 (20:02 +0000)
2012-10-24  Vladimir Makarov  <vmakarov@redhat.com>

PR rtl-optimization/55055
* lra-spills.c (alter_subregs): New function.
(lra_hard_reg_substitution): Use it.

From-SVN: r192779

gcc/ChangeLog
gcc/lra-spills.c

index 71311d908de476685b20ee8da197af8db10dbeda..9ee494d869ae9b2d83cfe0b94ff676475d3c8f44 100644 (file)
@@ -1,3 +1,9 @@
+2012-10-24  Vladimir Makarov  <vmakarov@redhat.com>
+
+       PR rtl-optimization/55055
+       * lra-spills.c (alter_subregs): New function.
+       (lra_hard_reg_substitution): Use it.
+
 2012-10-24  Sharad Singhai  <singhai@google.com>
 
        * dumpfile.c (dump_enabled_p): Make it inline and move the definition
index ecc1de4a4d9bc02b237112b71313d589b133b2e6..8ff91d811394436a9c6303ffb31dcc0f95f2c397 100644 (file)
@@ -571,6 +571,48 @@ lra_spill (void)
   free (pseudo_regnos);
 }
 
+/* Apply alter_subreg for subregs of regs in *LOC.  Use FINAL_P for
+   alter_subreg calls. Return true if any subreg of reg is
+   processed.  */
+static bool
+alter_subregs (rtx *loc, bool final_p)
+{
+  int i;
+  rtx x = *loc;
+  bool res;
+  const char *fmt;
+  enum rtx_code code;
+
+  if (x == NULL_RTX)
+    return false;
+  code = GET_CODE (x);
+  if (code == SUBREG && REG_P (SUBREG_REG (x)))
+    {
+      lra_assert (REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER);
+      alter_subreg (loc, final_p);
+      return true;
+    }
+  fmt = GET_RTX_FORMAT (code);
+  res = false;
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'e')
+       {
+         if (alter_subregs (&XEXP (x, i), final_p))
+           res = true;
+       }
+      else if (fmt[i] == 'E')
+       {
+         int j;
+         
+         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+           if (alter_subregs (&XVECEXP (x, i, j), final_p))
+             res = true;
+       }
+    }
+  return res;
+}
+
 /* Final change of pseudos got hard registers into the corresponding
    hard registers.  */
 void
@@ -589,22 +631,15 @@ lra_hard_reg_substitution (void)
     FOR_BB_INSNS (bb, insn)
       if (INSN_P (insn))
        {
-         lra_insn_recog_data_t id;
+         lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
          bool insn_change_p = false;
 
-         id = lra_get_insn_recog_data (insn);
          for (i = id->insn_static_data->n_operands - 1; i >= 0; i--)
-           {
-             rtx op = *id->operand_loc[i];
-
-             if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
-               {
-                 lra_assert (REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER);
-                 alter_subreg (id->operand_loc[i], ! DEBUG_INSN_P (insn));
-                 lra_update_dup (id, i);
-                 insn_change_p = true;
-               }
-           }
+           if (alter_subregs (id->operand_loc[i], ! DEBUG_INSN_P (insn)))
+             {
+               lra_update_dup (id, i);
+               insn_change_p = true;
+             }
          if (insn_change_p)
            lra_update_operator_dups (id);
        }