Module: Mesa
Branch: master
Commit: e84194686d1234f9c6e9ba02d223a61ad3ca7b6a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=e84194686d1234f9c6e9ba02d223a61ad3ca7b6a

Author: Jason Ekstrand <[email protected]>
Date:   Wed May 22 15:00:20 2019 -0500

nir/deref: Add a has_complex_use helper

This lets passes easily detect derefs which have uses that fall outside
the standard load/store/copy pattern so they can bail appropriately.

Reviewed-by: Dave Airlie <[email protected]>
Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>

---

 src/compiler/nir/nir.h       |  1 +
 src/compiler/nir/nir_deref.c | 78 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index d55b3569d11..e6ba0d977f3 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1085,6 +1085,7 @@ nir_deref_instr_get_variable(const nir_deref_instr *instr)
 }
 
 bool nir_deref_instr_has_indirect(nir_deref_instr *instr);
+bool nir_deref_instr_has_complex_use(nir_deref_instr *instr);
 
 bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
 
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 90bb9a0dc3c..cdb9105a751 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -121,6 +121,84 @@ nir_deref_instr_has_indirect(nir_deref_instr *instr)
    return false;
 }
 
+bool
+nir_deref_instr_has_complex_use(nir_deref_instr *deref)
+{
+   nir_foreach_use(use_src, &deref->dest.ssa) {
+      nir_instr *use_instr = use_src->parent_instr;
+
+      switch (use_instr->type) {
+      case nir_instr_type_deref: {
+         nir_deref_instr *use_deref = nir_instr_as_deref(use_instr);
+
+         /* A var deref has no sources */
+         assert(use_deref->deref_type != nir_deref_type_var);
+
+         /* If a deref shows up in an array index or something like that, it's
+          * a complex use.
+          */
+         if (use_src != &use_deref->parent)
+            return true;
+
+         /* Anything that isn't a basic struct or array deref is considered to
+          * be a "complex" use.  In particular, we don't allow ptr_as_array
+          * because we assume that opt_deref will turn any non-complex
+          * ptr_as_array derefs into regular array derefs eventually so passes
+          * which only want to handle simple derefs will pick them up in a
+          * later pass.
+          */
+         if (use_deref->deref_type != nir_deref_type_struct &&
+             use_deref->deref_type != nir_deref_type_array_wildcard &&
+             use_deref->deref_type != nir_deref_type_array)
+            return true;
+
+         if (nir_deref_instr_has_complex_use(use_deref))
+            return true;
+
+         continue;
+      }
+
+      case nir_instr_type_intrinsic: {
+         nir_intrinsic_instr *use_intrin = nir_instr_as_intrinsic(use_instr);
+         switch (use_intrin->intrinsic) {
+         case nir_intrinsic_load_deref:
+            assert(use_src == &use_intrin->src[0]);
+            continue;
+
+         case nir_intrinsic_copy_deref:
+            assert(use_src == &use_intrin->src[0] ||
+                   use_src == &use_intrin->src[1]);
+            continue;
+
+         case nir_intrinsic_store_deref:
+            /* A use in src[1] of a store means we're taking that pointer and
+             * writing it to a variable.  Because we have no idea who will
+             * read that variable and what they will do with the pointer, it's
+             * considered a "complex" use.  A use in src[0], on the other
+             * hand, is a simple use because we're just going to dereference
+             * it and write a value there.
+             */
+            if (use_src == &use_intrin->src[0])
+               continue;
+            return true;
+
+         default:
+            return true;
+         }
+         unreachable("Switch default failed");
+      }
+
+      default:
+         return true;
+      }
+   }
+
+   nir_foreach_if_use(use, &deref->dest.ssa)
+      return true;
+
+   return false;
+}
+
 unsigned
 nir_deref_instr_ptr_as_array_stride(nir_deref_instr *deref)
 {

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to