mono_value_hash_table_new (guint (*GHashFunc) (const void *) hash_func, gboolean (*GEqualFunc) (const void *, const void *) key_equal_func, void * (*MonoValueHashKeyExtractFunc) (void *) key_extract)
{
  int D.6689;
  long unsigned int D.6690;
  long unsigned int D.6691;
  void * D.6692;
  struct MonoValueHashTable * D.6693;
  struct MonoValueHashTable * hash;

  if (hash_func == 0B) goto <D.6685>; else goto <D.6686>;
  <D.6685>:
  hash_func = monoeg_g_direct_hash;
  <D.6686>:
  if (key_equal_func == 0B) goto <D.6687>; else goto <D.6688>;
  <D.6687>:
  key_equal_func = monoeg_g_direct_equal;
  <D.6688>:
  hash = monoeg_malloc0 (64);
  hash->hash_func = hash_func;
  hash->key_equal_func = key_equal_func;
  hash->key_extract_func = key_extract;
  mono_value_hash_table_set_shift (hash, 3);
  D.6689 = hash->table_size;
  D.6690 = (long unsigned int) D.6689;
  D.6691 = D.6690 * 8;
  D.6692 = monoeg_malloc0 (D.6691);
  hash->table = D.6692;
  D.6693 = hash;
  return D.6693;
}


mono_value_hash_table_set_shift (struct MonoValueHashTable * hash_table, gint shift)
{
  int D.6695;
  int mask.0;
  gint i;
  guint mask;

  mask = 0;
  D.6695 = 1 << shift;
  hash_table->table_size = D.6695;
  i = 0;
  goto <D.6588>;
  <D.6587>:
  mask = mask << 1;
  mask = mask | 1;
  i = i + 1;
  <D.6588>:
  if (i < shift) goto <D.6587>; else goto <D.6589>;
  <D.6589>:
  mask.0 = (int) mask;
  hash_table->table_mask = mask.0;
}


mono_value_hash_table_insert (struct MonoValueHashTable * hash, void * key, void * value)
{
  mono_value_hash_table_insert_replace (hash, key, value, 1);
}


