[Mesa-dev] [PATCH 2/2] nir: Optimize away IF statements with no body on either side.

Jason Ekstrand jason at jlekstrand.net
Thu Jul 7 01:44:21 UTC 2016


On Wed, Jul 6, 2016 at 5:12 PM, Eric Anholt <eric at anholt.net> wrote:

> Due to the rampant dead code elimination in coordinate shaders for vc4, we
> often end up with IFs that do nothing on either side.  In the
> loops-enabled build, shader-db gives:
>
> total instructions in shared programs: 125192 -> 119693 (-4.39%)
> instructions in affected programs:     30649 -> 25150 (-17.94%)
> total uniforms in shared programs: 38436 -> 37632 (-2.09%)
> uniforms in affected programs:     6168 -> 5364 (-13.04%)
> ---
>  src/compiler/nir/nir_opt_dead_cf.c | 41
> ++++++++++++++++++++++++++++++++++----
>  1 file changed, 37 insertions(+), 4 deletions(-)
>
> diff --git a/src/compiler/nir/nir_opt_dead_cf.c
> b/src/compiler/nir/nir_opt_dead_cf.c
> index 81c1b650da96..eb98dc9507fb 100644
> --- a/src/compiler/nir/nir_opt_dead_cf.c
> +++ b/src/compiler/nir/nir_opt_dead_cf.c
> @@ -60,6 +60,12 @@
>   * }
>   * ...
>   *
> + * We also delete IF statements with no instructions in either body:
> + *
> + * if (...) {
> + * } else {
> + * }
>

We already have a NIR pass that does exactly this called
opt_peephole_select.  From what I see with your pass, it doesn't properly
handle phi nodes that may occur after the if statement which is exactly
what the peephole_select pass is for.  Maybe that pass should just be
rolled into dead_cf?

--Jason


> + *
>   * Finally, we also handle removing useless loops, i.e. loops with no side
>   * effects and without any definitions that are used elsewhere. This case
> is a
>   * little different from the first two in that the code is actually run
> (it
> @@ -134,6 +140,32 @@ opt_constant_if(nir_if *if_stmt, bool condition)
>     nir_cf_node_remove(&if_stmt->cf_node);
>  }
>
> +/* If the nir_if has no instructions on either side, then we can delete
> the
> + * IF, and therefore also its use of the condition variable.
> + */
> +static bool
> +opt_empty_if(nir_if *if_stmt)
> +{
> +   nir_cf_node *then_node = nir_if_first_then_node(if_stmt);
> +   nir_cf_node *else_node = nir_if_first_else_node(if_stmt);
> +
> +   /* We can only have one block in each side, with no instructions in
> them */
> +   if (nir_if_last_then_node(if_stmt) != then_node)
> +      return false;
> +   if (nir_if_last_else_node(if_stmt) != else_node)
> +      return false;
> +   nir_block *then_block = nir_cf_node_as_block(then_node);
> +   nir_block *else_block = nir_cf_node_as_block(else_node);
> +   if (!exec_list_is_empty(&then_block->instr_list))
> +      return false;
> +   if (!exec_list_is_empty(&else_block->instr_list))
> +      return false;
> +
> +   nir_cf_node_remove(&if_stmt->cf_node);
> +
> +   return true;
> +}
> +
>  static bool
>  cf_node_has_side_effects(nir_cf_node *node)
>  {
> @@ -224,11 +256,12 @@ dead_cf_block(nir_block *block)
>        nir_const_value *const_value =
>           nir_src_as_const_value(following_if->condition);
>
> -      if (!const_value)
> -         return false;
> +      if (const_value) {
> +         opt_constant_if(following_if, const_value->u32[0] != 0);
> +         return true;
> +      }
>
> -      opt_constant_if(following_if, const_value->u32[0] != 0);
> -      return true;
> +      return opt_empty_if(following_if);
>     }
>
>     nir_loop *following_loop = nir_block_get_following_loop(block);
> --
> 2.8.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20160706/8f983b1d/attachment.html>


More information about the mesa-dev mailing list