<div dir="ltr"><div>Not mentioned in the original commit message, but this also switches the hashing functions to use a loop rather than recursion.<br></div>--Jason<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 6, 2015 at 4:34 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">---<br>
 src/glsl/nir/nir_lower_locals_to_regs.c |  65 ++++++++------------<br>
 src/glsl/nir/nir_lower_variables.c      | 101 +++++++++++++++++---------------<br>
 2 files changed, 79 insertions(+), 87 deletions(-)<br>
<br>
diff --git a/src/glsl/nir/nir_lower_locals_to_regs.c b/src/glsl/nir/nir_lower_locals_to_regs.c<br>
index fdbd4ae..d55618a 100644<br>
--- a/src/glsl/nir/nir_lower_locals_to_regs.c<br>
+++ b/src/glsl/nir/nir_lower_locals_to_regs.c<br>
@@ -43,61 +43,48 @@ struct locals_to_regs_state {<br>
 static uint32_t<br>
 hash_deref(const void *void_deref)<br>
 {<br>
-   const nir_deref *deref = void_deref;<br>
+   uint32_t hash = _mesa_FNV32_1a_offset_bias;<br>
<br>
-   uint32_t hash;<br>
-   if (deref->child) {<br>
-      hash = hash_deref(deref->child);<br>
-   } else {<br>
-      hash = 2166136261ul;<br>
-   }<br>
+   const nir_deref_var *deref_var = void_deref;<br>
+   hash = _mesa_FNV32_1a_accumulate(hash, deref_var->var);<br>
<br>
-   switch (deref->deref_type) {<br>
-   case nir_deref_type_var:<br>
-      hash ^= _mesa_hash_pointer(nir_deref_as_var(deref)->var);<br>
-      break;<br>
-   case nir_deref_type_array: {<br>
-      hash ^= 268435183;<br>
-      break;<br>
-   }<br>
-   case nir_deref_type_struct:<br>
-      hash ^= nir_deref_as_struct(deref)->index;<br>
-      break;<br>
+   for (const nir_deref *deref = deref_var->deref.child;<br>
+        deref; deref = deref->child) {<br>
+      if (deref->deref_type == nir_deref_type_struct) {<br>
+         const nir_deref_struct *deref_struct = nir_deref_as_struct(deref);<br>
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_struct->index);<br>
+      }<br>
    }<br>
<br>
-   return hash * 0x01000193;<br>
+   return hash;<br>
 }<br>
<br>
 static bool<br>
 derefs_equal(const void *void_a, const void *void_b)<br>
 {<br>
-   const nir_deref *a = void_a;<br>
-   const nir_deref *b = void_b;<br>
+   const nir_deref_var *a_var = void_a;<br>
+   const nir_deref_var *b_var = void_b;<br>
<br>
-   if (a->deref_type != b->deref_type)<br>
+   if (a_var->var != b_var->var)<br>
       return false;<br>
<br>
-   switch (a->deref_type) {<br>
-   case nir_deref_type_var:<br>
-      if (nir_deref_as_var(a)->var != nir_deref_as_var(b)->var)<br>
+   for (const nir_deref *a = a_var->deref.child, *b = b_var->deref.child;<br>
+        a != NULL; a = a->child, b = b->child) {<br>
+      if (a->deref_type != b->deref_type)<br>
          return false;<br>
-      break;<br>
-   case nir_deref_type_array:<br>
-      /* Do nothing.  All array derefs are the same */<br>
-      break;<br>
-   case nir_deref_type_struct:<br>
-      if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)<br>
+<br>
+      if (a->deref_type == nir_deref_type_struct) {<br>
+         if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)<br>
+            return false;<br>
+      }<br>
+      /* Do nothing for arrays.  They're all the same. */<br>
+<br>
+      assert((a->child == NULL) == (b->child == NULL));<br>
+      if((a->child == NULL) != (b->child == NULL))<br>
          return false;<br>
-      break;<br>
-   default:<br>
-      unreachable("Invalid dreference type");<br>
    }<br>
<br>
-   assert((a->child == NULL) == (b->child == NULL));<br>
-   if (a->child)<br>
-      return derefs_equal(a->child, b->child);<br>
-   else<br>
-      return true;<br>
+   return true;<br>
 }<br>
<br>
 static nir_register *<br>
