nir/deref: Consider COHERENT decorated var derefs as aliasing

If we get to two deref_var paths with different variables, we usually
know they don't alias.  However, if both of the paths are marked
coherent, we don't have to worry about it.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
Jason Ekstrand 2019-03-10 17:41:02 -05:00 committed by Jason Ekstrand
parent 8b073832ff
commit 60af3a93e9

View file

@ -307,6 +307,28 @@ modes_may_alias(nir_variable_mode a, nir_variable_mode b)
return a == b;
}
static bool
deref_path_contains_coherent_decoration(nir_deref_path *path)
{
assert(path->path[0]->deref_type == nir_deref_type_var);
if (path->path[0]->var->data.image.access & ACCESS_COHERENT)
return true;
for (nir_deref_instr **p = &path->path[1]; *p; p++) {
if ((*p)->deref_type != nir_deref_type_struct)
continue;
const struct glsl_type *struct_type = (*(p - 1))->type;
const struct glsl_struct_field *field =
glsl_get_struct_field_data(struct_type, (*p)->strct.index);
if (field->memory_coherent)
return true;
}
return false;
}
nir_deref_compare_result
nir_compare_deref_paths(nir_deref_path *a_path,
nir_deref_path *b_path)
@ -318,11 +340,32 @@ nir_compare_deref_paths(nir_deref_path *a_path,
return nir_derefs_may_alias_bit;
if (a_path->path[0]->deref_type == nir_deref_type_var) {
/* If we can chase the deref all the way back to the variable and
* they're not the same variable, we know they can't possibly alias.
*/
if (a_path->path[0]->var != b_path->path[0]->var)
if (a_path->path[0]->var != b_path->path[0]->var) {
/* Shader and function temporaries aren't backed by memory so two
* distinct variables never alias.
*/
static const nir_variable_mode temp_var_modes =
nir_var_shader_temp | nir_var_function_temp;
if ((a_path->path[0]->mode & temp_var_modes) ||
(b_path->path[0]->mode & temp_var_modes))
return nir_derefs_do_not_alias;
/* If they are both declared coherent or have coherent somewhere in
* their path (due to a member of an interface being declared
* coherent), we have to assume we that we could have any kind of
* aliasing. Otherwise, they could still alias but the client didn't
* tell us and that's their fault.
*/
if (deref_path_contains_coherent_decoration(a_path) &&
deref_path_contains_coherent_decoration(b_path))
return nir_derefs_may_alias_bit;
/* If we can chase the deref all the way back to the variable and
* they're not the same variable and at least one is not declared
* coherent, we know they can't possibly alias.
*/
return nir_derefs_do_not_alias;
}
} else {
assert(a_path->path[0]->deref_type == nir_deref_type_cast);
/* If they're not exactly the same cast, it's hard to compare them so we