aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2015-04-09 19:40:09 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2015-04-09 19:40:09 +0000
commit8fd827b8e58b04cdefeb3d5c4de4d53566fdc3ff (patch)
tree9684a6d40e6a42b869a0f236d04ab6c6882b0ca8
parentbf1b77dd092bb694be6fb0b1fcc369327db6143f (diff)
downloadgcc-8fd827b8e58b04cdefeb3d5c4de4d53566fdc3ff.zip
gcc-8fd827b8e58b04cdefeb3d5c4de4d53566fdc3ff.tar.gz
gcc-8fd827b8e58b04cdefeb3d5c4de4d53566fdc3ff.tar.bz2
re PR target/65710 (Thumb1 ICE caused by no register to spill)
2015-04-09 Vladimir Makarov <vmakarov@redhat.com> PR target/65710 * lra-int.h (lra_bad_spill_regno_start): New. * lra.c (lra_bad_spill_regno_start): New. (lra): Set up lra_bad_spill_regno_start. Set up lra_constraint_new_regno_start unconditionally. * lra-assigns.c (spill_for): Use lra_bad_spill_regno_start for spill preferences. From-SVN: r221956
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/lra-assigns.c9
-rw-r--r--gcc/lra-int.h1
-rw-r--r--gcc/lra.c19
4 files changed, 32 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 32149ba..17fe5a1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2015-04-09 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR target/65710
+ * lra-int.h (lra_bad_spill_regno_start): New.
+ * lra.c (lra_bad_spill_regno_start): New.
+ (lra): Set up lra_bad_spill_regno_start. Set up
+ lra_constraint_new_regno_start unconditionally.
+ * lra-assigns.c (spill_for): Use lra_bad_spill_regno_start for
+ spill preferences.
+
2015-04-09 Marek Polacek <polacek@redhat.com>
Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index e19156b..a74d8ab 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -910,6 +910,7 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
enum reg_class rclass;
unsigned int spill_regno, reload_regno, uid;
int insn_pseudos_num, best_insn_pseudos_num;
+ int bad_spills_num, smallest_bad_spills_num;
lra_live_range_t r;
bitmap_iterator bi;
@@ -928,6 +929,7 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
best_hard_regno = -1;
best_cost = INT_MAX;
best_insn_pseudos_num = INT_MAX;
+ smallest_bad_spills_num = INT_MAX;
rclass_size = ira_class_hard_regs_num[rclass];
mode = PSEUDO_REGNO_MODE (regno);
/* Invalidate try_hard_reg_pseudos elements. */
@@ -958,6 +960,7 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
&& ! bitmap_bit_p (&lra_optional_reload_pseudos, spill_regno)))
goto fail;
insn_pseudos_num = 0;
+ bad_spills_num = 0;
if (lra_dump_file != NULL)
fprintf (lra_dump_file, " Trying %d:", hard_regno);
sparseset_clear (live_range_reload_inheritance_pseudos);
@@ -965,6 +968,8 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
{
if (bitmap_bit_p (&insn_conflict_pseudos, spill_regno))
insn_pseudos_num++;
+ if (spill_regno >= (unsigned int) lra_bad_spill_regno_start)
+ bad_spills_num++;
for (r = lra_reg_info[spill_regno].live_ranges;
r != NULL;
r = r->next)
@@ -1035,7 +1040,9 @@ spill_for (int regno, bitmap spilled_pseudo_bitmap, bool first_p)
}
if (best_insn_pseudos_num > insn_pseudos_num
|| (best_insn_pseudos_num == insn_pseudos_num
- && best_cost > cost))
+ && (bad_spills_num < smallest_bad_spills_num
+ || (bad_spills_num == smallest_bad_spills_num
+ && best_cost > cost))))
{
best_insn_pseudos_num = insn_pseudos_num;
best_cost = cost;
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index c6b147e..12923ee 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -333,6 +333,7 @@ extern void lra_register_new_scratch_op (rtx_insn *, int);
extern int lra_new_regno_start;
extern int lra_constraint_new_regno_start;
+extern int lra_bad_spill_regno_start;
extern bitmap_head lra_inheritance_pseudos;
extern bitmap_head lra_split_regs;
extern bitmap_head lra_subreg_reload_pseudos;
diff --git a/gcc/lra.c b/gcc/lra.c
index a29266e..f4d7a3c 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2180,6 +2180,10 @@ int lra_new_regno_start;
/* Start of reload pseudo regnos before the new spill pass. */
int lra_constraint_new_regno_start;
+/* Avoid spilling pseudos with regno more than the following value if
+ it is possible. */
+int lra_bad_spill_regno_start;
+
/* Inheritance pseudo regnos before the new spill pass. */
bitmap_head lra_inheritance_pseudos;
@@ -2269,6 +2273,7 @@ lra (FILE *f)
permit changing reg classes for pseudos created by this
simplification. */
lra_constraint_new_regno_start = lra_new_regno_start = max_reg_num ();
+ lra_bad_spill_regno_start = INT_MAX;
remove_scratches ();
scratch_p = lra_constraint_new_regno_start != max_reg_num ();
@@ -2406,12 +2411,14 @@ lra (FILE *f)
/* Assignment of stack slots changes elimination offsets for
some eliminations. So update the offsets here. */
lra_eliminate (false, false);
- /* After switching off inheritance and rematerialization passes,
- don't forget reload pseudos after spilling sub-pass to avoid
- LRA cycling in some complicated cases. */
- if (lra_inheritance_iter <= LRA_MAX_INHERITANCE_PASSES
- || lra_rematerialization_iter <= LRA_MAX_REMATERIALIZATION_PASSES)
- lra_constraint_new_regno_start = max_reg_num ();
+ lra_constraint_new_regno_start = max_reg_num ();
+ if (lra_bad_spill_regno_start == INT_MAX
+ && lra_inheritance_iter > LRA_MAX_INHERITANCE_PASSES
+ && lra_rematerialization_iter > LRA_MAX_REMATERIALIZATION_PASSES)
+ /* After switching off inheritance and rematerialization
+ passes, avoid spilling reload pseudos will be created to
+ prevent LRA cycling in some complicated cases. */
+ lra_bad_spill_regno_start = lra_constraint_new_regno_start;
lra_assignment_iter_after_spill = 0;
}
restore_scratches ();