diff mbox series

RFA: reduce lra spill failures by splitting likely-spilled-reg hogging pseudo

Message ID CAMqJFCp-y2eTCCmk_wdxfnQq3bSixEyQbijs4uY0XiL57aNNdA@mail.gmail.com
State New
Headers show
Series RFA: reduce lra spill failures by splitting likely-spilled-reg hogging pseudo | expand

Commit Message

Joern Rennecke May 16, 2021, 5:02 p.m. UTC
Bootstrapped regtested and on x86_64-pc-linux-gnu.
2021-02-22  Joern Rennecke  <joern.rennecke@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 mbox series

Patch

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: */