aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2012-10-24 20:02:08 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2012-10-24 20:02:08 +0000
commit6e5769ce15b051c09cbec5d7b4acf42ff76d78e2 (patch)
tree36ee294a9560f006e403f8db6c4ba8724bb2d744
parenteb00e9592006bb3b5412a4857762e85ea56a8e3f (diff)
downloadgcc-6e5769ce15b051c09cbec5d7b4acf42ff76d78e2.zip
gcc-6e5769ce15b051c09cbec5d7b4acf42ff76d78e2.tar.gz
gcc-6e5769ce15b051c09cbec5d7b4acf42ff76d78e2.tar.bz2
re PR rtl-optimization/55055 (RTL check: expected code 'reg', have 'subreg' in rhs_regno, at rtl.h:1123)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-spills.c61
2 files changed, 54 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71311d9..9ee494d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index ecc1de4..8ff91d81 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -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);
}