__attribute__((visibility ("hidden")))
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.6592;
  long unsigned int D.6593;
  long unsigned int D.6594;
  void * D.6595;
  struct MonoValueHashTable * D.6596;
  struct MonoValueHashTable * hash;

  if (hash_func == 0B) goto <D.6588>; else goto <D.6589>;
  <D.6588>:
  hash_func = monoeg_g_direct_hash;
  <D.6589>:
  if (key_equal_func == 0B) goto <D.6590>; else goto <D.6591>;
  <D.6590>:
  key_equal_func = monoeg_g_direct_equal;
  <D.6591>:
  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.6592 = hash->table_size;
  D.6593 = (long unsigned int) D.6592;
  D.6594 = D.6593 * 8;
  D.6595 = monoeg_malloc0 (D.6594);
  hash->table = D.6595;
  D.6596 = hash;
  return D.6596;
}


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

  mask = 0;
  D.6598 = 1 << shift;
  hash_table->table_size = D.6598;
  i = 0;
  goto <D.6491>;
  <D.6490>:
  mask = mask << 1;
  mask = mask | 1;
  i = i + 1;
  <D.6491>:
  if (i < shift) goto <D.6490>; else goto <D.6492>;
  <D.6492>:
  mask.0 = (int) mask;
  hash_table->table_mask = mask.0;
}


__attribute__((visibility ("hidden")))
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.6600;
  long int D.6601;
  long int D.6602;
  void * (*<T11e6>) (void *) D.6605;
  void * D.6606;
  _Bool D.6607;
  long int D.6608;
  long int D.6609;
  guint (*<Tfe2>) (const void *) D.6614;
  int D.6615;
  unsigned int D.6616;
  struct Slot * D.6617;
  long unsigned int D.6618;
  long unsigned int D.6619;
  void * D.6620;
  long unsigned int D.6621;
  long unsigned int D.6622;
  int D.6625;
  void (*<Tf36>) (void *) D.6629;
  void (*<Tf36>) (void *) D.6632;
  void * D.6635;
  long unsigned int D.6636;
  long unsigned int D.6643;
  long unsigned int D.6644;
  int D.6646;
  int D.6647;
  int D.6648;
  int D.6649;
  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.6600 = value == 0B;
  D.6601 = (long int) D.6600;
  D.6602 = __builtin_expect (D.6601, 0);
  if (D.6602 != 0) goto <D.6603>; else goto <D.6604>;
  <D.6603>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-value-hash.c", 222, "value");
  <D.6604>:
  D.6605 = hash->key_extract_func;
  D.6606 = D.6605 (value);
  D.6607 = D.6606 != key;
  D.6608 = (long int) D.6607;
  D.6609 = __builtin_expect (D.6608, 0);
  if (D.6609 != 0) goto <D.6610>; else goto <D.6611>;
  <D.6610>:
  monoeg_assertion_message ("* Assertion at %s:%d, condition `%s\' not met\n", "mono-value-hash.c", 223, "hash->key_extract_func (value) == key");
  <D.6611>:
  if (hash == 0B) goto <D.6612>; else goto <D.6613>;
  <D.6612>:
  monoeg_g_log (0B, 8, "%s:%d: assertion \'%s\' failed", "mono-value-hash.c", 225, "hash != NULL");
  return;
  <D.6613>:
  D.6614 = hash->hash_func;
  hashcode = D.6614 (key);
  D.6615 = hash->table_mask;
  D.6616 = (unsigned int) D.6615;
  s_index = D.6616 & hashcode;
  D.6617 = hash->table;
  D.6618 = (long unsigned int) s_index;
  D.6619 = D.6618 * 8;
  s = D.6617 + D.6619;
  equal = hash->key_equal_func;
  goto <D.6552>;
  <D.6551>:
  {
    void * s_value;
    void * s_key;
    guint s_key_hash;

    D.6620 = s->value;
    D.6621 = (long unsigned int) D.6620;
    D.6622 = D.6621 & 18446744073709551612;
    s_value = (void *) D.6622;
    D.6605 = hash->key_extract_func;
    s_key = D.6605 (s_value);
    D.6614 = hash->hash_func;
    s_key_hash = D.6614 (s_key);
    if (s_key_hash == hashcode) goto <D.6624>; else goto <D.6623>;
    <D.6624>:
    D.6625 = equal (s_key, key);
    if (D.6625 != 0) goto <D.6626>; else goto <D.6623>;
    <D.6626>:
    if (replace != 0) goto <D.6627>; else goto <D.6628>;
    <D.6627>:
    D.6629 = hash->key_destroy_func;
    if (D.6629 != 0B) goto <D.6630>; else goto <D.6631>;
    <D.6630>:
    D.6629 = hash->key_destroy_func;
    D.6629 (s_key);
    <D.6631>:
    <D.6628>:
    D.6632 = hash->value_destroy_func;
    if (D.6632 != 0B) goto <D.6633>; else goto <D.6634>;
    <D.6633>:
    D.6632 = hash->value_destroy_func;
    D.6620 = s->value;
    D.6621 = (long unsigned int) D.6620;
    D.6622 = D.6621 & 18446744073709551612;
    D.6635 = (void *) D.6622;
    D.6632 (D.6635);
    <D.6634>:
    s->value = value;
    return;
    <D.6623>:
    D.6620 = s->value;
    D.6621 = (long unsigned int) D.6620;
    D.6636 = D.6621 & 1;
    if (D.6636 != 0) goto <D.6637>; else goto <D.6638>;
    <D.6637>:
    if (have_tombstone == 0) goto <D.6639>; else goto <D.6640>;
    <D.6639>:
    first_tombstone = s_index;
    have_tombstone = 1;
    <D.6640>:
    <D.6638>:
    step = step + 1;
    s_index = s_index + step;
    D.6615 = hash->table_mask;
    D.6616 = (unsigned int) D.6615;
    s_index = D.6616 & s_index;
    D.6617 = hash->table;
    D.6618 = (long unsigned int) s_index;
    D.6619 = D.6618 * 8;
    s = D.6617 + D.6619;
  }
  <D.6552>:
  D.6620 = s->value;
  D.6621 = (long unsigned int) D.6620;
  if (D.6621 != 0) goto <D.6551>; else goto <D.6553>;
  <D.6553>:
  if (have_tombstone != 0) goto <D.6641>; else goto <D.6642>;
  <D.6641>:
  D.6617 = hash->table;
  D.6643 = (long unsigned int) first_tombstone;
  D.6644 = D.6643 * 8;
  s = D.6617 + D.6644;
  goto <D.6645>;
  <D.6642>:
  D.6646 = hash->n_occupied;
  D.6647 = D.6646 + 1;
  hash->n_occupied = D.6647;
  <D.6645>:
  s->value = value;
  D.6648 = hash->in_use;
  D.6649 = D.6648 + 1;
  hash->in_use = D.6649;
  rehash (hash);
}


