Commit 0c0ca8b6 authored by Jason Ekstrand's avatar Jason Ekstrand
Browse files

nir: Use the actual FNV-1a hash for hashing derefs



We also switch to using loops rather than recursion.
Reviewed-by: default avatarConnor Abbott <cwabbott0@gmail.com>
parent a3b73ccf
......@@ -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 *
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment