[Mesa-dev] [PATCH 149/133] nir: Use the actual FNV-1a hash for hashing derefs

Jason Ekstrand jason at jlekstrand.net
Tue Jan 6 17:00:16 PST 2015


Not mentioned in the original commit message, but this also switches the
hashing functions to use a loop rather than recursion.
--Jason

On Tue, Jan 6, 2015 at 4:34 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:

> ---
>  src/glsl/nir/nir_lower_locals_to_regs.c |  65 ++++++++------------
>  src/glsl/nir/nir_lower_variables.c      | 101
> +++++++++++++++++---------------
>  2 files changed, 79 insertions(+), 87 deletions(-)
>
> diff --git a/src/glsl/nir/nir_lower_locals_to_regs.c
> b/src/glsl/nir/nir_lower_locals_to_regs.c
> index fdbd4ae..d55618a 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 cf9818b..84cf85f 100644
> --- a/src/glsl/nir/nir_lower_variables.c
> +++ b/src/glsl/nir/nir_lower_variables.c
> @@ -75,73 +75,78 @@ struct lower_variables_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: {
> -      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 == nir_deref_array_type_direct &&
> -          a_arr->base_offset != b_arr->base_offset)
> +         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)
> +            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.2.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150106/62aa5173/attachment.html>


More information about the mesa-dev mailing list