rehash (struct MonoValueHashTable * hash)
{
  int D.6654;
  int D.6655;
  int D.6657;
  int D.6658;
  int n_occupied;
  int table_size;

  n_occupied = hash->n_occupied;
  table_size = hash->table_size;
  D.6654 = hash->in_use;
  D.6655 = D.6654 * 4;
  if (D.6655 < table_size) goto <D.6656>; else goto <D.6651>;
  <D.6656>:
  if (table_size > 8) goto <D.6652>; else goto <D.6651>;
  <D.6651>:
  D.6657 = n_occupied / 16;
  D.6658 = D.6657 + n_occupied;
  if (D.6658 >= table_size) goto <D.6652>; else goto <D.6653>;
  <D.6652>:
  do_rehash (hash);
  <D.6653>:
}


do_rehash (struct MonoValueHashTable * hash)
{
  int D.6659;
  int D.6660;
  int D.6661;
  long unsigned int D.6662;
  long unsigned int D.6663;
  void * D.6664;
  long unsigned int D.6665;
  long unsigned int D.6666;
  void * D.6669;
  long unsigned int D.6670;
  long unsigned int D.6672;
  long unsigned int D.6673;
  void * (*<T11e6>) (void *) D.6674;
  guint (*<Tfe2>) (const void *) D.6675;
  unsigned int D.6676;
  int D.6677;
  unsigned int D.6678;
  struct Slot * D.6679;
  long unsigned int D.6680;
  long unsigned int D.6681;
  void * D.6682;
  long unsigned int D.6683;
  int i;
  int old_size;
  struct Slot * old_table;

  old_size = hash->table_size;
  old_table = hash->table;
  D.6659 = hash->in_use;
  D.6660 = D.6659 * 2;
  mono_value_hash_table_set_shift_from_size (hash, D.6660);
  D.6661 = hash->table_size;
  D.6662 = (long unsigned int) D.6661;
  D.6663 = D.6662 * 8;
  D.6664 = monoeg_malloc0 (D.6663);
  hash->table = D.6664;
  i = 0;
  goto <D.6528>;
  <D.6527>:
  {
    struct Slot * s;
    struct Slot * new_s;
    guint hash_val;
    guint step;
    void * s_value;
    void * s_key;

    D.6665 = (long unsigned int) i;
    D.6666 = D.6665 * 8;
    s = old_table + D.6666;
    step = 0;
    D.6669 = s->value;
    D.6670 = (long unsigned int) D.6669;
    if (D.6670 == 0) goto <D.6667>; else goto <D.6671>;
    <D.6671>:
    D.6669 = s->value;
    D.6670 = (long unsigned int) D.6669;
    D.6672 = D.6670 & 1;
    if (D.6672 != 0) goto <D.6667>; else goto <D.6668>;
    <D.6667>:
    // predicted unlikely by continue predictor.
    goto <D.6523>;
    <D.6668>:
    D.6669 = s->value;
    D.6670 = (long unsigned int) D.6669;
    D.6673 = D.6670 & 18446744073709551612;
    s_value = (void *) D.6673;
    D.6674 = hash->key_extract_func;
    s_key = D.6674 (s_value);
    D.6675 = hash->hash_func;
    D.6676 = D.6675 (s_key);
    D.6677 = hash->table_mask;
    D.6678 = (unsigned int) D.6677;
    hash_val = D.6676 & D.6678;
    D.6679 = hash->table;
    D.6680 = (long unsigned int) hash_val;
    D.6681 = D.6680 * 8;
    new_s = D.6679 + D.6681;
    goto <D.6525>;
    <D.6524>:
    step = step + 1;
    hash_val = hash_val + step;
    D.6677 = hash->table_mask;
    D.6678 = (unsigned int) D.6677;
    hash_val = D.6678 & hash_val;
    D.6679 = hash->table;
    D.6680 = (long unsigned int) hash_val;
    D.6681 = D.6680 * 8;
    new_s = D.6679 + D.6681;
    <D.6525>:
    D.6682 = new_s->value;
    D.6683 = (long unsigned int) D.6682;
    if (D.6683 != 0) goto <D.6524>; else goto <D.6526>;
    <D.6526>:
    *new_s = *s;
  }
  <D.6523>:
  i = i + 1;
  <D.6528>:
  if (i < old_size) goto <D.6527>; else goto <D.6529>;
  <D.6529>:
  monoeg_g_free (old_table);
  D.6659 = hash->in_use;
  hash->n_occupied = D.6659;
}


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.6684;
  gint i;

  i = 0;
  goto <D.6498>;
  <D.6497>:
  n = n >> 1;
  i = i + 1;
  <D.6498>:
  if (n != 0) goto <D.6497>; else goto <D.6499>;
  <D.6499>:
  D.6684 = i;
  return D.6684;
}


__attribute__((visibility ("hidden")))
mono_value_hash_table_lookup (struct MonoValueHashTable * hash, const void * key)
{
  void * D.6688;
  void * D.6689;
  long unsigned int D.6690;
  long unsigned int D.6691;
  struct Slot * slot;

  slot = lookup_internal (hash, key);
  if (slot != 0B) goto <D.6686>; else goto <D.6687>;
  <D.6686>:
  D.6689 = slot->value;
  D.6690 = (long unsigned int) D.6689;
  D.6691 = D.6690 & 18446744073709551612;
  D.6688 = (void *) D.6691;
  return D.6688;
  <D.6687>:
  D.6688 = 0B;
  return D.6688;
}


lookup_internal (struct MonoValueHashTable * hash, const void * key)
{
  guint (*<Tfe2>) (const void *) D.6693;
  int D.6694;
  unsigned int D.6695;
  struct Slot * D.6696;
  long unsigned int D.6697;
  long unsigned int D.6698;
  void * D.6699;
  long unsigned int D.6700;
  long unsigned int D.6701;
  void * (*<T11e6>) (void *) D.6702;
  void * D.6705;
  int D.6706;
  struct Slot * D.6709;
  gboolean (*GEqualFunc) (const void *, const void *) equal;
  struct Slot * s;
  guint hashcode;
  guint s_index;
  guint step;

  step = 0;
  D.6693 = hash->hash_func;
  hashcode = D.6693 (key);
  D.6694 = hash->table_mask;
  D.6695 = (unsigned int) D.6694;
  s_index = D.6695 & hashcode;
  D.6696 = hash->table;
  D.6697 = (long unsigned int) s_index;
  D.6698 = D.6697 * 8;
  s = D.6696 + D.6698;
  equal = hash->key_equal_func;
  goto <D.6572>;
  <D.6571>:
  {
    void * s_value;
    void * s_key;
    guint s_key_hash;

    D.6699 = s->value;
    D.6700 = (long unsigned int) D.6699;
    D.6701 = D.6700 & 18446744073709551612;
    s_value = (void *) D.6701;
    D.6702 = hash->key_extract_func;
    s_key = D.6702 (s_value);
    D.6693 = hash->hash_func;
    s_key_hash = D.6693 (s_key);
    if (s_key_hash == hashcode) goto <D.6703>; else goto <D.6704>;
    <D.6703>:
    D.6702 = hash->key_extract_func;
    D.6705 = D.6702 (s_value);
    D.6706 = equal (D.6705, key);
    if (D.6706 != 0) goto <D.6707>; else goto <D.6708>;
    <D.6707>:
    D.6709 = s;
    return D.6709;
    <D.6708>:
    <D.6704>:
    step = step + 1;
    s_index = s_index + step;
    D.6694 = hash->table_mask;
    D.6695 = (unsigned int) D.6694;
    s_index = D.6695 & s_index;
    D.6696 = hash->table;
    D.6697 = (long unsigned int) s_index;
    D.6698 = D.6697 * 8;
    s = D.6696 + D.6698;
  }
  <D.6572>:
  D.6699 = s->value;
  D.6700 = (long unsigned int) D.6699;
  if (D.6700 != 0) goto <D.6571>; else goto <D.6573>;
  <D.6573>:
  D.6709 = 0B;
  return D.6709;
}


