ir3: Add ir3_register::array.base

There were two different approaches I saw in the post-RA code for
figuring out what regiser range a relative access touched:

1. Use reg->array.offset and reg->array.size. This is wrong in case
   reg->array.offset was non-zero before RA, because array.size is
   the size of the whole array and array.offset has the const offset
   within the array baked in.
2. Lookup the array from the array ID and use the base + range there.
   This is correct, but won't work with the new RA, where an array might
   not always be assigned to the same register.

This replaces both methods with a new ir3_register::array.base field,
and switches all the users I could find to it.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9842>
This commit is contained in:
Connor Abbott 2021-02-19 11:18:02 +01:00 committed by Emma Anholt
parent 939ee6966f
commit 9ad83f51eb
4 changed files with 9 additions and 9 deletions

View file

@ -85,7 +85,7 @@ collect_reg_info(struct ir3_instruction *instr, struct ir3_register *reg,
if (reg->flags & IR3_REG_RELATIV) {
components = reg->size;
max = (reg->array.offset + repeat + components - 1);
max = (reg->array.base + components - 1);
} else {
components = util_last_bit(reg->wrmask);
max = (reg->num + repeat + components - 1);

View file

@ -151,6 +151,7 @@ struct ir3_register {
struct {
uint16_t id;
int16_t offset;
uint16_t base;
} array;
};
@ -1936,7 +1937,7 @@ static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg)
bool half = reg->flags & IR3_REG_HALF;
if (reg->flags & IR3_REG_RELATIV) {
for (unsigned i = 0; i < reg->size; i++)
__regmask_set(regmask, half, reg->array.offset + i);
__regmask_set(regmask, half, reg->array.base + i);
} else {
for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)
if (mask & 1)
@ -1950,7 +1951,7 @@ static inline bool regmask_get(regmask_t *regmask,
bool half = reg->flags & IR3_REG_HALF;
if (reg->flags & IR3_REG_RELATIV) {
for (unsigned i = 0; i < reg->size; i++)
if (__regmask_get(regmask, half, reg->array.offset + i))
if (__regmask_get(regmask, half, reg->array.base + i))
return true;
} else {
for (unsigned mask = reg->wrmask, n = reg->num; mask; mask >>= 1, n++)

View file

@ -425,9 +425,8 @@ calculate_deps(struct ir3_postsched_deps_state *state,
if (reg->flags & IR3_REG_RELATIV) {
/* mark entire array as read: */
struct ir3_array *arr = ir3_lookup_array(state->ctx->ir, reg->array.id);
for (unsigned j = 0; j < arr->length; j++) {
add_reg_dep(state, node, reg, arr->reg + j, i + 1);
for (unsigned j = 0; j < reg->size; j++) {
add_reg_dep(state, node, reg, reg->array.base + j, i + 1);
}
} else {
assert(reg->wrmask >= 1);
@ -451,9 +450,8 @@ calculate_deps(struct ir3_postsched_deps_state *state,
struct ir3_register *reg = node->instr->regs[0];
if (reg->flags & IR3_REG_RELATIV) {
/* mark the entire array as written: */
struct ir3_array *arr = ir3_lookup_array(state->ctx->ir, reg->array.id);
for (unsigned i = 0; i < arr->length; i++) {
add_reg_dep(state, node, reg, arr->reg + i, -1);
for (unsigned i = 0; i < reg->size; i++) {
add_reg_dep(state, node, reg, reg->array.base + i, -1);
}
} else {
assert(reg->wrmask >= 1);

View file

@ -1138,6 +1138,7 @@ reg_assign(struct ir3_ra_ctx *ctx, struct ir3_register *reg,
unsigned num = ctx->set->ra_reg_to_gpr[r];
if (reg->flags & IR3_REG_RELATIV) {
reg->array.base = arr->reg;
reg->array.offset = num;
} else {
reg->num = num;