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@redhat.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/2401>
This commit is contained in:
@@ -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);
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user