ir3/ra: Fix array reg liveness in scalar pass
authorConnor Abbott <cwabbott0@gmail.com>
Fri, 20 Nov 2020 23:27:34 +0000 (00:27 +0100)
committerMarge Bot <eric+marge@anholt.net>
Mon, 23 Nov 2020 11:33:13 +0000 (11:33 +0000)
Assigning an array reg removes IR3_REG_ARRAY, which means that
definitions and uses can't be tracked back to the array register's name
and liveness for the components of the array aren't correctly
calculated. To fix this we delay assigning array registers until the
scalar pass.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7711>

src/freedreno/ir3/ir3_ra.c

index abf6652..81ff38a 100644 (file)
@@ -1184,6 +1184,13 @@ reg_assign(struct ir3_ra_ctx *ctx, struct ir3_register *reg,
 static bool
 should_assign(struct ir3_ra_ctx *ctx, struct ir3_instruction *instr)
 {
+       /* Array regs are precolored completely separately, and we need to keep
+        * their array-ness until the end to be able to compute the array reg's
+        * live interval in the scalar pass.
+        */
+       if (instr->regs[0]->flags & IR3_REG_ARRAY)
+               return ctx->scalar_pass;
+
        if ((instr->opc == OPC_META_SPLIT) &&
                        (util_bitcount(instr->regs[1]->wrmask) > 1))
                return !ctx->scalar_pass;
@@ -1207,15 +1214,14 @@ ra_block_alloc(struct ir3_ra_ctx *ctx, struct ir3_block *block)
                foreach_src_n (reg, n, instr) {
                        struct ir3_instruction *src = reg->instr;
 
-                       if (src && !should_assign(ctx, src) && !should_assign(ctx, instr))
-                               continue;
-
                        if (src && should_assign(ctx, instr))
                                reg_assign(ctx, src->regs[0], src);
 
                        /* Note: reg->instr could be null for IR3_REG_ARRAY */
-                       if (src || (reg->flags & IR3_REG_ARRAY))
+                       if (((reg->flags & IR3_REG_ARRAY) && ctx->scalar_pass) ||
+                               (src && should_assign(ctx, src))) {
                                reg_assign(ctx, instr->regs[n+1], src);
+                       }
                }
        }