nir: add Continue Construct to nir_loop
The added continue_list corresponds to the SPIR-V Continue Construct and serves as a converged control-flow construct and is executed after each continue statement and before the next iteration of the loop body. Also adds validation rules for loops with Continue Construct Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13962>
This commit is contained in:
committed by
Marge Bot
parent
e0c6ad1ce5
commit
d4b97bf3fa
@@ -77,6 +77,9 @@ typedef struct {
|
||||
/* the current loop being visited */
|
||||
nir_loop *loop;
|
||||
|
||||
/* weather the loop continue construct is being visited */
|
||||
bool in_loop_continue_construct;
|
||||
|
||||
/* the parent of the current cf node being visited */
|
||||
nir_cf_node *parent_node;
|
||||
|
||||
@@ -1073,6 +1076,7 @@ validate_jump_instr(nir_jump_instr *instr, validate_state *state)
|
||||
validate_assert(state, block->successors[1] == NULL);
|
||||
validate_assert(state, instr->target == NULL);
|
||||
validate_assert(state, instr->else_target == NULL);
|
||||
validate_assert(state, !state->in_loop_continue_construct);
|
||||
break;
|
||||
|
||||
case nir_jump_break:
|
||||
@@ -1092,12 +1096,13 @@ validate_jump_instr(nir_jump_instr *instr, validate_state *state)
|
||||
validate_assert(state, state->impl->structured);
|
||||
validate_assert(state, state->loop != NULL);
|
||||
if (state->loop) {
|
||||
nir_block *first = nir_loop_first_block(state->loop);
|
||||
validate_assert(state, block->successors[0] == first);
|
||||
nir_block *cont_block = nir_loop_continue_target(state->loop);
|
||||
validate_assert(state, block->successors[0] == cont_block);
|
||||
}
|
||||
validate_assert(state, block->successors[1] == NULL);
|
||||
validate_assert(state, instr->target == NULL);
|
||||
validate_assert(state, instr->else_target == NULL);
|
||||
validate_assert(state, !state->in_loop_continue_construct);
|
||||
break;
|
||||
|
||||
case nir_jump_goto:
|
||||
@@ -1242,6 +1247,7 @@ collect_blocks(struct exec_list *cf_list, validate_state *state)
|
||||
|
||||
case nir_cf_node_loop:
|
||||
collect_blocks(&nir_cf_node_as_loop(node)->body, state);
|
||||
collect_blocks(&nir_cf_node_as_loop(node)->continue_list, state);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1310,8 +1316,15 @@ validate_block(nir_block *block, validate_state *state)
|
||||
if (next == NULL) {
|
||||
switch (state->parent_node->type) {
|
||||
case nir_cf_node_loop: {
|
||||
nir_block *first = nir_loop_first_block(state->loop);
|
||||
validate_assert(state, block->successors[0] == first);
|
||||
if (block == nir_loop_last_block(state->loop)) {
|
||||
nir_block *cont = nir_loop_continue_target(state->loop);
|
||||
validate_assert(state, block->successors[0] == cont);
|
||||
} else {
|
||||
validate_assert(state, nir_loop_has_continue_construct(state->loop) &&
|
||||
block == nir_loop_last_continue_block(state->loop));
|
||||
nir_block *head = nir_loop_first_block(state->loop);
|
||||
validate_assert(state, block->successors[0] == head);
|
||||
}
|
||||
/* due to the hack for infinite loops, block->successors[1] may
|
||||
* point to the block after the loop.
|
||||
*/
|
||||
@@ -1421,14 +1434,21 @@ validate_loop(nir_loop *loop, validate_state *state)
|
||||
nir_cf_node *old_parent = state->parent_node;
|
||||
state->parent_node = &loop->cf_node;
|
||||
nir_loop *old_loop = state->loop;
|
||||
bool old_continue_construct = state->in_loop_continue_construct;
|
||||
state->loop = loop;
|
||||
state->in_loop_continue_construct = false;
|
||||
|
||||
foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) {
|
||||
validate_cf_node(cf_node, state);
|
||||
}
|
||||
|
||||
state->in_loop_continue_construct = true;
|
||||
foreach_list_typed(nir_cf_node, cf_node, node, &loop->continue_list) {
|
||||
validate_cf_node(cf_node, state);
|
||||
}
|
||||
state->in_loop_continue_construct = false;
|
||||
state->parent_node = old_parent;
|
||||
state->loop = old_loop;
|
||||
state->in_loop_continue_construct = old_continue_construct;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1742,6 +1762,7 @@ init_validate_state(validate_state *state)
|
||||
state->errors = _mesa_pointer_hash_table_create(state->mem_ctx);
|
||||
|
||||
state->loop = NULL;
|
||||
state->in_loop_continue_construct = false;
|
||||
state->instr = NULL;
|
||||
state->var = NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user