aboutsummaryrefslogtreecommitdiffstats
path: root/src/freedreno/ir3
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2018-12-05 10:51:16 -0500
committerRob Clark <[email protected]>2018-12-07 13:49:21 -0500
commit5c2c1f0a2d5cec771b6cbfadf43f44a632ff57fc (patch)
tree8e5ff7e1c8cce27bdad6fded08494c746cda3f18 /src/freedreno/ir3
parent9517037bdcd997fbffc0b5b07eede0e6a114ece3 (diff)
freedreno/ir3: track max flow control depth for a5xx/a6xx
Rather than just hard-coding BRANCHSTACK size. Signed-off-by: Rob Clark <[email protected]>
Diffstat (limited to 'src/freedreno/ir3')
-rw-r--r--src/freedreno/ir3/ir3_compiler_nir.c24
-rw-r--r--src/freedreno/ir3/ir3_context.h5
-rw-r--r--src/freedreno/ir3/ir3_shader.h4
3 files changed, 33 insertions, 0 deletions
diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c
index 6b33c1f8981..f8155747c52 100644
--- a/src/freedreno/ir3/ir3_compiler_nir.c
+++ b/src/freedreno/ir3/ir3_compiler_nir.c
@@ -2341,6 +2341,20 @@ emit_loop(struct ir3_context *ctx, nir_loop *nloop)
}
static void
+stack_push(struct ir3_context *ctx)
+{
+ ctx->stack++;
+ ctx->max_stack = MAX2(ctx->max_stack, ctx->stack);
+}
+
+static void
+stack_pop(struct ir3_context *ctx)
+{
+ compile_assert(ctx, ctx->stack > 0);
+ ctx->stack--;
+}
+
+static void
emit_cf_list(struct ir3_context *ctx, struct exec_list *list)
{
foreach_list_typed(nir_cf_node, node, node, list) {
@@ -2349,10 +2363,14 @@ emit_cf_list(struct ir3_context *ctx, struct exec_list *list)
emit_block(ctx, nir_cf_node_as_block(node));
break;
case nir_cf_node_if:
+ stack_push(ctx);
emit_if(ctx, nir_cf_node_as_if(node));
+ stack_pop(ctx);
break;
case nir_cf_node_loop:
+ stack_push(ctx);
emit_loop(ctx, nir_cf_node_as_loop(node));
+ stack_pop(ctx);
break;
case nir_cf_node_function:
ir3_context_error(ctx, "TODO\n");
@@ -2479,9 +2497,13 @@ emit_function(struct ir3_context *ctx, nir_function_impl *impl)
{
nir_metadata_require(impl, nir_metadata_block_index);
+ compile_assert(ctx, ctx->stack == 0);
+
emit_cf_list(ctx, &impl->body);
emit_block(ctx, impl->end_block);
+ compile_assert(ctx, ctx->stack == 0);
+
/* at this point, we should have a single empty block,
* into which we emit the 'end' instruction.
*/
@@ -3079,6 +3101,8 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler,
ir3_print(ir);
}
+ so->branchstack = ctx->max_stack;
+
/* Note that actual_in counts inputs that are not bary.f'd for FS: */
if (so->type == MESA_SHADER_VERTEX)
so->total_in = actual_in;
diff --git a/src/freedreno/ir3/ir3_context.h b/src/freedreno/ir3/ir3_context.h
index 63c5d8baaf9..99f43cb5ab6 100644
--- a/src/freedreno/ir3/ir3_context.h
+++ b/src/freedreno/ir3/ir3_context.h
@@ -86,6 +86,11 @@ struct ir3_context {
unsigned num_arrays;
+ /* Tracking for max level of flowcontrol (branchstack) needed
+ * by a5xx+:
+ */
+ unsigned stack, max_stack;
+
/* a common pattern for indirect addressing is to request the
* same address register multiple times. To avoid generating
* duplicate instruction sequences (which our backend does not
diff --git a/src/freedreno/ir3/ir3_shader.h b/src/freedreno/ir3/ir3_shader.h
index bc47160d6ea..418c77ae8b0 100644
--- a/src/freedreno/ir3/ir3_shader.h
+++ b/src/freedreno/ir3/ir3_shader.h
@@ -295,6 +295,10 @@ struct ir3_shader_variant {
struct ir3_info info;
struct ir3 *ir;
+ /* Levels of nesting of flow control:
+ */
+ unsigned branchstack;
+
/* the instructions length is in units of instruction groups
* (4 instructions for a3xx, 16 instructions for a4xx.. each
* instruction is 2 dwords):