mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-02 22:30:11 +01:00
util/ra: Don't store a pointer to graph per ra_node
Each node stores a list of adjacent nodes. This was handled by util_dynarray, however each of those hold an extra pointer for the ra_graph (which serves as mem_ctx for that). Since the usage here is very simple, we just handle the array growth manually. For now keep using the same initial size as was being used by dynarray. Reviewed-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25744>
This commit is contained in:
parent
3753c9ed1b
commit
9cccb89dbc
2 changed files with 39 additions and 18 deletions
|
|
@ -517,7 +517,12 @@ ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
|
|||
int n2_class = g->nodes[n2].class;
|
||||
g->nodes[n1].q_total += g->regs->classes[n1_class]->q[n2_class];
|
||||
|
||||
util_dynarray_append(&g->nodes[n1].adjacency_list, unsigned int, n2);
|
||||
struct ra_list *adj = &g->nodes[n1].adjacency;
|
||||
if (adj->size == adj->cap) {
|
||||
adj->cap = MAX2(16, adj->cap * 2);
|
||||
adj->elems = reralloc(g, adj->elems, unsigned int, adj->cap);
|
||||
}
|
||||
adj->elems[adj->size++] = n2;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -530,8 +535,14 @@ ra_node_remove_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2)
|
|||
int n2_class = g->nodes[n2].class;
|
||||
g->nodes[n1].q_total -= g->regs->classes[n1_class]->q[n2_class];
|
||||
|
||||
util_dynarray_delete_unordered(&g->nodes[n1].adjacency_list, unsigned int,
|
||||
n2);
|
||||
struct ra_list *adj = &g->nodes[n1].adjacency;
|
||||
for (unsigned i = 0; i < adj->size; i++) {
|
||||
if (adj->elems[i] == n2) {
|
||||
adj->elems[i] = adj->elems[adj->size - 1];
|
||||
adj->size--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -554,7 +565,6 @@ ra_realloc_interference_graph(struct ra_graph *g, unsigned int alloc)
|
|||
/* Initialize new nodes. */
|
||||
for (unsigned i = g->alloc; i < alloc; i++) {
|
||||
struct ra_node* node = g->nodes + i;
|
||||
util_dynarray_init(&node->adjacency_list, g);
|
||||
node->q_total = 0;
|
||||
node->reg = NO_REG;
|
||||
g->nodes_extra[i].forced_reg = NO_REG;
|
||||
|
|
@ -647,11 +657,12 @@ ra_add_node_interference(struct ra_graph *g,
|
|||
void
|
||||
ra_reset_node_interference(struct ra_graph *g, unsigned int n)
|
||||
{
|
||||
util_dynarray_foreach(&g->nodes[n].adjacency_list, unsigned int, n2p) {
|
||||
ra_node_remove_adjacency(g, *n2p, n);
|
||||
}
|
||||
struct ra_list *adj = &g->nodes[n].adjacency;
|
||||
|
||||
util_dynarray_clear(&g->nodes[n].adjacency_list);
|
||||
for (unsigned i = 0; i < adj->size; i++)
|
||||
ra_node_remove_adjacency(g, adj->elems[i], n);
|
||||
|
||||
adj->size = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -684,8 +695,9 @@ add_node_to_stack(struct ra_graph *g, unsigned int n)
|
|||
|
||||
assert(!BITSET_TEST(g->tmp.in_stack, n));
|
||||
|
||||
util_dynarray_foreach(&g->nodes[n].adjacency_list, unsigned int, n2p) {
|
||||
unsigned int n2 = *n2p;
|
||||
struct ra_list *adj = &g->nodes[n].adjacency;
|
||||
for (unsigned i = 0; i < adj->size; i++) {
|
||||
unsigned int n2 = adj->elems[i];
|
||||
unsigned int n2_class = g->nodes[n2].class;
|
||||
|
||||
if (!BITSET_TEST(g->tmp.in_stack, n2) &&
|
||||
|
|
@ -833,8 +845,9 @@ ra_class_allocations_conflict(struct ra_class *c1, unsigned int r1,
|
|||
static struct ra_node *
|
||||
ra_find_conflicting_neighbor(struct ra_graph *g, unsigned int n, unsigned int r)
|
||||
{
|
||||
util_dynarray_foreach(&g->nodes[n].adjacency_list, unsigned int, n2p) {
|
||||
unsigned int n2 = *n2p;
|
||||
struct ra_list *adj = &g->nodes[n].adjacency;
|
||||
for (unsigned i = 0; i < adj->size; i++) {
|
||||
unsigned int n2 = adj->elems[i];
|
||||
|
||||
/* If our adjacent node is in the stack, it's not allocated yet. */
|
||||
if (!BITSET_TEST(g->tmp.in_stack, n2) &&
|
||||
|
|
@ -864,11 +877,12 @@ ra_compute_available_regs(struct ra_graph *g, unsigned int n, BITSET_WORD *regs)
|
|||
/* Remove any regs that conflict with nodes that we're adjacent to and have
|
||||
* already colored.
|
||||
*/
|
||||
util_dynarray_foreach(&g->nodes[n].adjacency_list, unsigned int, n2p) {
|
||||
struct ra_node *n2 = &g->nodes[*n2p];
|
||||
struct ra_list *adj = &g->nodes[n].adjacency;
|
||||
for (unsigned i = 0; i < adj->size; i++) {
|
||||
struct ra_node *n2 = &g->nodes[adj->elems[i]];
|
||||
struct ra_class *n2c = g->regs->classes[n2->class];
|
||||
|
||||
if (!BITSET_TEST(g->tmp.in_stack, *n2p)) {
|
||||
if (!BITSET_TEST(g->tmp.in_stack, adj->elems[i])) {
|
||||
if (c->contig_len) {
|
||||
int start = MAX2(0, (int)n2->reg - c->contig_len + 1);
|
||||
int end = MIN2(g->regs->count, n2->reg + n2c->contig_len);
|
||||
|
|
@ -1022,8 +1036,9 @@ ra_get_spill_benefit(struct ra_graph *g, unsigned int n)
|
|||
* "count number of edges" approach of traditional graph coloring,
|
||||
* but takes classes into account.
|
||||
*/
|
||||
util_dynarray_foreach(&g->nodes[n].adjacency_list, unsigned int, n2p) {
|
||||
unsigned int n2 = *n2p;
|
||||
struct ra_list *adj = &g->nodes[n].adjacency;
|
||||
for (unsigned i = 0; i < adj->size; i++) {
|
||||
unsigned int n2 = adj->elems[i];
|
||||
unsigned int n2_class = g->nodes[n2].class;
|
||||
benefit += ((float)g->regs->classes[n_class]->q[n2_class] /
|
||||
g->regs->classes[n_class]->p);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ extern "C" {
|
|||
#define class klass
|
||||
#endif
|
||||
|
||||
struct ra_list {
|
||||
unsigned int *elems;
|
||||
unsigned int size;
|
||||
unsigned int cap;
|
||||
};
|
||||
|
||||
struct ra_reg {
|
||||
BITSET_WORD *conflicts;
|
||||
struct util_dynarray conflict_list;
|
||||
|
|
@ -92,7 +98,7 @@ struct ra_node {
|
|||
* List of which nodes this node interferes with. This should be
|
||||
* symmetric with the other node.
|
||||
*/
|
||||
struct util_dynarray adjacency_list;
|
||||
struct ra_list adjacency;
|
||||
/** @} */
|
||||
|
||||
unsigned int class;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue