GC_find_header (char * h)
{
  struct hdr * D.4524;
  long unsigned int h.0;
  long unsigned int D.4526;
  struct bottom_index * D.4527;
  long unsigned int D.4528;
  long unsigned int D.4529;

  h.0 = (long unsigned int) h;
  D.4526 = h.0 >> 22;
  D.4527 = GC_arrays._top_index[D.4526];
  h.0 = (long unsigned int) h;
  D.4528 = h.0 >> 12;
  D.4529 = D.4528 & 1023;
  D.4524 = D.4527->index[D.4529];
  return D.4524;
}


GC_scratch_alloc (word bytes)
{
  char * scratch_free_ptr.1;
  char * scratch_free_ptr.2;
  char * D.4533;
  char * D.4536;
  long unsigned int GC_page_size.3;
  long unsigned int D.4540;
  long unsigned int D.4541;
  sizetype D.4542;
  char * scratch_free_ptr.4;
  char * D.4544;
  char * D.4547;
  register char * result;

  result = scratch_free_ptr;
  bytes = bytes + 7;
  bytes = bytes & 4294967288;
  scratch_free_ptr.1 = scratch_free_ptr;
  scratch_free_ptr.2 = scratch_free_ptr.1 + bytes;
  scratch_free_ptr = scratch_free_ptr.2;
  D.4533 = GC_arrays._scratch_end_ptr;
  scratch_free_ptr.1 = scratch_free_ptr;
  if (D.4533 >= scratch_free_ptr.1) goto <D.4534>; else goto <D.4535>;
  <D.4534>:
  D.4536 = result;
  return D.4536;
  <D.4535>:
  {
    word bytes_to_get;

    bytes_to_get = 65536;
    if (bytes_to_get <= bytes) goto <D.4537>; else goto <D.4538>;
    <D.4537>:
    bytes_to_get = bytes;
    GC_page_size.3 = GC_page_size;
    D.4540 = GC_page_size.3 + bytes_to_get;
    bytes_to_get = D.4540 + 4294967295;
    GC_page_size.3 = GC_page_size;
    D.4541 = -GC_page_size.3;
    bytes_to_get = D.4541 & bytes_to_get;
    result = GC_unix_get_mem (bytes_to_get);
    scratch_free_ptr.1 = scratch_free_ptr;
    D.4542 = -bytes;
    scratch_free_ptr.4 = scratch_free_ptr.1 + D.4542;
    scratch_free_ptr = scratch_free_ptr.4;
    D.4544 = result + bytes;
    GC_arrays._scratch_last_end_ptr = D.4544;
    D.4536 = result;
    return D.4536;
    <D.4538>:
    result = GC_unix_get_mem (bytes_to_get);
    if (result == 0B) goto <D.4545>; else goto <D.4546>;
    <D.4545>:
    scratch_free_ptr.1 = scratch_free_ptr;
    D.4542 = -bytes;
    scratch_free_ptr.4 = scratch_free_ptr.1 + D.4542;
    scratch_free_ptr = scratch_free_ptr.4;
    bytes_to_get = bytes;
    GC_page_size.3 = GC_page_size;
    D.4540 = GC_page_size.3 + bytes_to_get;
    bytes_to_get = D.4540 + 4294967295;
    GC_page_size.3 = GC_page_size;
    D.4541 = -GC_page_size.3;
    bytes_to_get = D.4541 & bytes_to_get;
    D.4536 = GC_unix_get_mem (bytes_to_get);
    return D.4536;
    <D.4546>:
    scratch_free_ptr = result;
    scratch_free_ptr.1 = scratch_free_ptr;
    D.4547 = scratch_free_ptr.1 + bytes_to_get;
    GC_arrays._scratch_end_ptr = D.4547;
    D.4533 = GC_arrays._scratch_end_ptr;
    GC_arrays._scratch_last_end_ptr = D.4533;
    D.4536 = GC_scratch_alloc (bytes);
    return D.4536;
  }
}


