Index: lra-assigns.c =================================================================== --- lra-assigns.c (revision 221949) +++ lra-assigns.c (working copy) @@ -910,6 +910,7 @@ spill_for (int regno, bitmap spilled_pse 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_pse 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_pse && ! 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_pse { 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_pse } 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; Index: lra.c =================================================================== --- lra.c (revision 221949) +++ lra.c (working copy) @@ -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 (); Index: lra-int.h =================================================================== --- lra-int.h (revision 221949) +++ lra-int.h (working copy) @@ -333,6 +333,7 @@ extern void lra_register_new_scratch_op 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;