mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 00:00:11 +01:00
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:
parent
8b073832ff
commit
60af3a93e9
1 changed files with 47 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue