/* We should only spill registers on the last scheduling. */
assert(!spilled_any_registers);
- do {
- allocated = assign_regs(can_spill, spill_all);
- } while (!allocated && can_spill && !failed);
+ allocated = assign_regs(can_spill, spill_all);
if (allocated)
break;
}
bool
fs_reg_alloc::assign_regs(bool allow_spilling, bool spill_all)
{
- build_interference_graph(fs->spilled_any_registers);
+ while (1) {
+ build_interference_graph(fs->spilled_any_registers);
+
+ /* Debug of register spilling: Go spill everything. */
+ if (unlikely(spill_all)) {
+ int reg = choose_spill_reg();
+ if (reg != -1) {
+ spill_reg(reg);
+ ralloc_free(g);
+ g = NULL;
+ continue;
+ }
+ }
- /* Debug of register spilling: Go spill everything. */
- if (unlikely(spill_all)) {
- int reg = choose_spill_reg();
+ if (ra_allocate(g))
+ break;
- if (reg != -1) {
- spill_reg(reg);
+ if (!allow_spilling)
return false;
- }
- }
- if (!ra_allocate(g)) {
/* Failed to allocate registers. Spill a reg, and the caller will
* loop back into here to try again.
*/
int reg = choose_spill_reg();
+ if (reg == -1)
+ return false;
- if (reg == -1) {
- fs->fail("no register to spill:\n");
- fs->dump_instructions(NULL);
- } else if (allow_spilling) {
- spill_reg(reg);
- }
-
- return false;
+ spill_reg(reg);
+ ralloc_free(g);
+ g = NULL;
}
/* Get the chosen virtual registers for each node, and map virtual
fs_visitor::assign_regs(bool allow_spilling, bool spill_all)
{
fs_reg_alloc alloc(this);
- return alloc.assign_regs(allow_spilling, spill_all);
+ bool success = alloc.assign_regs(allow_spilling, spill_all);
+ if (!success && allow_spilling) {
+ fail("no register to spill:\n");
+ dump_instructions(NULL);
+ }
+ return success;
}