summaryrefslogtreecommitdiff
path: root/gcc/lra.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2018-03-09 16:00:36 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2018-03-09 16:00:36 +0000
commite0cd6bc00966de0a3a77b642f9507d9c83b398f1 (patch)
treede7bad1e1e9a7a1d01900aa85dc8de1b2e98279f /gcc/lra.c
parenta4017ff7722614f749a0d5eab315e929b2035e8a (diff)
re PR target/83712 ("Unable to find a register to spill" when compiling for thumb1)
2018-03-09 Vladimir Makarov <vmakarov@redhat.com> PR target/83712 * lra-assigns.c (assign_by_spills): Return a flag of reload assignment failure. Do not process the reload assignment failures. Do not spill other reload pseudos if they has the same reg class. (lra_assign): Add a return arg. Set up from the result of assign_by_spills call. (find_reload_regno_insns, lra_split_hard_reg_for): New functions. * lra-constraints.c (split_reg): Add a new arg. Use it instead of usage_insns if it is not NULL. (spill_hard_reg_in_range): New function. (split_if_necessary, inherit_in_ebb): Pass a new arg to split_reg. * lra-int.h (spill_hard_reg_in_range, lra_split_hard_reg_for): New function prototypes. (lra_assign): Change prototype. * lra.c (lra): Add code to deal with fails by splitting hard reg live ranges. 2018-03-09 Vladimir Makarov <vmakarov@redhat.com> PR target/83712 * gcc.target/arm/pr83712.c: New. From-SVN: r258390
Diffstat (limited to 'gcc/lra.c')
-rw-r--r--gcc/lra.c67
1 files changed, 41 insertions, 26 deletions
diff --git a/gcc/lra.c b/gcc/lra.c
index a64d8f1a301..645b1665436 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -2460,38 +2460,53 @@ lra (FILE *f)
}
if (live_p)
lra_clear_live_ranges ();
- /* We need live ranges for lra_assign -- so build them. But
- don't remove dead insns or change global live info as we
- can undo inheritance transformations after inheritance
- pseudo assigning. */
- lra_create_live_ranges (true, false);
- live_p = true;
- /* If we don't spill non-reload and non-inheritance pseudos,
- there is no sense to run memory-memory move coalescing.
- If inheritance pseudos were spilled, the memory-memory
- moves involving them will be removed by pass undoing
- inheritance. */
- if (lra_simple_p)
- lra_assign ();
- else
+ bool fails_p;
+ do
{
- bool spill_p = !lra_assign ();
-
- if (lra_undo_inheritance ())
- live_p = false;
- if (spill_p)
+ /* We need live ranges for lra_assign -- so build them.
+ But don't remove dead insns or change global live
+ info as we can undo inheritance transformations after
+ inheritance pseudo assigning. */
+ lra_create_live_ranges (true, false);
+ live_p = true;
+ /* If we don't spill non-reload and non-inheritance
+ pseudos, there is no sense to run memory-memory move
+ coalescing. If inheritance pseudos were spilled, the
+ memory-memory moves involving them will be removed by
+ pass undoing inheritance. */
+ if (lra_simple_p)
+ lra_assign (fails_p);
+ else
{
- if (! live_p)
+ bool spill_p = !lra_assign (fails_p);
+
+ if (lra_undo_inheritance ())
+ live_p = false;
+ if (spill_p && ! fails_p)
{
- lra_create_live_ranges (true, true);
- live_p = true;
+ if (! live_p)
+ {
+ lra_create_live_ranges (true, true);
+ live_p = true;
+ }
+ if (lra_coalesce ())
+ live_p = false;
}
- if (lra_coalesce ())
- live_p = false;
+ if (! live_p)
+ lra_clear_live_ranges ();
+ }
+ if (fails_p)
+ {
+ /* It is a very rare case. It is the last hope to
+ split a hard regno live range for a reload
+ pseudo. */
+ if (live_p)
+ lra_clear_live_ranges ();
+ live_p = false;
+ lra_split_hard_reg_for ();
}
- if (! live_p)
- lra_clear_live_ranges ();
}
+ while (fails_p);
}
/* Don't clear optional reloads bitmap until all constraints are
satisfied as we need to differ them from regular reloads. */