nir/copy_prop_vars: don't get confused by array_deref of vectors
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Tue, 8 Jan 2019 23:53:02 +0000 (15:53 -0800)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Sat, 23 Feb 2019 05:00:50 +0000 (21:00 -0800)
For now these derefs are not handled, so don't let these get into the
copies list -- which would cause wrong propagations.  For load_derefs,
do nothing.  For store_derefs, invalidate whatever the store is
writing to.  For copy_derefs, invalidate whatever the copy is writing
to.

These cases will happen once derefs to SSBOs/UBOs are kept around long
enough to get optimized by copy_prop_vars.

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/nir/nir_opt_copy_prop_vars.c

index 392fef407cfd4d30bbbcd75d49d52d6a858ca98b..a7b85f4cc9b1810c24d236a92802e54c899a04a7 100644 (file)
@@ -616,6 +616,15 @@ invalidate_copies_for_cf_node(struct copy_prop_var_state *state,
    }
 }
 
+static bool
+is_array_deref_of_vector(nir_deref_instr *deref)
+{
+   if (deref->deref_type != nir_deref_type_array)
+      return false;
+   nir_deref_instr *parent = nir_deref_instr_parent(deref);
+   return glsl_type_is_vector(parent->type);
+}
+
 static void
 copy_prop_vars_block(struct copy_prop_var_state *state,
                      nir_builder *b, nir_block *block,
@@ -651,6 +660,11 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
       case nir_intrinsic_load_deref: {
          nir_deref_instr *src = nir_src_as_deref(intrin->src[0]);
 
+         if (is_array_deref_of_vector(src)) {
+            /* Not handled yet. This load won't invalidate existing copies. */
+            break;
+         }
+
          struct copy_entry *src_entry =
             lookup_entry_for_deref(copies, src, nir_derefs_a_contains_b_bit);
          struct value value;
@@ -720,6 +734,11 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
              * store is redundant so remove it.
              */
             nir_instr_remove(instr);
+         } else if (is_array_deref_of_vector(dst)) {
+            /* Not handled yet.  Writing into an element of 'dst' invalidates
+             * any related entries in copies.
+             */
+            kill_aliases(copies, nir_deref_instr_parent(dst), 0xf);
          } else {
             struct value value = {
                .is_ssa = true
@@ -747,6 +766,15 @@ copy_prop_vars_block(struct copy_prop_var_state *state,
             continue;
          }
 
+         if (is_array_deref_of_vector(src) || is_array_deref_of_vector(dst)) {
+            /* Cases not handled yet.  Writing into an element of 'dst'
+             * invalidates any related entries in copies.  Reading from 'src'
+             * doesn't invalidate anything, so no action needed for it.
+             */
+            kill_aliases(copies, dst, 0xf);
+            break;
+         }
+
          struct copy_entry *src_entry =
             lookup_entry_for_deref(copies, src, nir_derefs_a_contains_b_bit);
          struct value value;