* 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;
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;
}
{
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);
}
*/
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;
}
}
+/**
+ * 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;
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
}
}
}
+
+ for (b = 0; b < regs->count; b++) {
+ ralloc_free(regs->regs[b].conflict_list);
+ regs->regs[b].conflict_list = NULL;
+ }
}
static void
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);
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];
}
}
}