<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>