[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