aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-constraints.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-11-20 20:32:57 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-11-20 20:32:57 +0000
commita2d0d374f69a87cde1a18bbcf197ff45168764fa (patch)
tree438f88188d619344b0bd8235fbee7824d4eb962e /gcc/lra-constraints.c
parent1fef36449e233448605e7812f4e2874baf05ce53 (diff)
downloadgcc-a2d0d374f69a87cde1a18bbcf197ff45168764fa.zip
gcc-a2d0d374f69a87cde1a18bbcf197ff45168764fa.tar.gz
gcc-a2d0d374f69a87cde1a18bbcf197ff45168764fa.tar.bz2
re PR rtl-optimization/59133 (ICE after r204219 on SPEC2006 435.gromacs.)
2013-11-20 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/59133 * lra.c (expand_reg_data): Add new argument. Set up ALL_REGS for new pseudos. (lra_create_new_reg_with_unique_value): Pass new argument value. (lra_emit_add, lra_emit_move): Ditto. * lra-constraints.c (in_class_p): Add check for move for a new insn. (change_class): Rename to lra_change_class. Move to lra-int.h. (get_reload_reg, narrow_reload_pseudo_class): Adjust calls of change_class. (process_addr_reg, process_addr): Ditto. (curr_insn_transform): Ditto. Add check on old pseudo for optional reload. * lra-int.h (lra_get_regno_hard_regno): Move below. (lra_change_class): Renamed change_class from lra.c. 2013-11-20 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/59133 * gcc.target/i386/pr59133.c: New. From-SVN: r205141
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r--gcc/lra-constraints.c34
1 files changed, 12 insertions, 22 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 94b6e25..4c88cca 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -269,7 +269,11 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class)
typically moves that have many alternatives, and restricting
reload pseudos for one alternative may lead to situations
where other reload pseudos are no longer allocatable. */
- || INSN_UID (curr_insn) >= new_insn_uid_start)
+ || (INSN_UID (curr_insn) >= new_insn_uid_start
+ && curr_insn_set != NULL
+ && (OBJECT_P (SET_SRC (curr_insn_set))
+ || (GET_CODE (SET_SRC (curr_insn_set)) == SUBREG
+ && OBJECT_P (SUBREG_REG (SET_SRC (curr_insn_set)))))))
/* When we don't know what class will be used finally for reload
pseudos, we use ALL_REGS. */
return ((regno >= new_regno_start && rclass == ALL_REGS)
@@ -381,21 +385,6 @@ init_curr_insn_input_reloads (void)
curr_insn_input_reloads_num = 0;
}
-/* Change class of pseudo REGNO to NEW_CLASS. Print info about it
- using TITLE. Output a new line if NL_P. */
-static void
-change_class (int regno, enum reg_class new_class,
- const char *title, bool nl_p)
-{
- lra_assert (regno >= FIRST_PSEUDO_REGISTER);
- if (lra_dump_file != NULL)
- fprintf (lra_dump_file, "%s to class %s for r%d",
- title, reg_class_names[new_class], regno);
- setup_reg_classes (regno, new_class, NO_REGS, new_class);
- if (lra_dump_file != NULL && nl_p)
- fprintf (lra_dump_file, "\n");
-}
-
/* Create a new pseudo using MODE, RCLASS, ORIGINAL or reuse already
created input reload pseudo (only if TYPE is not OP_OUT). The
result pseudo is returned through RESULT_REG. Return TRUE if we
@@ -442,7 +431,7 @@ get_reload_reg (enum op_type type, enum machine_mode mode, rtx original,
dump_value_slim (lra_dump_file, original, 1);
}
if (new_class != lra_get_allocno_class (regno))
- change_class (regno, new_class, ", change", false);
+ lra_change_class (regno, new_class, ", change to", false);
if (lra_dump_file != NULL)
fprintf (lra_dump_file, "\n");
return false;
@@ -667,7 +656,7 @@ narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
if (! REG_P (reg) || (int) REGNO (reg) < new_regno_start)
return;
if (in_class_p (reg, cl, &rclass) && rclass != cl)
- change_class (REGNO (reg), rclass, " Change", true);
+ lra_change_class (REGNO (reg), rclass, " Change to", true);
}
/* Generate reloads for matching OUT and INS (array of input operand
@@ -1133,7 +1122,7 @@ process_addr_reg (rtx *loc, rtx *before, rtx *after, enum reg_class cl)
}
else if (new_class != NO_REGS && rclass != new_class)
{
- change_class (regno, new_class, " Change", true);
+ lra_change_class (regno, new_class, " Change to", true);
return false;
}
else
@@ -2796,7 +2785,7 @@ process_address (int nop, rtx *before, rtx *after)
regno = REGNO (*ad.base_term);
if (regno >= FIRST_PSEUDO_REGISTER
&& cl != lra_get_allocno_class (regno))
- change_class (regno, cl, " Change", true);
+ lra_change_class (regno, cl, " Change to", true);
new_reg = SET_SRC (set);
delete_insns_since (PREV_INSN (last_insn));
}
@@ -3316,7 +3305,7 @@ curr_insn_transform (void)
if (new_class != NO_REGS && get_reg_class (regno) != new_class)
{
lra_assert (ok_p);
- change_class (regno, new_class, " Change", true);
+ lra_change_class (regno, new_class, " Change to", true);
}
}
}
@@ -3395,7 +3384,7 @@ curr_insn_transform (void)
&& lra_former_scratch_operand_p (curr_insn, i))
{
int regno = REGNO (op);
- change_class (regno, NO_REGS, " Change", true);
+ lra_change_class (regno, NO_REGS, " Change to", true);
if (lra_get_regno_hard_regno (regno) >= 0)
/* We don't have to mark all insn affected by the
spilled pseudo as there is only one such insn, the
@@ -3410,6 +3399,7 @@ curr_insn_transform (void)
&& lra_undo_inheritance_iter < LRA_MAX_INHERITANCE_PASSES
&& goal_alt[i] != NO_REGS && REG_P (op)
&& (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
+ && regno < new_regno_start
&& ! lra_former_scratch_p (regno)
&& reg_renumber[regno] < 0
&& (curr_insn_set == NULL_RTX