1struct obstack {};
2struct bitmap_head_def;
3typedef struct bitmap_head_def *bitmap;
4typedef const struct bitmap_head_def *const_bitmap;
5typedef unsigned long BITMAP_WORD;
6typedef struct bitmap_obstack
7{
8  struct bitmap_element_def *elements;
9  struct bitmap_head_def *heads;
10  struct obstack obstack;
11} bitmap_obstack;
12typedef 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
20struct bitmap_descriptor;
21
22typedef struct bitmap_head_def {
23    bitmap_element *first;
24    bitmap_element *current;
25    unsigned int indx;
26    bitmap_obstack *obstack;
27} bitmap_head;
28
29bitmap_element bitmap_zero_bits;
30
31typedef struct
32{
33  bitmap_element *elt1;
34  bitmap_element *elt2;
35  unsigned word_no;
36  BITMAP_WORD bits;
37} bitmap_iterator;
38
39static void __attribute__((noinline))
40bmp_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
71static void __attribute__((noinline))
72bmp_iter_next (bitmap_iterator *bi, unsigned *bit_no)
73{
74  bi->bits >>= 1;
75  *bit_no += 1;
76}
77
78static unsigned char __attribute__((noinline))
79bmp_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
89static __inline__ unsigned char
90bmp_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
136extern void abort (void);
137
138static void __attribute__((noinline)) catchme(int i)
139{
140  if (i != 0 && i != 64)
141    abort ();
142}
143static 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
153int 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
161