[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