[gcc r13-9728] Revert "[LRA]: Backporting solutions for PR112918 and PR113354 to solve PR99015"

Vladimir Makarov vmakarov@gcc.gnu.org
Fri May 30 12:29:24 GMT 2025


https://gcc.gnu.org/g:3e26dca1bd94ca26b21c661a471e929ab58642fd

commit r13-9728-g3e26dca1bd94ca26b21c661a471e929ab58642fd
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Fri May 30 08:28:59 2025 -0400

    Revert "[LRA]: Backporting solutions for PR112918 and PR113354 to solve PR99015"
    
    This reverts commit af73c8bf5168848275bf909ee44fbb8f4973438f.

Diff:
---
 gcc/lra-constraints.cc | 124 +++++++++++++++++++------------------------------
 1 file changed, 49 insertions(+), 75 deletions(-)

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 2d31fcc9b4f2..21f05df0d618 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -233,41 +233,6 @@ get_reg_class (int regno)
   return NO_REGS;
 }
 
-/* Return true if REG_CLASS has enough allocatable hard regs to keep value of
-   REG_MODE.  */
-static bool
-enough_allocatable_hard_regs_p (enum reg_class reg_class,
-				enum machine_mode reg_mode)
-{
-  int i, j, hard_regno, class_size, nregs;
-
-  if (hard_reg_set_subset_p (reg_class_contents[reg_class], lra_no_alloc_regs))
-    return false;
-  class_size = ira_class_hard_regs_num[reg_class];
-  for (i = 0; i < class_size; i++)
-    {
-      hard_regno = ira_class_hard_regs[reg_class][i];
-      nregs = hard_regno_nregs (hard_regno, reg_mode);
-      if (nregs == 1)
-	return true;
-      for (j = 0; j < nregs; j++)
-	if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j)
-	    || ! TEST_HARD_REG_BIT (reg_class_contents[reg_class],
-				    hard_regno + j))
-	  break;
-      if (j >= nregs)
-	return true;
-    }
-  return false;
-}
-
-/* True if C is a non-empty register class that has too few registers
-   to be safely used as a reload target class.	*/
-#define SMALL_REGISTER_CLASS_P(C)		\
-  (ira_class_hard_regs_num [(C)] == 1		\
-   || (ira_class_hard_regs_num [(C)] >= 1	\
-       && targetm.class_likely_spilled_p (C)))
-
 /* Return true if REG satisfies (or will satisfy) reg class constraint
    CL.  Use elimination first if REG is a hard register.  If REG is a
    reload pseudo created by this constraints pass, assume that it will
@@ -287,6 +252,7 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
   enum reg_class rclass, common_class;
   machine_mode reg_mode;
   rtx src;
+  int class_size, hard_regno, nregs, i, j;
   int regno = REGNO (reg);
 
   if (new_class != NULL)
@@ -325,11 +291,26 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class,
       common_class = ira_reg_class_subset[rclass][cl];
       if (new_class != NULL)
 	*new_class = common_class;
-      return (enough_allocatable_hard_regs_p (common_class, reg_mode)
-	      /* Do not permit reload insn operand matching (new_class == NULL
-		 case) if the new class is too small.  */
-	      && (new_class != NULL || common_class == rclass
-		  || !SMALL_REGISTER_CLASS_P (common_class)));
+      if (hard_reg_set_subset_p (reg_class_contents[common_class],
+				 lra_no_alloc_regs))
+	return false;
+      /* Check that there are enough allocatable regs.  */
+      class_size = ira_class_hard_regs_num[common_class];
+      for (i = 0; i < class_size; i++)
+	{
+	  hard_regno = ira_class_hard_regs[common_class][i];
+	  nregs = hard_regno_nregs (hard_regno, reg_mode);
+	  if (nregs == 1)
+	    return true;
+	  for (j = 0; j < nregs; j++)
+	    if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j)
+		|| ! TEST_HARD_REG_BIT (reg_class_contents[common_class],
+					hard_regno + j))
+	      break;
+	  if (j >= nregs)
+	    return true;
+	}
+      return false;
     }
 }
 
@@ -933,6 +914,13 @@ operands_match_p (rtx x, rtx y, int y_hard_regno)
    && GET_MODE_SIZE (MODE).is_constant ()	\
    && !targetm.cannot_force_const_mem (MODE, X))
 
+/* True if C is a non-empty register class that has too few registers
+   to be safely used as a reload target class.	*/
+#define SMALL_REGISTER_CLASS_P(C)		\
+  (ira_class_hard_regs_num [(C)] == 1		\
+   || (ira_class_hard_regs_num [(C)] >= 1	\
+       && targetm.class_likely_spilled_p (C)))
+
 /* If REG is a reload pseudo, try to make its class satisfying CL.  */
 static void
 narrow_reload_pseudo_class (rtx reg, enum reg_class cl)
@@ -2070,7 +2058,6 @@ process_alt_operands (int only_alternative)
   int curr_alt_dont_inherit_ops_num;
   /* Numbers of operands whose reload pseudos should not be inherited.	*/
   int curr_alt_dont_inherit_ops[MAX_RECOG_OPERANDS];
