Module: Mesa Branch: main Commit: a433db60c194c894d8f197a58b4a8e9053211165 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=a433db60c194c894d8f197a58b4a8e9053211165
Author: Connor Abbott <[email protected]> Date: Mon Jan 10 13:34:16 2022 +0100 ir3: Track physical edges when inserting (ss) for shared regs Normally this wouldn't matter, but it will matter for the upcoming scan macro because the running tally is communicated through a shared register across a physical edge. It may also matter if a live-range split occurs. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14107> --- src/freedreno/ir3/ir3.h | 15 +++++++++++++++ src/freedreno/ir3/ir3_legalize.c | 11 +++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 21a564ae661..c71e8da329d 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -2502,6 +2502,21 @@ regmask_or(regmask_t *dst, regmask_t *a, regmask_t *b) dst->mask[i] = a->mask[i] | b->mask[i]; } +static inline void +regmask_or_shared(regmask_t *dst, regmask_t *a, regmask_t *b) +{ + regmaskstate_t shared_mask; + BITSET_ZERO(shared_mask); + + if (b->mergedregs) { + BITSET_SET_RANGE(shared_mask, 2 * 4 * 48, 2 * 4 * 56 - 1); + } else { + BITSET_SET_RANGE(shared_mask, 4 * 48, 4 * 56 - 1); + } + + for (unsigned i = 0; i < ARRAY_SIZE(dst->mask); i++) + dst->mask[i] = a->mask[i] | (b->mask[i] & shared_mask[i]); +} static inline void regmask_set(regmask_t *regmask, struct ir3_register *reg) diff --git a/src/freedreno/ir3/ir3_legalize.c b/src/freedreno/ir3/ir3_legalize.c index 0cf1d51ef9e..510e857e021 100644 --- a/src/freedreno/ir3/ir3_legalize.c +++ b/src/freedreno/ir3/ir3_legalize.c @@ -111,6 +111,17 @@ legalize_block(struct ir3_legalize_ctx *ctx, struct ir3_block *block) regmask_or(&state->needs_sy, &state->needs_sy, &pstate->needs_sy); } + /* We need to take phsyical-only edges into account when tracking shared + * registers. + */ + for (unsigned i = 0; i < block->physical_predecessors_count; i++) { + struct ir3_block *predecessor = block->physical_predecessors[i]; + struct ir3_legalize_block_data *pbd = predecessor->data; + struct ir3_legalize_state *pstate = &pbd->state; + + regmask_or_shared(&state->needs_ss, &state->needs_ss, &pstate->needs_ss); + } + unsigned input_count = 0; foreach_instr (n, &block->instr_list) {
