diff mbox

patch to fix PR57097

Message ID 517ECF58.6010904@redhat.com
State New
Headers show

Commit Message

Vladimir Makarov April 29, 2013, 7:51 p.m. UTC
The following patch fixes:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57097

The patch was successfully bootstrapped and tested on x86/x86-64.

Committed as rev. 198432.

2013-04-29  Vladimir Makarov  <vmakarov@redhat.com>

     PR target/57097
     * lra-constraints.c (process_alt_operands): Discourage a bit more
     using memory for pseudos.  Print cost dump for alternatives.
     Modify cost values for conflicts with early clobbers.
     (curr_insn_transform): Spill pseudos reassigned to NO_REGS.

2013-04-29  Vladimir Makarov  <vmakarov@redhat.com>

     PR target/57097
     * gcc.target/i386/pr57097.c: New test.
diff mbox

Patch

Index: lra-constraints.c
===================================================================
--- lra-constraints.c	(revision 198422)
+++ lra-constraints.c	(working copy)
@@ -2013,7 +2013,7 @@  process_alt_operands (int only_alternati
 		 although it might takes the same number of
 		 reloads.  */
 	      if (no_regs_p && REG_P (op))
-		reject++;
+		reject += 2;
 
 #ifdef SECONDARY_MEMORY_NEEDED
 	      /* If reload requires moving value through secondary
@@ -2044,7 +2044,13 @@  process_alt_operands (int only_alternati
 	     or non-important thing to be worth to do it.  */
 	  overall = losers * LRA_LOSER_COST_FACTOR + reject;
 	  if ((best_losers == 0 || losers != 0) && best_overall < overall)
-	    goto fail;
+            {
+              if (lra_dump_file != NULL)
+		fprintf (lra_dump_file,
+			 "          alt=%d,overall=%d,losers=%d -- reject\n",
+			 nalt, overall, losers);
+              goto fail;
+            }
 
 	  curr_alt[nop] = this_alternative;
 	  COPY_HARD_REG_SET (curr_alt_set[nop], this_alternative_set);
@@ -2139,7 +2145,10 @@  process_alt_operands (int only_alternati
 	      curr_alt_dont_inherit_ops[curr_alt_dont_inherit_ops_num++]
 		= last_conflict_j;
 	      losers++;
-	      overall += LRA_LOSER_COST_FACTOR;
+	      /* Early clobber was already reflected in REJECT. */
+	      lra_assert (reject > 0);
+	      reject--;
+	      overall += LRA_LOSER_COST_FACTOR - 1;
 	    }
 	  else
 	    {
@@ -2163,7 +2172,10 @@  process_alt_operands (int only_alternati
 		}
 	      curr_alt_win[i] = curr_alt_match_win[i] = false;
 	      losers++;
-	      overall += LRA_LOSER_COST_FACTOR;
+	      /* Early clobber was already reflected in REJECT. */
+	      lra_assert (reject > 0);
+	      reject--;
+	      overall += LRA_LOSER_COST_FACTOR - 1;
 	    }
 	}
       small_class_operands_num = 0;
@@ -2171,6 +2183,11 @@  process_alt_operands (int only_alternati
 	small_class_operands_num
 	  += SMALL_REGISTER_CLASS_P (curr_alt[nop]) ? 1 : 0;
 
+      if (lra_dump_file != NULL)
+	fprintf (lra_dump_file, "          alt=%d,overall=%d,losers=%d,"
+		 "small_class_ops=%d,rld_nregs=%d\n",
+		 nalt, overall, losers, small_class_operands_num, reload_nregs);
+
       /* If this alternative can be made to work by reloading, and it
 	 needs less reloading than the others checked so far, record
 	 it as the chosen goal for reloading.  */
@@ -3136,7 +3153,15 @@  curr_insn_transform (void)
 		 spilled.  Spilled scratch pseudos are transformed
 		 back to scratches at the LRA end.  */
 	      && lra_former_scratch_operand_p (curr_insn, i))
-	    change_class (REGNO (op), NO_REGS, "      Change", true);
+	    {
+	      int regno = REGNO (op);
+	      change_class (regno, NO_REGS, "      Change", true);
+	      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;
+	    }
 	  continue;
 	}
 
Index: testsuite/gcc.target/i386/pr57097.c
===================================================================
--- testsuite/gcc.target/i386/pr57097.c	(revision 0)
+++ testsuite/gcc.target/i386/pr57097.c	(working copy)
@@ -0,0 +1,29 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC" } */
+extern double ad[], bd[], cd[], dd[];
+extern long long all[], bll[], cll[], dll[];
+
+int
+main (int i, char **a)
+{
+  bd[i] = i + 64;
+  if (i % 3 == 0)
+    {
+      cd[i] = i;
+    }
+  dd[i] = i / 2;
+  ad[i] = i * 2;
+  if (i % 3 == 1)
+    {
+      dll[i] = 127;
+    }
+  dll[i] = i;
+  cll[i] = i * 2;
+  switch (i % 3)
+    {
+    case 0:
+      bll[i] = i + 64;
+    }
+  all[i] = i / 2;
+  return 0;
+}