agx: Lower p_split after RA
authorAlyssa Rosenzweig <alyssa@rosenzweig.io>
Wed, 13 Apr 2022 00:43:32 +0000 (20:43 -0400)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Mon, 2 May 2022 02:00:00 +0000 (22:00 -0400)
Using existing regalloc infrastructure.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16268>

src/asahi/compiler/agx_register_allocate.c

index ffffb1f..c5fc4d7 100644 (file)
@@ -184,6 +184,8 @@ agx_ra(agx_context *ctx)
 
    agx_foreach_instr_global_safe(ctx, ins) {
       /* Lower away RA pseudo-instructions */
+      agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
+
       if (ins->op == AGX_OPCODE_P_COMBINE) {
          unsigned base = agx_index_to_reg(ssa_to_reg, ins->dest[0]);
          unsigned width = agx_size_align_16(ins->dest[0].size);
@@ -203,9 +205,8 @@ agx_ra(agx_context *ctx)
             };
          }
 
-         /* Lower away the copies pseudo-instruction */
-         agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
          agx_emit_parallel_copies(&b, copies, n);
+         agx_remove_instruction(ins);
          continue;
       } else if (ins->op == AGX_OPCODE_P_EXTRACT) {
          /* Uses the destination size */
@@ -214,13 +215,36 @@ agx_ra(agx_context *ctx)
          unsigned right = agx_index_to_reg(ssa_to_reg, ins->src[0]) + (size * ins->imm);
 
          if (left != right) {
-            agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
             agx_mov_to(&b, agx_register(left, ins->dest[0].size),
                   agx_register(right, ins->src[0].size));
          }
 
          agx_remove_instruction(ins);
          continue;
+      } else if (ins->op == AGX_OPCODE_P_SPLIT) {
+         unsigned base = agx_index_to_reg(ssa_to_reg, ins->src[0]);
+         unsigned width = agx_size_align_16(ins->src[0].size);
+
+         struct agx_copy copies[4];
+         unsigned n = 0;
+
+         /* Move the sources */
+         for (unsigned i = 0; i < 4; ++i) {
+            if (agx_is_null(ins->dest[i])) continue;
+            assert(ins->dest[i].size == ins->src[0].size);
+
+            copies[n++] = (struct agx_copy) {
+               .dest = agx_index_to_reg(ssa_to_reg, ins->dest[i]),
+               .src = base + (i * width),
+               .size = ins->dest[i].size
+            };
+         }
+
+         /* Lower away */
+         agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
+         agx_emit_parallel_copies(&b, copies, n);
+         agx_remove_instruction(ins);
+         continue;
       }
 
       agx_foreach_src(ins, s) {