GC_init_headers ()
{
  char * D.4549;
  struct bottom_index * D.4550;
  struct hdr * GC_invalid_header.5;
  struct hdr * GC_invalid_header.6;
  register unsigned int i;

  D.4549 = GC_scratch_alloc (4108);
  GC_arrays._all_nils = D.4549;
  D.4550 = GC_arrays._all_nils;
  memset (D.4550, 0, 4108);
  i = 0;
  goto <D.4436>;
  <D.4435>:
  D.4550 = GC_arrays._all_nils;
  GC_arrays._top_index[i] = D.4550;
  i = i + 1;
  <D.4436>:
  if (i <= 1023) goto <D.4435>; else goto <D.4437>;
  <D.4437>:
  GC_invalid_header.5 = alloc_hdr ();
  GC_invalid_header = GC_invalid_header.5;
  GC_invalid_header.6 = GC_invalid_header;
  GC_invalidate_map (GC_invalid_header.6);
}


memset (void * __dest, int __ch, size_t __len)
{
  int D.4555;
  int D.4560;
  void * D.4562;
  unsigned int D.4563;

  D.4555 = __builtin_constant_p (__len);
  if (D.4555 != 0) goto <D.4556>; else goto <D.4557>;
  <D.4556>:
  if (__len == 0) goto <D.4558>; else goto <D.4559>;
  <D.4558>:
  D.4560 = __builtin_constant_p (__ch);
  if (D.4560 == 0) goto <D.4553>; else goto <D.4561>;
  <D.4561>:
  if (__ch != 0) goto <D.4553>; else goto <D.4554>;
  <D.4553>:
  __warn_memset_zero_len ();
  D.4562 = __dest;
  return D.4562;
  <D.4554>:
  <D.4559>:
  <D.4557>:
  D.4563 = __builtin_object_size (__dest, 0);
  D.4562 = __builtin___memset_chk (__dest, __ch, __len, D.4563);
  return D.4562;
}


alloc_hdr ()
{
  struct hdr * hdr_free_list.7;
  struct hblk * hdr_free_list.8;
  struct hdr * D.4570;
  register struct hdr * result;

  hdr_free_list.7 = hdr_free_list;
  if (hdr_free_list.7 == 0B) goto <D.4566>; else goto <D.4567>;
  <D.4566>:
  result = GC_scratch_alloc (152);
  goto <D.4568>;
  <D.4567>:
  result = hdr_free_list;
  hdr_free_list.8 = result->hb_next;
  hdr_free_list = hdr_free_list.8;
  <D.4568>:
  D.4570 = result;
  return D.4570;
}


GC_install_header (struct hblk * h)
{
  long unsigned int h.9;
  int D.4573;
  struct hblkhdr * D.4576;
  long unsigned int D.4577;
  struct bottom_index * D.4578;
  long unsigned int D.4579;
  long unsigned int D.4580;
  long unsigned int GC_gc_no.10;
  short unsigned int D.4582;
  struct hdr * result;

  h.9 = (long unsigned int) h;
  D.4573 = get_index (h.9);
  if (D.4573 == 0) goto <D.4574>; else goto <D.4575>;
  <D.4574>:
  D.4576 = 0B;
  return D.4576;
  <D.4575>:
  result = alloc_hdr ();
  h.9 = (long unsigned int) h;
  D.4577 = h.9 >> 22;
  D.4578 = GC_arrays._top_index[D.4577];
  h.9 = (long unsigned int) h;
  D.4579 = h.9 >> 12;
  D.4580 = D.4579 & 1023;
  D.4578->index[D.4580] = result;
  GC_gc_no.10 = GC_gc_no;
  D.4582 = (short unsigned int) GC_gc_no.10;
  result->hb_last_reclaimed = D.4582;
  D.4576 = result;
  return D.4576;
}


get_index (word addr)
{
  struct bottom_index * D.4584;
  struct bottom_index * D.4585;
  GC_bool D.4588;
  long unsigned int D.4592;
  word hi;
  struct bottom_index * r;
  struct bottom_index * p;
  struct bottom_index * * prev;
  struct bottom_index * pi;

  hi = addr >> 22;
  D.4584 = GC_arrays._top_index[hi];
  D.4585 = GC_arrays._all_nils;
  if (D.4584 != D.4585) goto <D.4586>; else goto <D.4587>;
  <D.4586>:
  D.4588 = 1;
  return D.4588;
  <D.4587>:
  r = GC_scratch_alloc (4108);
  if (r == 0B) goto <D.4589>; else goto <D.4590>;
  <D.4589>:
  D.4588 = 0;
  return D.4588;
  <D.4590>:
  GC_arrays._top_index[hi] = r;
  memset (r, 0, 4108);
  r->key = hi;
  prev = &GC_all_bottom_indices;
  pi = 0B;
  goto <D.4447>;
  <D.4446>:
  pi = p;
  prev = &p->asc_link;
  <D.4447>:
  p = *prev;
  if (p != 0B) goto <D.4591>; else goto <D.4448>;
  <D.4591>:
  D.4592 = p->key;
  if (D.4592 < hi) goto <D.4446>; else goto <D.4448>;
  <D.4448>:
  r->desc_link = pi;
  if (p == 0B) goto <D.4593>; else goto <D.4594>;
  <D.4593>:
  GC_all_bottom_indices_end = r;
  goto <D.4595>;
  <D.4594>:
  p->desc_link = r;
  <D.4595>:
  r->asc_link = p;
  *prev = r;
  D.4588 = 1;
  return D.4588;
}


GC_install_counts (struct hblk * h, word sz)
{
  long unsigned int hbp.11;
  int D.4598;
  GC_bool D.4601;
  char * D.4602;
  long unsigned int h.12;
  long unsigned int D.4604;
  long unsigned int D.4605;
  int D.4606;
  int hbp.13;
  int h.14;
  int D.4611;
  long unsigned int D.4612;
  struct bottom_index * D.4613;
  long unsigned int D.4614;
  long unsigned int D.4615;
  long unsigned int i.15;
  long unsigned int D.4617;
  struct hdr * D.4618;
  register struct hblk * hbp;
  register int i;

  hbp = h;
  goto <D.4460>;
  <D.4459>:
  hbp.11 = (long unsigned int) hbp;
  D.4598 = get_index (hbp.11);
  if (D.4598 == 0) goto <D.4599>; else goto <D.4600>;
  <D.4599>:
  D.4601 = 0;
  return D.4601;
  <D.4600>:
  hbp = hbp + 4194304;
  <D.4460>:
  D.4602 = h + sz;
  if (D.4602 > hbp) goto <D.4459>; else goto <D.4461>;
  <D.4461>:
  h.12 = (long unsigned int) h;
  D.4604 = h.12 + sz;
  D.4605 = D.4604 + 4294967295;
  D.4606 = get_index (D.4605);
  if (D.4606 == 0) goto <D.4607>; else goto <D.4608>;
  <D.4607>:
  D.4601 = 0;
  return D.4601;
  <D.4608>:
  hbp = h + 4096;
  goto <D.4463>;
  <D.4462>:
  hbp.13 = (int) hbp;
  h.14 = (int) h;
  D.4611 = hbp.13 - h.14;
  i = D.4611 >> 12;
  hbp.11 = (long unsigned int) hbp;
  D.4612 = hbp.11 >> 22;
  D.4613 = GC_arrays._top_index[D.4612];
  hbp.11 = (long unsigned int) hbp;
  D.4614 = hbp.11 >> 12;
  D.4615 = D.4614 & 1023;
  i.15 = (long unsigned int) i;
  D.4617 = MIN_EXPR <i.15, 4095>;
  D.4618 = (struct hdr *) D.4617;
  D.4613->index[D.4615] = D.4618;
  hbp = hbp + 4096;
  <D.4463>:
  D.4602 = h + sz;
  if (D.4602 > hbp) goto <D.4462>; else goto <D.4464>;
  <D.4464>:
  D.4601 = 1;
  return D.4601;
}


GC_remove_header (struct hblk * h)
{
  long unsigned int h.16;
  long unsigned int D.4621;
  struct bottom_index * D.4622;
  long unsigned int D.4623;
  long unsigned int D.4624;
  struct hdr * D.4625;
  struct hdr * * ha;

  h.16 = (long unsigned int) h;
  D.4621 = h.16 >> 22;
  D.4622 = GC_arrays._top_index[D.4621];
  h.16 = (long unsigned int) h;
  D.4623 = h.16 >> 12;
  D.4624 = D.4623 & 1023;
  ha = &D.4622->index[D.4624];
  D.4625 = *ha;
  free_hdr (D.4625);
  *ha = 0B;
}


free_hdr (struct hdr * hhdr)
{
  struct hdr * hdr_free_list.17;

  hdr_free_list.17 = hdr_free_list;
  hhdr->hb_next = hdr_free_list.17;
  hdr_free_list = hhdr;
}


