Bootstrapped regtested and on x86_64-pc-linux-gnu.
2021-02-22  Joern Rennecke  <joern.renne...@embecosm.com>

        lra fix to reduce fatal spill failures.
    
        * lra-constraints.c (split_reg): No longer static.
        * lra-int.h (split_reg): Declare.
        * lra-assigns.c (lra_split_hard_reg_for): Add strategy to split a
        longer range pseudo to accomodate a short range pseudo in a
        likely-spilled reg.

diff --git a/gcc/lra-assigns.c b/gcc/lra-assigns.c
index c6a941fe663..4f765bbd8de 100644
--- a/gcc/lra-assigns.c
+++ b/gcc/lra-assigns.c
@@ -1799,6 +1799,35 @@ lra_split_hard_reg_for (void)
            bitmap_clear (&failed_reload_pseudos);
            return true;
          }
+       /* For a likely spilled class, a pseudo hogging a hard register
+          and a hard reg use are pretty much interchangable.
+          If the use is for adjacent insns, we can win by splitting
+          a conflicting pseudo that has a larger range.  */
+       if (next_nonnote_insn (first) == last
+           && targetm.class_likely_spilled_p (rclass))
+         {
+           int j;
+           rtx_insn *j_first, *j_last;
+           for (j = lra_constraint_new_regno_start; j < max_regno; j++)
+             if (reg_renumber[j] >= 0
+                 && REGNO_REG_CLASS (reg_renumber[j]) == rclass
+                 && (hard_regno_nregs (reg_renumber[j],
+                                       GET_MODE (regno_reg_rtx[j]))
+                     >= hard_regno_nregs (reg_renumber[j],
+                                          GET_MODE (regno_reg_rtx[i])))
+                 && find_reload_regno_insns (j, j_first, j_last)
+                 && j_first != j_last && j_last != last)
+               {
+                 for (insn = NEXT_INSN (j_first); insn != j_last;
+                      insn = NEXT_INSN (insn))
+                   if (insn == first
+                       && split_reg (TRUE, j, first, NULL, last))
+                     {
+                       bitmap_clear (&failed_reload_pseudos);
+                       return true;
+                     }
+               }
+         }
        bitmap_set_bit (&failed_reload_pseudos, i);
       }
   bitmap_clear (&non_reload_pseudos);
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index a766f1fd7e8..a13d02a9028 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -5774,7 +5774,7 @@ lra_copy_reg_equiv (unsigned int new_regno, unsigned int 
original_regno)
    register and s is a new split pseudo.  The save is put before INSN
    if BEFORE_P is true.         Return true if we succeed in such
    transformation.  */
-static bool
+bool
 split_reg (bool before_p, int original_regno, rtx_insn *insn,
           rtx next_usage_insns, rtx_insn *to)
 {
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index 4dadccc79f4..eece250eafb 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -346,6 +346,9 @@ extern void lra_constraints_finish (void);
 extern bool spill_hard_reg_in_range (int, enum reg_class, rtx_insn *, rtx_insn 
*);
 extern void lra_inheritance (void);
 extern bool lra_undo_inheritance (void);
+extern bool split_reg (bool before_p, int original_regno, rtx_insn *insn,
+                      rtx next_usage_insns, rtx_insn *to);
+
 
 /* lra-lives.c: */
 

Reply via email to