[Mesa-dev] [PATCH 149/133] nir: Use the actual FNV-1a hash for hashing derefs

Jason Ekstrand jason at jlekstrand.net
Tue Jan 6 16:34:22 PST 2015


---
 src/glsl/nir/nir_lower_locals_to_regs.c |  65 ++++++++------------
 src/glsl/nir/nir_lower_variables.c      | 101 +++++++++++++++++---------------
 2 files changed, 79 insertions(+), 87 deletions(-)

diff --git a/src/glsl/nir/nir_lower_locals_to_regs.c b/src/glsl/nir/nir_lower_locals_to_regs.c
index fdbd4ae..d55618a 100644
--- a/src/glsl/nir/nir_lower_locals_to_regs.c
+++ b/src/glsl/nir/nir_lower_locals_to_regs.c
@@ -43,61 +43,48 @@ struct locals_to_regs_state {
 static uint32_t
 hash_deref(const void *void_deref)
 {
-   const nir_deref *deref = void_deref;
+   uint32_t hash = _mesa_FNV32_1a_offset_bias;
 
-   uint32_t hash;
-   if (deref->child) {
-      hash = hash_deref(deref->child);
-   } else {
-      hash = 2166136261ul;
-   }
+   const nir_deref_var *deref_var = void_deref;
+   hash = _mesa_FNV32_1a_accumulate(hash, deref_var->var);
 
-   switch (deref->deref_type) {
-   case nir_deref_type_var:
-      hash ^= _mesa_hash_pointer(nir_deref_as_var(deref)->var);
-      break;
-   case nir_deref_type_array: {
-      hash ^= 268435183;
-      break;
-   }
-   case nir_deref_type_struct:
-      hash ^= nir_deref_as_struct(deref)->index;
-      break;
+   for (const nir_deref *deref = deref_var->deref.child;
+        deref; deref = deref->child) {
+      if (deref->deref_type == nir_deref_type_struct) {
+         const nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_struct->index);
+      }
    }
 
-   return hash * 0x01000193;
+   return hash;
 }
 
 static bool
 derefs_equal(const void *void_a, const void *void_b)
 {
-   const nir_deref *a = void_a;
-   const nir_deref *b = void_b;
+   const nir_deref_var *a_var = void_a;
+   const nir_deref_var *b_var = void_b;
 
-   if (a->deref_type != b->deref_type)
+   if (a_var->var != b_var->var)
       return false;
 
-   switch (a->deref_type) {
-   case nir_deref_type_var:
-      if (nir_deref_as_var(a)->var != nir_deref_as_var(b)->var)
+   for (const nir_deref *a = a_var->deref.child, *b = b_var->deref.child;
+        a != NULL; a = a->child, b = b->child) {
+      if (a->deref_type != b->deref_type)
          return false;
-      break;
-   case nir_deref_type_array:
-      /* Do nothing.  All array derefs are the same */
-      break;
-   case nir_deref_type_struct:
-      if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)
+
+      if (a->deref_type == nir_deref_type_struct) {
+         if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)
+            return false;
+      }
+      /* Do nothing for arrays.  They're all the same. */
+
+      assert((a->child == NULL) == (b->child == NULL));
+      if((a->child == NULL) != (b->child == NULL))
          return false;
-      break;
-   default:
-      unreachable("Invalid dreference type");
    }
 
-   assert((a->child == NULL) == (b->child == NULL));
-   if (a->child)
-      return derefs_equal(a->child, b->child);
-   else
-      return true;
+   return true;
 }
 
 static nir_register *