GC_remove_counts (struct hblk * h, word sz)
{
  long unsigned int hbp.18;
  long unsigned int D.4628;
  struct bottom_index * D.4629;
  long unsigned int D.4630;
  long unsigned int D.4631;
  char * D.4632;
  register struct hblk * hbp;

  hbp = h + 4096;
  goto <D.4475>;
  <D.4474>:
  hbp.18 = (long unsigned int) hbp;
  D.4628 = hbp.18 >> 22;
  D.4629 = GC_arrays._top_index[D.4628];
  hbp.18 = (long unsigned int) hbp;
  D.4630 = hbp.18 >> 12;
  D.4631 = D.4630 & 1023;
  D.4629->index[D.4631] = 0B;
  hbp = hbp + 4096;
  <D.4475>:
  D.4632 = h + sz;
  if (D.4632 > hbp) goto <D.4474>; else goto <D.4476>;
  <D.4476>:
}


GC_apply_to_all_blocks (void (*<Tbdb>) (struct hblk *, word) fn, word client_data)
{
  struct hdr * D.4633;
  long unsigned int D.4634;
  map_entry_type * D.4637;
  map_entry_type * GC_invalid_map.19;
  long unsigned int D.4641;
  long unsigned int D.4642;
  long unsigned int j.20;
  long unsigned int D.4644;
  long unsigned int D.4645;
  struct hblk * D.4646;
  long unsigned int D.4651;
  register int j;
  register struct bottom_index * index_p;

  index_p = GC_all_bottom_indices;
  goto <D.4489>;
  <D.4488>:
  j = 1023;
  goto <D.4486>;
  <D.4485>:
  D.4633 = index_p->index[j];
  D.4634 = (long unsigned int) D.4633;
  if (D.4634 > 4095) goto <D.4635>; else goto <D.4636>;
  <D.4635>:
  D.4633 = index_p->index[j];
  D.4637 = D.4633->hb_map;
  GC_invalid_map.19 = GC_invalid_map;
  if (D.4637 != GC_invalid_map.19) goto <D.4639>; else goto <D.4640>;
  <D.4639>:
  D.4641 = index_p->key;
  D.4642 = D.4641 << 10;
  j.20 = (long unsigned int) j;
  D.4644 = D.4642 + j.20;
  D.4645 = D.4644 << 12;
  D.4646 = (struct hblk *) D.4645;
  fn (D.4646, client_data);
  <D.4640>:
  j = j + -1;
  goto <D.4647>;
  <D.4636>:
  D.4633 = index_p->index[j];
  if (D.4633 == 0B) goto <D.4648>; else goto <D.4649>;
  <D.4648>:
  j = j + -1;
  goto <D.4650>;
  <D.4649>:
  j.20 = (long unsigned int) j;
  D.4633 = index_p->index[j];
  D.4634 = (long unsigned int) D.4633;
  D.4651 = j.20 - D.4634;
  j = (int) D.4651;
  <D.4650>:
  <D.4647>:
  <D.4486>:
  if (j >= 0) goto <D.4485>; else goto <D.4487>;
  <D.4487>:
  index_p = index_p->asc_link;
  <D.4489>:
  if (index_p != 0B) goto <D.4488>; else goto <D.4490>;
  <D.4490>:
}


