summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Ekstrand <jason.ekstrand@intel.com>2015-01-06 11:13:22 -0800
committerJason Ekstrand <jason.ekstrand@intel.com>2015-01-15 07:20:23 -0800
commit0c0ca8b6aec0842e396b81ef984ad01e00883c3e (patch)
tree5c214bfa5578c47073dabdecbe62aa9a379d81c7
parenta3b73ccf6db3efe4ce0eed4c60d1e2709b335cac (diff)
nir: Use the actual FNV-1a hash for hashing derefs
We also switch to using loops rather than recursion. Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
-rw-r--r--src/glsl/nir/nir_lower_locals_to_regs.c65
-rw-r--r--src/glsl/nir/nir_lower_variables.c104
2 files changed, 79 insertions, 90 deletions
diff --git a/src/glsl/nir/nir_lower_locals_to_regs.c b/src/glsl/nir/nir_lower_locals_to_regs.c
index 443549c71b..c08a15b3d1 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 bae10b0d4e..aed71c89c0 100644
--- a/src/glsl/nir/nir_lower_variables.c
+++ b/src/glsl/nir/nir_lower_variables.c
@@ -68,80 +68,82 @@ struct lower_variables_state {
* variable dreferences. When the hash or equality function encounters an
* array, all indirects are treated as equal and are never equal to a
* direct dereference or a wildcard.
- *
- * Some of the magic numbers here were taken from _mesa_hash_data and one
- * was just a big prime I found on the internet.
*/
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 != 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)
+ 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