mono_value_hash_table_insert_replace (struct MonoValueHashTable * hash, void * key, void * value, gboolean replace)
{
  _Bool D.6697;
  long int D.6698;
  long int D.6699;
  void * (*<T10a5>) (void *) D.6702;
  void * D.6703;
  _Bool D.6704;
  long int D.6705;
  long int D.6706;
  guint (*<Te9d>) (const void *) D.6711;
  int D.6712;
  unsigned int D.6713;
  struct Slot * D.6714;
  long unsigned int D.6715;
  long unsigned int D.6716;
  void * D.6717;
  long unsigned int D.6718;
  long unsigned int D.6719;
  int D.6722;
  void (*<Tdf1>) (void *) D.6726;
  void (*<Tdf1>) (void *) D.6729;
  void * D.6732;
  long unsigned int D.6733;
  long unsigned int D.6740;
  long unsigned int D.6741;
  int D.6743;
  int D.6744;
  int D.6745;
  int D.6746;
  guint hashcode;
  struct Slot * s;
  guint s_index;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  guint first_tombstone;
  gboolean have_tombstone;
  guint step;

  first_tombstone = 0;
  have_tombstone = 0;
  step = 0;
  D.6697 = value == 0B;
  D.6698 = (long int) D.6697;
  D.6699 = __builtin_expect (D.6698, 0);
  if (D.6699 != 0) goto <D.6700>; else goto <D.6701>;
  <D.6700>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-value-hash.c", 222, "value");
  <D.6701>:
  D.6702 = hash->key_extract_func;
  D.6703 = D.6702 (value);
  D.6704 = D.6703 != key;
  D.6705 = (long int) D.6704;
  D.6706 = __builtin_expect (D.6705, 0);
  if (D.6706 != 0) goto <D.6707>; else goto <D.6708>;
  <D.6707>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-value-hash.c", 223, "hash->key_extract_func (value) == key");
  <D.6708>:
  if (hash == 0B) goto <D.6709>; else goto <D.6710>;
  <D.6709>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-value-hash.c", 225, "hash != NULL");
  return;
  <D.6710>:
  D.6711 = hash->hash_func;
  hashcode = D.6711 (key);
  D.6712 = hash->table_mask;
  D.6713 = (unsigned int) D.6712;
  s_index = D.6713 & hashcode;
  D.6714 = hash->table;
  D.6715 = (long unsigned int) s_index;
  D.6716 = D.6715 * 8;
  s = D.6714 + D.6716;
  equal = hash->key_equal_func;
  goto <D.6649>;
  <D.6648>:
  {
    void * s_value;
    void * s_key;
    guint s_key_hash;

    D.6717 = s->value;
    D.6718 = (long unsigned int) D.6717;
    D.6719 = D.6718 & 18446744073709551612;
    s_value = (void *) D.6719;
    D.6702 = hash->key_extract_func;
    s_key = D.6702 (s_value);
    D.6711 = hash->hash_func;
    s_key_hash = D.6711 (s_key);
    if (s_key_hash == hashcode) goto <D.6721>; else goto <D.6720>;
    <D.6721>:
    D.6722 = equal (s_key, key);
    if (D.6722 != 0) goto <D.6723>; else goto <D.6720>;
    <D.6723>:
    if (replace != 0) goto <D.6724>; else goto <D.6725>;
    <D.6724>:
    D.6726 = hash->key_destroy_func;
    if (D.6726 != 0B) goto <D.6727>; else goto <D.6728>;
    <D.6727>:
    D.6726 = hash->key_destroy_func;
    D.6726 (s_key);
    <D.6728>:
    <D.6725>:
    D.6729 = hash->value_destroy_func;
    if (D.6729 != 0B) goto <D.6730>; else goto <D.6731>;
    <D.6730>:
    D.6729 = hash->value_destroy_func;
    D.6717 = s->value;
    D.6718 = (long unsigned int) D.6717;
    D.6719 = D.6718 & 18446744073709551612;
    D.6732 = (void *) D.6719;
    D.6729 (D.6732);
    <D.6731>:
    s->value = value;
    return;
    <D.6720>:
    D.6717 = s->value;
    D.6718 = (long unsigned int) D.6717;
    D.6733 = D.6718 & 1;
    if (D.6733 != 0) goto <D.6734>; else goto <D.6735>;
    <D.6734>:
    if (have_tombstone == 0) goto <D.6736>; else goto <D.6737>;
    <D.6736>:
    first_tombstone = s_index;
    have_tombstone = 1;
    <D.6737>:
    <D.6735>:
    step = step + 1;
    s_index = s_index + step;
    D.6712 = hash->table_mask;
    D.6713 = (unsigned int) D.6712;
    s_index = D.6713 & s_index;
    D.6714 = hash->table;
    D.6715 = (long unsigned int) s_index;
    D.6716 = D.6715 * 8;
    s = D.6714 + D.6716;
  }
  <D.6649>:
  D.6717 = s->value;
  D.6718 = (long unsigned int) D.6717;
  if (D.6718 != 0) goto <D.6648>; else goto <D.6650>;
  <D.6650>:
  if (have_tombstone != 0) goto <D.6738>; else goto <D.6739>;
  <D.6738>:
  D.6714 = hash->table;
  D.6740 = (long unsigned int) first_tombstone;
  D.6741 = D.6740 * 8;
  s = D.6714 + D.6741;
  goto <D.6742>;
  <D.6739>:
  D.6743 = hash->n_occupied;
  D.6744 = D.6743 + 1;
  hash->n_occupied = D.6744;
  <D.6742>:
  s->value = value;
  D.6745 = hash->in_use;
  D.6746 = D.6745 + 1;
  hash->in_use = D.6746;
  rehash (hash);
}


rehash (struct MonoValueHashTable * hash)
{
  int D.6751;
  int D.6752;
  int D.6754;
  int D.6755;
  int n_occupied;
  int table_size;

  n_occupied = hash->n_occupied;
  table_size = hash->table_size;
  D.6751 = hash->in_use;
  D.6752 = D.6751 * 4;
  if (D.6752 < table_size) goto <D.6753>; else goto <D.6748>;
  <D.6753>:
  if (table_size > 8) goto <D.6749>; else goto <D.6748>;
  <D.6748>:
  D.6754 = n_occupied / 16;
  D.6755 = D.6754 + n_occupied;
  if (D.6755 >= table_size) goto <D.6749>; else goto <D.6750>;
  <D.6749>:
  do_rehash (hash);
  <D.6750>:
}