diff --git a/src/glsl/nir/nir_lower_variables.c b/src/glsl/nir/nir_lower_variables.c<br>
index cf9818b..84cf85f 100644<br>
--- a/src/glsl/nir/nir_lower_variables.c<br>
+++ b/src/glsl/nir/nir_lower_variables.c<br>
@@ -75,73 +75,78 @@ struct lower_variables_state {<br>
 static uint32_t<br>
 hash_deref(const void *void_deref)<br>
 {<br>
-   const nir_deref *deref = void_deref;<br>
+   uint32_t hash = _mesa_FNV32_1a_offset_bias;<br>
<br>
-   uint32_t hash;<br>
-   if (deref->child) {<br>
-      hash = hash_deref(deref->child);<br>
-   } else {<br>
-      hash = 2166136261ul;<br>
-   }<br>
+   const nir_deref_var *deref_var = void_deref;<br>
+   hash = _mesa_FNV32_1a_accumulate(hash, deref_var->var);<br>
<br>
-   switch (deref->deref_type) {<br>
-   case nir_deref_type_var:<br>
-      hash ^= _mesa_hash_pointer(nir_deref_as_var(deref)->var);<br>
-      break;<br>
-   case nir_deref_type_array: {<br>
-      nir_deref_array *array = nir_deref_as_array(deref);<br>
-      hash += 268435183 * array->deref_array_type;<br>
-      if (array->deref_array_type == nir_deref_array_type_direct)<br>
-         hash ^= array->base_offset; /* Some prime */<br>
-      break;<br>
-   }<br>
-   case nir_deref_type_struct:<br>
-      hash ^= nir_deref_as_struct(deref)->index;<br>
-      break;<br>
+   for (const nir_deref *deref = deref_var->deref.child;<br>
+        deref; deref = deref->child) {<br>
+      switch (deref->deref_type) {<br>
+      case nir_deref_type_array: {<br>
+         nir_deref_array *deref_array = nir_deref_as_array(deref);<br>
+<br>
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_array->deref_array_type);<br>
+<br>
+         if (deref_array->deref_array_type == nir_deref_array_type_direct)<br>
+            hash = _mesa_FNV32_1a_accumulate(hash, deref_array->base_offset);<br>
+         break;<br>
+      }<br>
+      case nir_deref_type_struct: {<br>
+         nir_deref_struct *deref_struct = nir_deref_as_struct(deref);<br>
+         hash = _mesa_FNV32_1a_accumulate(hash, deref_struct->index);<br>
+         break;<br>
+      }<br>
+      default:<br>
+         assert("Invalid deref chain");<br>
+      }<br>
    }<br>
<br>
-   return hash * 0x01000193;<br>
+   return hash;<br>
 }<br>
<br>
 static bool<br>
 derefs_equal(const void *void_a, const void *void_b)<br>
 {<br>
-   const nir_deref *a = void_a;<br>
-   const nir_deref *b = void_b;<br>
+   const nir_deref_var *a_var = void_a;<br>
+   const nir_deref_var *b_var = void_b;<br>
<br>
-   if (a->deref_type != b->deref_type)<br>
+   if (a_var->var != b_var->var)<br>
       return false;<br>
<br>
-   switch (a->deref_type) {<br>
-   case nir_deref_type_var:<br>
-      if (nir_deref_as_var(a)->var != nir_deref_as_var(b)->var)<br>
+   for (const nir_deref *a = a_var->deref.child, *b = b_var->deref.child;<br>
+        a != NULL; a = a->child, b = b->child) {<br>
+      if (a->deref_type != b->deref_type)<br>
          return false;<br>
-      break;<br>
-   case nir_deref_type_array: {<br>
-      nir_deref_array *a_arr = nir_deref_as_array(a);<br>
-      nir_deref_array *b_arr = nir_deref_as_array(b);<br>
<br>
-      if (a_arr->deref_array_type != b_arr->deref_array_type)<br>
-         return false;<br>
+      switch (a->deref_type) {<br>
+      case nir_deref_type_array: {<br>
+         nir_deref_array *a_arr = nir_deref_as_array(a);<br>
+         nir_deref_array *b_arr = nir_deref_as_array(b);<br>
<br>
-      if (a_arr->deref_array_type == nir_deref_array_type_direct &&<br>
-          a_arr->base_offset != b_arr->base_offset)<br>
+         if (a_arr->deref_array_type != b_arr->deref_array_type)<br>
+            return false;<br>
+<br>
+         if (a_arr->deref_array_type == nir_deref_array_type_direct &&<br>
+             a_arr->base_offset != b_arr->base_offset)<br>
+            return false;<br>
+         break;<br>
+      }<br>
+      case nir_deref_type_struct:<br>
+         if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)<br>
+            return false;<br>
+         break;<br>
+      default:<br>
+         assert("Invalid deref chain");<br>
          return false;<br>
-      break;<br>
-   }<br>
-   case nir_deref_type_struct:<br>
-      if (nir_deref_as_struct(a)->index != nir_deref_as_struct(b)->index)<br>
+      }<br>
+<br>
+      assert((a->child == NULL) == (b->child == NULL));<br>
+      if((a->child == NULL) != (b->child == NULL))<br>
          return false;<br>
-      break;<br>
-   default:<br>
-      unreachable("Invalid dreference type");<br>
    }<br>
<br>
-   assert((a->child == NULL) == (b->child == NULL));<br>
-   if (a->child)<br>
-      return derefs_equal(a->child, b->child);<br>
-   else<br>
-      return true;<br>
+   return true;<br>
 }<br>
<br>
 static int<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.2.0<br>
<br>
</font></span></blockquote></div><br></div>