summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
authorCaio Marcelo de Oliveira Filho <[email protected]>2019-01-08 15:53:02 -0800
committerCaio Marcelo de Oliveira Filho <[email protected]>2019-02-22 21:00:50 -0800
commit60d9bb9ff50b1bbaf917cc9fb40dbab71e180add (patch)
treeb5ac20ab4cfa89f37c90b0d4641d9707ef88deb5 /src/compiler/nir
parentf48527e51ac54d4f0ae0db3dbc1acd1c64eb70b4 (diff)
nir/copy_prop_vars: don't get confused by array_deref of vectors
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 <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir_opt_copy_prop_vars.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c
index 392fef407cf..a7b85f4cc9b 100644
--- a/src/compiler/nir/nir_opt_copy_prop_vars.c
+++ b/src/compiler/nir/nir_opt_copy_prop_vars.c
@@ -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;