Skip to content

Commit

Permalink
Changing cost propagation and ordering colorable bucket heuristics fo…
Browse files Browse the repository at this point in the history
…r PR93564.

2020-02-23  Vladimir Makarov  <vmakarov@redhat.com>

	PR rtl-optimization/93564
	* ira-color.c (struct update_cost_queue_elem): New member start.
	(queue_update_cost, get_next_update_cost): Add new arg start.
	(allocnos_conflict_p): New function.
	(update_costs_from_allocno): Add new arg conflict_cost_update_p.
	Add checking conflicts with allocnos_conflict_p.
	(update_costs_from_prefs, restore_costs_from_copies): Adjust
	update_costs_from_allocno calls.
	(update_conflict_hard_regno_costs): Add checking conflicts with
	allocnos_conflict_p.  Adjust calls of queue_update_cost and
	get_next_update_cost.
	(assign_hard_reg): Adjust calls of queue_update_cost.  Add
	debugging print.
	(bucket_allocno_compare_func): Restore previous version.
  • Loading branch information
vnmakarov committed Feb 23, 2020
1 parent 92e8508 commit 3133bed
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 33 deletions.
17 changes: 17 additions & 0 deletions gcc/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
2020-02-23 Vladimir Makarov <vmakarov@redhat.com>

PR rtl-optimization/93564
* ira-color.c (struct update_cost_queue_elem): New member start.
(queue_update_cost, get_next_update_cost): Add new arg start.
(allocnos_conflict_p): New function.
(update_costs_from_allocno): Add new arg conflict_cost_update_p.
Add checking conflicts with allocnos_conflict_p.
(update_costs_from_prefs, restore_costs_from_copies): Adjust
update_costs_from_allocno calls.
(update_conflict_hard_regno_costs): Add checking conflicts with
allocnos_conflict_p. Adjust calls of queue_update_cost and
get_next_update_cost.
(assign_hard_reg): Adjust calls of queue_update_cost. Add
debugging print.
(bucket_allocno_compare_func): Restore previous version.

2020-02-21 John David Anglin <danglin@gcc.gnu.org>

* gcc/config/pa/pa.c (pa_function_value): Fix check for word and
Expand Down
97 changes: 64 additions & 33 deletions gcc/ira-color.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,10 @@ struct update_cost_queue_elem
connecting this allocno to the one being allocated. */
int divisor;

/* Allocno from which we started chaining costs of connected
allocnos. */
ira_allocno_t start;

/* Allocno from which we are chaining costs of connected allocnos.
It is used not go back in graph of allocnos connected by
copies. */
Expand Down Expand Up @@ -1258,10 +1262,11 @@ start_update_cost (void)
update_cost_queue = NULL;
}

/* Add (ALLOCNO, FROM, DIVISOR) to the end of update_cost_queue, unless
/* Add (ALLOCNO, START, FROM, DIVISOR) to the end of update_cost_queue, unless
ALLOCNO is already in the queue, or has NO_REGS class. */
static inline void
queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
queue_update_cost (ira_allocno_t allocno, ira_allocno_t start,
ira_allocno_t from, int divisor)
{
struct update_cost_queue_elem *elem;

Expand All @@ -1270,6 +1275,7 @@ queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
&& ALLOCNO_CLASS (allocno) != NO_REGS)
{
elem->check = update_cost_check;
elem->start = start;
elem->from = from;
elem->divisor = divisor;
elem->next = NULL;
Expand All @@ -1282,10 +1288,11 @@ queue_update_cost (ira_allocno_t allocno, ira_allocno_t from, int divisor)
}

