From 0c0ca8b6aec0842e396b81ef984ad01e00883c3e Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 6 Jan 2015 11:13:22 -0800 Subject: [PATCH] nir: Use the actual FNV-1a hash for hashing derefs We also switch to using loops rather than recursion. Reviewed-by: Connor Abbott --- src/glsl/nir/nir_lower_locals_to_regs.c | 65 ++++++--------- src/glsl/nir/nir_lower_variables.c | 104 ++++++++++++------------ 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 443549c71b3..c08a15b3d16 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 bae10b0d4e2..aed71c89c03 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 -- 2.30.2