[Mesa-dev] [PATCH] gallium/ttn: Simplify control flow stack handling.
Kenneth Graunke
kenneth at whitecape.org
Wed Sep 9 15:01:42 PDT 2015
Instead of storing insertion points, we simply store a single stack of
control flow nodes representing the nir_if / nir_loop we're currently
filling in.
When handling ELSE, we can simply switch to the current nir_if's
else_list. When handling ENDIF or ENDLOOP, we move the cursor to
after the current if/loop, and pop it off since we're done.
This has a few advantages:
- We only need one stack entry for IF/ELSE/ENDIF instead of two.
- Each stack entry is sizeof(nir_cf_node *), which is smaller than
sizeof(nir_cursor) (this is how it used to be).
- We only need one stack, not two.
Lightly tested with ir3_compiler - both TGSI programs Rob gave me
generate identical code before and after this patch.
Cc: Rob Clark <robclark at freedesktop.org>
Cc: Eric Anholt <eric at anholt.net>
Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
src/gallium/auxiliary/nir/tgsi_to_nir.c | 53 ++++++++++++---------------------
1 file changed, 19 insertions(+), 34 deletions(-)
diff --git a/src/gallium/auxiliary/nir/tgsi_to_nir.c b/src/gallium/auxiliary/nir/tgsi_to_nir.c
index cccc560..41aca6b 100644
--- a/src/gallium/auxiliary/nir/tgsi_to_nir.c
+++ b/src/gallium/auxiliary/nir/tgsi_to_nir.c
@@ -65,25 +65,13 @@ struct ttn_compile {
nir_register *addr_reg;
/**
- * Stack of nir_cursors where instructions should be pushed as we pop
- * back out of the control flow stack.
+ * Stack of CF nodes.
*
- * For each IF/ELSE/ENDIF block, if_stack[if_stack_pos] has where the else
- * instructions should be placed, and if_stack[if_stack_pos - 1] has where
- * the next instructions outside of the if/then/else block go.
+ * The top element stores the nir_if or nir_loop that we're currently
+ * emitting code for.
*/
- nir_cursor *if_stack;
- unsigned if_stack_pos;
-
- /**
- * Stack of nir_cursors where instructions should be pushed as we pop
- * back out of the control flow stack.
- *
- * loop_stack[loop_stack_pos - 1] contains the cf_node_list for the outside
- * of the loop.
- */
- nir_cursor *loop_stack;
- unsigned loop_stack_pos;
+ nir_cf_node **cf_stack;
+ unsigned cf_stack_pos;
/* How many TGSI_FILE_IMMEDIATE vec4s have been parsed so far. */
unsigned next_imm;
@@ -931,13 +919,10 @@ ttn_if(struct ttn_compile *c, nir_ssa_def *src, bool is_uint)
}
nir_builder_cf_insert(b, &if_stmt->cf_node);
- c->if_stack[c->if_stack_pos] = nir_after_cf_node(&if_stmt->cf_node);
- c->if_stack_pos++;
-
b->cursor = nir_after_cf_list(&if_stmt->then_list);
- c->if_stack[c->if_stack_pos] = nir_after_cf_list(&if_stmt->else_list);
- c->if_stack_pos++;
+ c->cf_stack[c->cf_stack_pos] = &if_stmt->cf_node;
+ c->cf_stack_pos++;
}
static void
@@ -945,7 +930,8 @@ ttn_else(struct ttn_compile *c)
{
nir_builder *b = &c->build;
- b->cursor = c->if_stack[c->if_stack_pos - 1];
+ nir_if *if_node = nir_cf_node_as_if(c->cf_stack[c->cf_stack_pos - 1]);
+ b->cursor = nir_after_cf_list(&if_node->else_list);
}
static void
@@ -953,8 +939,8 @@ ttn_endif(struct ttn_compile *c)
{
nir_builder *b = &c->build;
- c->if_stack_pos -= 2;
- b->cursor = c->if_stack[c->if_stack_pos];
+ c->cf_stack_pos--;
+ b->cursor = nir_after_cf_node(c->cf_stack[c->cf_stack_pos]);
}
static void
@@ -965,8 +951,8 @@ ttn_bgnloop(struct ttn_compile *c)
nir_loop *loop = nir_loop_create(b->shader);
nir_builder_cf_insert(b, &loop->cf_node);
- c->loop_stack[c->loop_stack_pos] = nir_after_cf_node(&loop->cf_node);
- c->loop_stack_pos++;
+ c->cf_stack[c->cf_stack_pos] = &loop->cf_node;
+ c->cf_stack_pos++;
b->cursor = nir_after_cf_list(&loop->body);
}
@@ -990,8 +976,8 @@ ttn_endloop(struct ttn_compile *c)
{
nir_builder *b = &c->build;
- c->loop_stack_pos--;
- b->cursor = c->loop_stack[c->loop_stack_pos];
+ c->cf_stack_pos--;
+ b->cursor = nir_after_cf_node(c->cf_stack[c->cf_stack_pos]);
}
static void
@@ -1817,11 +1803,10 @@ tgsi_to_nir(const void *tgsi_tokens,
c->num_samp_types = scan.file_max[TGSI_FILE_SAMPLER_VIEW] + 1;
c->samp_types = rzalloc_array(c, nir_alu_type, c->num_samp_types);
- c->if_stack = rzalloc_array(c, nir_cursor,
- (scan.opcode_count[TGSI_OPCODE_IF] +
- scan.opcode_count[TGSI_OPCODE_UIF]) * 2);
- c->loop_stack = rzalloc_array(c, nir_cursor,
- scan.opcode_count[TGSI_OPCODE_BGNLOOP]);
+ c->cf_stack = rzalloc_array(c, nir_cf_node *,
+ scan.opcode_count[TGSI_OPCODE_IF] +
+ scan.opcode_count[TGSI_OPCODE_UIF] +
+ scan.opcode_count[TGSI_OPCODE_BGNLOOP]);
ret = tgsi_parse_init(&parser, tgsi_tokens);
assert(ret == TGSI_PARSE_OK);
--
2.5.1
More information about the mesa-dev
mailing list