do_rehash (struct MonoValueHashTable * hash)
{
  int D.6756;
  int D.6757;
  int D.6758;
  long unsigned int D.6759;
  long unsigned int D.6760;
  void * D.6761;
  long unsigned int D.6762;
  long unsigned int D.6763;
  void * D.6766;
  long unsigned int D.6767;
  long unsigned int D.6769;
  long unsigned int D.6770;
  void * (*<T10a5>) (void *) D.6771;
  guint (*<Te9d>) (const void *) D.6772;
  unsigned int D.6773;
  int D.6774;
  unsigned int D.6775;
  struct Slot * D.6776;
  long unsigned int D.6777;
  long unsigned int D.6778;
  void * D.6779;
  long unsigned int D.6780;
  int i;
  int old_size;
  struct Slot * old_table;

  old_size = hash->table_size;
  old_table = hash->table;
  D.6756 = hash->in_use;
  D.6757 = D.6756 * 2;
  mono_value_hash_table_set_shift_from_size (hash, D.6757);
  D.6758 = hash->table_size;
  D.6759 = (long unsigned int) D.6758;
  D.6760 = D.6759 * 8;
  D.6761 = monoeg_malloc0 (D.6760);
  hash->table = D.6761;
  i = 0;
  goto <D.6625>;
  <D.6624>:
  {
    struct Slot * s;
    struct Slot * new_s;
    guint hash_val;
    guint step;
    void * s_value;
    void * s_key;

    D.6762 = (long unsigned int) i;
    D.6763 = D.6762 * 8;
    s = old_table + D.6763;
    step = 0;
    D.6766 = s->value;
    D.6767 = (long unsigned int) D.6766;
    if (D.6767 == 0) goto <D.6764>; else goto <D.6768>;
    <D.6768>:
    D.6766 = s->value;
    D.6767 = (long unsigned int) D.6766;
    D.6769 = D.6767 & 1;
    if (D.6769 != 0) goto <D.6764>; else goto <D.6765>;
    <D.6764>:
    // predicted unlikely by continue predictor.
    goto <D.6620>;
    <D.6765>:
    D.6766 = s->value;
    D.6767 = (long unsigned int) D.6766;
    D.6770 = D.6767 & 18446744073709551612;
    s_value = (void *) D.6770;
    D.6771 = hash->key_extract_func;
    s_key = D.6771 (s_value);
    D.6772 = hash->hash_func;
    D.6773 = D.6772 (s_key);
    D.6774 = hash->table_mask;
    D.6775 = (unsigned int) D.6774;
    hash_val = D.6773 & D.6775;
    D.6776 = hash->table;
    D.6777 = (long unsigned int) hash_val;
    D.6778 = D.6777 * 8;
    new_s = D.6776 + D.6778;
    goto <D.6622>;
    <D.6621>:
    step = step + 1;
    hash_val = hash_val + step;
    D.6774 = hash->table_mask;
    D.6775 = (unsigned int) D.6774;
    hash_val = D.6775 & hash_val;
    D.6776 = hash->table;
    D.6777 = (long unsigned int) hash_val;
    D.6778 = D.6777 * 8;
    new_s = D.6776 + D.6778;
    <D.6622>:
    D.6779 = new_s->value;
    D.6780 = (long unsigned int) D.6779;
    if (D.6780 != 0) goto <D.6621>; else goto <D.6623>;
    <D.6623>:
    *new_s = *s;
  }
  <D.6620>:
  i = i + 1;
  <D.6625>:
  if (i < old_size) goto <D.6624>; else goto <D.6626>;
  <D.6626>:
  monoeg_g_free (old_table);
  D.6756 = hash->in_use;
  hash->n_occupied = D.6756;
}


mono_value_hash_table_set_shift_from_size (struct MonoValueHashTable * hash_table, gint size)
{
  gint shift;

  shift = mono_value_hash_table_find_closest_shift (size);
  shift = MAX_EXPR <shift, 3>;
  mono_value_hash_table_set_shift (hash_table, shift);
}


mono_value_hash_table_find_closest_shift (gint n)
{
  gint D.6781;
  gint i;

  i = 0;
  goto <D.6595>;
  <D.6594>:
  n = n >> 1;
  i = i + 1;
  <D.6595>:
  if (n != 0) goto <D.6594>; else goto <D.6596>;
  <D.6596>:
  D.6781 = i;
  return D.6781;
}


mono_value_hash_table_lookup (struct MonoValueHashTable * hash, const void * key)
{
  void * D.6785;
  void * D.6786;
  long unsigned int D.6787;
  long unsigned int D.6788;
  struct Slot * slot;

  slot = lookup_internal (hash, key);
  if (slot != 0B) goto <D.6783>; else goto <D.6784>;
  <D.6783>:
  D.6786 = slot->value;
  D.6787 = (long unsigned int) D.6786;
  D.6788 = D.6787 & 18446744073709551612;
  D.6785 = (void *) D.6788;
  return D.6785;
  <D.6784>:
  D.6785 = 0B;
  return D.6785;
}


