Mesa (master): nir/deref: Consider COHERENT decorated var derefs as aliasing

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Mar 15 01:50:35 UTC 2019


Module: Mesa
Branch: master
Commit: 60af3a93e9c25e9d5661bfda215a0b07463fe146
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=60af3a93e9c25e9d5661bfda215a0b07463fe146

Author: Jason Ekstrand <jason.ekstrand at intel.com>
Date:   Sun Mar 10 17:41:02 2019 -0500

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 at intel.com>

---

 src/compiler/nir/nir_deref.c | 51 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index c07a8c50691..14d8804c389 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -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




More information about the mesa-commit mailing list