/* Try to remove the first element from update_cost_queue. Return
false if the queue was empty, otherwise make (*ALLOCNO, *FROM,
*DIVISOR) describe the removed element. */
false if the queue was empty, otherwise make (*ALLOCNO, *START,
*FROM, *DIVISOR) describe the removed element. */
static inline bool
get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)
get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *start,
ira_allocno_t *from, int *divisor)
{
struct update_cost_queue_elem *elem;

Expand All @@ -1294,6 +1301,7 @@ get_next_update_cost (ira_allocno_t *allocno, ira_allocno_t *from, int *divisor)

*allocno = update_cost_queue;
elem = &update_cost_queue_elems[ALLOCNO_NUM (*allocno)];
*start = elem->start;
*from = elem->from;
*divisor = elem->divisor;
update_cost_queue = elem->next;
Expand Down Expand Up @@ -1325,18 +1333,41 @@ update_allocno_cost (ira_allocno_t allocno, int hard_regno,
return true;
}

/* Return TRUE if allocnos A1 and A2 conflicts. Here we are
interesting only in conflicts of allocnos with intersected allocno
classes. */
static bool
allocnos_conflict_p (ira_allocno_t a1, ira_allocno_t a2)
{
ira_object_t obj, conflict_obj;
ira_object_conflict_iterator oci;
int word, nwords = ALLOCNO_NUM_OBJECTS (a1);

for (word = 0; word < nwords; word++)
{
obj = ALLOCNO_OBJECT (a1, word);
/* Take preferences of conflicting allocnos into account. */
FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci)
if (OBJECT_ALLOCNO (conflict_obj) == a2)
return true;
}
return false;
}