-  bool curr_alt_class_change_p;
   rtx op;
   /* The register when the operand is a subreg of register, otherwise the
      operand itself.  */
@@ -2146,7 +2133,6 @@ process_alt_operands (int only_alternative)
 	}
       reject += static_reject;
       early_clobbered_regs_num = 0;
-      curr_alt_class_change_p = false;
 
       for (nop = 0; nop < n_operands; nop++)
 	{
@@ -2171,7 +2157,6 @@ process_alt_operands (int only_alternative)
 	  bool scratch_p;
 	  machine_mode mode;
 	  enum constraint_num cn;
-	  bool class_change_p = false;
 
 	  opalt_num = nalt * n_operands + nop;
 	  if (curr_static_id->operand_alternative[opalt_num].anything_ok)
@@ -2539,16 +2524,9 @@ process_alt_operands (int only_alternative)
 			      (this_alternative_exclude_start_hard_regs,
 			       hard_regno[nop]))
 			win = true;
-		      else if (hard_regno[nop] < 0)
-			{
-			  if (in_class_p (op, this_alternative, NULL))
-			    win = true;
-			  else if (in_class_p (op, this_alternative, NULL, true))
-			    {
-			      class_change_p = true;
-			      win = true;
-			    }
-			}
+		      else if (hard_regno[nop] < 0
+			       && in_class_p (op, this_alternative, NULL))
+			win = true;
 		    }
 		  break;
 		}
@@ -2563,15 +2541,6 @@ process_alt_operands (int only_alternative)
 	  if (win)
 	    {
 	      this_alternative_win = true;
-	      if (class_change_p)
-		{
-		  curr_alt_class_change_p = true;
-		  if (lra_dump_file != NULL)
-		    fprintf (lra_dump_file,
-			     "            %d Narrowing class: reject+=3\n",
-			     nop);
-		  reject += 3;
-		}
 	      if (operand_reg[nop] != NULL_RTX)
 		{
 		  if (hard_regno[nop] >= 0)
@@ -2600,7 +2569,7 @@ process_alt_operands (int only_alternative)
 			  reject++;
 			}
 		      if (in_class_p (operand_reg[nop],
-				      this_costly_alternative, NULL, true))
+				      this_costly_alternative, NULL))
 			{
 			  if (lra_dump_file != NULL)
 			    fprintf
@@ -3281,7 +3250,7 @@ process_alt_operands (int only_alternative)
 	  best_reload_sum = reload_sum;
 	  goal_alt_number = nalt;
 	}
-      if (losers == 0 && !curr_alt_class_change_p)
+      if (losers == 0)
 	/* Everything is satisfied.  Do not process alternatives
 	   anymore.  */
 	break;
@@ -4386,7 +4355,7 @@ curr_insn_transform (bool check_only_p)
 
 	if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER)
 	  {
-	    bool ok_p = in_class_p (reg, goal_alt[i], &new_class, true);
+	    bool ok_p = in_class_p (reg, goal_alt[i], &new_class);
 
 	    if (new_class != NO_REGS && get_reg_class (regno) != new_class)
 	      {
@@ -4466,18 +4435,23 @@ curr_insn_transform (bool check_only_p)
 	{
 	  if (goal_alt[i] == NO_REGS
 	      && REG_P (op)
-	      && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER
-	      /* We assigned a hard register to the pseudo in the past but now
-		 decided to spill it for the insn.  If the pseudo is used only
-		 in this insn, it is better to spill it here as we free hard
-		 registers for other pseudos referenced in the insn.  The most
-		 common case of this is a scratch register which will be
-		 transformed to scratch back at the end of LRA.  */
-	      && lra_get_regno_hard_regno (regno) >= 0
-	      && bitmap_single_bit_set_p (&lra_reg_info[regno].insn_bitmap))
+	      /* When we assign NO_REGS it means that we will not
+		 assign a hard register to the scratch pseudo by
+		 assigment pass and the scratch pseudo will be
+		 spilled.  Spilled scratch pseudos are transformed
+		 back to scratches at the LRA end.  */
+	      && ira_former_scratch_operand_p (curr_insn, i)
+	      && ira_former_scratch_p (REGNO (op)))
 	    {
+	      int regno = REGNO (op);
 	      lra_change_class (regno, NO_REGS, "      Change to", true);
-	      reg_renumber[regno] = -1;
+	      if (lra_get_regno_hard_regno (regno) >= 0)
+		/* We don't have to mark all insn affected by the
+		   spilled pseudo as there is only one such insn, the
+		   current one.  */
+		reg_renumber[regno] = -1;
+	      lra_assert (bitmap_single_bit_set_p
+			  (&lra_reg_info[REGNO (op)].insn_bitmap));
 	    }
 	  /* We can do an optional reload.  If the pseudo got a hard
 	     reg, we might improve the code through inheritance.  If


More information about the Gcc-cvs mailing list