[Mesa-dev] [PATCH 2/9] nir: insert ssa_undef instructions when cleanup up defs/uses

Jason Ekstrand jason at jlekstrand.net
Fri May 8 22:52:20 PDT 2015


On Fri, May 8, 2015 at 10:03 PM, Connor Abbott <cwabbott0 at gmail.com> wrote:
> The point of cleanup_defs_uses() is to make an instruction safe to
> remove by removing any references that the rest of the shader may have
> to it. Previously, it was handling register use/def sets and removing
> the instruction from the use sets of any SSA sources it had, but if the
> instruction defined an SSA value that was used by other instructions it
> wasn't doing anything. This was ok, since we were always careful to make
> sure that no removed instruction ever had any uses, but now we want to
> start removing unreachable instruction which might still be used in
> reachable parts of the code. In that case, the value that any uses get
> is undefined since the instruction never actually executes, so we can
> just replace the instruction with an ssa_undef_instr.
>
> Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
> ---
>  src/glsl/nir/nir.c | 47 ++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 34 insertions(+), 13 deletions(-)
>
> diff --git a/src/glsl/nir/nir.c b/src/glsl/nir/nir.c
> index f03e80a..362ac30 100644
> --- a/src/glsl/nir/nir.c
> +++ b/src/glsl/nir/nir.c
> @@ -1206,26 +1206,29 @@ stitch_blocks(nir_block *before, nir_block *after)
>  }
>
>  static void
> -remove_defs_uses(nir_instr *instr);
> +remove_defs_uses(nir_instr *instr, nir_function_impl *impl);
>
>  static void
> -cleanup_cf_node(nir_cf_node *node)
> +cleanup_cf_node(nir_cf_node *node, nir_function_impl *impl)
>  {
>     switch (node->type) {
>     case nir_cf_node_block: {
>        nir_block *block = nir_cf_node_as_block(node);
>        /* We need to walk the instructions and clean up defs/uses */
> -      nir_foreach_instr(block, instr)
> -         remove_defs_uses(instr);
> +      nir_foreach_instr(block, instr) {
> +         if (instr->type == nir_instr_type_jump)
> +            handle_remove_jump(block, nir_instr_as_jump(instr)->type);
> +         remove_defs_uses(instr, impl);
> +      }

This looks like an unrelated change.  Maybe split that out?  The rest
of the patch looks plausible.
--Jason

>        break;
>     }
>
>     case nir_cf_node_if: {
>        nir_if *if_stmt = nir_cf_node_as_if(node);
>        foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list)
> -         cleanup_cf_node(child);
> +         cleanup_cf_node(child, impl);
>        foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list)
> -         cleanup_cf_node(child);
> +         cleanup_cf_node(child, impl);
>
>        list_del(&if_stmt->condition.use_link);
>        break;
> @@ -1234,13 +1237,12 @@ cleanup_cf_node(nir_cf_node *node)
>     case nir_cf_node_loop: {
>        nir_loop *loop = nir_cf_node_as_loop(node);
>        foreach_list_typed(nir_cf_node, child, node, &loop->body)
> -         cleanup_cf_node(child);
> +         cleanup_cf_node(child, impl);
>        break;
>     }
>     case nir_cf_node_function: {
> -      nir_function_impl *impl = nir_cf_node_as_function(node);
>        foreach_list_typed(nir_cf_node, child, node, &impl->body)
> -         cleanup_cf_node(child);
> +         cleanup_cf_node(child, impl);
>        break;
>     }
>     default:
> @@ -1254,6 +1256,8 @@ nir_cf_node_remove(nir_cf_node *node)
>     nir_function_impl *impl = nir_cf_node_get_function(node);
>     nir_metadata_preserve(impl, nir_metadata_none);
>
> +   cleanup_cf_node(node, impl);
> +
>     if (node->type == nir_cf_node_block) {
>        /*
>         * Basic blocks can't really be removed by themselves, since they act as
> @@ -1275,8 +1279,6 @@ nir_cf_node_remove(nir_cf_node *node)
>        exec_node_remove(&node->node);
>        stitch_blocks(before_block, after_block);
>     }
> -
> -   cleanup_cf_node(node);
>  }
>
>  static bool
> @@ -1443,16 +1445,35 @@ remove_def_cb(nir_dest *dest, void *state)
>     return true;
>  }
>
> +static bool
> +remove_ssa_def_cb(nir_ssa_def *def, void *state)
> +{
> +   nir_function_impl *impl = state;
> +   nir_shader *shader = impl->overload->function->shader;
> +
> +   if (!list_empty(&def->uses) || !list_empty(&def->if_uses)) {
> +      nir_ssa_undef_instr *undef =
> +         nir_ssa_undef_instr_create(shader, def->num_components);
> +      nir_instr_insert_before_cf_list(&impl->body, &undef->instr);
> +      nir_ssa_def_rewrite_uses(def, nir_src_for_ssa(&undef->def), shader);
> +   }
> +
> +   return true;
> +}
> +
> +
>  static void
> -remove_defs_uses(nir_instr *instr)
> +remove_defs_uses(nir_instr *instr, nir_function_impl *impl)
>  {
>     nir_foreach_dest(instr, remove_def_cb, instr);
>     nir_foreach_src(instr, remove_use_cb, instr);
> +   nir_foreach_ssa_def(instr, remove_ssa_def_cb, impl);
>  }
>
>  void nir_instr_remove(nir_instr *instr)
>  {
> -   remove_defs_uses(instr);
> +   nir_function_impl *impl = nir_cf_node_get_function(&instr->block->cf_node);
> +   remove_defs_uses(instr, impl);
>     exec_node_remove(&instr->node);
>
>     if (instr->type == nir_instr_type_jump) {
> --
> 2.1.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list