Mesa (main): nir/deref: Break out a helper for compare_deref_paths

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 8 22:03:45 UTC 2022


Module: Mesa
Branch: main
Commit: 4d80b3217e692e626182511c9a4d87f25a09221d
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4d80b3217e692e626182511c9a4d87f25a09221d

Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date:   Fri Jun  3 15:45:37 2022 -0500

nir/deref: Break out a helper for compare_deref_paths

Tested-by: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Reviewed-by: M Henning <drawoc at darkrefraction.com>
Reviewed-by: Rhys Perry <pendingchaos02 at gmail.com>
Cc: mesa-stable at lists.freedesktop.org
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16894>

---

 src/compiler/nir/nir_deref.c | 119 +++++++++++++++++++++++--------------------
 1 file changed, 63 insertions(+), 56 deletions(-)

diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c
index c0b57c42155..e6890f321b6 100644
--- a/src/compiler/nir/nir_deref.c
+++ b/src/compiler/nir/nir_deref.c
@@ -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)
 {



More information about the mesa-commit mailing list