diff options
author | Caio Marcelo de Oliveira Filho <[email protected]> | 2019-01-08 15:53:02 -0800 |
---|---|---|
committer | Caio Marcelo de Oliveira Filho <[email protected]> | 2019-02-22 21:00:50 -0800 |
commit | 60d9bb9ff50b1bbaf917cc9fb40dbab71e180add (patch) | |
tree | b5ac20ab4cfa89f37c90b0d4641d9707ef88deb5 /src/compiler/nir | |
parent | f48527e51ac54d4f0ae0db3dbc1acd1c64eb70b4 (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.c | 28 |
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; |