From 9ad83f51eb3c089aad0640c2ee6ad6d9477fc2b6 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 19 Feb 2021 11:18:02 +0100 Subject: [PATCH] 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: --- src/freedreno/ir3/ir3.c | 2 +- src/freedreno/ir3/ir3.h | 5 +++-- src/freedreno/ir3/ir3_postsched.c | 10 ++++------ src/freedreno/ir3/ir3_ra.c | 1 + 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index 5a5b416b469..e4a2f32caab 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -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); diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 7f89d51bfef..791417b06d4 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -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++) diff --git a/src/freedreno/ir3/ir3_postsched.c b/src/freedreno/ir3/ir3_postsched.c index 2ef06eed537..c59c3b94e93 100644 --- a/src/freedreno/ir3/ir3_postsched.c +++ b/src/freedreno/ir3/ir3_postsched.c @@ -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); diff --git a/src/freedreno/ir3/ir3_ra.c b/src/freedreno/ir3/ir3_ra.c index 2c292ca1a05..7151a2eb991 100644 --- a/src/freedreno/ir3/ir3_ra.c +++ b/src/freedreno/ir3/ir3_ra.c @@ -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;