[Mesa-dev] [PATCH 1/8] nir/builder: Add support for easily building control-flow

Samuel Iglesias Gonsálvez siglesias at igalia.com
Fri Feb 24 14:05:57 UTC 2017



On 24/02/17 02:14, Jason Ekstrand wrote:
> 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.
> ---
>  src/compiler/nir/nir_builder.h | 95 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 95 insertions(+)
> 
> diff --git a/src/compiler/nir/nir_builder.h b/src/compiler/nir/nir_builder.h
> index 194d327..2eaa025 100644
> --- a/src/compiler/nir/nir_builder.h
> +++ b/src/compiler/nir/nir_builder.h
> @@ -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);

Is this fine? In the places you replace code with this function, there
was nir_after_cf_list(&nif->then_list), and same for the others.

Sam

> +   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)
>  {
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 862 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170224/a62806a2/attachment-0001.sig>


More information about the mesa-dev mailing list