GC_next_used_block (struct hblk * h)
{
  long unsigned int h.21;
  long unsigned int D.4653;
  long unsigned int D.4654;
  struct bottom_index * D.4655;
  long unsigned int D.4659;
  long unsigned int hhdr.22;
  map_entry_type * D.4664;
  map_entry_type * GC_invalid_map.23;
  struct hblk * D.4668;
  long unsigned int D.4669;
  long unsigned int D.4670;
  long unsigned int D.4671;
  long unsigned int D.4672;
  long unsigned int D.4673;
  register struct bottom_index * bi;
  register word j;

  h.21 = (long unsigned int) h;
  D.4653 = h.21 >> 12;
  j = D.4653 & 1023;
  h.21 = (long unsigned int) h;
  D.4654 = h.21 >> 22;
  bi = GC_arrays._top_index[D.4654];
  D.4655 = GC_arrays._all_nils;
  if (D.4655 == bi) goto <D.4656>; else goto <D.4657>;
  <D.4656>:
  {
    register word hi;

    h.21 = (long unsigned int) h;
    hi = h.21 >> 22;
    bi = GC_all_bottom_indices;
    goto <D.4498>;
    <D.4497>:
    bi = bi->asc_link;
    <D.4498>:
    if (bi != 0B) goto <D.4658>; else goto <D.4499>;
    <D.4658>:
    D.4659 = bi->key;
    if (D.4659 < hi) goto <D.4497>; else goto <D.4499>;
    <D.4499>:
    j = 0;
  }
  <D.4657>:
  goto <D.4505>;
  <D.4504>:
  goto <D.4502>;
  <D.4501>:
  {
    struct hdr * hhdr;

    hhdr = bi->index[j];
    hhdr.22 = (long unsigned int) hhdr;
    if (hhdr.22 <= 4095) goto <D.4661>; else goto <D.4662>;
    <D.4661>:
    j = j + 1;
    goto <D.4663>;
    <D.4662>:
    D.4664 = hhdr->hb_map;
    GC_invalid_map.23 = GC_invalid_map;
    if (D.4664 != GC_invalid_map.23) goto <D.4666>; else goto <D.4667>;
    <D.4666>:
    D.4659 = bi->key;
    D.4669 = D.4659 << 10;
    D.4670 = D.4669 + j;
    D.4671 = D.4670 << 12;
    D.4668 = (struct hblk *) D.4671;
    return D.4668;
    <D.4667>:
    D.4672 = hhdr->hb_sz;
    D.4673 = D.4672 >> 12;
    j = D.4673 + j;
    <D.4663>:
  }
  <D.4502>:
  if (j <= 1023) goto <D.4501>; else goto <D.4503>;
  <D.4503>:
  j = 0;
  bi = bi->asc_link;
  <D.4505>:
  if (bi != 0B) goto <D.4504>; else goto <D.4506>;
  <D.4506>:
  D.4668 = 0B;
  return D.4668;
}


GC_prev_block (struct hblk * h)
{
  long unsigned int h.24;
  long unsigned int D.4676;
  long int D.4677;
  long unsigned int D.4678;
  struct bottom_index * D.4679;
  long unsigned int D.4683;
  long unsigned int hhdr.25;
  long int hhdr.26;
  struct hblk * D.4692;
  long unsigned int D.4693;
  long unsigned int j.27;
  long unsigned int D.4695;
  long unsigned int D.4696;
  register struct bottom_index * bi;
  register signed_word j;

  h.24 = (long unsigned int) h;
  D.4676 = h.24 >> 12;
  D.4677 = (long int) D.4676;
  j = D.4677 & 1023;
  h.24 = (long unsigned int) h;
  D.4678 = h.24 >> 22;
  bi = GC_arrays._top_index[D.4678];
  D.4679 = GC_arrays._all_nils;
  if (D.4679 == bi) goto <D.4680>; else goto <D.4681>;
  <D.4680>:
  {
    register word hi;

    h.24 = (long unsigned int) h;
    hi = h.24 >> 22;
    bi = GC_all_bottom_indices_end;
    goto <D.4514>;
    <D.4513>:
    bi = bi->desc_link;
    <D.4514>:
    if (bi != 0B) goto <D.4682>; else goto <D.4515>;
    <D.4682>:
    D.4683 = bi->key;
    if (D.4683 > hi) goto <D.4513>; else goto <D.4515>;
    <D.4515>:
    j = 1023;
  }
  <D.4681>:
  goto <D.4521>;
  <D.4520>:
  goto <D.4518>;
  <D.4517>:
  {
    struct hdr * hhdr;

    hhdr = bi->index[j];
    if (hhdr == 0B) goto <D.4684>; else goto <D.4685>;
    <D.4684>:
    j = j + -1;
    goto <D.4686>;
    <D.4685>:
    hhdr.25 = (long unsigned int) hhdr;
    if (hhdr.25 <= 4095) goto <D.4688>; else goto <D.4689>;
    <D.4688>:
    hhdr.26 = (long int) hhdr;
    j = j - hhdr.26;
    goto <D.4691>;
    <D.4689>:
    D.4683 = bi->key;
    D.4693 = D.4683 << 10;
    j.27 = (long unsigned int) j;
    D.4695 = D.4693 + j.27;
    D.4696 = D.4695 << 12;
    D.4692 = (struct hblk *) D.4696;
    return D.4692;
    <D.4691>:
    <D.4686>:
  }
  <D.4518>:
  if (j >= 0) goto <D.4517>; else goto <D.4519>;
  <D.4519>:
  j = 1023;
  bi = bi->desc_link;
  <D.4521>:
  if (bi != 0B) goto <D.4520>; else goto <D.4522>;
  <D.4522>:
  D.4692 = 0B;
  return D.4692;
}


