mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 22:20:09 +01:00
nir/deref: Break out a helper for compare_deref_paths
Tested-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com> Reviewed-by: M Henning <drawoc@darkrefraction.com> Reviewed-by: Rhys Perry <pendingchaos02@gmail.com> Cc: mesa-stable@lists.freedesktop.org Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16894>
This commit is contained in:
parent
cb5c1bcb7c
commit
4d80b3217e
1 changed files with 63 additions and 56 deletions
|
|
@ -442,62 +442,9 @@ modes_may_alias(nir_variable_mode a, nir_variable_mode b)
|
|||
return a & b;
|
||||
}
|
||||
|
||||
nir_deref_compare_result
|
||||
nir_compare_deref_paths(nir_deref_path *a_path,
|
||||
nir_deref_path *b_path)
|
||||
ALWAYS_INLINE static nir_deref_compare_result
|
||||
compare_deref_paths(nir_deref_path *a_path, nir_deref_path *b_path)
|
||||
{
|
||||
if (!modes_may_alias(b_path->path[0]->modes, a_path->path[0]->modes))
|
||||
return nir_derefs_do_not_alias;
|
||||
|
||||
if (a_path->path[0]->deref_type != b_path->path[0]->deref_type)
|
||||
return nir_derefs_may_alias_bit;
|
||||
|
||||
if (a_path->path[0]->deref_type == nir_deref_type_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]->modes & ~temp_var_modes) ||
|
||||
!(b_path->path[0]->modes & ~temp_var_modes))
|
||||
return nir_derefs_do_not_alias;
|
||||
|
||||
/* Per SPV_KHR_workgroup_memory_explicit_layout and GL_EXT_shared_memory_block,
|
||||
* shared blocks alias each other.
|
||||
*/
|
||||
if (a_path->path[0]->modes & nir_var_mem_shared &&
|
||||
b_path->path[0]->modes & nir_var_mem_shared &&
|
||||
(glsl_type_is_interface(a_path->path[0]->var->type) ||
|
||||
glsl_type_is_interface(b_path->path[0]->var->type))) {
|
||||
assert(glsl_type_is_interface(a_path->path[0]->var->type) &&
|
||||
glsl_type_is_interface(b_path->path[0]->var->type));
|
||||
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
|
||||
* just assume they alias. Comparing casts is tricky as there are lots
|
||||
* of things such as mode, type, etc. to make sure work out; for now, we
|
||||
* just assume nit_opt_deref will combine them and compare the deref
|
||||
* instructions.
|
||||
*
|
||||
* TODO: At some point in the future, we could be clever and understand
|
||||
* that a float[] and int[] have the same layout and aliasing structure
|
||||
* but double[] and vec3[] do not and we could potentially be a bit
|
||||
* smarter here.
|
||||
*/
|
||||
if (a_path->path[0] != b_path->path[0])
|
||||
return nir_derefs_may_alias_bit;
|
||||
}
|
||||
|
||||
/* Start off assuming they fully compare. We ignore equality for now. In
|
||||
* the end, we'll determine that by containment.
|
||||
*/
|
||||
|
|
@ -594,12 +541,72 @@ nir_compare_deref_paths(nir_deref_path *a_path,
|
|||
result &= ~nir_derefs_b_contains_a_bit;
|
||||
|
||||
/* If a contains b and b contains a they must be equal. */
|
||||
if ((result & nir_derefs_a_contains_b_bit) && (result & nir_derefs_b_contains_a_bit))
|
||||
if ((result & nir_derefs_a_contains_b_bit) &&
|
||||
(result & nir_derefs_b_contains_a_bit))
|
||||
result |= nir_derefs_equal_bit;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nir_deref_compare_result
|
||||
nir_compare_deref_paths(nir_deref_path *a_path,
|
||||
nir_deref_path *b_path)
|
||||
{
|
||||
if (!modes_may_alias(b_path->path[0]->modes, a_path->path[0]->modes))
|
||||
return nir_derefs_do_not_alias;
|
||||
|
||||
if (a_path->path[0]->deref_type != b_path->path[0]->deref_type)
|
||||
return nir_derefs_may_alias_bit;
|
||||
|
||||
if (a_path->path[0]->deref_type == nir_deref_type_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]->modes & ~temp_var_modes) ||
|
||||
!(b_path->path[0]->modes & ~temp_var_modes))
|
||||
return nir_derefs_do_not_alias;
|
||||
|
||||
/* Per SPV_KHR_workgroup_memory_explicit_layout and GL_EXT_shared_memory_block,
|
||||
* shared blocks alias each other.
|
||||
*/
|
||||
if (a_path->path[0]->modes & nir_var_mem_shared &&
|
||||
b_path->path[0]->modes & nir_var_mem_shared &&
|
||||
(glsl_type_is_interface(a_path->path[0]->var->type) ||
|
||||
glsl_type_is_interface(b_path->path[0]->var->type))) {
|
||||
assert(glsl_type_is_interface(a_path->path[0]->var->type) &&
|
||||
glsl_type_is_interface(b_path->path[0]->var->type));
|
||||
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
|
||||
* just assume they alias. Comparing casts is tricky as there are lots
|
||||
* of things such as mode, type, etc. to make sure work out; for now, we
|
||||
* just assume nit_opt_deref will combine them and compare the deref
|
||||
* instructions.
|
||||
*
|
||||
* TODO: At some point in the future, we could be clever and understand
|
||||
* that a float[] and int[] have the same layout and aliasing structure
|
||||
* but double[] and vec3[] do not and we could potentially be a bit
|
||||
* smarter here.
|
||||
*/
|
||||
if (a_path->path[0] != b_path->path[0])
|
||||
return nir_derefs_may_alias_bit;
|
||||
}
|
||||
|
||||
return compare_deref_paths(a_path, b_path);
|
||||
}
|
||||
|
||||
nir_deref_compare_result
|
||||
nir_compare_derefs(nir_deref_instr *a, nir_deref_instr *b)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue