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:
Eric Anholt 2021-03-04 15:14:15 -08:00 committed by Marge Bot
parent 7e0127fb3e
commit 95d41a3525
18 changed files with 126 additions and 116 deletions

View File

@ -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];
};
/**

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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++;
/*

View File

@ -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:

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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] ==

View File

@ -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;

View File

@ -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);

View File

@ -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.
*

View File

@ -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 {

View File

@ -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);
}