nir/deref: Drop zero ptr_as_array derefs
authorJason Ekstrand <jason.ekstrand@intel.com>
Sun, 3 Feb 2019 15:32:32 +0000 (09:32 -0600)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 5 Feb 2019 21:17:19 +0000 (15:17 -0600)
They are effectively (&x)[0] or *&x which does nothing.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/compiler/nir/nir_deref.c

index 2f5fda643cabc8bbbe1f11657808ed0dd9acda5c..13aa10c753249c304ad5892aacae3bc564b13ac4 100644 (file)
@@ -670,6 +670,27 @@ opt_deref_ptr_as_array(nir_builder *b, nir_deref_instr *deref)
    assert(deref->deref_type == nir_deref_type_ptr_as_array);
 
    nir_deref_instr *parent = nir_deref_instr_parent(deref);
+
+   if (nir_src_is_const(deref->arr.index) &&
+       nir_src_as_int(deref->arr.index) == 0) {
+      /* If it's a ptr_as_array deref with an index of 0, it does nothing
+       * and we can just replace its uses with its parent.
+       *
+       * The source of a ptr_as_array deref always has a deref_type of
+       * nir_deref_type_array or nir_deref_type_cast.  If it's a cast, it
+       * may be trivial and we may be able to get rid of that too.  Any
+       * trivial cast of trivial cast cases should be handled already by
+       * opt_deref_cast() above.
+       */
+      if (parent->deref_type == nir_deref_type_cast &&
+          is_trivial_deref_cast(parent))
+         parent = nir_deref_instr_parent(parent);
+      nir_ssa_def_rewrite_uses(&deref->dest.ssa,
+                               nir_src_for_ssa(&parent->dest.ssa));
+      nir_instr_remove(&deref->instr);
+      return true;
+   }
+
    if (parent->deref_type != nir_deref_type_array &&
        parent->deref_type != nir_deref_type_ptr_as_array)
       return false;