/* Update (decrease if DECR_P) HARD_REGNO cost of allocnos connected
by copies to ALLOCNO to increase chances to remove some copies as
the result of subsequent assignment. Record cost updates if
RECORD_P is true. */
the result of subsequent assignment. Update conflict costs only
for true CONFLICT_COST_UPDATE_P. Record cost updates if RECORD_P is
true. */
static void
update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
int divisor, bool decr_p, bool record_p)
int divisor, bool decr_p, bool record_p,
bool conflict_cost_update_p)
{
int cost, update_cost, update_conflict_cost;
machine_mode mode;
enum reg_class rclass, aclass;
ira_allocno_t another_allocno, from = NULL;
ira_allocno_t another_allocno, start = allocno, from = NULL;
ira_copy_t cp, next_cp;

rclass = REGNO_REG_CLASS (hard_regno);
Expand All @@ -1359,7 +1390,8 @@ update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
else
gcc_unreachable ();

if (another_allocno == from)
if (another_allocno == from
|| allocnos_conflict_p (another_allocno, start))
continue;

aclass = ALLOCNO_CLASS (another_allocno);
Expand All @@ -1384,7 +1416,8 @@ update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
if (decr_p)
cost = -cost;

update_conflict_cost = update_cost = cp->freq * cost / divisor;
update_cost = cp->freq * cost / divisor;
update_conflict_cost = conflict_cost_update_p ? update_cost : 0;

if (ALLOCNO_COLOR_DATA (another_allocno) != NULL
&& (ALLOCNO_COLOR_DATA (allocno)->first_thread_allocno
Expand All @@ -1399,15 +1432,16 @@ update_costs_from_allocno (ira_allocno_t allocno, int hard_regno,
if (! update_allocno_cost (another_allocno, hard_regno,
update_cost, update_conflict_cost))
continue;
queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
queue_update_cost (another_allocno, start, allocno,
divisor * COST_HOP_DIVISOR);
if (record_p && ALLOCNO_COLOR_DATA (another_allocno) != NULL)
ALLOCNO_COLOR_DATA (another_allocno)->update_cost_records
= get_update_cost_record (hard_regno, divisor,
ALLOCNO_COLOR_DATA (another_allocno)
->update_cost_records);
}
}
while (get_next_update_cost (&allocno, &from, &divisor));
while (get_next_update_cost (&allocno, &start, &from, &divisor));
}

/* Decrease preferred ALLOCNO hard register costs and costs of
Expand All @@ -1420,7 +1454,7 @@ update_costs_from_prefs (ira_allocno_t allocno)
start_update_cost ();
for (pref = ALLOCNO_PREFS (allocno); pref != NULL; pref = pref->next_pref)
update_costs_from_allocno (allocno, pref->hard_regno,
COST_HOP_DIVISOR, true, true);
COST_HOP_DIVISOR, true, true, false);
}

/* Update (decrease if DECR_P) the cost of allocnos connected to
Expand All @@ -1435,7 +1469,7 @@ update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p)
hard_regno = ALLOCNO_HARD_REGNO (allocno);
ira_assert (hard_regno >= 0 && ALLOCNO_CLASS (allocno) != NO_REGS);
start_update_cost ();
update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p);
update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p, true);
}

/* Update conflict_allocno_hard_prefs of allocnos conflicting with
Expand Down Expand Up @@ -1485,7 +1519,7 @@ restore_costs_from_copies (ira_allocno_t allocno)
start_update_cost ();
for (curr = records; curr != NULL; curr = curr->next)
update_costs_from_allocno (allocno, curr->hard_regno,
curr->divisor, true, false);
curr->divisor, true, false, true);
free_update_cost_record_list (records);
ALLOCNO_COLOR_DATA (allocno)->update_cost_records = NULL;
}
Expand All @@ -1503,10 +1537,10 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
int *conflict_costs;
bool cont_p;
enum reg_class another_aclass;
ira_allocno_t allocno, another_allocno, from;
ira_allocno_t allocno, another_allocno, start, from;
ira_copy_t cp, next_cp;

while (get_next_update_cost (&allocno, &from, &divisor))
while (get_next_update_cost (&allocno, &start, &from, &divisor))
for (cp = ALLOCNO_COPIES (allocno); cp != NULL; cp = next_cp)
{
if (cp->first == allocno)
Expand All @@ -1522,7 +1556,8 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
else
gcc_unreachable ();

if (another_allocno == from)
if (another_allocno == from
|| allocnos_conflict_p (another_allocno, start))
continue;

another_aclass = ALLOCNO_CLASS (another_allocno);
Expand Down Expand Up @@ -1568,7 +1603,7 @@ update_conflict_hard_regno_costs (int *costs, enum reg_class aclass,
* COST_HOP_DIVISOR
* COST_HOP_DIVISOR
* COST_HOP_DIVISOR))
queue_update_cost (another_allocno, allocno, divisor * COST_HOP_DIVISOR);
queue_update_cost (another_allocno, start, from, divisor * COST_HOP_DIVISOR);
}
}

Expand Down Expand Up @@ -1837,8 +1872,7 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
continue;
full_costs[j] -= conflict_costs[k];
}
queue_update_cost (conflict_a, NULL, COST_HOP_DIVISOR);

queue_update_cost (conflict_a, conflict_a, NULL, COST_HOP_DIVISOR);
}
}
}
Expand All @@ -1852,7 +1886,7 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
if (! retry_p)
{
start_update_cost ();
queue_update_cost (a, NULL, COST_HOP_DIVISOR);
queue_update_cost (a, a, NULL, COST_HOP_DIVISOR);
update_conflict_hard_regno_costs (full_costs, aclass, false);
}
min_cost = min_full_cost = INT_MAX;
Expand Down Expand Up @@ -1897,6 +1931,8 @@ assign_hard_reg (ira_allocno_t a, bool retry_p)
best_hard_regno = hard_regno;
ira_assert (hard_regno >= 0);
}
if (internal_flag_ira_verbose > 5 && ira_dump_file != NULL)
fprintf (ira_dump_file, "(%d=%d,%d) ", hard_regno, cost, full_cost);
}
if (min_full_cost > mem_cost
/* Do not spill static chain pointer pseudo when non-local goto
Expand Down Expand Up @@ -2259,16 +2295,6 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno;
int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2);

/* Push allocnos with minimal hard_reg_prefs first. */
pref1 = ALLOCNO_COLOR_DATA (a1)->hard_reg_prefs;
pref2 = ALLOCNO_COLOR_DATA (a2)->hard_reg_prefs;
if ((diff = pref1 - pref2) != 0)
return diff;
/* Push allocnos with minimal conflict_allocno_hard_prefs first. */
pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
if ((diff = pref1 - pref2) != 0)
return diff;
freq1 = ALLOCNO_COLOR_DATA (t1)->thread_freq;
freq2 = ALLOCNO_COLOR_DATA (t2)->thread_freq;
if ((diff = freq1 - freq2) != 0)
Expand All @@ -2294,6 +2320,11 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p)
a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num;
if ((diff = a2_num - a1_num) != 0)
return diff;
/* Push allocnos with minimal conflict_allocno_hard_prefs first. */
pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs;
pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs;
if ((diff = pref1 - pref2) != 0)
return diff;
return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1);
}

Expand Down

0 comments on commit 3133bed

Please sign in to comment.