This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch, lra] PR70751, correct the cost for spilling non-pseudo into memory


As discussed on the PR

  https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70751,

here is the patch.

For this particular failure on arm, *arm_movsi_insn has the following operand
constraints:
operand 0: "=rk,r,r,r,rk,m"
  operand 1: "rk, I,K,j,mi,rk"

gcc won't explicitly refuse an unmatch CT_MEMORY operand (r235184) if it
comes from substituion that alternative (alt) 4 got a chance to compete with
alt 0, and eventually be the winner as it's with rld_nregs=0 while alt 0 is
with rld_nregs=1.

I fell it's OK to give alt 4 a chance here, but we should calculate the cost
correctly.

For alt 4, it should be treated as spill into memory, but currently lra only
recognize a spill for pseudo register.   While the spilled rtx for alt 4 is a
plus after equiv substitution.

         (plus:SI (reg/f:SI 102 sfp)
            (const_int 4 [0x4]))

This patch thus let lra-constraint cost spill of Non-pseudo as well and fixed
the regression.

x86_64/aarch64/arm boostrap and regression OK.
arm bootstrapped cc1 is about 0.3% smaller in code size.

OK for trunk?

gcc/
        PR rtl-optimization/70751
        * lra-constraints.c (process_alt_operands): Recognize Non-pseudo spilled into
        memory.

diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index e4e6c8c..8f2db87 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -2474,14 +2474,29 @@ process_alt_operands (int only_alternative)
 	      /* We are trying to spill pseudo into memory.  It is
 		 usually more costly than moving to a hard register
 		 although it might takes the same number of
-		 reloads.  */
-	      if (no_regs_p && REG_P (op) && hard_regno[nop] >= 0)
+		 reloads.
+
+		 PR 70751, non-pseudo spill may happen also.  For example, if an
+		 operand comes from equiv substitution, then we won't reject it
+		 if it's an unmatch CT_MEMORY in above code (see r235184).
+		 Suppose a target allows both register and memory in the
+		 operand constraint alternatives, then it's typical that an
+		 eliminable register has a substition of "base + offset" which
+		 can either be reloaded by a simple "new_reg <= base + offset"
+		 which will match the register constraint, or a similar reg
+		 addition followed by further spill to and reload from memory
+		 which will match the memory constraint, but this memory spill
+		 will be much more costly usually.
+
+		 Code below increases the reject for both pseudo and non-pseudo
+		 spill.  */
+	      if (no_regs_p && !(REG_P (op) && hard_regno[nop] < 0))
 		{
 		  if (lra_dump_file != NULL)
 		    fprintf
 		      (lra_dump_file,
-		       "            %d Spill pseudo into memory: reject+=3\n",
-		       nop);
+		       "            %d Spill %spseudo into memory: reject+=3\n",
+		       nop, REG_P (op) ? "" : "Non-");
 		  reject += 3;
 		  if (VECTOR_MODE_P (mode))
 		    {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]