ir3: Rename high registers to shared registers

This more accurately reflects what they are.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8175>
This commit is contained in:
Connor Abbott 2020-09-10 12:14:24 +02:00 committed by Marge Bot
parent 2b29ec7ca4
commit f9804673fb
10 changed files with 74 additions and 75 deletions

View File

@ -1357,7 +1357,7 @@ ir3_valid_flags(struct ir3_instruction *instr, unsigned n,
struct ir3_compiler *compiler = instr->block->shader->compiler;
unsigned valid_flags;
if ((flags & IR3_REG_HIGH) &&
if ((flags & IR3_REG_SHARED) &&
(opc_cat(instr->opc) > 1) &&
(compiler->gpu_id >= 600))
return false;

View File

@ -83,12 +83,11 @@ struct ir3_register {
IR3_REG_CONST = 0x001,
IR3_REG_IMMED = 0x002,
IR3_REG_HALF = 0x004,
/* high registers are used for some things in compute shaders,
* for example. Seems to be for things that are global to all
* threads in a wave, so possibly these are global/shared by
* all the threads in the wave?
/* Shared registers have the same value for all threads when read.
* They can only be written when one thread is active (that is, inside
* a "getone" block).
*/
IR3_REG_HIGH = 0x008,
IR3_REG_SHARED = 0x008,
IR3_REG_RELATIV= 0x010,
IR3_REG_R = 0x020,
/* Most instructions, it seems, can do float abs/neg but not
@ -672,8 +671,8 @@ static inline bool is_nop(struct ir3_instruction *instr)
static inline bool is_same_type_reg(struct ir3_register *reg1,
struct ir3_register *reg2)
{
unsigned type_reg1 = (reg1->flags & (IR3_REG_HIGH | IR3_REG_HALF));
unsigned type_reg2 = (reg2->flags & (IR3_REG_HIGH | IR3_REG_HALF));
unsigned type_reg1 = (reg1->flags & (IR3_REG_SHARED | IR3_REG_HALF));
unsigned type_reg2 = (reg2->flags & (IR3_REG_SHARED | IR3_REG_HALF));
if (type_reg1 ^ type_reg2)
return false;
@ -783,9 +782,9 @@ is_half(struct ir3_instruction *instr)
}
static inline bool
is_high(struct ir3_instruction *instr)
is_shared(struct ir3_instruction *instr)
{
return !!(instr->regs[0]->flags & IR3_REG_HIGH);
return !!(instr->regs[0]->flags & IR3_REG_SHARED);
}
static inline bool
@ -1449,7 +1448,7 @@ ir3_MOV(struct ir3_block *block, struct ir3_instruction *src, type_t type)
struct ir3_register *src_reg = __ssa_src(instr, src, IR3_REG_ARRAY);
src_reg->array = src->regs[0]->array;
} else {
__ssa_src(instr, src, src->regs[0]->flags & IR3_REG_HIGH);
__ssa_src(instr, src, src->regs[0]->flags & IR3_REG_SHARED);
}
debug_assert(!(src->regs[0]->flags & IR3_REG_RELATIV));
instr->cat1.src_type = type;

View File

@ -1919,7 +1919,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
if (!ctx->work_group_id) {
ctx->work_group_id =
create_sysval_input(ctx, SYSTEM_VALUE_WORK_GROUP_ID, 0x7);
ctx->work_group_id->regs[0]->flags |= IR3_REG_HIGH;
ctx->work_group_id->regs[0]->flags |= IR3_REG_SHARED;
}
ir3_split_dest(b, dst, ctx->work_group_id, 0, 3);
break;

View File

@ -239,14 +239,14 @@ ir3_put_dst(struct ir3_context *ctx, nir_dest *dst)
{
unsigned bit_size = nir_dest_bit_size(*dst);
/* add extra mov if dst value is HIGH reg.. in some cases not all
* instructions can read from HIGH regs, in cases where they can
/* add extra mov if dst value is shared reg.. in some cases not all
* instructions can read from shared regs, in cases where they can
* ir3_cp will clean up the extra mov:
*/
for (unsigned i = 0; i < ctx->last_dst_n; i++) {
if (!ctx->last_dst[i])
continue;
if (ctx->last_dst[i]->regs[0]->flags & IR3_REG_HIGH) {
if (ctx->last_dst[i]->regs[0]->flags & IR3_REG_SHARED) {
ctx->last_dst[i] = ir3_MOV(ctx->block, ctx->last_dst[i], TYPE_U32);
}
}
@ -293,7 +293,7 @@ ir3_put_dst(struct ir3_context *ctx, nir_dest *dst)
static unsigned
dest_flags(struct ir3_instruction *instr)
{
return instr->regs[0]->flags & (IR3_REG_HALF | IR3_REG_HIGH);
return instr->regs[0]->flags & (IR3_REG_HALF | IR3_REG_SHARED);
}
struct ir3_instruction *

View File

@ -132,7 +132,7 @@ static void combine_flags(unsigned *dstflags, struct ir3_instruction *src)
*dstflags |= srcflags & IR3_REG_IMMED;
*dstflags |= srcflags & IR3_REG_RELATIV;
*dstflags |= srcflags & IR3_REG_ARRAY;
*dstflags |= srcflags & IR3_REG_HIGH;
*dstflags |= srcflags & IR3_REG_SHARED;
/* if src of the src is boolean we can drop the (abs) since we know
* the source value is already a postitive integer. This cleans

View File

@ -173,8 +173,8 @@ static void print_reg_name(struct ir3_register *reg)
if (reg->flags & IR3_REG_R)
printf("(r)");
if (reg->flags & IR3_REG_HIGH)
printf("H");
if (reg->flags & IR3_REG_SHARED)
printf("s");
if (reg->flags & IR3_REG_HALF)
printf("h");

View File

@ -261,7 +261,7 @@ ra_block_find_definers(struct ir3_ra_ctx *ctx, struct ir3_block *block)
} else {
/* and the normal case: */
id->defn = get_definer(ctx, instr, &id->sz, &id->off);
id->cls = ra_size_to_class(id->sz, is_half(id->defn), is_high(id->defn));
id->cls = ra_size_to_class(id->sz, is_half(id->defn), is_shared(id->defn));
/* this is a bit of duct-tape.. if we have a scenario like:
*
@ -399,8 +399,8 @@ 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);
bool half, high;
int sz = ra_class_to_size(class, &half, &high);
bool half, shared;
int sz = ra_class_to_size(class, &half, &shared);
assert (sz > 0);
@ -430,15 +430,15 @@ ra_select_reg_merged(unsigned int n, BITSET_WORD *regs, void *data)
*/
if (!ctx->scalar_pass) {
base = ctx->set->gpr_to_ra_reg[class][0];
if (high) {
max_target = HIGH_CLASS_REGS(class - HIGH_OFFSET);
if (shared) {
max_target = SHARED_CLASS_REGS(class - SHARED_OFFSET);
} else if (half) {
max_target = HALF_CLASS_REGS(class - HALF_OFFSET);
} else {
max_target = CLASS_REGS(class);
}
if ((sz == 1) && !high) {
if ((sz == 1) && !shared) {
return pick_in_range_rev(regs, base, base + max_target);
} else {
return pick_in_range(regs, base, base + max_target);
@ -451,8 +451,8 @@ ra_select_reg_merged(unsigned int n, BITSET_WORD *regs, void *data)
* class will be one of the scalar classes (ie. idx==0):
*/
base = ctx->set->gpr_to_ra_reg[class][0];
if (high) {
max_target = HIGH_CLASS_REGS(0);
if (shared) {
max_target = SHARED_CLASS_REGS(0);
start = 0;
} else if (half) {
max_target = ctx->max_target;
@ -700,9 +700,9 @@ ra_block_compute_live_ranges(struct ir3_ra_ctx *ctx, struct ir3_block *block)
}
} else {
struct ir3_ra_instr_data *id = &ctx->instrd[instr->ip];
if (is_high(instr)) {
if (is_shared(instr)) {
ra_set_node_class(ctx->g, name,
ctx->set->high_classes[id->cls - HIGH_OFFSET]);
ctx->set->shared_classes[id->cls - SHARED_OFFSET]);
} else if (is_half(instr)) {
ra_set_node_class(ctx->g, name,
ctx->set->half_classes[id->cls - HALF_OFFSET]);
@ -848,7 +848,7 @@ live_size(struct ir3_instruction *instr)
{
if (is_half(instr)) {
return 1;
} else if (is_high(instr)) {
} else if (is_shared(instr)) {
/* doesn't count towards footprint */
return 0;
} else {
@ -1168,8 +1168,8 @@ reg_assign(struct ir3_ra_ctx *ctx, struct ir3_register *reg,
ra_assert(ctx, num >= first_component);
if (is_high(id->defn))
num += FIRST_HIGH_REG;
if (is_shared(id->defn))
num += FIRST_SHARED_REG;
reg->num = num - first_component;
@ -1363,7 +1363,7 @@ ra_precolor(struct ir3_ra_ctx *ctx, struct ir3_instruction **precolor, unsigned
struct ir3_ra_instr_data *id = &ctx->instrd[instr->ip];
ra_assert(ctx, !(instr->regs[0]->flags & (IR3_REG_HALF | IR3_REG_HIGH)));
ra_assert(ctx, !(instr->regs[0]->flags & (IR3_REG_HALF | IR3_REG_SHARED)));
/* 'base' is in scalar (class 0) but we need to map that
* the conflicting register of the appropriate class (ie.
@ -1440,8 +1440,8 @@ precolor(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr)
unsigned name = scalar_name(ctx, instr, i);
unsigned regid = instr->regs[0]->num + i;
if (instr->regs[0]->flags & IR3_REG_HIGH)
regid -= FIRST_HIGH_REG;
if (instr->regs[0]->flags & IR3_REG_SHARED)
regid -= FIRST_SHARED_REG;
unsigned vreg = ctx->set->gpr_to_ra_reg[id->cls][regid];
ra_set_node_reg(ctx->g, name, vreg);

View File

@ -47,17 +47,17 @@ static const unsigned half_class_sizes[] = {
/* seems to just be used for compute shaders? Seems like vec1 and vec3
* are sufficient (for now?)
*/
static const unsigned high_class_sizes[] = {
static const unsigned shared_class_sizes[] = {
1, 3,
};
#define high_class_count ARRAY_SIZE(high_class_sizes)
#define shared_class_count ARRAY_SIZE(shared_class_sizes)
#define total_class_count (class_count + half_class_count + high_class_count)
#define total_class_count (class_count + half_class_count + shared_class_count)
/* Below a0.x are normal regs. RA doesn't need to assign a0.x/p0.x. */
#define NUM_REGS (4 * 48) /* r0 to r47 */
#define NUM_HIGH_REGS (4 * 8) /* r48 to r55 */
#define FIRST_HIGH_REG (4 * 48)
#define NUM_SHARED_REGS (4 * 8) /* r48 to r55 */
#define FIRST_SHARED_REG (4 * 48)
/* Number of virtual regs in a given class: */
static inline unsigned CLASS_REGS(unsigned i)
@ -74,22 +74,22 @@ static inline unsigned HALF_CLASS_REGS(unsigned i)
return (NUM_REGS - (half_class_sizes[i] - 1));
}
static inline unsigned HIGH_CLASS_REGS(unsigned i)
static inline unsigned SHARED_CLASS_REGS(unsigned i)
{
assert(i < high_class_count);
assert(i < shared_class_count);
return (NUM_HIGH_REGS - (high_class_sizes[i] - 1));
return (NUM_SHARED_REGS - (shared_class_sizes[i] - 1));
}
#define HALF_OFFSET (class_count)
#define HIGH_OFFSET (class_count + half_class_count)
#define SHARED_OFFSET (class_count + half_class_count)
/* 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 high_classes[high_class_count];
unsigned int 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
@ -100,7 +100,7 @@ struct ir3_ra_reg_set {
unsigned prefetch_exclude_reg;
/* The virtual register space flattens out all the classes,
* starting with full, followed by half and then high, ie:
* starting with full, followed by half and then shared, ie:
*
* scalar full (starting at zero)
* vec2 full
@ -111,12 +111,12 @@ struct ir3_ra_reg_set {
* vec2 half
* ...
* vecN half
* scalar high (starting at first_high_reg)
* scalar shared (starting at first_shared_reg)
* ...
* vecN high
* vecN shared
*
*/
unsigned first_half_reg, first_high_reg;
unsigned first_half_reg, first_shared_reg;
/* maps flat virtual register space to base gpr: */
uint16_t *ra_reg_to_gpr;
@ -373,7 +373,7 @@ __ra_init_use_itr(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr)
for (unsigned __name = __ra_init_use_itr(__ctx, __instr); \
__name != NO_NAME; __name = __ra_itr_pop(__ctx))
int ra_size_to_class(unsigned sz, bool half, bool high);
int ra_class_to_size(unsigned class, bool *half, bool *high);
int ra_size_to_class(unsigned sz, bool half, bool shared);
int ra_class_to_size(unsigned class, bool *half, bool *shared);
#endif /* IR3_RA_H_ */

View File

@ -60,11 +60,11 @@ setup_conflicts(struct ir3_ra_reg_set *set)
}
}
for (unsigned i = 0; i < high_class_count; i++) {
for (unsigned j = 0; j < HIGH_CLASS_REGS(i); j++) {
for (unsigned br = j; br < j + high_class_sizes[i]; br++) {
for (unsigned i = 0; i < shared_class_count; i++) {
for (unsigned j = 0; j < SHARED_CLASS_REGS(i); j++) {
for (unsigned br = j; br < j + shared_class_sizes[i]; br++) {
ra_add_transitive_reg_conflict(set->regs,
br + set->first_high_reg, reg);
br + set->first_shared_reg, reg);
}
reg++;
@ -116,8 +116,8 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
ra_reg_count += CLASS_REGS(i);
for (unsigned i = 0; i < half_class_count; i++)
ra_reg_count += HALF_CLASS_REGS(i);
for (unsigned i = 0; i < high_class_count; i++)
ra_reg_count += HIGH_CLASS_REGS(i);
for (unsigned i = 0; i < shared_class_count; i++)
ra_reg_count += SHARED_CLASS_REGS(i);
ra_reg_count += 1; /* for tex-prefetch excludes */
@ -162,17 +162,17 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
}
}
set->first_high_reg = reg;
base = HIGH_OFFSET;
set->first_shared_reg = reg;
base = SHARED_OFFSET;
for (unsigned i = 0; i < high_class_count; i++) {
set->high_classes[i] = ra_alloc_reg_class(set->regs);
for (unsigned i = 0; i < shared_class_count; i++) {
set->shared_classes[i] = ra_alloc_reg_class(set->regs);
set->gpr_to_ra_reg[base + i] =
ralloc_array(set, uint16_t, HIGH_CLASS_REGS(i));
ralloc_array(set, uint16_t, SHARED_CLASS_REGS(i));
for (unsigned j = 0; j < HIGH_CLASS_REGS(i); j++) {
ra_class_add_reg(set->regs, set->high_classes[i], reg);
for (unsigned j = 0; j < SHARED_CLASS_REGS(i); j++) {
ra_class_add_reg(set->regs, set->shared_classes[i], reg);
set->ra_reg_to_gpr[reg] = j;
set->gpr_to_ra_reg[base + i][j] = reg;
@ -213,12 +213,12 @@ ir3_ra_alloc_reg_set(struct ir3_compiler *compiler, bool mergedregs)
}
int
ra_size_to_class(unsigned sz, bool half, bool high)
ra_size_to_class(unsigned sz, bool half, bool shared)
{
if (high) {
for (unsigned i = 0; i < high_class_count; i++)
if (high_class_sizes[i] >= sz)
return i + HIGH_OFFSET;
if (shared) {
for (unsigned i = 0; i < shared_class_count; i++)
if (shared_class_sizes[i] >= sz)
return i + SHARED_OFFSET;
} else if (half) {
for (unsigned i = 0; i < half_class_count; i++)
if (half_class_sizes[i] >= sz)
@ -233,13 +233,13 @@ ra_size_to_class(unsigned sz, bool half, bool high)
}
int
ra_class_to_size(unsigned class, bool *half, bool *high)
ra_class_to_size(unsigned class, bool *half, bool *shared)
{
*half = *high = false;
*half = *shared = false;
if (class >= HIGH_OFFSET) {
*high = true;
return high_class_sizes[class - HIGH_OFFSET];
if (class >= SHARED_OFFSET) {
*shared = true;
return shared_class_sizes[class - SHARED_OFFSET];
} else if (class >= HALF_OFFSET) {
*half = true;
return half_class_sizes[class - HALF_OFFSET];

View File

@ -56,7 +56,7 @@ validate_error(struct ir3_validate_ctx *ctx, const char *condstr)
static unsigned
reg_class_flags(struct ir3_register *reg)
{
return reg->flags & (IR3_REG_HALF | IR3_REG_HIGH);
return reg->flags & (IR3_REG_HALF | IR3_REG_SHARED);
}
static void