diff mbox

[google,gcc-4_9] update hardreg costs only when conflict_costs[] < 0

Message ID CA+4CFy72OGeDQnw1DCALArMJ5XEmEqxtyqK==sBEEh9dt91cfA@mail.gmail.com
State New
Headers show

Commit Message

Wei Mi Dec. 10, 2015, 6:17 p.m. UTC
Hi,

The patch is for google branch only.

In r216697, when a hardreg is assigned to an allocno, a positive cost
will be added to those conflict allocnos to reflect the disfavor of
the hardreg.

However, the fact that conflict allocno disfavors a hard_regno doesn't
necessarily mean current allocno should prefer the hard_regno, so it
is incorrect to update the costs of an allocno directly according to
its conflict allocnos. The patch changes the code to update costs[i]
of an allocno only when conflict_costs[i] < 0, .i.e, when conflict
allocno prefer hardreg i.

Another issue is the costs of an allocno is updated only when the
conflict allocno is not marked as may_be_spilled_p. However, even if a
conflict allocno is marked as may_be_spilled_p right now, it still has
high probablity to get colored later. It is not right to ignore the
preferences from those conflict allocnos marked as may_be_spilled_p.
The patch changes it.

Test:
Gcc unit tests ok.
Minor improvement for google internal benchmarks.

Thanks,
Wei.
gcc/ChangeLog:

2015-12-10  Wei Mi  <wmi@google.com>

	* ira-color.c (restore_costs_from_conflicts): Don't record the
	cost change.
	(update_conflict_hard_regno_costs): Update costs[i] only when
	conflict_costs[i] < 0.
	(assign_hard_reg): Ditto.
diff mbox

Patch

Index: gcc/ira-color.c
===================================================================
--- gcc/ira-color.c	(revision 231143)
+++ gcc/ira-color.c	(working copy)
@@ -1588,9 +1588,11 @@  restore_costs_from_conflicts (ira_allocn
 		prev = curr;
 	    }
 	  /* Propagate the disfavor of hardreg from conflict_a to the
-	     allocnos connecting with conflict_a via copies.  */
+	     allocnos connecting with conflict_a via copies.
+	     Note: once the hardreg is assigned to a, it will not be
+	     changed, so we don't need to record this change. */
 	  update_costs_from_allocno (conflict_a, hardreg,
-				     1, false, true, true);
+				     1, false, false, true);
 	}
     }
 }
@@ -1601,7 +1603,7 @@  restore_costs_from_conflicts (ira_allocn
    update increases chances to remove some copies.  */
 static void
 update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
-				  bool decr_p)
+				  bool decr_p, bool conflict)
 {
   int i, cost, class_size, freq, mult, div, divisor;
   int index, hard_regno;
@@ -1682,7 +1684,16 @@  update_conflict_hard_regno_costs (int *c
 		cont_p = true;
 		if (decr_p)
 		  cost = -cost;
-		costs[index] += cost;
+		/* conflict being true indicates this is updating costs[]
+		   according to preferences of allocnos connected by copies
+		   to the conflict allocnos.
+		   The fact conflict allocno disfavors hard_regno doesn't
+		   necessarily mean current allocno should prefer hard_regno
+		   (actually only a little), so we update costs[] only
+		   when conflict allocno prefers hard_regno, .i.e, when
+		   conflict_costs[i] < 0. */
+		if (conflict && conflict_costs [i] < 0)
+		  costs[index] += cost;
 	      }
 	  }
 	/* Probably 5 hops will be enough.  */
@@ -1934,7 +1945,6 @@  assign_hard_reg (ira_allocno_t a, bool r
 		}
 	    }
 	  else if (! retry_p
-		   && ! ALLOCNO_COLOR_DATA (conflict_a)->may_be_spilled_p
 		   /* Don't process the conflict allocno twice.  */
 		   && (ALLOCNO_COLOR_DATA (conflict_a)->last_process
 		       != curr_allocno_process))
@@ -1967,7 +1977,13 @@  assign_hard_reg (ira_allocno_t a, bool r
 					      ->new_conflict_hard_regs,
 					      hard_regno))
 		      continue;
-		    full_costs[j] -= conflict_costs[k];
+		    /* The fact conflict_a disfavors hard_regno doesn't
+		       necessarily mean current allocno should prefer
+		       hard_regno so much (only a little), so we only
+		       update full_costs[] when conflict_a prefers
+		       hard_regno, .i.e, when conflict_costs[k] < 0. */
+		    if (conflict_costs[k] < 0)
+		      full_costs[j] -= conflict_costs[k];
 		  }
 	      queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);
 
@@ -1977,7 +1993,7 @@  assign_hard_reg (ira_allocno_t a, bool r
   if (! retry_p)
     /* Take into account preferences of allocnos connected by copies to
        the conflict allocnos.  */
-    update_conflict_hard_regno_costs (full_costs, aclass, true);
+    update_conflict_hard_regno_costs (full_costs, aclass, true, true);
 
   /* Take preferences of allocnos connected by copies into
      account.  */
@@ -1985,7 +2001,7 @@  assign_hard_reg (ira_allocno_t a, bool r
     {
       start_update_cost ();
       queue_update_cost (a, NULL,  COST_HOP_DIVISOR);
-      update_conflict_hard_regno_costs (full_costs, aclass, false);
+      update_conflict_hard_regno_costs (full_costs, aclass, false, false);
     }
   min_cost = min_full_cost = INT_MAX;
   /* We don't care about giving callee saved registers to allocnos no