lookup_internal (struct MonoValueHashTable * hash, const void * key)
{
  guint (*<Te9d>) (const void *) D.6790;
  int D.6791;
  unsigned int D.6792;
  struct Slot * D.6793;
  long unsigned int D.6794;
  long unsigned int D.6795;
  void * D.6796;
  long unsigned int D.6797;
  long unsigned int D.6798;
  void * (*<T10a5>) (void *) D.6799;
  void * D.6802;
  int D.6803;
  struct Slot * D.6806;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  guint hashcode;
  guint s_index;
  guint step;

  step = 0;
  D.6790 = hash->hash_func;
  hashcode = D.6790 (key);
  D.6791 = hash->table_mask;
  D.6792 = (unsigned int) D.6791;
  s_index = D.6792 & hashcode;
  D.6793 = hash->table;
  D.6794 = (long unsigned int) s_index;
  D.6795 = D.6794 * 8;
  s = D.6793 + D.6795;
  equal = hash->key_equal_func;
  goto <D.6669>;
  <D.6668>:
  {
    void * s_value;
    void * s_key;
    guint s_key_hash;

    D.6796 = s->value;
    D.6797 = (long unsigned int) D.6796;
    D.6798 = D.6797 & 18446744073709551612;
    s_value = (void *) D.6798;
    D.6799 = hash->key_extract_func;
    s_key = D.6799 (s_value);
    D.6790 = hash->hash_func;
    s_key_hash = D.6790 (s_key);
    if (s_key_hash == hashcode) goto <D.6800>; else goto <D.6801>;
    <D.6800>:
    D.6799 = hash->key_extract_func;
    D.6802 = D.6799 (s_value);
    D.6803 = equal (D.6802, key);
    if (D.6803 != 0) goto <D.6804>; else goto <D.6805>;
    <D.6804>:
    D.6806 = s;
    return D.6806;
    <D.6805>:
    <D.6801>:
    step = step + 1;
    s_index = s_index + step;
    D.6791 = hash->table_mask;
    D.6792 = (unsigned int) D.6791;
    s_index = D.6792 & s_index;
    D.6793 = hash->table;
    D.6794 = (long unsigned int) s_index;
    D.6795 = D.6794 * 8;
    s = D.6793 + D.6795;
  }
  <D.6669>:
  D.6796 = s->value;
  D.6797 = (long unsigned int) D.6796;
  if (D.6797 != 0) goto <D.6668>; else goto <D.6670>;
  <D.6670>:
  D.6806 = 0B;
  return D.6806;
}


mono_value_hash_table_destroy (struct MonoValueHashTable * hash)
{
  struct Slot * D.6810;
  long unsigned int D.6811;
  long unsigned int D.6812;
  void * D.6813;
  long unsigned int D.6814;
  long unsigned int D.6817;
  void (*<Tdf1>) (void *) D.6820;
  void * (*<T10a5>) (void *) D.6823;
  long unsigned int D.6824;
  void * D.6825;
  void * D.6826;
  void (*<Tdf1>) (void *) D.6827;
  int D.6830;
  int i;

  if (hash == 0B) goto <D.6808>; else goto <D.6809>;
  <D.6808>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-value-hash.c", 324, "hash != NULL");
  return;
  <D.6809>:
  i = 0;
  goto <D.6682>;
  <D.6681>:
  {
    struct Slot * s;

    D.6810 = hash->table;
    D.6811 = (long unsigned int) i;
    D.6812 = D.6811 * 8;
    s = D.6810 + D.6812;
    D.6813 = s->value;
    D.6814 = (long unsigned int) D.6813;
    if (D.6814 != 0) goto <D.6815>; else goto <D.6816>;
    <D.6815>:
    D.6813 = s->value;
    D.6814 = (long unsigned int) D.6813;
    D.6817 = D.6814 & 1;
    if (D.6817 == 0) goto <D.6818>; else goto <D.6819>;
    <D.6818>:
    D.6820 = hash->key_destroy_func;
    if (D.6820 != 0B) goto <D.6821>; else goto <D.6822>;
    <D.6821>:
    D.6820 = hash->key_destroy_func;
    D.6823 = hash->key_extract_func;
    D.6813 = s->value;
    D.6814 = (long unsigned int) D.6813;
    D.6824 = D.6814 & 18446744073709551612;
    D.6825 = (void *) D.6824;
    D.6826 = D.6823 (D.6825);
    D.6820 (D.6826);
    <D.6822>:
    D.6827 = hash->value_destroy_func;
    if (D.6827 != 0B) goto <D.6828>; else goto <D.6829>;
    <D.6828>:
    D.6827 = hash->value_destroy_func;
    D.6813 = s->value;
    D.6814 = (long unsigned int) D.6813;
    D.6824 = D.6814 & 18446744073709551612;
    D.6825 = (void *) D.6824;
    D.6827 (D.6825);
    <D.6829>:
    <D.6819>:
    <D.6816>:
  }
  i = i + 1;
  <D.6682>:
  D.6830 = hash->table_size;
  if (D.6830 > i) goto <D.6681>; else goto <D.6683>;
  <D.6683>:
  D.6810 = hash->table;
  monoeg_g_free (D.6810);
  monoeg_g_free (hash);
}