__attribute__((visibility ("hidden")))
mono_value_hash_table_destroy (struct MonoValueHashTable * hash)
{
  struct Slot * D.6713;
  long unsigned int D.6714;
  long unsigned int D.6715;
  void * D.6716;
  long unsigned int D.6717;
  long unsigned int D.6720;
  void (*<Tf36>) (void *) D.6723;
  void * (*<T11e6>) (void *) D.6726;
  long unsigned int D.6727;
  void * D.6728;
  void * D.6729;
  void (*<Tf36>) (void *) D.6730;
  int D.6733;
  int i;

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

    D.6713 = hash->table;
    D.6714 = (long unsigned int) i;
    D.6715 = D.6714 * 8;
    s = D.6713 + D.6715;
    D.6716 = s->value;
    D.6717 = (long unsigned int) D.6716;
    if (D.6717 != 0) goto <D.6718>; else goto <D.6719>;
    <D.6718>:
    D.6716 = s->value;
    D.6717 = (long unsigned int) D.6716;
    D.6720 = D.6717 & 1;
    if (D.6720 == 0) goto <D.6721>; else goto <D.6722>;
    <D.6721>:
    D.6723 = hash->key_destroy_func;
    if (D.6723 != 0B) goto <D.6724>; else goto <D.6725>;
    <D.6724>:
    D.6723 = hash->key_destroy_func;
    D.6726 = hash->key_extract_func;
    D.6716 = s->value;
    D.6717 = (long unsigned int) D.6716;
    D.6727 = D.6717 & 18446744073709551612;
    D.6728 = (void *) D.6727;
    D.6729 = D.6726 (D.6728);
    D.6723 (D.6729);
    <D.6725>:
    D.6730 = hash->value_destroy_func;
    if (D.6730 != 0B) goto <D.6731>; else goto <D.6732>;
    <D.6731>:
    D.6730 = hash->value_destroy_func;
    D.6716 = s->value;
    D.6717 = (long unsigned int) D.6716;
    D.6727 = D.6717 & 18446744073709551612;
    D.6728 = (void *) D.6727;
    D.6730 (D.6728);
    <D.6732>:
    <D.6722>:
    <D.6719>:
  }
  i = i + 1;
  <D.6585>:
  D.6733 = hash->table_size;
  if (D.6733 > i) goto <D.6584>; else goto <D.6586>;
  <D.6586>:
  D.6713 = hash->table;
  monoeg_g_free (D.6713);
  monoeg_g_free (hash);
}


