sbitmap.c revision 96489
1179237Sjb/* Simple bitmaps.
2179237Sjb   Copyright (C) 1999, 2000 Free Software Foundation, Inc.
3179237Sjb
4179237SjbThis file is part of GCC.
5179237Sjb
6179237SjbGCC is free software; you can redistribute it and/or modify it under
7179237Sjbthe terms of the GNU General Public License as published by the Free
8179237SjbSoftware Foundation; either version 2, or (at your option) any later
9179237Sjbversion.
10179237Sjb
11179237SjbGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12179237SjbWARRANTY; without even the implied warranty of MERCHANTABILITY or
13179237SjbFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14179237Sjbfor more details.
15179237Sjb
16179237SjbYou should have received a copy of the GNU General Public License
17179237Sjbalong with GCC; see the file COPYING.  If not, write to the Free
18179237SjbSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
19179237Sjb02111-1307, USA.  */
20179237Sjb
21179237Sjb#include "config.h"
22179237Sjb#include "system.h"
23179237Sjb#include "rtl.h"
24179237Sjb#include "flags.h"
25179237Sjb#include "hard-reg-set.h"
26266102Smarkj#include "basic-block.h"
27266102Smarkj
28179237Sjb/* Bitmap manipulation routines.  */
29179237Sjb
30179237Sjb/* Allocate a simple bitmap of N_ELMS bits.  */
31211608Srpaulo
32211608Srpaulosbitmap
33211608Srpaulosbitmap_alloc (n_elms)
34211608Srpaulo     unsigned int n_elms;
35211608Srpaulo{
36211608Srpaulo  unsigned int bytes, size, amt;
37211608Srpaulo  sbitmap bmap;
38211608Srpaulo
39211608Srpaulo  size = SBITMAP_SET_SIZE (n_elms);
40211608Srpaulo  bytes = size * sizeof (SBITMAP_ELT_TYPE);
41211608Srpaulo  amt = (sizeof (struct simple_bitmap_def)
42211608Srpaulo	 + bytes - sizeof (SBITMAP_ELT_TYPE));
43233521Sgonzo  bmap = (sbitmap) xmalloc (amt);
44211608Srpaulo  bmap->n_bits = n_elms;
45211608Srpaulo  bmap->size = size;
46211608Srpaulo  bmap->bytes = bytes;
47211608Srpaulo  return bmap;
48211608Srpaulo}
49211608Srpaulo
50211608Srpaulo/* Allocate a vector of N_VECS bitmaps of N_ELMS bits.  */
51211608Srpaulo
52211608Srpaulosbitmap *
53211608Srpaulosbitmap_vector_alloc (n_vecs, n_elms)
54211608Srpaulo     unsigned int n_vecs, n_elms;
55211608Srpaulo{
56211608Srpaulo  unsigned int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
57211608Srpaulo  sbitmap *bitmap_vector;
58211608Srpaulo
59211608Srpaulo  size = SBITMAP_SET_SIZE (n_elms);
60211608Srpaulo  bytes = size * sizeof (SBITMAP_ELT_TYPE);
61211608Srpaulo  elm_bytes = (sizeof (struct simple_bitmap_def)
62211608Srpaulo	       + bytes - sizeof (SBITMAP_ELT_TYPE));
63211608Srpaulo  vector_bytes = n_vecs * sizeof (sbitmap *);
64211608Srpaulo
65211608Srpaulo  /* Round up `vector_bytes' to account for the alignment requirements
66211608Srpaulo     of an sbitmap.  One could allocate the vector-table and set of sbitmaps
67211608Srpaulo     separately, but that requires maintaining two pointers or creating
68211608Srpaulo     a cover struct to hold both pointers (so our result is still just
69211608Srpaulo     one pointer).  Neither is a bad idea, but this is simpler for now.  */
70211608Srpaulo  {
71211608Srpaulo    /* Based on DEFAULT_ALIGNMENT computation in obstack.c.  */
72211608Srpaulo    struct { char x; SBITMAP_ELT_TYPE y; } align;
73211608Srpaulo    int alignment = (char *) & align.y - & align.x;
74211608Srpaulo    vector_bytes = (vector_bytes + alignment - 1) & ~ (alignment - 1);
75211608Srpaulo  }
76179237Sjb
77179237Sjb  amt = vector_bytes + (n_vecs * elm_bytes);
78179237Sjb  bitmap_vector = (sbitmap *) xmalloc (amt);
79179237Sjb
80179237Sjb  for (i = 0, offset = vector_bytes; i < n_vecs; i++, offset += elm_bytes)
81184698Srodrigc    {
82184698Srodrigc      sbitmap b = (sbitmap) ((char *) bitmap_vector + offset);
83273110Spfg
84179237Sjb      bitmap_vector[i] = b;
85179237Sjb      b->n_bits = n_elms;
86179237Sjb      b->size = size;
87179237Sjb      b->bytes = bytes;
88179237Sjb    }
89179237Sjb
90179237Sjb  return bitmap_vector;
91179237Sjb}
92179237Sjb
93179237Sjb/* Copy sbitmap SRC to DST.  */
94179237Sjb
95179237Sjbvoid
96179237Sjbsbitmap_copy (dst, src)
97179237Sjb     sbitmap dst, src;
98179237Sjb{
99179237Sjb  memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
100179237Sjb}
101179237Sjb
102179237Sjb/* Determine if a == b.  */
103179237Sjbint
104179237Sjbsbitmap_equal (a, b)
105179237Sjb     sbitmap a, b;
106179237Sjb{
107179237Sjb  return !memcmp (a->elms, b->elms, sizeof (SBITMAP_ELT_TYPE) * a->size);
108179237Sjb}
109179237Sjb/* Zero all elements in a bitmap.  */
110179237Sjb
111179237Sjbvoid
112179237Sjbsbitmap_zero (bmap)
113179237Sjb     sbitmap bmap;
114179237Sjb{
115179237Sjb  memset ((PTR) bmap->elms, 0, bmap->bytes);
116179237Sjb}
117179237Sjb
118179237Sjb/* Set all elements in a bitmap to ones.  */
119179237Sjb
120179237Sjbvoid
121179237Sjbsbitmap_ones (bmap)
122179237Sjb     sbitmap bmap;
123179237Sjb{
124179237Sjb  unsigned int last_bit;
125179237Sjb
126179237Sjb  memset ((PTR) bmap->elms, -1, bmap->bytes);
127179237Sjb
128179237Sjb  last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
129179237Sjb  if (last_bit)
130179237Sjb    bmap->elms[bmap->size - 1]
131179237Sjb      = (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
132179237Sjb}
133179237Sjb
134179237Sjb/* Zero a vector of N_VECS bitmaps.  */
135179237Sjb
136179237Sjbvoid
137179237Sjbsbitmap_vector_zero (bmap, n_vecs)
138179237Sjb     sbitmap *bmap;
139179237Sjb     unsigned int n_vecs;
140179237Sjb{
141179237Sjb  unsigned int i;
142179237Sjb
143179237Sjb  for (i = 0; i < n_vecs; i++)
144179237Sjb    sbitmap_zero (bmap[i]);
145179237Sjb}
146179237Sjb
147179237Sjb/* Set a vector of N_VECS bitmaps to ones.  */
148179237Sjb
149179237Sjbvoid
150179237Sjbsbitmap_vector_ones (bmap, n_vecs)
151179237Sjb     sbitmap *bmap;
152179237Sjb     unsigned int n_vecs;
153179237Sjb{
154179237Sjb  unsigned int i;
155179237Sjb
156179237Sjb  for (i = 0; i < n_vecs; i++)
157179237Sjb    sbitmap_ones (bmap[i]);
158179237Sjb}
159179237Sjb
160179237Sjb/* Set DST to be A union (B - C).
161179237Sjb   DST = A | (B & ~C).
162179237Sjb   Return non-zero if any change is made.  */
163179237Sjb
164179237Sjbint
165179237Sjbsbitmap_union_of_diff (dst, a, b, c)
166179237Sjb     sbitmap dst, a, b, c;
167179237Sjb{
168179237Sjb  unsigned int i;
169179237Sjb  sbitmap_ptr dstp, ap, bp, cp;
170179237Sjb  int changed = 0;
171179237Sjb
172179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, cp = c->elms, i = 0;
173179237Sjb       i < dst->size; i++, dstp++)
174179237Sjb    {
175179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & ~*cp++);
176179237Sjb
177179237Sjb      if (*dstp != tmp)
178179237Sjb	{
179179237Sjb	  changed = 1;
180179237Sjb	  *dstp = tmp;
181179237Sjb	}
182179237Sjb    }
183179237Sjb
184179237Sjb  return changed;
185179237Sjb}
186179237Sjb
187179237Sjb/* Set bitmap DST to the bitwise negation of the bitmap SRC.  */
188179237Sjb
189179237Sjbvoid
190179237Sjbsbitmap_not (dst, src)
191179237Sjb     sbitmap dst, src;
192179237Sjb{
193179237Sjb  unsigned int i;
194179237Sjb  sbitmap_ptr dstp, srcp;
195179237Sjb
196179237Sjb  for (dstp = dst->elms, srcp = src->elms, i = 0; i < dst->size; i++)
197179237Sjb    *dstp++ = ~(*srcp++);
198179237Sjb}
199179237Sjb
200179237Sjb/* Set the bits in DST to be the difference between the bits
201179237Sjb   in A and the bits in B. i.e. dst = a & (~b).  */
202179237Sjb
203179237Sjbvoid
204179237Sjbsbitmap_difference (dst, a, b)
205179237Sjb     sbitmap dst, a, b;
206179237Sjb{
207179237Sjb  unsigned int i;
208179237Sjb  sbitmap_ptr dstp, ap, bp;
209179237Sjb
210179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, i = 0; i < dst->size; i++)
211179237Sjb    *dstp++ = *ap++ & (~*bp++);
212179237Sjb}
213179237Sjb
214179237Sjb/* Set DST to be (A and B).
215179237Sjb   Return non-zero if any change is made.  */
216246538Spluknet
217179237Sjbint
218179237Sjbsbitmap_a_and_b (dst, a, b)
219179237Sjb     sbitmap dst, a, b;
220179237Sjb{
221179237Sjb  unsigned int i;
222179237Sjb  sbitmap_ptr dstp, ap, bp;
223179237Sjb  int changed = 0;
224179237Sjb
225179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, i = 0; i < dst->size;
226179237Sjb       i++, dstp++)
227179237Sjb    {
228179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
229179237Sjb
230179237Sjb      if (*dstp != tmp)
231179237Sjb	{
232179237Sjb	  changed = 1;
233179237Sjb	  *dstp = tmp;
234179237Sjb	}
235179237Sjb    }
236179237Sjb
237179237Sjb  return changed;
238179237Sjb}
239179237Sjb
240179237Sjb/* Set DST to be (A xor B)).
241179237Sjb   Return non-zero if any change is made.  */
242179237Sjb
243179237Sjbint
244179237Sjbsbitmap_a_xor_b (dst, a, b)
245179237Sjb     sbitmap dst, a, b;
246179237Sjb{
247179237Sjb  unsigned int i;
248179237Sjb  sbitmap_ptr dstp, ap, bp;
249179237Sjb  int changed = 0;
250179237Sjb
251179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, i = 0; i < dst->size;
252179237Sjb       i++, dstp++)
253179237Sjb    {
254179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
255179237Sjb
256179237Sjb      if (*dstp != tmp)
257179237Sjb	{
258179237Sjb	  changed = 1;
259179237Sjb	  *dstp = tmp;
260179237Sjb	}
261179237Sjb    }
262179237Sjb  return changed;
263179237Sjb}
264179237Sjb
265179237Sjb/* Set DST to be (A or B)).
266179237Sjb   Return non-zero if any change is made.  */
267179237Sjb
268179237Sjbint
269179237Sjbsbitmap_a_or_b (dst, a, b)
270179237Sjb     sbitmap dst, a, b;
271179237Sjb{
272179237Sjb  unsigned int i;
273179237Sjb  sbitmap_ptr dstp, ap, bp;
274179237Sjb  int changed = 0;
275250574Smarkj
276179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, i = 0; i < dst->size;
277179237Sjb       i++, dstp++)
278179237Sjb    {
279179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
280179237Sjb
281179237Sjb      if (*dstp != tmp)
282179237Sjb	{
283179237Sjb	  changed = 1;
284179237Sjb	  *dstp = tmp;
285179237Sjb	}
286179237Sjb    }
287179237Sjb
288179237Sjb  return changed;
289179237Sjb}
290179237Sjb
291179237Sjb/* Return non-zero if A is a subset of B.  */
292179237Sjb
293179237Sjbint
294179237Sjbsbitmap_a_subset_b_p (a, b)
295179237Sjb     sbitmap a, b;
296179237Sjb{
297179237Sjb  unsigned int i;
298179237Sjb  sbitmap_ptr ap, bp;
299179237Sjb
300179237Sjb  for (ap = a->elms, bp = b->elms, i = 0; i < a->size; i++, ap++, bp++)
301179237Sjb    if ((*ap | *bp) != *bp)
302179237Sjb      return 0;
303179237Sjb
304179237Sjb  return 1;
305179237Sjb}
306179237Sjb
307179237Sjb/* Set DST to be (A or (B and C)).
308179237Sjb   Return non-zero if any change is made.  */
309179237Sjb
310179237Sjbint
311179237Sjbsbitmap_a_or_b_and_c (dst, a, b, c)
312179237Sjb     sbitmap dst, a, b, c;
313179237Sjb{
314179237Sjb  unsigned int i;
315179237Sjb  sbitmap_ptr dstp, ap, bp, cp;
316179237Sjb  int changed = 0;
317179237Sjb
318179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, cp = c->elms, i = 0;
319179237Sjb       i < dst->size; i++, dstp++)
320179237Sjb    {
321179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & *cp++);
322179237Sjb
323179237Sjb      if (*dstp != tmp)
324179237Sjb	{
325179237Sjb	  changed = 1;
326179237Sjb	  *dstp = tmp;
327179237Sjb	}
328179237Sjb    }
329179237Sjb
330250574Smarkj  return changed;
331179237Sjb}
332179237Sjb
333179237Sjb/* Set DST to be (A and (B or C)).
334179237Sjb   Return non-zero if any change is made.  */
335179237Sjb
336179237Sjbint
337179237Sjbsbitmap_a_and_b_or_c (dst, a, b, c)
338179237Sjb     sbitmap dst, a, b, c;
339179237Sjb{
340179237Sjb  unsigned int i;
341179237Sjb  sbitmap_ptr dstp, ap, bp, cp;
342179237Sjb  int changed = 0;
343179237Sjb
344179237Sjb  for (dstp = dst->elms, ap = a->elms, bp = b->elms, cp = c->elms, i = 0;
345179237Sjb       i < dst->size; i++, dstp++)
346179237Sjb    {
347179237Sjb      SBITMAP_ELT_TYPE tmp = *ap++ & (*bp++ | *cp++);
348179237Sjb
349179237Sjb      if (*dstp != tmp)
350179237Sjb	{
351179237Sjb	  changed = 1;
352179237Sjb	  *dstp = tmp;
353179237Sjb	}
354179237Sjb    }
355179237Sjb
356179237Sjb  return changed;
357179237Sjb}
358179237Sjb
359179237Sjb#ifdef IN_GCC
360179237Sjb/* Set the bitmap DST to the intersection of SRC of successors of
361179237Sjb   block number BB, using the new flow graph structures.  */
362179237Sjb
363179237Sjbvoid
364179237Sjbsbitmap_intersection_of_succs (dst, src, bb)
365179237Sjb     sbitmap dst;
366179237Sjb     sbitmap *src;
367179237Sjb     int bb;
368179237Sjb{
369179237Sjb  basic_block b = BASIC_BLOCK (bb);
370179237Sjb  unsigned int set_size = dst->size;
371179237Sjb  edge e;
372179237Sjb
373179237Sjb  for (e = b->succ; e != 0; e = e->succ_next)
374179237Sjb    {
375179237Sjb      if (e->dest == EXIT_BLOCK_PTR)
376179237Sjb        continue;
377179237Sjb
378179237Sjb      sbitmap_copy (dst, src[e->dest->index]);
379179237Sjb      break;
380179237Sjb    }
381179237Sjb
382179237Sjb  if (e == 0)
383179237Sjb    sbitmap_ones (dst);
384179237Sjb  else
385179237Sjb    for (e = e->succ_next; e != 0; e = e->succ_next)
386179237Sjb      {
387179237Sjb	unsigned int i;
388179237Sjb	sbitmap_ptr p, r;
389179237Sjb
390179237Sjb	if (e->dest == EXIT_BLOCK_PTR)
391179237Sjb	  continue;
392179237Sjb
393179237Sjb	p = src[e->dest->index]->elms;
394179237Sjb	r = dst->elms;
395179237Sjb	for (i = 0; i < set_size; i++)
396179237Sjb	  *r++ &= *p++;
397179237Sjb      }
398179237Sjb}
399179237Sjb
400179237Sjb/* Set the bitmap DST to the intersection of SRC of predecessors of
401179237Sjb   block number BB, using the new flow graph structures.  */
402179237Sjb
403179237Sjbvoid
404179237Sjbsbitmap_intersection_of_preds (dst, src, bb)
405179237Sjb     sbitmap dst;
406179237Sjb     sbitmap *src;
407179237Sjb     int bb;
408179237Sjb{
409179237Sjb  basic_block b = BASIC_BLOCK (bb);
410179237Sjb  unsigned int set_size = dst->size;
411179237Sjb  edge e;
412179237Sjb
413179237Sjb  for (e = b->pred; e != 0; e = e->pred_next)
414179237Sjb    {
415179237Sjb      if (e->src == ENTRY_BLOCK_PTR)
416179237Sjb        continue;
417179237Sjb
418179237Sjb      sbitmap_copy (dst, src[e->src->index]);
419179237Sjb      break;
420179237Sjb    }
421179237Sjb
422179237Sjb  if (e == 0)
423179237Sjb    sbitmap_ones (dst);
424179237Sjb  else
425179237Sjb    for (e = e->pred_next; e != 0; e = e->pred_next)
426179237Sjb      {
427179237Sjb	unsigned int i;
428179237Sjb	sbitmap_ptr p, r;
429179237Sjb
430179237Sjb	if (e->src == ENTRY_BLOCK_PTR)
431179237Sjb	  continue;
432179237Sjb
433179237Sjb	p = src[e->src->index]->elms;
434179237Sjb	r = dst->elms;
435179237Sjb	for (i = 0; i < set_size; i++)
436179237Sjb	  *r++ &= *p++;
437179237Sjb      }
438179237Sjb}
439179237Sjb
440179237Sjb/* Set the bitmap DST to the union of SRC of successors of
441179237Sjb   block number BB, using the new flow graph structures.  */
442179237Sjb
443179237Sjbvoid
444179237Sjbsbitmap_union_of_succs (dst, src, bb)
445179237Sjb     sbitmap dst;
446179237Sjb     sbitmap *src;
447179237Sjb     int bb;
448179237Sjb{
449179237Sjb  basic_block b = BASIC_BLOCK (bb);
450179237Sjb  unsigned int set_size = dst->size;
451179237Sjb  edge e;
452179237Sjb
453179237Sjb  for (e = b->succ; e != 0; e = e->succ_next)
454179237Sjb    {
455179237Sjb      if (e->dest == EXIT_BLOCK_PTR)
456179237Sjb        continue;
457179237Sjb
458179237Sjb      sbitmap_copy (dst, src[e->dest->index]);
459179237Sjb      break;
460179237Sjb    }
461179237Sjb
462179237Sjb  if (e == 0)
463179237Sjb    sbitmap_zero (dst);
464179237Sjb  else
465179237Sjb    for (e = e->succ_next; e != 0; e = e->succ_next)
466179237Sjb      {
467179237Sjb	unsigned int i;
468179237Sjb	sbitmap_ptr p, r;
469179237Sjb
470179237Sjb	if (e->dest == EXIT_BLOCK_PTR)
471179237Sjb	  continue;
472179237Sjb
473179237Sjb	p = src[e->dest->index]->elms;
474179237Sjb	r = dst->elms;
475179237Sjb	for (i = 0; i < set_size; i++)
476179237Sjb	  *r++ |= *p++;
477179237Sjb      }
478179237Sjb}
479179237Sjb
480179237Sjb/* Set the bitmap DST to the union of SRC of predecessors of
481179237Sjb   block number BB, using the new flow graph structures.  */
482179237Sjb
483179237Sjbvoid
484179237Sjbsbitmap_union_of_preds (dst, src, bb)
485179237Sjb     sbitmap dst;
486179237Sjb     sbitmap *src;
487179237Sjb     int bb;
488179237Sjb{
489179237Sjb  basic_block b = BASIC_BLOCK (bb);
490179237Sjb  unsigned int set_size = dst->size;
491179237Sjb  edge e;
492179237Sjb
493179237Sjb  for (e = b->pred; e != 0; e = e->pred_next)
494179237Sjb    {
495179237Sjb      if (e->src== ENTRY_BLOCK_PTR)
496179237Sjb        continue;
497179237Sjb
498179237Sjb      sbitmap_copy (dst, src[e->src->index]);
499179237Sjb      break;
500179237Sjb    }
501179237Sjb
502179237Sjb  if (e == 0)
503179237Sjb    sbitmap_zero (dst);
504179237Sjb  else
505179237Sjb    for (e = e->pred_next; e != 0; e = e->pred_next)
506179237Sjb      {
507179237Sjb	unsigned int i;
508179237Sjb	sbitmap_ptr p, r;
509179237Sjb
510179237Sjb	if (e->src == ENTRY_BLOCK_PTR)
511179237Sjb	  continue;
512179237Sjb
513179237Sjb	p = src[e->src->index]->elms;
514179237Sjb	r = dst->elms;
515179237Sjb	for (i = 0; i < set_size; i++)
516179237Sjb	  *r++ |= *p++;
517179237Sjb      }
518179237Sjb}
519179237Sjb#endif
520179237Sjb
521179237Sjb/* Return number of first bit set in the bitmap, -1 if none.  */
522179237Sjb
523179237Sjbint
524179237Sjbsbitmap_first_set_bit (bmap)
525179237Sjb     sbitmap bmap;
526179237Sjb{
527179237Sjb  unsigned int n;
528179237Sjb
529179237Sjb  EXECUTE_IF_SET_IN_SBITMAP (bmap, 0, n, { return n; });
530179237Sjb  return -1;
531179237Sjb}
532179237Sjb
533179237Sjb/* Return number of last bit set in the bitmap, -1 if none.  */
534179237Sjb
535179237Sjbint
536179237Sjbsbitmap_last_set_bit (bmap)
537179237Sjb     sbitmap bmap;
538179237Sjb{
539179237Sjb  int i;
540179237Sjb  SBITMAP_ELT_TYPE *ptr = bmap->elms;
541179237Sjb
542179237Sjb  for (i = bmap->size - 1; i >= 0; i--)
543179237Sjb    {
544179237Sjb      SBITMAP_ELT_TYPE word = ptr[i];
545179237Sjb
546179237Sjb      if (word != 0)
547179237Sjb	{
548179237Sjb	  unsigned int index = (i + 1) * SBITMAP_ELT_BITS - 1;
549179237Sjb	  SBITMAP_ELT_TYPE mask
550179237Sjb	    = (SBITMAP_ELT_TYPE) 1 << (SBITMAP_ELT_BITS - 1);
551179237Sjb
552179237Sjb	  while (1)
553179237Sjb	    {
554179237Sjb	      if ((word & mask) != 0)
555179237Sjb		return index;
556179237Sjb
557179237Sjb	      mask >>= 1;
558179237Sjb	      index--;
559179237Sjb	    }
560179237Sjb	}
561179237Sjb    }
562179237Sjb
563179237Sjb  return -1;
564179237Sjb}
565179237Sjb
566179237Sjbvoid
567179237Sjbdump_sbitmap (file, bmap)
568179237Sjb     FILE *file;
569179237Sjb     sbitmap bmap;
570179237Sjb{
571179237Sjb  unsigned int i, n, j;
572179237Sjb  unsigned int set_size = bmap->size;
573179237Sjb  unsigned int total_bits = bmap->n_bits;
574179237Sjb
575179237Sjb  fprintf (file, "  ");
576179237Sjb  for (i = n = 0; i < set_size && n < total_bits; i++)
577179237Sjb    for (j = 0; j < SBITMAP_ELT_BITS && n < total_bits; j++, n++)
578179237Sjb      {
579179237Sjb	if (n != 0 && n % 10 == 0)
580179237Sjb	  fprintf (file, " ");
581252850Smarkj
582179237Sjb	fprintf (file, "%d",
583252850Smarkj		 (bmap->elms[i] & ((SBITMAP_ELT_TYPE) 1 << j)) != 0);
584179237Sjb      }
585179237Sjb
586179237Sjb  fprintf (file, "\n");
587179237Sjb}
588252850Smarkj
589179237Sjbvoid
590252850Smarkjdebug_sbitmap (bmap)
591179237Sjb     sbitmap bmap;
592179237Sjb{
593179237Sjb  unsigned int i, pos;
594179237Sjb
595179237Sjb  fprintf (stderr, "n_bits = %d, set = {", bmap->n_bits);
596179237Sjb
597252850Smarkj  for (pos = 30, i = 0; i < bmap->n_bits; i++)
598179237Sjb    if (TEST_BIT (bmap, i))
599252850Smarkj      {
600179237Sjb	if (pos > 70)
601179237Sjb	  {
602179237Sjb	    fprintf (stderr, "\n");
603179237Sjb	    pos = 0;
604179237Sjb	  }
605179237Sjb
606179237Sjb	fprintf (stderr, "%d ", i);
607179237Sjb	pos += 1 + (i >= 10) + (i >= 100);
608179237Sjb      }
609179237Sjb
610179237Sjb  fprintf (stderr, "}\n");
611179237Sjb}
612179237Sjb
613179237Sjbvoid
614179237Sjbdump_sbitmap_vector (file, title, subtitle, bmaps, n_maps)
615179237Sjb     FILE *file;
616179237Sjb     const char *title, *subtitle;
617179237Sjb     sbitmap *bmaps;
618179237Sjb     int n_maps;
619179237Sjb{
620179237Sjb  int bb;
621179237Sjb
622179237Sjb  fprintf (file, "%s\n", title);
623252850Smarkj  for (bb = 0; bb < n_maps; bb++)
624179237Sjb    {
625252850Smarkj      fprintf (file, "%s %d\n", subtitle, bb);
626179237Sjb      dump_sbitmap (file, bmaps[bb]);
627179237Sjb    }
628179237Sjb
629179237Sjb  fprintf (file, "\n");
630179237Sjb}
631179237Sjb