Mesa (master): nir: Add a structured flag to nir_shader

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Aug 14 20:55:37 UTC 2020


Module: Mesa
Branch: master
Commit: 4768ea1a77ad7559004949d0cf1eb7af9a4499d9
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4768ea1a77ad7559004949d0cf1eb7af9a4499d9

Author: Karol Herbst <kherbst at redhat.com>
Date:   Wed Oct 23 20:42:40 2019 +0200

nir: Add a structured flag to nir_shader

v2 (Jason Ekstrand):
 - Make "structured" a property of nir_function_impl not nir_shader
 - More validation and asserts

Signed-off-by: Karol Herbst <kherbst at redhat.com>
Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2401>

---

 src/compiler/nir/nir.c           |  5 +++++
 src/compiler/nir/nir.h           |  6 ++++++
 src/compiler/nir/nir_serialize.c |  4 ++++
 src/compiler/nir/nir_validate.c  | 16 +++++++++++++---
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index e17b11cdd4a..070c2751a5b 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -295,6 +295,7 @@ nir_function_impl_create_bare(nir_shader *shader)
    impl->reg_alloc = 0;
    impl->ssa_alloc = 0;
    impl->valid_metadata = nir_metadata_none;
+   impl->structured = true;
 
    /* create start & end blocks */
    nir_block *start_block = nir_block_create(shader);
@@ -1600,6 +1601,8 @@ nir_block_cf_tree_next(nir_block *block)
       return NULL;
    }
 
+   assert(nir_cf_node_get_function(&block->cf_node)->structured);
+
    nir_cf_node *cf_next = nir_cf_node_next(&block->cf_node);
    if (cf_next)
       return nir_cf_node_cf_tree_first(cf_next);
@@ -1636,6 +1639,8 @@ nir_block_cf_tree_prev(nir_block *block)
       return NULL;
    }
 
+   assert(nir_cf_node_get_function(&block->cf_node)->structured);
+
    nir_cf_node *cf_prev = nir_cf_node_prev(&block->cf_node);
    if (cf_prev)
       return nir_cf_node_cf_tree_last(cf_prev);
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 0f3578e7f8a..281a5b17898 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2775,6 +2775,12 @@ typedef struct {
    /* total number of basic blocks, only valid when block_index_dirty = false */
    unsigned num_blocks;
 
+   /** True if this nir_function_impl uses structured control-flow
+    *
+    * Structured nir_function_impls have different validation rules.
+    */
+   bool structured;
+
    nir_metadata valid_metadata;
 } nir_function_impl;
 
diff --git a/src/compiler/nir/nir_serialize.c b/src/compiler/nir/nir_serialize.c
index 8baa735def0..b2b3afb151e 100644
--- a/src/compiler/nir/nir_serialize.c
+++ b/src/compiler/nir/nir_serialize.c
@@ -1901,6 +1901,8 @@ read_cf_list(read_ctx *ctx, struct exec_list *cf_list)
 static void
 write_function_impl(write_ctx *ctx, const nir_function_impl *fi)
 {
+   blob_write_uint8(ctx->blob, fi->structured);
+
    write_var_list(ctx, &fi->locals);
    write_reg_list(ctx, &fi->registers);
    blob_write_uint32(ctx->blob, fi->reg_alloc);
@@ -1915,6 +1917,8 @@ read_function_impl(read_ctx *ctx, nir_function *fxn)
    nir_function_impl *fi = nir_function_impl_create_bare(ctx->nir);
    fi->function = fxn;
 
+   fi->structured = blob_read_uint8(ctx->blob);
+
    read_var_list(ctx, &fi->locals);
    read_reg_list(ctx, &fi->registers);
    fi->reg_alloc = blob_read_uint32(ctx->blob);
diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c
index 6d498b0b154..2f6e312826e 100644
--- a/src/compiler/nir/nir_validate.c
+++ b/src/compiler/nir/nir_validate.c
@@ -780,6 +780,7 @@ validate_jump_instr(nir_jump_instr *instr, validate_state *state)
       break;
 
    case nir_jump_break:
+      validate_assert(state, state->impl->structured);
       validate_assert(state, state->loop != NULL);
       if (state->loop) {
          nir_block *after =
@@ -790,6 +791,7 @@ validate_jump_instr(nir_jump_instr *instr, validate_state *state)
       break;
 
    case nir_jump_continue:
+      validate_assert(state, state->impl->structured);
       validate_assert(state, state->loop != NULL);
       if (state->loop) {
          nir_block *first = nir_loop_first_block(state->loop);
@@ -926,7 +928,9 @@ validate_block(nir_block *block, validate_state *state)
              pred->successors[1] == block);
    }
 
-   if (!nir_block_ends_in_jump(block)) {
+   if (!state->impl->structured) {
+      validate_assert(state, nir_block_ends_in_jump(block));
+   } else if (!nir_block_ends_in_jump(block)) {
       nir_cf_node *next = nir_cf_node_next(&block->cf_node);
       if (next == NULL) {
          switch (state->parent_node->type) {
@@ -962,12 +966,14 @@ validate_block(nir_block *block, validate_state *state)
                    nir_if_first_then_block(if_stmt));
             validate_assert(state, block->successors[1] ==
                    nir_if_first_else_block(if_stmt));
-         } else {
-            validate_assert(state, next->type == nir_cf_node_loop);
+         } else if (next->type == nir_cf_node_loop) {
             nir_loop *loop = nir_cf_node_as_loop(next);
             validate_assert(state, block->successors[0] ==
                    nir_loop_first_block(loop));
             validate_assert(state, block->successors[1] == NULL);
+         } else {
+            validate_assert(state,
+               !"Structured NIR cannot have consecutive blocks");
          }
       }
    }
@@ -976,6 +982,8 @@ validate_block(nir_block *block, validate_state *state)
 static void
 validate_if(nir_if *if_stmt, validate_state *state)
 {
+   validate_assert(state, state->impl->structured);
+
    state->if_stmt = if_stmt;
 
    validate_assert(state, !exec_node_is_head_sentinel(if_stmt->cf_node.node.prev));
@@ -1011,6 +1019,8 @@ validate_if(nir_if *if_stmt, validate_state *state)
 static void
 validate_loop(nir_loop *loop, validate_state *state)
 {
+   validate_assert(state, state->impl->structured);
+
    validate_assert(state, !exec_node_is_head_sentinel(loop->cf_node.node.prev));
    nir_cf_node *prev_node = nir_cf_node_prev(&loop->cf_node);
    validate_assert(state, prev_node->type == nir_cf_node_block);



More information about the mesa-commit mailing list