diff options
author | Jason Ekstrand <[email protected]> | 2019-05-09 18:53:04 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2019-05-14 12:30:22 -0500 |
commit | 698bb9b98462e0a3a374ede4bf852a884f907c7f (patch) | |
tree | 90423e11158cea1f259959579a7bb7d67715b944 /src/util | |
parent | 6c0f75c953e6640838d818b8f3603a56b0483f5d (diff) |
util/ra: Add helpers for adding nodes to an interference graph
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/register_allocate.c | 90 | ||||
-rw-r--r-- | src/util/register_allocate.h | 2 |
2 files changed, 72 insertions, 20 deletions
diff --git a/src/util/register_allocate.c b/src/util/register_allocate.c index 4ab0a50566f..8c10741870b 100644 --- a/src/util/register_allocate.c +++ b/src/util/register_allocate.c @@ -157,6 +157,8 @@ struct ra_graph { struct ra_node *nodes; unsigned int count; /**< count of nodes. */ + unsigned int alloc; /**< count of nodes allocated. */ + unsigned int *stack; unsigned int stack_count; @@ -423,30 +425,33 @@ ra_add_node_adjacency(struct ra_graph *g, unsigned int n1, unsigned int n2) g->nodes[n1].adjacency_count++; } -struct ra_graph * -ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) +static void +ra_realloc_interference_graph(struct ra_graph *g, unsigned int alloc) { - struct ra_graph *g; - unsigned int i; - - g = rzalloc(NULL, struct ra_graph); - g->regs = regs; - g->nodes = rzalloc_array(g, struct ra_node, count); - g->count = count; + if (alloc <= g->alloc) + return; - g->stack = rzalloc_array(g, unsigned int, count); - - int bitset_count = BITSET_WORDS(count); - g->in_stack = rzalloc_array(g, BITSET_WORD, bitset_count); - - g->reg_assigned = rzalloc_array(g, BITSET_WORD, bitset_count); - g->pq_test = rzalloc_array(g, BITSET_WORD, bitset_count); - g->min_q_total = rzalloc_array(g, unsigned int, bitset_count); - g->min_q_node = rzalloc_array(g, unsigned int, bitset_count); + /* If we always have a whole number of BITSET_WORDs, it makes it much + * easier to memset the top of the growing bitsets. + */ + assert(g->alloc % BITSET_WORDBITS == 0); + alloc = ALIGN(alloc, BITSET_WORDBITS); + + g->nodes = reralloc(g, g->nodes, struct ra_node, alloc); + + unsigned g_bitset_count = BITSET_WORDS(g->alloc); + unsigned bitset_count = BITSET_WORDS(alloc); + /* For nodes already in the graph, we just have to grow the adjacency set */ + for (unsigned i = 0; i < g->alloc; i++) { + assert(g->nodes[i].adjacency != NULL); + g->nodes[i].adjacency = rerzalloc(g, g->nodes[i].adjacency, BITSET_WORD, + g_bitset_count, bitset_count); + } - for (i = 0; i < count; i++) { + /* For new nodes, we have to fully initialize them */ + for (unsigned i = g->alloc; i < alloc; i++) { + memset(&g->nodes[i], 0, sizeof(g->nodes[i])); g->nodes[i].adjacency = rzalloc_array(g, BITSET_WORD, bitset_count); - g->nodes[i].adjacency_list_size = 4; g->nodes[i].adjacency_list = ralloc_array(g, unsigned int, g->nodes[i].adjacency_list_size); @@ -456,9 +461,43 @@ ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) g->nodes[i].reg = NO_REG; } + g->stack = reralloc(g, g->stack, unsigned int, alloc); + g->in_stack = rerzalloc(g, g->in_stack, BITSET_WORD, + g_bitset_count, bitset_count); + + g->reg_assigned = rerzalloc(g, g->reg_assigned, BITSET_WORD, + g_bitset_count, bitset_count); + g->pq_test = rerzalloc(g, g->pq_test, BITSET_WORD, + g_bitset_count, bitset_count); + g->min_q_total = rerzalloc(g, g->min_q_total, unsigned int, + g_bitset_count, bitset_count); + g->min_q_node = rerzalloc(g, g->min_q_node, unsigned int, + g_bitset_count, bitset_count); + + g->alloc = alloc; +} + +struct ra_graph * +ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) +{ + struct ra_graph *g; + + g = rzalloc(NULL, struct ra_graph); + g->regs = regs; + g->count = count; + ra_realloc_interference_graph(g, count); + return g; } +void +ra_resize_interference_graph(struct ra_graph *g, unsigned int count) +{ + g->count = count; + if (count > g->alloc) + ra_realloc_interference_graph(g, g->alloc * 2); +} + void ra_set_select_reg_callback(struct ra_graph *g, unsigned int (*callback)(struct ra_graph *g, BITSET_WORD *regs, @@ -476,6 +515,17 @@ ra_set_node_class(struct ra_graph *g, g->nodes[n].class = class; } +unsigned int +ra_add_node(struct ra_graph *g, unsigned int class) +{ + unsigned int n = g->count; + ra_resize_interference_graph(g, g->count + 1); + + ra_set_node_class(g, n, class); + + return n; +} + void ra_add_node_interference(struct ra_graph *g, unsigned int n1, unsigned int n2) diff --git a/src/util/register_allocate.h b/src/util/register_allocate.h index d3448a11c77..834503ea55b 100644 --- a/src/util/register_allocate.h +++ b/src/util/register_allocate.h @@ -74,7 +74,9 @@ void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts); */ struct ra_graph *ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count); +void ra_resize_interference_graph(struct ra_graph *g, unsigned int count); void ra_set_node_class(struct ra_graph *g, unsigned int n, unsigned int c); +unsigned int ra_add_node(struct ra_graph *g, unsigned int c); void ra_set_select_reg_callback(struct ra_graph *g, unsigned int (*callback)(struct ra_graph *g, BITSET_WORD *regs, |