diff --git a/src/broadcom/compiler/v3d_compiler.h b/src/broadcom/compiler/v3d_compiler.h index 87753a626c3..51c755c6d56 100644 --- a/src/broadcom/compiler/v3d_compiler.h +++ b/src/broadcom/compiler/v3d_compiler.h @@ -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]; }; /** diff --git a/src/broadcom/compiler/vir_register_allocate.c b/src/broadcom/compiler/vir_register_allocate.c index 6089179ce49..6a6bfd8a3d0 100644 --- a/src/broadcom/compiler/vir_register_allocate.c +++ b/src/broadcom/compiler/vir_register_allocate.c @@ -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); } diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index 7ef7dbf37d9..508793c4303 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -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; } diff --git a/src/freedreno/ir3/ir3_ra.h b/src/freedreno/ir3/ir3_ra.h index 0b49099c9c3..1380734f705 100644 --- a/src/freedreno/ir3/ir3_ra.h +++ b/src/freedreno/ir3/ir3_ra.h @@ -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, diff --git a/src/freedreno/ir3/ir3_ra_regset.c b/src/freedreno/ir3/ir3_ra_regset.c index 12d41392c95..d7290bffd09 100644 --- a/src/freedreno/ir3/ir3_ra_regset.c +++ b/src/freedreno/ir3/ir3_ra_regset.c @@ -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++; /* diff --git a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_ra.c b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_ra.c index f97f796a53e..2400b9c3087 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_ra.c +++ b/src/gallium/drivers/etnaviv/etnaviv_compiler_nir_ra.c @@ -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: diff --git a/src/gallium/drivers/lima/ir/pp/regalloc.c b/src/gallium/drivers/lima/ir/pp/regalloc.c index 7ac47c65b9e..21829754032 100644 --- a/src/gallium/drivers/lima/ir/pp/regalloc.c +++ b/src/gallium/drivers/lima/ir/pp/regalloc.c @@ -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); diff --git a/src/gallium/drivers/r300/compiler/radeon_pair_regalloc.c b/src/gallium/drivers/r300/compiler/radeon_pair_regalloc.c index 7f9d8cb7f4f..d3a589c98d1 100644 --- a/src/gallium/drivers/r300/compiler/radeon_pair_regalloc.c +++ b/src/gallium/drivers/r300/compiler/radeon_pair_regalloc.c @@ -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); } } } diff --git a/src/gallium/drivers/r300/compiler/radeon_regalloc.h b/src/gallium/drivers/r300/compiler/radeon_regalloc.h index 260a3caf91d..6f12289e247 100644 --- a/src/gallium/drivers/r300/compiler/radeon_regalloc.h +++ b/src/gallium/drivers/r300/compiler/radeon_regalloc.h @@ -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); diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index f02992f07ee..6fb54d56b90 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -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; diff --git a/src/gallium/drivers/vc4/vc4_register_allocate.c b/src/gallium/drivers/vc4/vc4_register_allocate.c index 53faf1ae779..9613369a589 100644 --- a/src/gallium/drivers/vc4/vc4_register_allocate.c +++ b/src/gallium/drivers/vc4/vc4_register_allocate.c @@ -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); } } } diff --git a/src/intel/compiler/brw_compiler.h b/src/intel/compiler/brw_compiler.h index 8bea789e8ad..7c7128634d9 100644 --- a/src/intel/compiler/brw_compiler.h +++ b/src/intel/compiler/brw_compiler.h @@ -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); diff --git a/src/intel/compiler/brw_fs_reg_allocate.cpp b/src/intel/compiler/brw_fs_reg_allocate.cpp index b2fbb109456..f260325125f 100644 --- a/src/intel/compiler/brw_fs_reg_allocate.cpp +++ b/src/intel/compiler/brw_fs_reg_allocate.cpp @@ -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] == diff --git a/src/intel/compiler/brw_vec4_reg_allocate.cpp b/src/intel/compiler/brw_vec4_reg_allocate.cpp index 19917124d79..284af171b98 100644 --- a/src/intel/compiler/brw_vec4_reg_allocate.cpp +++ b/src/intel/compiler/brw_vec4_reg_allocate.cpp @@ -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; diff --git a/src/util/register_allocate.c b/src/util/register_allocate.c index efffbd627d3..b9886e802fd 100644 --- a/src/util/register_allocate.c +++ b/src/util/register_allocate.c @@ -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); diff --git a/src/util/register_allocate.h b/src/util/register_allocate.h index c9170e7762a..820f7569475 100644 --- a/src/util/register_allocate.h +++ b/src/util/register_allocate.h @@ -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. * diff --git a/src/util/register_allocate_internal.h b/src/util/register_allocate_internal.h index fd53bff9afd..de5a5564db9 100644 --- a/src/util/register_allocate_internal.h +++ b/src/util/register_allocate_internal.h @@ -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 { diff --git a/src/util/register_allocate_test.cpp b/src/util/register_allocate_test.cpp index 84b20617604..09b499d9a54 100644 --- a/src/util/register_allocate_test.cpp +++ b/src/util/register_allocate_test.cpp @@ -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); }