pan/bi: Handle loops when ingesting CFG
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 5 Mar 2020 22:03:53 +0000 (17:03 -0500)
committerMarge Bot <eric+marge@anholt.net>
Sat, 7 Mar 2020 00:37:39 +0000 (00:37 +0000)
Not very useful without also handling breaks and continues, of course.
We use the strategy from v3d (vir_to_nir) instead of Midgard's, since
the latter is mildly insane. I mean, it passes deqp but...

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

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

index 361c8fcdaa2697b24bb84ba9cee04c0a916a7087..01f20c44d5579d6106ed2faa81189e4e0b120a1f 100644 (file)
@@ -174,6 +174,36 @@ emit_if(bi_context *ctx, nir_if *nif)
         bi_block_add_successor(end_else_block, ctx->after_block); /* fallthrough */
 }
 
+static void
+emit_loop(bi_context *ctx, nir_loop *nloop)
+{
+        /* Remember where we are */
+        bi_block *start_block = ctx->current_block;
+
+        bi_block *saved_break = ctx->break_block;
+        bi_block *saved_continue = ctx->continue_block;
+
+        ctx->continue_block = create_empty_block(ctx);
+        ctx->break_block = create_empty_block(ctx);
+        ctx->after_block = ctx->continue_block;
+
+        /* Emit the body itself */
+        emit_cf_list(ctx, &nloop->body);
+
+        /* Branch back to loop back */
+        bi_instruction *br_back = bi_emit_branch(ctx);
+        br_back->branch.target = ctx->continue_block;
+        bi_block_add_successor(start_block, ctx->continue_block);
+        bi_block_add_successor(ctx->current_block, ctx->continue_block);
+
+        ctx->after_block = ctx->break_block;
+
+        /* Pop off */
+        ctx->break_block = saved_break;
+        ctx->continue_block = saved_continue;
+        ++ctx->loop_count;
+}
+
 static bi_block *
 emit_cf_list(bi_context *ctx, struct exec_list *list)
 {
@@ -194,11 +224,9 @@ emit_cf_list(bi_context *ctx, struct exec_list *list)
                         emit_if(ctx, nir_cf_node_as_if(node));
                         break;
 
-#if 0
                 case nir_cf_node_loop:
                         emit_loop(ctx, nir_cf_node_as_loop(node));
                         break;
-#endif
 
                 default:
                         unreachable("Unknown control flow");
index d57bdc2c9cc72c2a35c7293f4e8fd241c460353f..c63f175f5424b6a2a3c40a323af02ca0a8255f33 100644 (file)
@@ -325,9 +325,12 @@ typedef struct {
        bi_block *current_block;
        unsigned block_name_count;
        bi_block *after_block;
+       bi_block *break_block;
+       bi_block *continue_block;
 
        /* Stats for shader-db */
        unsigned instruction_count;
+       unsigned loop_count;
 } bi_context;
 
 static inline bi_instruction *