[Mesa-dev] [PATCH 2/2] nir: Optimize away IF statements with no body on either side.
Eric Anholt
eric at anholt.net
Thu Jul 7 00:12:33 UTC 2016
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
More information about the mesa-dev
mailing list