[Mesa-dev] [PATCH v4 007/129] nir/deref: Add some deref cleanup functions

Jason Ekstrand jason at jlekstrand.net
Fri Jun 1 05:01:50 UTC 2018


Sometimes it's useful for a pass to be able to clean up its own derefs
instead of waiting for DCE.  This little helper makes it very easy.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
---
 src/compiler/nir/nir.h       |  4 ++++
 src/compiler/nir/nir_deref.c | 53 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 8b826d8..f8a12c1 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1021,6 +1021,8 @@ nir_deref_instr_get_variable(const nir_deref_instr *instr)
    return instr->var;
 }
 
+bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
+
 nir_deref_var *
 nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx);
 
@@ -2675,6 +2677,8 @@ bool nir_lower_regs_to_ssa_impl(nir_function_impl *impl);
 bool nir_lower_regs_to_ssa(nir_shader *shader);
 bool nir_lower_vars_to_ssa(nir_shader *shader);
 
+bool nir_remove_dead_derefs(nir_shader *shader);
+bool nir_remove_dead_derefs_impl(nir_function_impl *impl);
 bool nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes);
 bool nir_lower_constant_initializers(nir_shader *shader,
                                      nir_variable_mode modes);
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 87a8192..0e8699a 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -24,6 +24,59 @@
 #include "nir.h"
 #include "nir_builder.h"
 
+/**
+ * Recursively removes unused deref instructions
+ */
+bool
+nir_deref_instr_remove_if_unused(nir_deref_instr *instr)
+{
+   bool progress = false;
+
+   for (nir_deref_instr *d = instr; d; d = nir_deref_instr_parent(d)) {
+      /* If anyone is using this deref, leave it alone */
+      assert(d->dest.is_ssa);
+      if (!list_empty(&d->dest.ssa.uses))
+         break;
+
+      nir_instr_remove(&d->instr);
+      progress = true;
+   }
+
+   return progress;
+}
+
+bool
+nir_remove_dead_derefs_impl(nir_function_impl *impl)
+{
+   bool progress = false;
+
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         if (instr->type == nir_instr_type_deref &&
+             nir_deref_instr_remove_if_unused(nir_instr_as_deref(instr)))
+            progress = true;
+      }
+   }
+
+   if (progress)
+      nir_metadata_preserve(impl, nir_metadata_block_index |
+                                  nir_metadata_dominance);
+
+   return progress;
+}
+
+bool
+nir_remove_dead_derefs(nir_shader *shader)
+{
+   bool progress = false;
+   nir_foreach_function(function, shader) {
+      if (function->impl && nir_remove_dead_derefs_impl(function->impl))
+         progress = true;
+   }
+
+   return progress;
+}
+
 nir_deref_var *
 nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx)
 {
-- 
2.5.0.400.gff86faf



More information about the mesa-dev mailing list