[Mesa-dev] [PATCH 07/13] nir: create nir_opt_remove_phi() helper

Timothy Arceri timothy.arceri at collabora.com
Mon Aug 29 04:59:15 UTC 2016


This will be useful for cleaning up phis when unrolling loops.
---
 src/compiler/nir/nir.h                 |  1 +
 src/compiler/nir/nir_opt_remove_phis.c | 94 +++++++++++++++++++---------------
 2 files changed, 53 insertions(+), 42 deletions(-)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 60aeb8f..0ab3ebc 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -2676,6 +2676,7 @@ void nir_opt_gcm(nir_shader *shader);
 bool nir_opt_peephole_select(nir_shader *shader);
 
 bool nir_opt_remove_phis(nir_shader *shader);
+bool nir_opt_remove_phi(nir_phi_instr *phi);
 
 bool nir_opt_undef(nir_shader *shader);
 
diff --git a/src/compiler/nir/nir_opt_remove_phis.c b/src/compiler/nir/nir_opt_remove_phis.c
index 6d9e0ff..7dea9c7 100644
--- a/src/compiler/nir/nir_opt_remove_phis.c
+++ b/src/compiler/nir/nir_opt_remove_phis.c
@@ -47,6 +47,57 @@ matching_mov(nir_alu_instr *mov1, nir_ssa_def *ssa)
    return mov2 && nir_alu_srcs_equal(mov1, mov2, 0, 0);
 }
 
+bool
+nir_opt_remove_phi(nir_phi_instr *phi)
+{
+   nir_ssa_def *def = NULL;
+   nir_alu_instr *mov = NULL;
+   bool srcs_same = true;
+
+   nir_foreach_phi_src(src, phi) {
+      assert(src->src.is_ssa);
+
+      /* For phi nodes at the beginning of loops, we may encounter some
+       * sources from backedges that point back to the destination of the
+       * same phi, i.e. something like:
+       *
+       * a = phi(a, b, ...)
+       *
+       * We can safely ignore these sources, since if all of the normal
+       * sources point to the same definition, then that definition must
+       * still dominate the phi node, and the phi will still always take
+       * the value of that definition.
+       */
+      if (src->src.ssa == &phi->dest.ssa)
+         continue;
+
+      if (def == NULL) {
+         def  = src->src.ssa;
+         mov = get_parent_mov(def);
+      } else {
+         if (src->src.ssa != def && !matching_mov(mov, src->src.ssa)) {
+            srcs_same = false;
+            break;
+         }
+      }
+   }
+
+   if (!srcs_same)
+      return false;
+
+   /* We must have found at least one definition, since there must be at
+    * least one forward edge.
+    */
+    assert(def != NULL);
+
+
+   assert(phi->dest.is_ssa);
+   nir_ssa_def_rewrite_uses(&phi->dest.ssa, nir_src_for_ssa(def));
+   nir_instr_remove(&phi->instr);
+
+   return true;
+}
+
 /*
  * This is a pass for removing phi nodes that look like:
  * a = phi(b, b, b, ...)
@@ -74,50 +125,9 @@ remove_phis_block(nir_block *block)
       nir_phi_instr *phi = nir_instr_as_phi(instr);
       bool is_lcssa_phi = phi->is_lcssa_phi;
 
-      nir_ssa_def *def = NULL;
-      nir_alu_instr *mov = NULL;
-      bool srcs_same = true;
-
-      nir_foreach_phi_src(src, phi) {
-         assert(src->src.is_ssa);
-
-         /* For phi nodes at the beginning of loops, we may encounter some
-          * sources from backedges that point back to the destination of the
-          * same phi, i.e. something like:
-          *
-          * a = phi(a, b, ...)
-          *
-          * We can safely ignore these sources, since if all of the normal
-          * sources point to the same definition, then that definition must
-          * still dominate the phi node, and the phi will still always take
-          * the value of that definition.
-          */
-         if (src->src.ssa == &phi->dest.ssa)
-            continue;
-         
-         if (def == NULL) {
-            def  = src->src.ssa;
-            mov = get_parent_mov(def);
-         } else {
-            if (src->src.ssa != def && !matching_mov(mov, src->src.ssa)) {
-               srcs_same = false;
-               break;
-            }
-         }
-      }
-
-      if (!srcs_same)
+      if (!nir_opt_remove_phi(phi))
          continue;
 
-      /* We must have found at least one definition, since there must be at
-       * least one forward edge.
-       */
-      assert(def != NULL);
-
-      assert(phi->dest.is_ssa);
-      nir_ssa_def_rewrite_uses(&phi->dest.ssa, nir_src_for_ssa(def));
-      nir_instr_remove(instr);
-
       if (!is_lcssa_phi)
          progress = true;
    }
-- 
2.7.4



More information about the mesa-dev mailing list