1/* Functions to support general ended bitmaps.
2   Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003
3   Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING.  If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA.  */
21
22#include "config.h"
23#include "system.h"
24#include "rtl.h"
25#include "flags.h"
26#include "obstack.h"
27#include "ggc.h"
28#include "bitmap.h"
29
30/* Obstack to allocate bitmap elements from.  */
31static struct obstack bitmap_obstack;
32static int bitmap_obstack_init = FALSE;
33
34#ifndef INLINE
35#ifndef __GNUC__
36#define INLINE
37#else
38#define INLINE __inline__
39#endif
40#endif
41
42/* Global data */
43bitmap_element bitmap_zero_bits;	/* An element of all zero bits.  */
44static bitmap_element *bitmap_free;	/* Freelist of bitmap elements.  */
45static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
46
47static void bitmap_elem_to_freelist	PARAMS ((bitmap, bitmap_element *));
48static void bitmap_element_free		PARAMS ((bitmap, bitmap_element *));
49static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
50static int bitmap_element_zerop		PARAMS ((bitmap_element *));
51static void bitmap_element_link		PARAMS ((bitmap, bitmap_element *));
52static bitmap_element *bitmap_find_bit	PARAMS ((bitmap, unsigned int));
53
54/* Add ELEM to the appropriate freelist.  */
55static INLINE void
56bitmap_elem_to_freelist (head, elt)
57     bitmap head;
58     bitmap_element *elt;
59{
60  if (head->using_obstack)
61    {
62      elt->next = bitmap_free;
63      bitmap_free = elt;
64    }
65  else
66    {
67      elt->next = bitmap_ggc_free;
68      bitmap_ggc_free = elt;
69    }
70}
71
72/* Free a bitmap element.  Since these are allocated off the
73   bitmap_obstack, "free" actually means "put onto the freelist".  */
74
75static INLINE void
76bitmap_element_free (head, elt)
77     bitmap head;
78     bitmap_element *elt;
79{
80  bitmap_element *next = elt->next;
81  bitmap_element *prev = elt->prev;
82
83  if (prev)
84    prev->next = next;
85
86  if (next)
87    next->prev = prev;
88
89  if (head->first == elt)
90    head->first = next;
91
92  /* Since the first thing we try is to insert before current,
93     make current the next entry in preference to the previous.  */
94  if (head->current == elt)
95    {
96      head->current = next != 0 ? next : prev;
97      if (head->current)
98	head->indx = head->current->indx;
99    }
100  bitmap_elem_to_freelist (head, elt);
101}
102
103/* Allocate a bitmap element.  The bits are cleared, but nothing else is.  */
104
105static INLINE bitmap_element *
106bitmap_element_allocate (head)
107     bitmap head;
108{
109  bitmap_element *element;
110
111  if (head->using_obstack)
112    {
113      if (bitmap_free != 0)
114	{
115	  element = bitmap_free;
116	  bitmap_free = element->next;
117	}
118      else
119	{
120	  /* We can't use gcc_obstack_init to initialize the obstack since
121	     print-rtl.c now calls bitmap functions, and bitmap is linked
122	     into the gen* functions.  */
123	  if (!bitmap_obstack_init)
124	    {
125	      bitmap_obstack_init = TRUE;
126
127	      /* Let particular systems override the size of a chunk.  */
128#ifndef OBSTACK_CHUNK_SIZE
129#define OBSTACK_CHUNK_SIZE 0
130#endif
131	      /* Let them override the alloc and free routines too.  */
132#ifndef OBSTACK_CHUNK_ALLOC
133#define OBSTACK_CHUNK_ALLOC xmalloc
134#endif
135#ifndef OBSTACK_CHUNK_FREE
136#define OBSTACK_CHUNK_FREE free
137#endif
138
139#if !defined(__GNUC__) || (__GNUC__ < 2)
140#define __alignof__(type) 0
141#endif
142
143	      obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
144					  __alignof__ (bitmap_element),
145					  (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
146					  (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
147	    }
148
149	  element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
150						      sizeof (bitmap_element));
151	}
152    }
153  else
154    {
155      if (bitmap_ggc_free != NULL)
156	{
157          element = bitmap_ggc_free;
158          bitmap_ggc_free = element->next;
159	}
160      else
161	element = ggc_alloc (sizeof (bitmap_element));
162    }
163
164  memset (element->bits, 0, sizeof (element->bits));
165
166  return element;
167}
168
169/* Release any memory allocated by bitmaps.  */
170
171void
172bitmap_release_memory ()
173{
174  bitmap_free = 0;
175  if (bitmap_obstack_init)
176    {
177      bitmap_obstack_init = FALSE;
178      obstack_free (&bitmap_obstack, NULL);
179    }
180}
181
182/* Return nonzero if all bits in an element are zero.  */
183
184static INLINE int
185bitmap_element_zerop (element)
186     bitmap_element *element;
187{
188#if BITMAP_ELEMENT_WORDS == 2
189  return (element->bits[0] | element->bits[1]) == 0;
190#else
191  int i;
192
193  for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
194    if (element->bits[i] != 0)
195      return 0;
196
197  return 1;
198#endif
199}
200
201/* Link the bitmap element into the current bitmap linked list.  */
202
203static INLINE void
204bitmap_element_link (head, element)
205     bitmap head;
206     bitmap_element *element;
207{
208  unsigned int indx = element->indx;
209  bitmap_element *ptr;
210
211  /* If this is the first and only element, set it in.  */
212  if (head->first == 0)
213    {
214      element->next = element->prev = 0;
215      head->first = element;
216    }
217
218  /* If this index is less than that of the current element, it goes someplace
219     before the current element.  */
220  else if (indx < head->indx)
221    {
222      for (ptr = head->current;
223	   ptr->prev != 0 && ptr->prev->indx > indx;
224	   ptr = ptr->prev)
225	;
226
227      if (ptr->prev)
228	ptr->prev->next = element;
229      else
230	head->first = element;
231
232      element->prev = ptr->prev;
233      element->next = ptr;
234      ptr->prev = element;
235    }
236
237  /* Otherwise, it must go someplace after the current element.  */
238  else
239    {
240      for (ptr = head->current;
241	   ptr->next != 0 && ptr->next->indx < indx;
242	   ptr = ptr->next)
243	;
244
245      if (ptr->next)
246	ptr->next->prev = element;
247
248      element->next = ptr->next;
249      element->prev = ptr;
250      ptr->next = element;
251    }
252
253  /* Set up so this is the first element searched.  */
254  head->current = element;
255  head->indx = indx;
256}
257
258/* Clear a bitmap by freeing the linked list.  */
259
260INLINE void
261bitmap_clear (head)
262     bitmap head;
263{
264  bitmap_element *element, *next;
265
266  for (element = head->first; element != 0; element = next)
267    {
268      next = element->next;
269      bitmap_elem_to_freelist (head, element);
270    }
271
272  head->first = head->current = 0;
273}
274
275/* Copy a bitmap to another bitmap.  */
276
277void
278bitmap_copy (to, from)
279     bitmap to;
280     bitmap from;
281{
282  bitmap_element *from_ptr, *to_ptr = 0;
283#if BITMAP_ELEMENT_WORDS != 2
284  int i;
285#endif
286
287  bitmap_clear (to);
288
289  /* Copy elements in forward direction one at a time */
290  for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
291    {
292      bitmap_element *to_elt = bitmap_element_allocate (to);
293
294      to_elt->indx = from_ptr->indx;
295
296#if BITMAP_ELEMENT_WORDS == 2
297      to_elt->bits[0] = from_ptr->bits[0];
298      to_elt->bits[1] = from_ptr->bits[1];
299#else
300      for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
301	to_elt->bits[i] = from_ptr->bits[i];
302#endif
303
304      /* Here we have a special case of bitmap_element_link, for the case
305	 where we know the links are being entered in sequence.  */
306      if (to_ptr == 0)
307	{
308	  to->first = to->current = to_elt;
309	  to->indx = from_ptr->indx;
310	  to_elt->next = to_elt->prev = 0;
311	}
312      else
313	{
314	  to_elt->prev = to_ptr;
315	  to_elt->next = 0;
316	  to_ptr->next = to_elt;
317	}
318
319      to_ptr = to_elt;
320    }
321}
322
323/* Find a bitmap element that would hold a bitmap's bit.
324   Update the `current' field even if we can't find an element that
325   would hold the bitmap's bit to make eventual allocation
326   faster.  */
327
328static INLINE bitmap_element *
329bitmap_find_bit (head, bit)
330     bitmap head;
331     unsigned int bit;
332{
333  bitmap_element *element;
334  unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
335
336  if (head->current == 0
337      || head->indx == indx)
338    return head->current;
339
340  if (head->indx > indx)
341    for (element = head->current;
342	 element->prev != 0 && element->indx > indx;
343	 element = element->prev)
344      ;
345
346  else
347    for (element = head->current;
348	 element->next != 0 && element->indx < indx;
349	 element = element->next)
350      ;
351
352  /* `element' is the nearest to the one we want.  If it's not the one we
353     want, the one we want doesn't exist.  */
354  head->current = element;
355  head->indx = element->indx;
356  if (element != 0 && element->indx != indx)
357    element = 0;
358
359  return element;
360}
361
362/* Clear a single bit in a bitmap.  */
363
364void
365bitmap_clear_bit (head, bit)
366     bitmap head;
367     int bit;
368{
369  bitmap_element *ptr = bitmap_find_bit (head, bit);
370
371  if (ptr != 0)
372    {
373      unsigned bit_num  = bit % BITMAP_WORD_BITS;
374      unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
375      ptr->bits[word_num] &= ~ (((BITMAP_WORD) 1) << bit_num);
376
377      /* If we cleared the entire word, free up the element */
378      if (bitmap_element_zerop (ptr))
379	bitmap_element_free (head, ptr);
380    }
381}
382
383/* Set a single bit in a bitmap.  */
384
385void
386bitmap_set_bit (head, bit)
387     bitmap head;
388     int bit;
389{
390  bitmap_element *ptr = bitmap_find_bit (head, bit);
391  unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
392  unsigned bit_num  = bit % BITMAP_WORD_BITS;
393  BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
394
395  if (ptr == 0)
396    {
397      ptr = bitmap_element_allocate (head);
398      ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
399      ptr->bits[word_num] = bit_val;
400      bitmap_element_link (head, ptr);
401    }
402  else
403    ptr->bits[word_num] |= bit_val;
404}
405
406/* Return whether a bit is set within a bitmap.  */
407
408int
409bitmap_bit_p (head, bit)
410     bitmap head;
411     int bit;
412{
413  bitmap_element *ptr;
414  unsigned bit_num;
415  unsigned word_num;
416
417  ptr = bitmap_find_bit (head, bit);
418  if (ptr == 0)
419    return 0;
420
421  bit_num = bit % BITMAP_WORD_BITS;
422  word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
423
424  return (ptr->bits[word_num] >> bit_num) & 1;
425}
426
427/* Return the bit number of the first set bit in the bitmap, or -1
428   if the bitmap is empty.  */
429
430int
431bitmap_first_set_bit (a)
432     bitmap a;
433{
434  bitmap_element *ptr = a->first;
435  BITMAP_WORD word;
436  unsigned word_num, bit_num;
437
438  if (ptr == NULL)
439    return -1;
440
441#if BITMAP_ELEMENT_WORDS == 2
442  word_num = 0, word = ptr->bits[0];
443  if (word == 0)
444    word_num = 1, word = ptr->bits[1];
445#else
446  for (word_num = 0; word_num < BITMAP_ELEMENT_WORDS; ++word_num)
447    if ((word = ptr->bits[word_num]) != 0)
448      break;
449#endif
450
451  /* Binary search for the first set bit.  */
452  /* ??? It'd be nice to know if ffs or ffsl was available.  */
453
454  bit_num = 0;
455  word = word & -word;
456
457#if nBITMAP_WORD_BITS > 64
458 #error "Fill out the table."
459#endif
460#if nBITMAP_WORD_BITS > 32
461  if ((word & 0xffffffff) == 0)
462    word >>= 32, bit_num += 32;
463#endif
464  if ((word & 0xffff) == 0)
465    word >>= 16, bit_num += 16;
466  if ((word & 0xff) == 0)
467    word >>= 8, bit_num += 8;
468  if (word & 0xf0)
469    bit_num += 4;
470  if (word & 0xcc)
471    bit_num += 2;
472  if (word & 0xaa)
473    bit_num += 1;
474
475  return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
476	  + word_num * BITMAP_WORD_BITS
477	  + bit_num);
478}
479
480/* Return the bit number of the last set bit in the bitmap, or -1
481   if the bitmap is empty.  */
482
483int
484bitmap_last_set_bit (a)
485     bitmap a;
486{
487  bitmap_element *ptr = a->first;
488  BITMAP_WORD word;
489  unsigned word_num, bit_num;
490
491  if (ptr == NULL)
492    return -1;
493
494  while (ptr->next != NULL)
495    ptr = ptr->next;
496
497#if BITMAP_ELEMENT_WORDS == 2
498  word_num = 1, word = ptr->bits[1];
499  if (word == 0)
500    word_num = 0, word = ptr->bits[0];
501#else
502  for (word_num = BITMAP_ELEMENT_WORDS; word_num-- > 0; )
503    if ((word = ptr->bits[word_num]) != 0)
504      break;
505#endif
506
507  /* Binary search for the last set bit.  */
508
509  bit_num = 0;
510#if nBITMAP_WORD_BITS > 64
511 #error "Fill out the table."
512#endif
513#if nBITMAP_WORD_BITS > 32
514  if (word & ~(BITMAP_WORD)0xffffffff)
515    word >>= 32, bit_num += 32;
516#endif
517  if (word & 0xffff0000)
518    word >>= 16, bit_num += 16;
519  if (word & 0xff00)
520    word >>= 8, bit_num += 8;
521  if (word & 0xf0)
522    word >>= 4, bit_num += 4;
523  if (word & 0xc)
524    word >>= 2, bit_num += 2;
525  if (word & 0x2)
526    bit_num += 1;
527
528  return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
529	  + word_num * BITMAP_WORD_BITS
530	  + bit_num);
531}
532
533/* Store in bitmap TO the result of combining bitmap FROM1 and FROM2 using
534   a specific bit manipulation.  Return true if TO changes.  */
535
536int
537bitmap_operation (to, from1, from2, operation)
538     bitmap to;
539     bitmap from1;
540     bitmap from2;
541     enum bitmap_bits operation;
542{
543#define HIGHEST_INDEX (unsigned int) ~0
544
545  bitmap_element *from1_ptr = from1->first;
546  bitmap_element *from2_ptr = from2->first;
547  unsigned int indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
548  unsigned int indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
549  bitmap_element *to_ptr = to->first;
550  bitmap_element *from1_tmp;
551  bitmap_element *from2_tmp;
552  bitmap_element *to_tmp;
553  unsigned int indx;
554  int changed = 0;
555
556#if BITMAP_ELEMENT_WORDS == 2
557#define DOIT(OP)					\
558  do {							\
559    BITMAP_WORD t0, t1, f10, f11, f20, f21;		\
560    f10 = from1_tmp->bits[0];				\
561    f20 = from2_tmp->bits[0];				\
562    t0 = f10 OP f20;					\
563    changed |= (t0 != to_tmp->bits[0]);			\
564    f11 = from1_tmp->bits[1];				\
565    f21 = from2_tmp->bits[1];				\
566    t1 = f11 OP f21;					\
567    changed |= (t1 != to_tmp->bits[1]);			\
568    to_tmp->bits[0] = t0;				\
569    to_tmp->bits[1] = t1;				\
570  } while (0)
571#else
572#define DOIT(OP)					\
573  do {							\
574    BITMAP_WORD t, f1, f2;				\
575    int i;						\
576    for (i = 0; i < BITMAP_ELEMENT_WORDS; ++i)		\
577      {							\
578	f1 = from1_tmp->bits[i];			\
579	f2 = from2_tmp->bits[i];			\
580	t = f1 OP f2;					\
581	changed |= (t != to_tmp->bits[i]);		\
582	to_tmp->bits[i] = t;				\
583      }							\
584  } while (0)
585#endif
586
587  to->first = to->current = 0;
588
589  while (from1_ptr != 0 || from2_ptr != 0)
590    {
591      /* Figure out whether we need to substitute zero elements for
592	 missing links.  */
593      if (indx1 == indx2)
594	{
595	  indx = indx1;
596	  from1_tmp = from1_ptr;
597	  from2_tmp = from2_ptr;
598	  from1_ptr = from1_ptr->next;
599	  indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
600	  from2_ptr = from2_ptr->next;
601	  indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
602	}
603      else if (indx1 < indx2)
604	{
605	  indx = indx1;
606	  from1_tmp = from1_ptr;
607	  from2_tmp = &bitmap_zero_bits;
608	  from1_ptr = from1_ptr->next;
609	  indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
610	}
611      else
612	{
613	  indx = indx2;
614	  from1_tmp = &bitmap_zero_bits;
615	  from2_tmp = from2_ptr;
616	  from2_ptr = from2_ptr->next;
617	  indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
618	}
619
620      /* Find the appropriate element from TO.  Begin by discarding
621	 elements that we've skipped.  */
622      while (to_ptr && to_ptr->indx < indx)
623	{
624	  changed = 1;
625	  to_tmp = to_ptr;
626	  to_ptr = to_ptr->next;
627	  bitmap_elem_to_freelist (to, to_tmp);
628	}
629      if (to_ptr && to_ptr->indx == indx)
630	{
631	  to_tmp = to_ptr;
632	  to_ptr = to_ptr->next;
633	}
634      else
635	to_tmp = bitmap_element_allocate (to);
636
637      /* Do the operation, and if any bits are set, link it into the
638	 linked list.  */
639      switch (operation)
640	{
641	default:
642	  abort ();
643
644	case BITMAP_AND:
645	  DOIT (&);
646	  break;
647
648	case BITMAP_AND_COMPL:
649	  DOIT (&~);
650	  break;
651
652	case BITMAP_IOR:
653	  DOIT (|);
654	  break;
655	case BITMAP_IOR_COMPL:
656	  DOIT (|~);
657	  break;
658	case BITMAP_XOR:
659	  DOIT (^);
660	  break;
661	}
662
663      if (! bitmap_element_zerop (to_tmp))
664	{
665	  to_tmp->indx = indx;
666	  bitmap_element_link (to, to_tmp);
667	}
668      else
669	{
670	  bitmap_elem_to_freelist (to, to_tmp);
671	}
672    }
673
674  /* If we have elements of TO left over, free the lot.  */
675  if (to_ptr)
676    {
677      changed = 1;
678      for (to_tmp = to_ptr; to_tmp->next ; to_tmp = to_tmp->next)
679	continue;
680      if (to->using_obstack)
681	{
682	  to_tmp->next = bitmap_free;
683	  bitmap_free = to_ptr;
684	}
685      else
686	{
687	  to_tmp->next = bitmap_ggc_free;
688	  bitmap_ggc_free = to_ptr;
689	}
690    }
691
692#undef DOIT
693
694  return changed;
695}
696
697/* Return true if two bitmaps are identical.  */
698
699int
700bitmap_equal_p (a, b)
701     bitmap a;
702     bitmap b;
703{
704  bitmap_head c;
705  int ret;
706
707  memset (&c, 0, sizeof (c));
708  ret = ! bitmap_operation (&c, a, b, BITMAP_XOR);
709  bitmap_clear (&c);
710
711  return ret;
712}
713
714/* Or into bitmap TO bitmap FROM1 and'ed with the complement of
715   bitmap FROM2.  */
716
717void
718bitmap_ior_and_compl (to, from1, from2)
719     bitmap to;
720     bitmap from1;
721     bitmap from2;
722{
723  bitmap_head tmp;
724
725  tmp.first = tmp.current = 0;
726  tmp.using_obstack = 0;
727
728  bitmap_operation (&tmp, from1, from2, BITMAP_AND_COMPL);
729  bitmap_operation (to, to, &tmp, BITMAP_IOR);
730  bitmap_clear (&tmp);
731}
732
733int
734bitmap_union_of_diff (dst, a, b, c)
735     bitmap dst;
736     bitmap a;
737     bitmap b;
738     bitmap c;
739{
740  bitmap_head tmp;
741  int changed;
742
743  tmp.first = tmp.current = 0;
744  tmp.using_obstack = 0;
745
746  bitmap_operation (&tmp, b, c, BITMAP_AND_COMPL);
747  changed = bitmap_operation (dst, &tmp, a, BITMAP_IOR);
748  bitmap_clear (&tmp);
749
750  return changed;
751}
752
753/* Initialize a bitmap header.  */
754
755bitmap
756bitmap_initialize (head, using_obstack)
757     bitmap head;
758     int using_obstack;
759{
760  if (head == NULL && ! using_obstack)
761    head = ggc_alloc (sizeof (*head));
762
763  head->first = head->current = 0;
764  head->using_obstack = using_obstack;
765
766  return head;
767}
768
769/* Debugging function to print out the contents of a bitmap.  */
770
771void
772debug_bitmap_file (file, head)
773     FILE *file;
774     bitmap head;
775{
776  bitmap_element *ptr;
777
778  fprintf (file, "\nfirst = ");
779  fprintf (file, HOST_PTR_PRINTF, (PTR) head->first);
780  fprintf (file, " current = ");
781  fprintf (file, HOST_PTR_PRINTF, (PTR) head->current);
782  fprintf (file, " indx = %u\n", head->indx);
783
784  for (ptr = head->first; ptr; ptr = ptr->next)
785    {
786      unsigned int i, j, col = 26;
787
788      fprintf (file, "\t");
789      fprintf (file, HOST_PTR_PRINTF, (PTR) ptr);
790      fprintf (file, " next = ");
791      fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->next);
792      fprintf (file, " prev = ");
793      fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->prev);
794      fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
795
796      for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
797	for (j = 0; j < BITMAP_WORD_BITS; j++)
798	  if ((ptr->bits[i] >> j) & 1)
799	    {
800	      if (col > 70)
801		{
802		  fprintf (file, "\n\t\t\t");
803		  col = 24;
804		}
805
806	      fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
807				     + i * BITMAP_WORD_BITS + j));
808	      col += 4;
809	    }
810
811      fprintf (file, " }\n");
812    }
813}
814
815/* Function to be called from the debugger to print the contents
816   of a bitmap.  */
817
818void
819debug_bitmap (head)
820     bitmap head;
821{
822  debug_bitmap_file (stdout, head);
823}
824
825/* Function to print out the contents of a bitmap.  Unlike debug_bitmap_file,
826   it does not print anything but the bits.  */
827
828void
829bitmap_print (file, head, prefix, suffix)
830     FILE *file;
831     bitmap head;
832     const char *prefix;
833     const char *suffix;
834{
835  const char *comma = "";
836  int i;
837
838  fputs (prefix, file);
839  EXECUTE_IF_SET_IN_BITMAP (head, 0, i,
840			    {
841			      fprintf (file, "%s%d", comma, i);
842			      comma = ", ";
843			    });
844  fputs (suffix, file);
845}
846
847#include "gt-bitmap.h"
848