On Wed, Jul 6, 2016 at 5:12 PM, Eric Anholt <e...@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@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev