ir3: Track physical edges when inserting (ss) for shared regs
authorConnor Abbott <cwabbott0@gmail.com>
Mon, 10 Jan 2022 12:34:16 +0000 (13:34 +0100)
committerMarge Bot <emma+marge@anholt.net>
Thu, 10 Mar 2022 17:15:29 +0000 (17:15 +0000)
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
src/freedreno/ir3/ir3_legalize.c

index 21a564a..c71e8da 100644 (file)
@@ -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)
index 0cf1d51..510e857 100644 (file)
@@ -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) {