diff options
author | Vladimir Makarov <vmakarov@redhat.com> | 2018-03-09 16:00:36 +0000 |
---|---|---|
committer | Vladimir Makarov <vmakarov@gcc.gnu.org> | 2018-03-09 16:00:36 +0000 |
commit | e0cd6bc00966de0a3a77b642f9507d9c83b398f1 (patch) | |
tree | de7bad1e1e9a7a1d01900aa85dc8de1b2e98279f /gcc/lra.c | |
parent | a4017ff7722614f749a0d5eab315e929b2035e8a (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.c | 67 |
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. */ |