aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWei Mi <wmi@google.com>2015-12-16 00:49:32 +0000
committerWei Mi <wmi@google.com>2015-12-16 00:49:32 +0000
commit3060fba7eabcd17b5c065131e34cb6ae2f663961 (patch)
treec5c0df5f3a2c2ada2b8179cb4b1597803ddf1862
parent6740f8fb743efb1f838dc31ae7205a0c81060ef7 (diff)
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. 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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/google/gcc-4_9@231669 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ira-color.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index a34d34a60ed..b65031b4fcb 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -1588,9 +1588,11 @@ restore_costs_from_conflicts (ira_allocno_t a, int hardreg)
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_allocno_t a, int hardreg)
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 *costs, enum reg_class aclass,
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 retry_p)
}
}
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 retry_p)
->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 retry_p)
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 retry_p)
{
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