ra: Use struct ra_class in the public API.
All these unsigned ints are awful to keep track of. Use pointers so we get some type checking. Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9437>
This commit is contained in:
parent
7e0127fb3e
commit
95d41a3525
|
@ -549,10 +549,10 @@ enum v3d_compilation_result {
|
|||
struct v3d_compiler {
|
||||
const struct v3d_device_info *devinfo;
|
||||
struct ra_regs *regs;
|
||||
unsigned int reg_class_any[3];
|
||||
unsigned int reg_class_r5[3];
|
||||
unsigned int reg_class_phys[3];
|
||||
unsigned int reg_class_phys_or_acc[3];
|
||||
struct ra_class *reg_class_any[3];
|
||||
struct ra_class *reg_class_r5[3];
|
||||
struct ra_class *reg_class_phys[3];
|
||||
struct ra_class *reg_class_phys_or_acc[3];
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -517,28 +517,21 @@ vir_init_reg_sets(struct v3d_compiler *compiler)
|
|||
|
||||
for (int i = PHYS_INDEX;
|
||||
i < PHYS_INDEX + (PHYS_COUNT >> threads); i++) {
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_phys_or_acc[threads], i);
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_phys[threads], i);
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_any[threads], i);
|
||||
ra_class_add_reg(compiler->reg_class_phys_or_acc[threads], i);
|
||||
ra_class_add_reg(compiler->reg_class_phys[threads], i);
|
||||
ra_class_add_reg(compiler->reg_class_any[threads], i);
|
||||
}
|
||||
|
||||
for (int i = ACC_INDEX + 0; i < ACC_INDEX + ACC_COUNT - 1; i++) {
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_phys_or_acc[threads], i);
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_any[threads], i);
|
||||
ra_class_add_reg(compiler->reg_class_phys_or_acc[threads], i);
|
||||
ra_class_add_reg(compiler->reg_class_any[threads], i);
|
||||
}
|
||||
/* r5 can only store a single 32-bit value, so not much can
|
||||
* use it.
|
||||
*/
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_r5[threads],
|
||||
ra_class_add_reg(compiler->reg_class_r5[threads],
|
||||
ACC_INDEX + 5);
|
||||
ra_class_add_reg(compiler->regs,
|
||||
compiler->reg_class_any[threads],
|
||||
ra_class_add_reg(compiler->reg_class_any[threads],
|
||||
ACC_INDEX + 5);
|
||||
}
|
||||
|
||||
|
|
|
@ -398,7 +398,8 @@ static unsigned int
|
|||
ra_select_reg_merged(unsigned int n, BITSET_WORD *regs, void *data)
|
||||
{
|
||||
struct ir3_ra_ctx *ctx = data;
|
||||
unsigned int class = ra_get_node_class(ctx->g, n);
|
||||
struct ra_class *classp = ra_get_node_class(ctx->g, n);
|
||||
unsigned int class = ra_class_index(classp);
|
||||
bool half, shared;
|
||||
int sz = ra_class_to_size(class, &half, &shared);
|
||||
|
||||
|
@ -501,10 +502,10 @@ ra_select_reg_merged(unsigned int n, BITSET_WORD *regs, void *data)
|
|||
return ra_select_reg_merged(n, regs, data);
|
||||
}
|
||||
|
||||
if (class == ctx->set->half_classes[0]) {
|
||||
if (classp == ctx->set->half_classes[0]) {
|
||||
int n = r - base;
|
||||
ctx->start_search_reg = (n + 1) % ctx->max_target;
|
||||
} else if (class == ctx->set->classes[0]) {
|
||||
} else if (classp == ctx->set->classes[0]) {
|
||||
int n = (r - base) * 2;
|
||||
ctx->start_search_reg = (n + 1) % ctx->max_target;
|
||||
}
|
||||
|
|
|
@ -87,16 +87,16 @@ static inline unsigned SHARED_CLASS_REGS(unsigned i)
|
|||
/* register-set, created one time, used for all shaders: */
|
||||
struct ir3_ra_reg_set {
|
||||
struct ra_regs *regs;
|
||||
unsigned int classes[class_count];
|
||||
unsigned int half_classes[half_class_count];
|
||||
unsigned int shared_classes[shared_class_count];
|
||||
struct ra_class *classes[class_count];
|
||||
struct ra_class *half_classes[half_class_count];
|
||||
struct ra_class *shared_classes[shared_class_count];
|
||||
|
||||
/* pre-fetched tex dst is limited, on current gens to regs
|
||||
* 0x3f and below. An additional register class, with one
|
||||
* vreg, that is setup to conflict with any regs above that
|
||||
* limit.
|
||||
*/
|
||||
unsigned prefetch_exclude_class;
|
||||
struct ra_class *prefetch_exclude_class;
|
||||
unsigned prefetch_exclude_reg;
|
||||
|
||||
/* The virtual register space flattens out all the classes,
|
||||
|
|
|
@ -134,7 +134,7 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
|
|||
set->gpr_to_ra_reg[i] = ralloc_array(set, uint16_t, CLASS_REGS(i));
|
||||
|
||||
for (unsigned j = 0; j < CLASS_REGS(i); j++) {
|
||||
ra_class_add_reg(set->regs, set->classes[i], reg);
|
||||
ra_class_add_reg(set->classes[i], reg);
|
||||
|
||||
set->ra_reg_to_gpr[reg] = j;
|
||||
set->gpr_to_ra_reg[i][j] = reg;
|
||||
|
@ -153,7 +153,7 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
|
|||
ralloc_array(set, uint16_t, HALF_CLASS_REGS(i));
|
||||
|
||||
for (unsigned j = 0; j < HALF_CLASS_REGS(i); j++) {
|
||||
ra_class_add_reg(set->regs, set->half_classes[i], reg);
|
||||
ra_class_add_reg(set->half_classes[i], reg);
|
||||
|
||||
set->ra_reg_to_gpr[reg] = j;
|
||||
set->gpr_to_ra_reg[base + i][j] = reg;
|
||||
|
@ -172,7 +172,7 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
|
|||
ralloc_array(set, uint16_t, SHARED_CLASS_REGS(i));
|
||||
|
||||
for (unsigned j = 0; j < SHARED_CLASS_REGS(i); j++) {
|
||||
ra_class_add_reg(set->regs, set->shared_classes[i], reg);
|
||||
ra_class_add_reg(set->shared_classes[i], reg);
|
||||
|
||||
set->ra_reg_to_gpr[reg] = j;
|
||||
set->gpr_to_ra_reg[base + i][j] = reg;
|
||||
|
@ -188,7 +188,7 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
|
|||
* knows to allocate prefetch dst regs below the limit:
|
||||
*/
|
||||
set->prefetch_exclude_class = ra_alloc_reg_class(set->regs);
|
||||
ra_class_add_reg(set->regs, set->prefetch_exclude_class, reg);
|
||||
ra_class_add_reg(set->prefetch_exclude_class, reg);
|
||||
set->prefetch_exclude_reg = reg++;
|
||||
|
||||
/*
|
||||
|
|
|
@ -90,11 +90,12 @@ etna_ra_setup(void *mem_ctx)
|
|||
/* classes always be created from index 0, so equal to the class enum
|
||||
* which represents a register with (c+1) components
|
||||
*/
|
||||
struct ra_class *classes[NUM_REG_CLASSES];
|
||||
for (int c = 0; c < NUM_REG_CLASSES; c++)
|
||||
ra_alloc_reg_class(regs);
|
||||
classes[c] = ra_alloc_reg_class(regs);
|
||||
/* add each register of each class */
|
||||
for (int r = 0; r < NUM_REG_TYPES * ETNA_MAX_TEMPS; r++)
|
||||
ra_class_add_reg(regs, reg_get_class(r), r);
|
||||
ra_class_add_reg(classes[reg_get_class(r)], r);
|
||||
/* set conflicts */
|
||||
for (int r = 0; r < ETNA_MAX_TEMPS; r++) {
|
||||
for (int i = 0; i < NUM_REG_TYPES; i++) {
|
||||
|
@ -172,7 +173,7 @@ etna_ra_assign(struct etna_compile *c, nir_shader *shader)
|
|||
}
|
||||
}
|
||||
|
||||
ra_set_node_class(g, i, comp);
|
||||
ra_set_node_class(g, i, ra_get_class_from_index(regs, comp));
|
||||
}
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
|
@ -197,7 +198,7 @@ etna_ra_assign(struct etna_compile *c, nir_shader *shader)
|
|||
deref->var->data.location == FRAG_RESULT_DEPTH) {
|
||||
ra_set_node_reg(g, index, REG_FRAG_DEPTH);
|
||||
} else {
|
||||
ra_set_node_class(g, index, REG_CLASS_VEC4);
|
||||
ra_set_node_class(g, index, ra_get_class_from_index(regs, REG_CLASS_VEC4));
|
||||
}
|
||||
} continue;
|
||||
case nir_intrinsic_load_input:
|
||||
|
|
|
@ -121,13 +121,14 @@ struct ra_regs *ppir_regalloc_init(void *mem_ctx)
|
|||
for (int i = 0; i < PPIR_VEC1_REG_NUM; i++)
|
||||
ra_make_reg_conflicts_transitive(ret, i);
|
||||
|
||||
struct ra_class *classes[ppir_ra_reg_class_num];
|
||||
for (int i = 0; i < ppir_ra_reg_class_num; i++)
|
||||
ra_alloc_reg_class(ret);
|
||||
classes[i] = ra_alloc_reg_class(ret);
|
||||
|
||||
int reg_index = 0;
|
||||
for (int i = 0; i < ppir_ra_reg_class_num; i++) {
|
||||
while (reg_index < ppir_ra_reg_base[i + 1])
|
||||
ra_class_add_reg(ret, i, reg_index++);
|
||||
ra_class_add_reg(classes[i], reg_index++);
|
||||
}
|
||||
|
||||
ra_set_finalize(ret, ppir_ra_reg_q_values);
|
||||
|
@ -609,7 +610,7 @@ static bool ppir_regalloc_prog_try(ppir_compiler *comp, bool *spilled)
|
|||
int c = ppir_ra_reg_class_vec1 + (reg->num_components - 1);
|
||||
if (reg->is_head)
|
||||
c += 4;
|
||||
ra_set_node_class(g, n++, c);
|
||||
ra_set_node_class(g, n++, ra_get_class_from_index(comp->ra, c));
|
||||
}
|
||||
|
||||
ppir_liveness_analysis(comp);
|
||||
|
|
|
@ -516,7 +516,7 @@ static void do_advanced_regalloc(struct regalloc_state * s)
|
|||
{
|
||||
|
||||
unsigned int i, input_node, node_count, node_index;
|
||||
unsigned int * node_classes;
|
||||
struct ra_class ** node_classes;
|
||||
struct rc_instruction * inst;
|
||||
struct rc_list * var_ptr;
|
||||
struct rc_list * variables;
|
||||
|
@ -527,7 +527,7 @@ static void do_advanced_regalloc(struct regalloc_state * s)
|
|||
variables = rc_get_variables(s->C);
|
||||
node_count = rc_list_count(variables);
|
||||
node_classes = memory_pool_malloc(&s->C->Pool,
|
||||
node_count * sizeof(unsigned int));
|
||||
node_count * sizeof(struct ra_class *));
|
||||
|
||||
for (var_ptr = variables, node_index = 0; var_ptr;
|
||||
var_ptr = var_ptr->Next, node_index++) {
|
||||
|
@ -536,7 +536,7 @@ static void do_advanced_regalloc(struct regalloc_state * s)
|
|||
rc_variable_compute_live_intervals(var_ptr->Item);
|
||||
|
||||
class_index = variable_get_class(var_ptr->Item, rc_class_list);
|
||||
node_classes[node_index] = ra_state->class_ids[class_index];
|
||||
node_classes[node_index] = ra_state->classes[class_index];
|
||||
}
|
||||
|
||||
|
||||
|
@ -699,15 +699,14 @@ void rc_init_regalloc_state(struct rc_regalloc_state *s)
|
|||
/* Create the register classes */
|
||||
for (i = 0; i < RC_REG_CLASS_COUNT; i++) {
|
||||
const struct rc_class *class = &rc_class_list[i];
|
||||
s->class_ids[class->ID] = ra_alloc_reg_class(s->regs);
|
||||
s->classes[class->ID] = ra_alloc_reg_class(s->regs);
|
||||
|
||||
/* Assign registers to the classes */
|
||||
for (index = 0; index < R500_PFS_NUM_TEMP_REGS; index++) {
|
||||
for (j = 0; j < class->WritemaskCount; j++) {
|
||||
int reg_id = get_reg_id(index,
|
||||
class->Writemasks[j]);
|
||||
ra_class_add_reg(s->regs,
|
||||
s->class_ids[class->ID], reg_id);
|
||||
ra_class_add_reg(s->classes[class->ID], reg_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ enum rc_reg_class {
|
|||
|
||||
struct rc_regalloc_state {
|
||||
struct ra_regs *regs;
|
||||
unsigned class_ids[RC_REG_CLASS_COUNT];
|
||||
struct ra_class *classes[RC_REG_CLASS_COUNT];
|
||||
};
|
||||
|
||||
void rc_init_regalloc_state(struct rc_regalloc_state *s);
|
||||
|
|
|
@ -336,12 +336,12 @@ struct vc4_context {
|
|||
uint64_t next_compiled_program_id;
|
||||
|
||||
struct ra_regs *regs;
|
||||
unsigned int reg_class_any[2];
|
||||
unsigned int reg_class_a_or_b[2];
|
||||
unsigned int reg_class_a_or_b_or_acc[2];
|
||||
unsigned int reg_class_r0_r3;
|
||||
unsigned int reg_class_r4_or_a[2];
|
||||
unsigned int reg_class_a[2];
|
||||
struct ra_class *reg_class_any[2];
|
||||
struct ra_class *reg_class_a_or_b[2];
|
||||
struct ra_class *reg_class_a_or_b_or_acc[2];
|
||||
struct ra_class *reg_class_r0_r3;
|
||||
struct ra_class *reg_class_r4_or_a[2];
|
||||
struct ra_class *reg_class_a[2];
|
||||
|
||||
uint8_t prim_mode;
|
||||
|
||||
|
|
|
@ -132,19 +132,17 @@ vc4_alloc_reg_set(struct vc4_context *vc4)
|
|||
|
||||
/* r0-r3 */
|
||||
for (uint32_t i = ACC_INDEX; i < ACC_INDEX + 4; i++) {
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_r0_r3, i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b_or_acc[0], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b_or_acc[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_r0_r3, i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b_or_acc[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b_or_acc[1], i);
|
||||
}
|
||||
|
||||
/* R4 gets a special class because it can't be written as a general
|
||||
* purpose register. (it's TMU_NOSWAP as a write address).
|
||||
*/
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_r4_or_a[i],
|
||||
ACC_INDEX + 4);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_any[i],
|
||||
ACC_INDEX + 4);
|
||||
ra_class_add_reg(vc4->reg_class_r4_or_a[i], ACC_INDEX + 4);
|
||||
ra_class_add_reg(vc4->reg_class_any[i], ACC_INDEX + 4);
|
||||
}
|
||||
|
||||
/* A/B */
|
||||
|
@ -155,27 +153,25 @@ vc4_alloc_reg_set(struct vc4_context *vc4)
|
|||
if (vc4_regs[i].addr == 14)
|
||||
continue;
|
||||
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_any[0], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b[0], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b_or_acc[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_any[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b_or_acc[0], i);
|
||||
|
||||
if (vc4_regs[i].addr < 16) {
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_any[1], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b[1], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a_or_b_or_acc[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_any[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_a_or_b_or_acc[1], i);
|
||||
}
|
||||
|
||||
|
||||
/* A only */
|
||||
if (((i - AB_INDEX) & 1) == 0) {
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_a[0], i);
|
||||
ra_class_add_reg(vc4->regs, vc4->reg_class_r4_or_a[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_a[0], i);
|
||||
ra_class_add_reg(vc4->reg_class_r4_or_a[0], i);
|
||||
|
||||
if (vc4_regs[i].addr < 16) {
|
||||
ra_class_add_reg(vc4->regs,
|
||||
vc4->reg_class_a[1], i);
|
||||
ra_class_add_reg(vc4->regs,
|
||||
vc4->reg_class_r4_or_a[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_a[1], i);
|
||||
ra_class_add_reg(vc4->reg_class_r4_or_a[1], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ struct brw_compiler {
|
|||
* Array of the ra classes for the unaligned contiguous register
|
||||
* block sizes used.
|
||||
*/
|
||||
int *classes;
|
||||
struct ra_class **classes;
|
||||
|
||||
/**
|
||||
* Mapping for register-allocated objects in *regs to the first
|
||||
|
@ -66,7 +66,7 @@ struct brw_compiler {
|
|||
* Array of the ra classes for the unaligned contiguous register
|
||||
* block sizes used, indexed by register size.
|
||||
*/
|
||||
int classes[16];
|
||||
struct ra_class *classes[16];
|
||||
|
||||
/**
|
||||
* Mapping from classes to ra_reg ranges. Each of the per-size
|
||||
|
@ -88,7 +88,7 @@ struct brw_compiler {
|
|||
* ra class for the aligned barycentrics we use for PLN, which doesn't
|
||||
* appear in *classes.
|
||||
*/
|
||||
int aligned_bary_class;
|
||||
struct ra_class *aligned_bary_class;
|
||||
} fs_reg_sets[3];
|
||||
|
||||
void (*shader_debug_log)(void *, const char *str, ...) PRINTFLIKE(2, 3);
|
||||
|
|
|
@ -154,8 +154,8 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
|
|||
struct ra_regs *regs = ra_alloc_reg_set(compiler, ra_reg_count, false);
|
||||
if (devinfo->ver >= 6)
|
||||
ra_set_allocate_round_robin(regs);
|
||||
int *classes = ralloc_array(compiler, int, class_count);
|
||||
int aligned_bary_class = -1;
|
||||
struct ra_class **classes = ralloc_array(compiler, struct ra_class *, class_count);
|
||||
struct ra_class *aligned_bary_class = NULL;
|
||||
|
||||
/* Allocate space for q values. We allocate class_count + 1 because we
|
||||
* want to leave room for the aligned barycentric class if we have it.
|
||||
|
@ -221,7 +221,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
|
|||
|
||||
if (devinfo->ver <= 5 && dispatch_width >= 16) {
|
||||
for (int j = 0; j < class_reg_count; j++) {
|
||||
ra_class_add_reg(regs, classes[i], reg);
|
||||
ra_class_add_reg(classes[i], reg);
|
||||
|
||||
ra_reg_to_grf[reg] = j * 2;
|
||||
|
||||
|
@ -235,7 +235,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
|
|||
}
|
||||
} else {
|
||||
for (int j = 0; j < class_reg_count; j++) {
|
||||
ra_class_add_reg(regs, classes[i], reg);
|
||||
ra_class_add_reg(classes[i], reg);
|
||||
|
||||
ra_reg_to_grf[reg] = j;
|
||||
|
||||
|
@ -266,7 +266,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
|
|||
|
||||
for (int i = 0; i < aligned_bary_reg_count; i++) {
|
||||
if ((ra_reg_to_grf[aligned_bary_base_reg + i] & 1) == 0) {
|
||||
ra_class_add_reg(regs, aligned_bary_class,
|
||||
ra_class_add_reg(aligned_bary_class,
|
||||
aligned_bary_base_reg + i);
|
||||
}
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ brw_alloc_reg_set(struct brw_compiler *compiler, int dispatch_width)
|
|||
|
||||
compiler->fs_reg_sets[index].regs = regs;
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(compiler->fs_reg_sets[index].classes); i++)
|
||||
compiler->fs_reg_sets[index].classes[i] = -1;
|
||||
compiler->fs_reg_sets[index].classes[i] = NULL;
|
||||
for (int i = 0; i < class_count; i++)
|
||||
compiler->fs_reg_sets[index].classes[class_sizes[i] - 1] = classes[i];
|
||||
compiler->fs_reg_sets[index].ra_reg_to_grf = ra_reg_to_grf;
|
||||
|
@ -848,7 +848,7 @@ fs_reg_alloc::build_interference_graph(bool allow_spilling)
|
|||
* of a PLN instruction needs to be an even-numbered register, so we have a
|
||||
* special register class aligned_bary_class to handle this case.
|
||||
*/
|
||||
if (compiler->fs_reg_sets[rsi].aligned_bary_class >= 0) {
|
||||
if (compiler->fs_reg_sets[rsi].aligned_bary_class) {
|
||||
foreach_block_and_inst(block, fs_inst, inst, fs->cfg) {
|
||||
if (inst->opcode == FS_OPCODE_LINTERP && inst->src[0].file == VGRF &&
|
||||
fs->alloc.sizes[inst->src[0].nr] ==
|
||||
|
|
|
@ -117,7 +117,7 @@ brw_vec4_alloc_reg_set(struct brw_compiler *compiler)
|
|||
if (compiler->devinfo->ver >= 6)
|
||||
ra_set_allocate_round_robin(compiler->vec4_reg_set.regs);
|
||||
ralloc_free(compiler->vec4_reg_set.classes);
|
||||
compiler->vec4_reg_set.classes = ralloc_array(compiler, int, class_count);
|
||||
compiler->vec4_reg_set.classes = ralloc_array(compiler, struct ra_class *, class_count);
|
||||
|
||||
/* Now, add the registers to their classes, and add the conflicts
|
||||
* between them and the base GRF registers (and also each other).
|
||||
|
@ -131,7 +131,7 @@ brw_vec4_alloc_reg_set(struct brw_compiler *compiler)
|
|||
q_values[i] = new unsigned[MAX_VGRF_SIZE];
|
||||
|
||||
for (int j = 0; j < class_reg_count; j++) {
|
||||
ra_class_add_reg(compiler->vec4_reg_set.regs, compiler->vec4_reg_set.classes[i], reg);
|
||||
ra_class_add_reg(compiler->vec4_reg_set.classes[i], reg);
|
||||
|
||||
compiler->vec4_reg_set.ra_reg_to_grf[reg] = j;
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int r)
|
|||
}
|
||||
}
|
||||
|
||||
unsigned int
|
||||
struct ra_class *
|
||||
ra_alloc_reg_class(struct ra_regs *regs)
|
||||
{
|
||||
struct ra_class *class;
|
||||
|
@ -223,20 +223,33 @@ ra_alloc_reg_class(struct ra_regs *regs)
|
|||
regs->class_count + 1);
|
||||
|
||||
class = rzalloc(regs, struct ra_class);
|
||||
regs->classes[regs->class_count] = class;
|
||||
class->regset = regs;
|
||||
|
||||
/* Users may rely on the class index being allocated in order starting from 0. */
|
||||
class->index = regs->class_count++;
|
||||
regs->classes[class->index] = class;
|
||||
|
||||
class->regs = rzalloc_array(class, BITSET_WORD, BITSET_WORDS(regs->count));
|
||||
|
||||
/* Users may rely on the class index being allocated in order starting from 0. */
|
||||
return regs->class_count++;
|
||||
return class;
|
||||
}
|
||||
|
||||
struct ra_class *
|
||||
ra_get_class_from_index(struct ra_regs *regs, unsigned int class)
|
||||
{
|
||||
return regs->classes[class];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ra_class_index(struct ra_class *c)
|
||||
{
|
||||
return c->index;
|
||||
}
|
||||
|
||||
void
|
||||
ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int r)
|
||||
ra_class_add_reg(struct ra_class *class, unsigned int r)
|
||||
{
|
||||
struct ra_class *class = regs->classes[c];
|
||||
|
||||
assert(r < regs->count);
|
||||
assert(r < class->regset->count);
|
||||
|
||||
BITSET_SET(class->regs, r);
|
||||
class->p++;
|
||||
|
@ -475,20 +488,20 @@ void ra_set_select_reg_callback(struct ra_graph *g,
|
|||
|
||||
void
|
||||
ra_set_node_class(struct ra_graph *g,
|
||||
unsigned int n, unsigned int class)
|
||||
unsigned int n, struct ra_class *class)
|
||||
{
|
||||
g->nodes[n].class = class;
|
||||
g->nodes[n].class = class->index;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
struct ra_class *
|
||||
ra_get_node_class(struct ra_graph *g,
|
||||
unsigned int n)
|
||||
{
|
||||
return g->nodes[n].class;
|
||||
return g->regs->classes[g->nodes[n].class];
|
||||
}
|
||||
|
||||
unsigned int
|
||||
ra_add_node(struct ra_graph *g, unsigned int class)
|
||||
ra_add_node(struct ra_graph *g, struct ra_class *class)
|
||||
{
|
||||
unsigned int n = g->count;
|
||||
ra_resize_interference_graph(g, g->count + 1);
|
||||
|
|
|
@ -53,7 +53,8 @@ struct blob_reader;
|
|||
struct ra_regs *ra_alloc_reg_set(void *mem_ctx, unsigned int count,
|
||||
bool need_conflict_lists);
|
||||
void ra_set_allocate_round_robin(struct ra_regs *regs);
|
||||
unsigned int ra_alloc_reg_class(struct ra_regs *regs);
|
||||
struct ra_class *ra_alloc_reg_class(struct ra_regs *regs);
|
||||
unsigned int ra_class_index(struct ra_class *c);
|
||||
void ra_add_reg_conflict(struct ra_regs *regs,
|
||||
unsigned int r1, unsigned int r2);
|
||||
void ra_add_transitive_reg_conflict(struct ra_regs *regs,
|
||||
|
@ -64,7 +65,8 @@ ra_add_transitive_reg_pair_conflict(struct ra_regs *regs,
|
|||
unsigned int base_reg, unsigned int reg0, unsigned int reg1);
|
||||
|
||||
void ra_make_reg_conflicts_transitive(struct ra_regs *regs, unsigned int reg);
|
||||
void ra_class_add_reg(struct ra_regs *regs, unsigned int c, unsigned int reg);
|
||||
void ra_class_add_reg(struct ra_class *c, unsigned int reg);
|
||||
struct ra_class *ra_get_class_from_index(struct ra_regs *regs, unsigned int c);
|
||||
void ra_set_num_conflicts(struct ra_regs *regs, unsigned int class_a,
|
||||
unsigned int class_b, unsigned int num_conflicts);
|
||||
void ra_set_finalize(struct ra_regs *regs, unsigned int **conflicts);
|
||||
|
@ -86,9 +88,9 @@ struct ra_regs *ra_set_deserialize(void *mem_ctx, struct blob_reader *blob);
|
|||
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_get_node_class(struct ra_graph *g, unsigned int n);
|
||||
unsigned int ra_add_node(struct ra_graph *g, unsigned int c);
|
||||
void ra_set_node_class(struct ra_graph *g, unsigned int n, struct ra_class *c);
|
||||
struct ra_class *ra_get_node_class(struct ra_graph *g, unsigned int n);
|
||||
unsigned int ra_add_node(struct ra_graph *g, struct ra_class *c);
|
||||
|
||||
/** @{ Register selection callback.
|
||||
*
|
||||
|
|
|
@ -54,6 +54,8 @@ struct ra_regs {
|
|||
};
|
||||
|
||||
struct ra_class {
|
||||
struct ra_regs *regset;
|
||||
|
||||
/**
|
||||
* Bitset indicating which registers belong to this class.
|
||||
*
|
||||
|
@ -74,6 +76,8 @@ struct ra_class {
|
|||
* the worst choice register from C conflict with".
|
||||
*/
|
||||
unsigned int *q;
|
||||
|
||||
int index;
|
||||
};
|
||||
|
||||
struct ra_node {
|
||||
|
|
|
@ -53,27 +53,27 @@ TEST_F(ra_test, thumb)
|
|||
int next_vreg = 16;
|
||||
|
||||
/* reg32low is any of the low 8 registers. */
|
||||
int reg32low = ra_alloc_reg_class(regs);
|
||||
struct ra_class *reg32low = ra_alloc_reg_class(regs);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int vreg = next_vreg++;
|
||||
ra_class_add_reg(regs, reg32low, vreg);
|
||||
ra_class_add_reg(reg32low, vreg);
|
||||
ra_add_transitive_reg_conflict(regs, i, vreg);
|
||||
}
|
||||
|
||||
/* reg64low is pairs of the low 8 registers (with wraparound!) */
|
||||
int reg64low = ra_alloc_reg_class(regs);
|
||||
struct ra_class *reg64low = ra_alloc_reg_class(regs);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int vreg = next_vreg++;
|
||||
ra_class_add_reg(regs, reg64low, vreg);
|
||||
ra_class_add_reg(reg64low, vreg);
|
||||
ra_add_transitive_reg_conflict(regs, i, vreg);
|
||||
ra_add_transitive_reg_conflict(regs, (i + 1) % 8, vreg);
|
||||
}
|
||||
|
||||
/* reg96 is one of either r[0..2] or r[1..3] */
|
||||
int reg96 = ra_alloc_reg_class(regs);
|
||||
struct ra_class *reg96 = ra_alloc_reg_class(regs);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
int vreg = next_vreg++;
|
||||
ra_class_add_reg(regs, reg96, vreg);
|
||||
ra_class_add_reg(reg96, vreg);
|
||||
for (int j = 0; j < 3; j++)
|
||||
ra_add_transitive_reg_conflict(regs, i + j, vreg);
|
||||
}
|
||||
|
@ -81,16 +81,16 @@ TEST_F(ra_test, thumb)
|
|||
ra_set_finalize(regs, NULL);
|
||||
|
||||
/* Table 4.1 */
|
||||
ASSERT_EQ(regs->classes[reg32low]->p, 8);
|
||||
ASSERT_EQ(regs->classes[reg32low]->q[reg32low], 1);
|
||||
ASSERT_EQ(regs->classes[reg32low]->q[reg64low], 2);
|
||||
ASSERT_EQ(regs->classes[reg32low]->q[reg96], 3);
|
||||
ASSERT_EQ(regs->classes[reg64low]->p, 8);
|
||||
ASSERT_EQ(regs->classes[reg64low]->q[reg32low], 2);
|
||||
ASSERT_EQ(regs->classes[reg64low]->q[reg64low], 3);
|
||||
ASSERT_EQ(regs->classes[reg64low]->q[reg96], 4);
|
||||
ASSERT_EQ(regs->classes[reg96]->p, 2);
|
||||
ASSERT_EQ(regs->classes[reg96]->q[reg96], 2);
|
||||
ASSERT_EQ(regs->classes[reg96]->q[reg64low], 2);
|
||||
ASSERT_EQ(regs->classes[reg96]->q[reg96], 2);
|
||||
ASSERT_EQ(reg32low->p, 8);
|
||||
ASSERT_EQ(reg32low->q[reg32low->index], 1);
|
||||
ASSERT_EQ(reg32low->q[reg64low->index], 2);
|
||||
ASSERT_EQ(reg32low->q[reg96->index], 3);
|
||||
ASSERT_EQ(reg64low->p, 8);
|
||||
ASSERT_EQ(reg64low->q[reg32low->index], 2);
|
||||
ASSERT_EQ(reg64low->q[reg64low->index], 3);
|
||||
ASSERT_EQ(reg64low->q[reg96->index], 4);
|
||||
ASSERT_EQ(reg96->p, 2);
|
||||
ASSERT_EQ(reg96->q[reg96->index], 2);
|
||||
ASSERT_EQ(reg96->q[reg64low->index], 2);
|
||||
ASSERT_EQ(reg96->q[reg96->index], 2);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue