/* The following two functions implement a hash and equality check for
 * variable dreferences.  When the hash or equality function encounters an
 * array, it ignores the offset and whether it is direct or indirect
 * entirely.
 */
static uint32_t
hash_deref(const void *void_deref)
{
   uint32_t hash = _mesa_fnv32_1a_offset_bias;

   for (const nir_deref_instr *deref = void_deref; deref;
        deref = nir_deref_instr_parent(deref)) {
      switch (deref->deref_type) {
      case nir_deref_type_var:
         return _mesa_fnv32_1a_accumulate(hash, deref->var);

      case nir_deref_type_array:
         continue; /* Do nothing */

      case nir_deref_type_struct:
         hash = _mesa_fnv32_1a_accumulate(hash, deref->strct.index);
         continue;

      default:
         unreachable("Invalid deref type");
      }
   }

   unreachable("We should have hit a variable dereference");
}
/* The following two functions implement a hash and equality check for
 * variable dreferences.  When the hash or equality function encounters an
 * array, it ignores the offset and whether it is direct or indirect
 * entirely.
 */
static uint32_t
hash_deref(const void *void_deref)
{
   uint32_t hash = _mesa_fnv32_1a_offset_bias;

   const nir_deref_var *deref_var = void_deref;
   hash = _mesa_fnv32_1a_accumulate(hash, deref_var->var);

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