pan/bi: Translate phis from NIR
authorAlyssa Rosenzweig <alyssa@collabora.com>
Mon, 9 May 2022 21:17:31 +0000 (17:17 -0400)
committerMarge Bot <emma+marge@anholt.net>
Fri, 2 Sep 2022 16:03:23 +0000 (16:03 +0000)
Code lifted from AGX, which in turn is based on ir3 and aco.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17794>

src/panfrost/bifrost/bifrost_compile.c
src/panfrost/bifrost/compiler.h

index 3712cae..04a9735 100644 (file)
@@ -3933,6 +3933,55 @@ bi_emit_tex(bi_builder *b, nir_tex_instr *instr)
 }
 
 static void
+bi_emit_phi(bi_builder *b, nir_phi_instr *instr)
+{
+        unsigned nr_srcs = exec_list_length(&instr->srcs);
+        bi_instr *I = bi_phi_to(b, bi_dest_index(&instr->dest), nr_srcs);
+
+        /* Deferred */
+        I->phi = instr;
+}
+
+/* Look up the AGX block corresponding to a given NIR block. Used when
+ * translating phi nodes after emitting all blocks.
+ */
+static bi_block *
+bi_from_nir_block(bi_context *ctx, nir_block *block)
+{
+        return ctx->indexed_nir_blocks[block->index];
+}
+
+static void
+bi_emit_phi_deferred(bi_context *ctx, bi_block *block, bi_instr *I)
+{
+        nir_phi_instr *phi = I->phi;
+
+        /* Guaranteed by lower_phis_to_scalar */
+        assert(phi->dest.ssa.num_components == 1);
+
+        nir_foreach_phi_src(src, phi) {
+                bi_block *pred = bi_from_nir_block(ctx, src->pred);
+                unsigned i = bi_predecessor_index(block, pred);
+                assert(i < I->nr_srcs);
+
+                I->src[i] = bi_src_index(&src->src);
+        }
+
+        I->phi = NULL;
+}
+
+static void
+bi_emit_phis_deferred(bi_context *ctx)
+{
+        bi_foreach_block(ctx, block) {
+                bi_foreach_instr_in_block(block, I) {
+                        if (I->op == BI_OPCODE_PHI)
+                                bi_emit_phi_deferred(ctx, block, I);
+                }
+        }
+}
+
+static void
 bi_emit_instr(bi_builder *b, struct nir_instr *instr)
 {
         switch (instr->type) {
@@ -3956,6 +4005,10 @@ bi_emit_instr(bi_builder *b, struct nir_instr *instr)
                 bi_emit_jump(b, nir_instr_as_jump(instr));
                 break;
 
+        case nir_instr_type_phi:
+                bi_emit_phi(b, nir_instr_as_phi(instr));
+                break;
+
         default:
                 unreachable("should've been lowered");
         }
@@ -3986,6 +4039,8 @@ emit_block(bi_context *ctx, nir_block *block)
 
         bi_builder _b = bi_init_builder(ctx, bi_after_block(ctx->current_block));
 
+        ctx->indexed_nir_blocks[block->index] = ctx->current_block;
+
         nir_foreach_instr(instr, block) {
                 bi_emit_instr(&_b, instr);
         }
@@ -4989,10 +5044,16 @@ bi_compile_variant_nir(nir_shader *nir,
                 if (!func->impl)
                         continue;
 
+                nir_index_blocks(func->impl);
+
+                ctx->indexed_nir_blocks =
+                        rzalloc_array(ctx, bi_block *, func->impl->num_blocks);
+
                 ctx->ssa_alloc += func->impl->ssa_alloc;
                 ctx->reg_alloc += func->impl->reg_alloc;
 
                 emit_cf_list(ctx, &func->impl->body);
+                bi_emit_phis_deferred(ctx);
                 break; /* TODO: Multi-function shaders */
         }
 
index 2d70b2f..9ca858e 100644 (file)
@@ -378,8 +378,15 @@ typedef struct {
         uint8_t nr_srcs;
         uint8_t nr_dests;
 
-        /* For a branch */
-        struct bi_block *branch_target;
+        union {
+                /* For a branch */
+                struct bi_block *branch_target;
+
+                /* For a phi node that hasn't been translated yet. This is only
+                 * used during NIR->BIR
+                 */
+                nir_phi_instr *phi;
+        };
 
         /* These don't fit neatly with anything else.. */
         enum bi_register_format register_format;
@@ -810,6 +817,7 @@ typedef struct {
        bi_block *after_block;
        bi_block *break_block;
        bi_block *continue_block;
+       bi_block **indexed_nir_blocks;
        bool emitted_atest;
 
        /* During NIR->BIR, the coverage bitmap. If this is NULL, the default