Patchwork patch to fix PR55342

login
register
mail settings
Submitter Vladimir Makarov
Date Nov. 17, 2012, 6 p.m.
Message ID <50A7D0D9.7000003@redhat.com>
Download mbox | patch
Permalink /patch/199867/
State New
Headers show

Comments

Vladimir Makarov - Nov. 17, 2012, 6 p.m.
The following patch solves

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

   LRA after spilling a pseudo tries to assign freed hard regno to other 
reload pseudos and chooses the best.  The more reload pseudos got the 
freed hard regno, the less cost of spilling.  But the reload pseudos 
could get another hard regno without spilling.  So LRA code before the 
patch incorrectly evaluated the cost of spilling.  The patch tries to 
allocate a hard reg to the other reload pseudos before and after 
spilling in order to correctly evaluate spilling cost.

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

   Committed as rev. 193588.

2012-11-17  Vladimir Makarov  <vmakarov@redhat.com>

         PR rtl-optimization/55342
         * lra-assigns.c (spill_for): Try to allocate other reload pseudos
         before and after spilling.

Patch

Index: lra-assigns.c
===================================================================
--- lra-assigns.c	(revision 193557)
+++ lra-assigns.c	(working copy)
@@ -795,9 +795,8 @@  spill_for (int regno, bitmap spilled_pse
 {
   int i, j, n, p, hard_regno, best_hard_regno, cost, best_cost, rclass_size;
   int reload_hard_regno, reload_cost;
-  enum machine_mode mode, mode2;
+  enum machine_mode mode;
   enum reg_class rclass;
-  HARD_REG_SET spilled_hard_regs;
   unsigned int spill_regno, reload_regno, uid;
   int insn_pseudos_num, best_insn_pseudos_num;
   lra_live_range_t r;
@@ -838,7 +837,6 @@  spill_for (int regno, bitmap spilled_pse
 			   &try_hard_reg_pseudos[hard_regno + j]);
 	}
       /* Spill pseudos.	 */
-      CLEAR_HARD_REG_SET (spilled_hard_regs);
       EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
 	if ((int) spill_regno >= lra_constraint_new_regno_start
 	    && ! bitmap_bit_p (&lra_inheritance_pseudos, spill_regno)
@@ -853,13 +851,6 @@  spill_for (int regno, bitmap spilled_pse
 	{
 	  if (bitmap_bit_p (&insn_conflict_pseudos, spill_regno))
 	    insn_pseudos_num++;
-	  mode2 = PSEUDO_REGNO_MODE (spill_regno);
-	  update_lives (spill_regno, true);
-	  if (lra_dump_file != NULL)
-	    fprintf (lra_dump_file, " spill %d(freq=%d)",
-		     spill_regno, lra_reg_info[spill_regno].freq);
-	  add_to_hard_reg_set (&spilled_hard_regs,
-			       mode2, reg_renumber[spill_regno]);
 	  for (r = lra_reg_info[spill_regno].live_ranges;
 	       r != NULL;
 	       r = r->next)
@@ -877,19 +868,26 @@  spill_for (int regno, bitmap spilled_pse
 		}
 	    }
 	}
+      n = 0;
+      EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
+				   reload_regno)
+	if ((int) reload_regno != regno
+	    && (ira_reg_classes_intersect_p
+		[rclass][regno_allocno_class_array[reload_regno]])
+	    && live_pseudos_reg_renumber[reload_regno] < 0
+	    && find_hard_regno_for (reload_regno, &cost, -1) < 0)
+	  sorted_reload_pseudos[n++] = reload_regno;
+      EXECUTE_IF_SET_IN_BITMAP (&spill_pseudos_bitmap, 0, spill_regno, bi)
+	{
+	  update_lives (spill_regno, true);
+	  if (lra_dump_file != NULL)
+	    fprintf (lra_dump_file, " spill %d(freq=%d)",
+		     spill_regno, lra_reg_info[spill_regno].freq);
+	}
       hard_regno = find_hard_regno_for (regno, &cost, -1);
       if (hard_regno >= 0)
 	{
 	  assign_temporarily (regno, hard_regno);
-	  n = 0;
-	  EXECUTE_IF_SET_IN_SPARSESET (live_range_reload_inheritance_pseudos,
-				       reload_regno)
-	    if (live_pseudos_reg_renumber[reload_regno] < 0
-		&& (hard_reg_set_intersect_p
-		    (reg_class_contents
-		     [regno_allocno_class_array[reload_regno]],
-		     spilled_hard_regs)))
-	      sorted_reload_pseudos[n++] = reload_regno;
 	  qsort (sorted_reload_pseudos, n, sizeof (int),
 		 reload_pseudo_compare_func);
 	  for (j = 0; j < n; j++)
@@ -898,10 +896,7 @@  spill_for (int regno, bitmap spilled_pse
 	      lra_assert (live_pseudos_reg_renumber[reload_regno] < 0);
 	      if ((reload_hard_regno
 		   = find_hard_regno_for (reload_regno,
-					  &reload_cost, -1)) >= 0
-		  && (overlaps_hard_reg_set_p
-		      (spilled_hard_regs,
-		       PSEUDO_REGNO_MODE (reload_regno), reload_hard_regno)))
+					  &reload_cost, -1)) >= 0)
 		{
 		  if (lra_dump_file != NULL)
 		    fprintf (lra_dump_file, " assign %d(cost=%d)",