mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-17 16:08:06 +02:00
nir/builder: Add support for easily building control-flow
Each of the pop functions (and push_else) take a control flow parameter as their second argument. If NULL, it assumes that the builder is in a block that's a direct child of the control-flow node you want to pop off the virtual stack. This is what 90% of consumers will want. The SPIR-V pass, however, is a bit more "creative" about how it walks the CFG and it needs to be able to pop multiple levels at a time, hence the argument. Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
This commit is contained in:
parent
d5b355ce5f
commit
e27c716ad7
1 changed files with 95 additions and 0 deletions
|
|
@ -81,6 +81,101 @@ nir_builder_cf_insert(nir_builder *build, nir_cf_node *cf)
|
|||
nir_cf_node_insert(build->cursor, cf);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
nir_builder_is_inside_cf(nir_builder *build, nir_cf_node *cf_node)
|
||||
{
|
||||
nir_block *block = nir_cursor_current_block(build->cursor);
|
||||
for (nir_cf_node *n = &block->cf_node; n; n = n->parent) {
|
||||
if (n == cf_node)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline nir_if *
|
||||
nir_push_if(nir_builder *build, nir_ssa_def *condition)
|
||||
{
|
||||
nir_if *nif = nir_if_create(build->shader);
|
||||
nif->condition = nir_src_for_ssa(condition);
|
||||
nir_builder_cf_insert(build, &nif->cf_node);
|
||||
build->cursor = nir_before_cf_list(&nif->then_list);
|
||||
return nif;
|
||||
}
|
||||
|
||||
static inline nir_if *
|
||||
nir_push_else(nir_builder *build, nir_if *nif)
|
||||
{
|
||||
if (nif) {
|
||||
assert(nir_builder_is_inside_cf(build, &nif->cf_node));
|
||||
} else {
|
||||
nir_block *block = nir_cursor_current_block(build->cursor);
|
||||
nif = nir_cf_node_as_if(block->cf_node.parent);
|
||||
}
|
||||
build->cursor = nir_before_cf_list(&nif->else_list);
|
||||
return nif;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_pop_if(nir_builder *build, nir_if *nif)
|
||||
{
|
||||
if (nif) {
|
||||
assert(nir_builder_is_inside_cf(build, &nif->cf_node));
|
||||
} else {
|
||||
nir_block *block = nir_cursor_current_block(build->cursor);
|
||||
nif = nir_cf_node_as_if(block->cf_node.parent);
|
||||
}
|
||||
build->cursor = nir_after_cf_node(&nif->cf_node);
|
||||
}
|
||||
|
||||
static inline nir_ssa_def *
|
||||
nir_if_phi(nir_builder *build, nir_ssa_def *then_def, nir_ssa_def *else_def)
|
||||
{
|
||||
nir_block *block = nir_cursor_current_block(build->cursor);
|
||||
nir_if *nif = nir_cf_node_as_if(nir_cf_node_prev(&block->cf_node));
|
||||
|
||||
nir_phi_instr *phi = nir_phi_instr_create(build->shader);
|
||||
|
||||
nir_phi_src *src = ralloc(phi, nir_phi_src);
|
||||
src->pred = nir_if_last_then_block(nif);
|
||||
src->src = nir_src_for_ssa(then_def);
|
||||
exec_list_push_tail(&phi->srcs, &src->node);
|
||||
|
||||
src = ralloc(phi, nir_phi_src);
|
||||
src->pred = nir_if_last_else_block(nif);
|
||||
src->src = nir_src_for_ssa(else_def);
|
||||
exec_list_push_tail(&phi->srcs, &src->node);
|
||||
|
||||
assert(then_def->num_components == else_def->num_components);
|
||||
assert(then_def->bit_size == else_def->bit_size);
|
||||
nir_ssa_dest_init(&phi->instr, &phi->dest,
|
||||
then_def->num_components, then_def->bit_size, NULL);
|
||||
|
||||
nir_builder_instr_insert(build, &phi->instr);
|
||||
|
||||
return &phi->dest.ssa;
|
||||
}
|
||||
|
||||
static inline nir_loop *
|
||||
nir_push_loop(nir_builder *build)
|
||||
{
|
||||
nir_loop *loop = nir_loop_create(build->shader);
|
||||
nir_builder_cf_insert(build, &loop->cf_node);
|
||||
build->cursor = nir_before_cf_list(&loop->body);
|
||||
return loop;
|
||||
}
|
||||
|
||||
static inline void
|
||||
nir_pop_loop(nir_builder *build, nir_loop *loop)
|
||||
{
|
||||
if (loop) {
|
||||
assert(nir_builder_is_inside_cf(build, &loop->cf_node));
|
||||
} else {
|
||||
nir_block *block = nir_cursor_current_block(build->cursor);
|
||||
loop = nir_cf_node_as_loop(block->cf_node.parent);
|
||||
}
|
||||
build->cursor = nir_after_cf_node(&loop->cf_node);
|
||||
}
|
||||
|
||||
static inline nir_ssa_def *
|
||||
nir_ssa_undef(nir_builder *build, unsigned num_components, unsigned bit_size)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue