[Mesa-dev] [PATCH] nir/deref: Support casts in comparisons
Jason Ekstrand
jason at jlekstrand.net
Fri Oct 26 18:57:13 UTC 2018
The code which constructs deref paths already gives you the path
starting at the nearest deref_cast or deref_var. All we need to do is
handle the case where the start of the path isn't a deref_var.
Cc: Caio Marcelo de Oliveira Filho <caio.oliveira at intel.com>
---
src/compiler/nir/nir_deref.c | 40 +++++++++++++++++++++++++++++++++---
1 file changed, 37 insertions(+), 3 deletions(-)
diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index 16502c23d04..ed7e1369ca6 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -278,13 +278,49 @@ nir_fixup_deref_modes(nir_shader *shader)
}
}
+static bool
+modes_may_alias(nir_variable_mode a, nir_variable_mode b)
+{
+ /* Function parameters can alias anything except local variables in the
+ * current function.
+ */
+ if ((a == nir_var_param && b != nir_var_local) ||
+ (b == nir_var_param && a != nir_var_local))
+ return true;
+
+ /* For everything else, they can only alias if they have the same mode.
+ * This may not hold for external things such UBOs and SSBOs but those
+ * don't use derefs today.
+ */
+ return a == b;
+}
+
nir_deref_compare_result
nir_compare_deref_paths(nir_deref_path *a_path,
nir_deref_path *b_path)
{
- if (a_path->path[0]->var != b_path->path[0]->var)
+ if (!modes_may_alias(b_path->path[0]->mode, a_path->path[0]->mode))
return 0;
+ 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 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)
+ return 0;
+ } else {
+ /* If they're not exactly the same cast, we can't compare them so we
+ * have to assume they alias. We could potentially be a bit smarter
+ * here and compare the two casts for equality but let's just hope CSE
+ * combines identical casts instead.
+ */
+ 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.
*/
@@ -376,8 +412,6 @@ nir_compare_derefs(nir_deref_instr *a, nir_deref_instr *b)
nir_deref_path a_path, b_path;
nir_deref_path_init(&a_path, a, NULL);
nir_deref_path_init(&b_path, b, NULL);
- assert(a_path.path[0]->deref_type == nir_deref_type_var);
- assert(b_path.path[0]->deref_type == nir_deref_type_var);
nir_deref_compare_result result = nir_compare_deref_paths(&a_path, &b_path);
--
2.19.1
More information about the mesa-dev
mailing list