1  struct obstack {};
       2  struct bitmap_head_def;
       3  typedef struct bitmap_head_def *bitmap;
       4  typedef const struct bitmap_head_def *const_bitmap;
       5  typedef unsigned long BITMAP_WORD;
       6  typedef struct bitmap_obstack
       7  {
       8    struct bitmap_element_def *elements;
       9    struct bitmap_head_def *heads;
      10    struct obstack obstack;
      11  } bitmap_obstack;
      12  typedef struct bitmap_element_def
      13  {
      14    struct bitmap_element_def *next;
      15    struct bitmap_element_def *prev;
      16    unsigned int indx;
      17    BITMAP_WORD bits[((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u))];
      18  } bitmap_element;
      19  
      20  struct bitmap_descriptor;
      21  
      22  typedef struct bitmap_head_def {
      23      bitmap_element *first;
      24      bitmap_element *current;
      25      unsigned int indx;
      26      bitmap_obstack *obstack;
      27  } bitmap_head;
      28  
      29  bitmap_element bitmap_zero_bits;
      30  
      31  typedef struct
      32  {
      33    bitmap_element *elt1;
      34    bitmap_element *elt2;
      35    unsigned word_no;
      36    BITMAP_WORD bits;
      37  } bitmap_iterator;
      38  
      39  static void __attribute__((noinline))
      40  bmp_iter_set_init (bitmap_iterator *bi, const_bitmap map,
      41  		   unsigned start_bit, unsigned *bit_no)
      42  {
      43    bi->elt1 = map->first;
      44    bi->elt2 = ((void *)0);
      45  
      46    while (1)
      47      {
      48        if (!bi->elt1)
      49  	{
      50  	  bi->elt1 = &bitmap_zero_bits;
      51  	  break;
      52  	}
      53  
      54        if (bi->elt1->indx >= start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u)))
      55  	break;
      56        bi->elt1 = bi->elt1->next;
      57      }
      58  
      59    if (bi->elt1->indx != start_bit / (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u)))
      60      start_bit = bi->elt1->indx * (((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u)) * (8 * 8 * 1u));
      61  
      62    bi->word_no = start_bit / (8 * 8 * 1u) % ((128 + (8 * 8 * 1u) - 1) / (8 * 8 * 1u));
      63    bi->bits = bi->elt1->bits[bi->word_no];
      64    bi->bits >>= start_bit % (8 * 8 * 1u);
      65  
      66    start_bit += !bi->bits;
      67  
      68    *bit_no = start_bit;
      69  }
      70  
      71  static void __attribute__((noinline))
      72  bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
      73  {
      74    bi->bits >>= 1;
      75    *bit_no += 1;
      76  }
      77  
      78  static unsigned char __attribute__((noinline))
      79  bmp_iter_set_tail (bitmap_iterator *bi, unsigned *bit_no)
      80  {
      81    while (!(bi->bits & 1))
      82      {
      83        bi->bits >>= 1;
      84        *bit_no += 1;
      85      }
      86    return 1;
      87  }
      88  
      89  static __inline__ unsigned char
      90  bmp_iter_set (bitmap_iterator *bi, unsigned *bit_no)
      91  {
      92    unsigned bno = *bit_no;
      93    BITMAP_WORD bits = bi->bits;
      94    bitmap_element *elt1;
      95  
      96    if (bits)
      97      {
      98        while (!(bits & 1))
      99  	{
     100  	  bits >>= 1;
     101  	  bno += 1;
     102  	}
     103        *bit_no = bno;
     104        return 1;
     105      }
     106  
     107    *bit_no = ((bno + 64 - 1) / 64 * 64);
     108    bi->word_no++;
     109  
     110    elt1 = bi->elt1;
     111    while (1)
     112      {
     113        while (bi->word_no != 2)
     114  	{
     115  	  bi->bits = elt1->bits[bi->word_no];
     116  	  if (bi->bits)
     117  	    {
     118  	      bi->elt1 = elt1;
     119  	      return bmp_iter_set_tail (bi, bit_no);
     120  	    }
     121  	  *bit_no += 64;
     122  	  bi->word_no++;
     123  	}
     124  
     125        elt1 = elt1->next;
     126        if (!elt1)
     127  	{
     128  	  bi->elt1 = elt1;
     129  	  return 0;
     130  	}
     131        *bit_no = elt1->indx * (2 * 64);
     132        bi->word_no = 0;
     133      }
     134  }
     135  
     136  extern void abort (void);
     137  
     138  static void __attribute__((noinline)) catchme(int i)
     139  {
     140    if (i != 0 && i != 64)
     141      abort ();
     142  }
     143  static void __attribute__((noinline)) foobar (bitmap_head *chain)
     144  {
     145    bitmap_iterator rsi;
     146    unsigned int regno;
     147    for (bmp_iter_set_init (&(rsi), (chain), (0), &(regno));
     148         bmp_iter_set (&(rsi), &(regno));
     149         bmp_iter_next (&(rsi), &(regno)))
     150      catchme(regno);
     151  }
     152  
     153  int main()
     154  {
     155    bitmap_element elem = { (void *)0, (void *)0, 0, { 1, 1 } };
     156    bitmap_head live_throughout = { &elem, &elem, 0, (void *)0 };
     157    foobar (&live_throughout);
     158    return 0;
     159  }
     160