X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fregister_allocate.c;h=8af93c0406c581af4574da0e061ac233235c14c6;hb=f4df2a196eb441dac91b323184534bfe3ba44262;hp=129d58d229203a4729bad856c3e267f448a134b4;hpb=7539ac7fe2077f7634250dcb34497e1ac643b0df;p=mesa.git diff --git a/src/util/register_allocate.c b/src/util/register_allocate.c index 129d58d2292..8af93c0406c 100644 --- a/src/util/register_allocate.c +++ b/src/util/register_allocate.c @@ -183,7 +183,7 @@ struct ra_graph { * using ralloc_free(). */ struct ra_regs * -ra_alloc_reg_set(void *mem_ctx, unsigned int count) +ra_alloc_reg_set(void *mem_ctx, unsigned int count, bool need_conflict_lists) { unsigned int i; struct ra_regs *regs; @@ -197,9 +197,15 @@ ra_alloc_reg_set(void *mem_ctx, unsigned int count) BITSET_WORDS(count)); BITSET_SET(regs->regs[i].conflicts, i); - regs->regs[i].conflict_list = ralloc_array(regs->regs, unsigned int, 4); - regs->regs[i].conflict_list_size = 4; - regs->regs[i].conflict_list[0] = i; + if (need_conflict_lists) { + regs->regs[i].conflict_list = ralloc_array(regs->regs, + unsigned int, 4); + regs->regs[i].conflict_list_size = 4; + regs->regs[i].conflict_list[0] = i; + } else { + regs->regs[i].conflict_list = NULL; + regs->regs[i].conflict_list_size = 0; + } regs->regs[i].num_conflicts = 1; } @@ -227,12 +233,14 @@ ra_add_conflict_list(struct ra_regs *regs, unsigned int r1, unsigned int r2) { struct ra_reg *reg1 = ®s->regs[r1]; - if (reg1->conflict_list_size == reg1->num_conflicts) { - reg1->conflict_list_size *= 2; - reg1->conflict_list = reralloc(regs->regs, reg1->conflict_list, - unsigned int, reg1->conflict_list_size); + if (reg1->conflict_list) { + if (reg1->conflict_list_size == reg1->num_conflicts) { + reg1->conflict_list_size *= 2; + reg1->conflict_list = reralloc(regs->regs, reg1->conflict_list, + unsigned int, reg1->conflict_list_size); + } + reg1->conflict_list[reg1->num_conflicts++] = r2; } - reg1->conflict_list[reg1->num_conflicts++] = r2; BITSET_SET(reg1->conflicts, r2); } @@ -255,7 +263,7 @@ ra_add_reg_conflict(struct ra_regs *regs, unsigned int r1, unsigned int r2) */ void ra_add_transitive_reg_conflict(struct ra_regs *regs, - unsigned int base_reg, unsigned int reg) + unsigned int base_reg, unsigned int reg) { unsigned int i; @@ -266,13 +274,37 @@ ra_add_transitive_reg_conflict(struct ra_regs *regs, } } +/** + * Makes every conflict on the given register transitive. In other words, + * every register that conflicts with r will now conflict with every other + * register conflicting with r. + * + * This can simplify code for setting up multiple register classes + * which are aggregates of some base hardware registers, compared to + * explicitly using ra_add_reg_conflict. + */ +void +ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int r) +{ + struct ra_reg *reg = ®s->regs[r]; + BITSET_WORD tmp; + int c; + + BITSET_FOREACH_SET(c, tmp, reg->conflicts, regs->count) { + struct ra_reg *other = ®s->regs[c]; + unsigned i; + for (i = 0; i < BITSET_WORDS(regs->count); i++) + other->conflicts[i] |= reg->conflicts[i]; + } +} + unsigned int ra_alloc_reg_class(struct ra_regs *regs) { struct ra_class *class; regs->classes = reralloc(regs->regs, regs->classes, struct ra_class *, - regs->class_count + 1); + regs->class_count + 1); class = rzalloc(regs, struct ra_class); regs->classes[regs->class_count] = class; @@ -319,7 +351,7 @@ ra_set_finalize(struct ra_regs *regs, unsigned int **q_values) for (b = 0; b < regs->class_count; b++) { for (c = 0; c < regs->class_count; c++) { regs->classes[b]->q[c] = q_values[b][c]; - } + } } } else { /* Compute, for each class B and C, how many regs of B an @@ -348,6 +380,11 @@ ra_set_finalize(struct ra_regs *regs, unsigned int **q_values) } } } + + for (b = 0; b < regs->count; b++) { + ralloc_free(regs->regs[b].conflict_list); + regs->regs[b].conflict_list = NULL; + } } static void @@ -405,14 +442,14 @@ ra_alloc_interference_graph(struct ra_regs *regs, unsigned int count) void ra_set_node_class(struct ra_graph *g, - unsigned int n, unsigned int class) + unsigned int n, unsigned int class) { g->nodes[n].class = class; } void ra_add_node_interference(struct ra_graph *g, - unsigned int n1, unsigned int n2) + unsigned int n1, unsigned int n2) { if (!BITSET_TEST(g->nodes[n1].adjacency, n2)) { ra_add_node_adjacency(g, n1, n2); @@ -440,7 +477,7 @@ decrement_q(struct ra_graph *g, unsigned int n) if (n != n2 && !g->nodes[n2].in_stack) { assert(g->nodes[n2].q_total >= g->regs->classes[n2_class]->q[n_class]); - g->nodes[n2].q_total -= g->regs->classes[n2_class]->q[n_class]; + g->nodes[n2].q_total -= g->regs->classes[n2_class]->q[n_class]; } } }