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

Reply via email to