diff --git a/src/glsl/nir/nir_lower_variables.c b/src/glsl/nir/nir_lower_variables.c
index cf9818b..84cf85f 100644
--- a/src/glsl/nir/nir_lower_variables.c
+++ b/src/glsl/nir/nir_lower_variables.c
@@ -75,73 +75,78 @@ struct lower_variables_state {
 static uint32_t
 hash_deref(const void *void_deref)
 {
-   const nir_deref *deref = void_deref;
+   uint32_t hash = _mesa_FNV32_1a_offset_bias;
 
-   uint32_t hash;
-   if (deref->child) {
-      hash = hash_deref(deref->child);
-   } else {
-      hash = 2166136261ul;
-   }
+   const nir_deref_var *deref_var = void_deref;
+   hash = _mesa_FNV32_1a_accumulate(hash, deref_var->var);
 
-   switch (deref->deref_type) {
-   case nir_deref_type_var:
-      hash ^= _mesa_hash_pointer(nir_deref_as_var(deref)->var);
-      break;
-   case nir_deref_type_array: {
-      nir_deref_array *array = nir_deref_as_array(deref);
-      hash += 268435183 * array->deref_array_type;
-      if (array->deref_array_type == nir_deref_array_type_direct)
-         hash ^= array->base_offset; /* Some prime */
-      break;
-   }
-   case nir_deref_type_struct:
-      hash ^= nir_deref_as_struct(deref)->index;
-      break;
+   for (const nir_deref *deref = deref_var->deref.child;
+        deref; deref = deref->child) {
+      switch (deref->deref_type) {
+      case nir_deref_type_array: {
+         nir_deref_array *deref_array = nir_deref_as_array(deref);
+
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_array->deref_array_type);
+
+         if (deref_array->deref_array_type == nir_deref_array_type_direct)
+            hash = _mesa_FNV32_1a_accumulate(hash, deref_array->base_offset);
+         break;
+      }
+      case nir_deref_type_struct: {
+         nir_deref_struct *deref_struct = nir_deref_as_struct(deref);
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_struct->index);
+         break;
+      }
+      default:
+         assert("Invalid deref chain");
+      }
    }
 
-   return hash * 0x01000193;
+   return hash;
 }
 
 static bool
 derefs_equal(const void *void_a, const void *void_b)
 {
-   const nir_deref *a = void_a;
-   const nir_deref *b = void_b;
+   const nir_deref_var *a_var = void_a;
+   const nir_deref_var *b_var = void_b;
 
-   if (a->deref_type != b->deref_type)
+   if (a_var->var != b_var->var)
       return false;
 
-   switch (a->deref_type) {
-   case nir_deref_type_var:
-      if (nir_deref_as_var(a)->var != nir_deref_as_var(b)->var)
+   for (const nir_deref *a = a_var->deref.child, *b = b_var->deref.child;
+        a != NULL; a = a->child, b = b->child) {
+      if (a->deref_type != b->deref_type)
          return false;
-      break;
-   case nir_deref_type_array: {
-      nir_deref_array *a_arr = nir_deref_as_array(a);
-      nir_deref_array *b_arr = nir_deref_as_array(b);
 
-      if (a_arr->deref_array_type != b_arr->deref_array_type)
-         return false;
+      switch (a->deref_type) {
+      case nir_deref_type_array: {
+         nir_deref_array *a_arr = nir_deref_as_array(a);
+         nir_deref_array *b_arr = nir_deref_as_array(b);
 
-      if (a_arr->deref_array_type == nir_deref_array_type_direct &&
-          a_arr->base_offset != b_arr->base_offset)
+         if (a_arr->deref_array_type != b_arr->deref_array_type)
+            return false;
+
+         if (a_arr->deref_array_type == nir_deref_array_type_direct &&
+             a_arr->base_offset != b_arr->base_offset)
+            return false;
+         break;
+      }
+      case nir_deref_type_struct:
+         if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)
+            return false;
+         break;
+      default:
+         assert("Invalid deref chain");
          return false;
-      break;
-   }
-   case nir_deref_type_struct:
-      if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)
+      }
+
+      assert((a->child == NULL) == (b->child == NULL));
+      if((a->child == NULL) != (b->child == NULL))
          return false;
-      break;
-   default:
-      unreachable("Invalid dreference type");
    }
 
-   assert((a->child == NULL) == (b->child == NULL));
-   if (a->child)
-      return derefs_equal(a->child, b->child);
-   else
-      return true;
+   return true;
 }
 
 static int
-- 
2.2.0



More information about the mesa-dev mailing list