agx: Implement emit_if the simplest way
authorAlyssa Rosenzweig <alyssa@collabora.com>
Sun, 23 May 2021 21:26:50 +0000 (17:26 -0400)
committerAlyssa Rosenzweig <alyssa@rosenzweig.io>
Sun, 30 May 2021 19:53:35 +0000 (01:23 +0530)
Lots of optimizations are possible from here.

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

src/asahi/compiler/agx_compile.c

index d3fb649..c9ab2d3 100644 (file)
@@ -743,10 +743,41 @@ emit_block(agx_context *ctx, nir_block *block)
    return blk;
 }
 
+static agx_block *
+emit_cf_list(agx_context *ctx, struct exec_list *list);
+
+/* Emit if-else as
+ *
+ *    if_icmp cond != 0
+ *       ...
+ *    else_icmp cond == 0
+ *       ...
+ *    pop_exec
+ *
+ * This is not usually optimal, but it's a start.
+ */
+
 static void
 emit_if(agx_context *ctx, nir_if *nif)
 {
-   unreachable("if-statements todo");
+   agx_builder _b = agx_init_builder(ctx, agx_after_block(ctx->current_block));
+   agx_index cond = agx_src_index(&nif->condition);
+
+   agx_if_icmp(&_b, cond, agx_zero(), 1, AGX_ICOND_UEQ, true);
+   ctx->loop_nesting++;
+
+   /* Emit the two subblocks. */
+   emit_cf_list(ctx, &nif->then_list);
+
+   _b.cursor = agx_after_block(ctx->current_block);
+   agx_else_icmp(&_b, cond, agx_zero(), 1, AGX_ICOND_UEQ, false);
+
+   emit_cf_list(ctx, &nif->else_list);
+   _b.cursor = agx_after_block(ctx->current_block);
+   agx_pop_exec(&_b, 1);
+   ctx->loop_nesting--;
+
+   /* TODO: control flow graph(s) */
 }
 
 static void