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 { + * } + * * 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