xref: /dflybsd-src/contrib/gcc-4.7/gcc/sbitmap.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Simple bitmaps.
2*e4b17023SJohn Marino    Copyright (C) 1999, 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino 
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino 
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
10*e4b17023SJohn Marino version.
11*e4b17023SJohn Marino 
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino 
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
20*e4b17023SJohn Marino 
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "coretypes.h"
24*e4b17023SJohn Marino #include "sbitmap.h"
25*e4b17023SJohn Marino 
26*e4b17023SJohn Marino #ifdef IN_GCC
27*e4b17023SJohn Marino /* FIXME: sbitmap is just a data structure, but we define dataflow functions
28*e4b17023SJohn Marino    here also.  This is conditional on IN_GCC (see second #ifdef IN_GCC
29*e4b17023SJohn Marino    further down).
30*e4b17023SJohn Marino    For now, also only conditionally include basic-block.h, but we should
31*e4b17023SJohn Marino    find a better place for the dataflow functions.  Perhaps cfganal.c?  */
32*e4b17023SJohn Marino #include "basic-block.h"
33*e4b17023SJohn Marino #endif
34*e4b17023SJohn Marino 
35*e4b17023SJohn Marino #if GCC_VERSION >= 3400
36*e4b17023SJohn Marino #  if HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONG
37*e4b17023SJohn Marino #    define do_popcount(x) __builtin_popcountl(x)
38*e4b17023SJohn Marino #  elif HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONGLONG
39*e4b17023SJohn Marino #    define do_popcount(x) __builtin_popcountll(x)
40*e4b17023SJohn Marino #  else
41*e4b17023SJohn Marino #    error "internal error: sbitmap.h and hwint.h are inconsistent"
42*e4b17023SJohn Marino #  endif
43*e4b17023SJohn Marino #else
44*e4b17023SJohn Marino static unsigned long sbitmap_elt_popcount (SBITMAP_ELT_TYPE);
45*e4b17023SJohn Marino #  define do_popcount(x) sbitmap_elt_popcount((x))
46*e4b17023SJohn Marino #endif
47*e4b17023SJohn Marino 
48*e4b17023SJohn Marino typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
49*e4b17023SJohn Marino typedef const SBITMAP_ELT_TYPE *const_sbitmap_ptr;
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino /* This macro controls debugging that is as expensive as the
52*e4b17023SJohn Marino    operations it verifies.  */
53*e4b17023SJohn Marino 
54*e4b17023SJohn Marino /* #define BITMAP_DEBUGGING  */
55*e4b17023SJohn Marino #ifdef BITMAP_DEBUGGING
56*e4b17023SJohn Marino 
57*e4b17023SJohn Marino /* Verify the population count of sbitmap A matches the cached value,
58*e4b17023SJohn Marino    if there is a cached value. */
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino void
sbitmap_verify_popcount(const_sbitmap a)61*e4b17023SJohn Marino sbitmap_verify_popcount (const_sbitmap a)
62*e4b17023SJohn Marino {
63*e4b17023SJohn Marino   unsigned ix;
64*e4b17023SJohn Marino   unsigned int lastword;
65*e4b17023SJohn Marino 
66*e4b17023SJohn Marino   if (!a->popcount)
67*e4b17023SJohn Marino     return;
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino   lastword = a->size;
70*e4b17023SJohn Marino   for (ix = 0; ix < lastword; ix++)
71*e4b17023SJohn Marino     gcc_assert (a->popcount[ix] == do_popcount (a->elms[ix]));
72*e4b17023SJohn Marino }
73*e4b17023SJohn Marino #endif
74*e4b17023SJohn Marino 
75*e4b17023SJohn Marino /* Bitmap manipulation routines.  */
76*e4b17023SJohn Marino 
77*e4b17023SJohn Marino /* Allocate a simple bitmap of N_ELMS bits.  */
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino sbitmap
sbitmap_alloc(unsigned int n_elms)80*e4b17023SJohn Marino sbitmap_alloc (unsigned int n_elms)
81*e4b17023SJohn Marino {
82*e4b17023SJohn Marino   unsigned int bytes, size, amt;
83*e4b17023SJohn Marino   sbitmap bmap;
84*e4b17023SJohn Marino 
85*e4b17023SJohn Marino   size = SBITMAP_SET_SIZE (n_elms);
86*e4b17023SJohn Marino   bytes = size * sizeof (SBITMAP_ELT_TYPE);
87*e4b17023SJohn Marino   amt = (sizeof (struct simple_bitmap_def)
88*e4b17023SJohn Marino 	 + bytes - sizeof (SBITMAP_ELT_TYPE));
89*e4b17023SJohn Marino   bmap = (sbitmap) xmalloc (amt);
90*e4b17023SJohn Marino   bmap->n_bits = n_elms;
91*e4b17023SJohn Marino   bmap->size = size;
92*e4b17023SJohn Marino   bmap->popcount = NULL;
93*e4b17023SJohn Marino   return bmap;
94*e4b17023SJohn Marino }
95*e4b17023SJohn Marino 
96*e4b17023SJohn Marino /* Allocate a simple bitmap of N_ELMS bits, and a popcount array.  */
97*e4b17023SJohn Marino 
98*e4b17023SJohn Marino sbitmap
sbitmap_alloc_with_popcount(unsigned int n_elms)99*e4b17023SJohn Marino sbitmap_alloc_with_popcount (unsigned int n_elms)
100*e4b17023SJohn Marino {
101*e4b17023SJohn Marino   sbitmap const bmap = sbitmap_alloc (n_elms);
102*e4b17023SJohn Marino   bmap->popcount = XNEWVEC (unsigned char, bmap->size);
103*e4b17023SJohn Marino   return bmap;
104*e4b17023SJohn Marino }
105*e4b17023SJohn Marino 
106*e4b17023SJohn Marino /* Resize a simple bitmap BMAP to N_ELMS bits.  If increasing the
107*e4b17023SJohn Marino    size of BMAP, clear the new bits to zero if the DEF argument
108*e4b17023SJohn Marino    is zero, and set them to one otherwise.  */
109*e4b17023SJohn Marino 
110*e4b17023SJohn Marino sbitmap
sbitmap_resize(sbitmap bmap,unsigned int n_elms,int def)111*e4b17023SJohn Marino sbitmap_resize (sbitmap bmap, unsigned int n_elms, int def)
112*e4b17023SJohn Marino {
113*e4b17023SJohn Marino   unsigned int bytes, size, amt;
114*e4b17023SJohn Marino   unsigned int last_bit;
115*e4b17023SJohn Marino 
116*e4b17023SJohn Marino   size = SBITMAP_SET_SIZE (n_elms);
117*e4b17023SJohn Marino   bytes = size * sizeof (SBITMAP_ELT_TYPE);
118*e4b17023SJohn Marino   if (bytes > SBITMAP_SIZE_BYTES (bmap))
119*e4b17023SJohn Marino     {
120*e4b17023SJohn Marino       amt = (sizeof (struct simple_bitmap_def)
121*e4b17023SJohn Marino 	    + bytes - sizeof (SBITMAP_ELT_TYPE));
122*e4b17023SJohn Marino       bmap = (sbitmap) xrealloc (bmap, amt);
123*e4b17023SJohn Marino       if (bmap->popcount)
124*e4b17023SJohn Marino 	bmap->popcount = XRESIZEVEC (unsigned char, bmap->popcount, size);
125*e4b17023SJohn Marino     }
126*e4b17023SJohn Marino 
127*e4b17023SJohn Marino   if (n_elms > bmap->n_bits)
128*e4b17023SJohn Marino     {
129*e4b17023SJohn Marino       if (def)
130*e4b17023SJohn Marino 	{
131*e4b17023SJohn Marino 	  memset (bmap->elms + bmap->size, -1,
132*e4b17023SJohn Marino 		  bytes - SBITMAP_SIZE_BYTES (bmap));
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino 	  /* Set the new bits if the original last element.  */
135*e4b17023SJohn Marino 	  last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
136*e4b17023SJohn Marino 	  if (last_bit)
137*e4b17023SJohn Marino 	    bmap->elms[bmap->size - 1]
138*e4b17023SJohn Marino 	      |= ~((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
139*e4b17023SJohn Marino 
140*e4b17023SJohn Marino 	  /* Clear the unused bit in the new last element.  */
141*e4b17023SJohn Marino 	  last_bit = n_elms % SBITMAP_ELT_BITS;
142*e4b17023SJohn Marino 	  if (last_bit)
143*e4b17023SJohn Marino 	    bmap->elms[size - 1]
144*e4b17023SJohn Marino 	      &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
145*e4b17023SJohn Marino 	}
146*e4b17023SJohn Marino       else
147*e4b17023SJohn Marino 	{
148*e4b17023SJohn Marino 	  memset (bmap->elms + bmap->size, 0,
149*e4b17023SJohn Marino 		  bytes - SBITMAP_SIZE_BYTES (bmap));
150*e4b17023SJohn Marino 	  if (bmap->popcount)
151*e4b17023SJohn Marino 	    memset (bmap->popcount + bmap->size, 0,
152*e4b17023SJohn Marino 		    (size * sizeof (unsigned char))
153*e4b17023SJohn Marino 		    - (bmap->size * sizeof (unsigned char)));
154*e4b17023SJohn Marino 
155*e4b17023SJohn Marino 	}
156*e4b17023SJohn Marino     }
157*e4b17023SJohn Marino   else if (n_elms < bmap->n_bits)
158*e4b17023SJohn Marino     {
159*e4b17023SJohn Marino       /* Clear the surplus bits in the last word.  */
160*e4b17023SJohn Marino       last_bit = n_elms % SBITMAP_ELT_BITS;
161*e4b17023SJohn Marino       if (last_bit)
162*e4b17023SJohn Marino 	{
163*e4b17023SJohn Marino 	  bmap->elms[size - 1]
164*e4b17023SJohn Marino 	    &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
165*e4b17023SJohn Marino 	  if (bmap->popcount)
166*e4b17023SJohn Marino 	    bmap->popcount[size - 1] = do_popcount (bmap->elms[size - 1]);
167*e4b17023SJohn Marino 	}
168*e4b17023SJohn Marino     }
169*e4b17023SJohn Marino 
170*e4b17023SJohn Marino   bmap->n_bits = n_elms;
171*e4b17023SJohn Marino   bmap->size = size;
172*e4b17023SJohn Marino   return bmap;
173*e4b17023SJohn Marino }
174*e4b17023SJohn Marino 
175*e4b17023SJohn Marino /* Re-allocate a simple bitmap of N_ELMS bits. New storage is uninitialized.  */
176*e4b17023SJohn Marino 
177*e4b17023SJohn Marino sbitmap
sbitmap_realloc(sbitmap src,unsigned int n_elms)178*e4b17023SJohn Marino sbitmap_realloc (sbitmap src, unsigned int n_elms)
179*e4b17023SJohn Marino {
180*e4b17023SJohn Marino   unsigned int bytes, size, amt;
181*e4b17023SJohn Marino   sbitmap bmap;
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   size = SBITMAP_SET_SIZE (n_elms);
184*e4b17023SJohn Marino   bytes = size * sizeof (SBITMAP_ELT_TYPE);
185*e4b17023SJohn Marino   amt = (sizeof (struct simple_bitmap_def)
186*e4b17023SJohn Marino 	 + bytes - sizeof (SBITMAP_ELT_TYPE));
187*e4b17023SJohn Marino 
188*e4b17023SJohn Marino   if (SBITMAP_SIZE_BYTES (src)  >= bytes)
189*e4b17023SJohn Marino     {
190*e4b17023SJohn Marino       src->n_bits = n_elms;
191*e4b17023SJohn Marino       return src;
192*e4b17023SJohn Marino     }
193*e4b17023SJohn Marino 
194*e4b17023SJohn Marino   bmap = (sbitmap) xrealloc (src, amt);
195*e4b17023SJohn Marino   bmap->n_bits = n_elms;
196*e4b17023SJohn Marino   bmap->size = size;
197*e4b17023SJohn Marino   return bmap;
198*e4b17023SJohn Marino }
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino /* Allocate a vector of N_VECS bitmaps of N_ELMS bits.  */
201*e4b17023SJohn Marino 
202*e4b17023SJohn Marino sbitmap *
sbitmap_vector_alloc(unsigned int n_vecs,unsigned int n_elms)203*e4b17023SJohn Marino sbitmap_vector_alloc (unsigned int n_vecs, unsigned int n_elms)
204*e4b17023SJohn Marino {
205*e4b17023SJohn Marino   unsigned int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
206*e4b17023SJohn Marino   sbitmap *bitmap_vector;
207*e4b17023SJohn Marino 
208*e4b17023SJohn Marino   size = SBITMAP_SET_SIZE (n_elms);
209*e4b17023SJohn Marino   bytes = size * sizeof (SBITMAP_ELT_TYPE);
210*e4b17023SJohn Marino   elm_bytes = (sizeof (struct simple_bitmap_def)
211*e4b17023SJohn Marino 	       + bytes - sizeof (SBITMAP_ELT_TYPE));
212*e4b17023SJohn Marino   vector_bytes = n_vecs * sizeof (sbitmap *);
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino   /* Round up `vector_bytes' to account for the alignment requirements
215*e4b17023SJohn Marino      of an sbitmap.  One could allocate the vector-table and set of sbitmaps
216*e4b17023SJohn Marino      separately, but that requires maintaining two pointers or creating
217*e4b17023SJohn Marino      a cover struct to hold both pointers (so our result is still just
218*e4b17023SJohn Marino      one pointer).  Neither is a bad idea, but this is simpler for now.  */
219*e4b17023SJohn Marino   {
220*e4b17023SJohn Marino     /* Based on DEFAULT_ALIGNMENT computation in obstack.c.  */
221*e4b17023SJohn Marino     struct { char x; SBITMAP_ELT_TYPE y; } align;
222*e4b17023SJohn Marino     int alignment = (char *) & align.y - & align.x;
223*e4b17023SJohn Marino     vector_bytes = (vector_bytes + alignment - 1) & ~ (alignment - 1);
224*e4b17023SJohn Marino   }
225*e4b17023SJohn Marino 
226*e4b17023SJohn Marino   amt = vector_bytes + (n_vecs * elm_bytes);
227*e4b17023SJohn Marino   bitmap_vector = (sbitmap *) xmalloc (amt);
228*e4b17023SJohn Marino 
229*e4b17023SJohn Marino   for (i = 0, offset = vector_bytes; i < n_vecs; i++, offset += elm_bytes)
230*e4b17023SJohn Marino     {
231*e4b17023SJohn Marino       sbitmap b = (sbitmap) ((char *) bitmap_vector + offset);
232*e4b17023SJohn Marino 
233*e4b17023SJohn Marino       bitmap_vector[i] = b;
234*e4b17023SJohn Marino       b->n_bits = n_elms;
235*e4b17023SJohn Marino       b->size = size;
236*e4b17023SJohn Marino       b->popcount = NULL;
237*e4b17023SJohn Marino     }
238*e4b17023SJohn Marino 
239*e4b17023SJohn Marino   return bitmap_vector;
240*e4b17023SJohn Marino }
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino /* Copy sbitmap SRC to DST.  */
243*e4b17023SJohn Marino 
244*e4b17023SJohn Marino void
sbitmap_copy(sbitmap dst,const_sbitmap src)245*e4b17023SJohn Marino sbitmap_copy (sbitmap dst, const_sbitmap src)
246*e4b17023SJohn Marino {
247*e4b17023SJohn Marino   memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
248*e4b17023SJohn Marino   if (dst->popcount)
249*e4b17023SJohn Marino     memcpy (dst->popcount, src->popcount, sizeof (unsigned char) * dst->size);
250*e4b17023SJohn Marino }
251*e4b17023SJohn Marino 
252*e4b17023SJohn Marino /* Copy the first N elements of sbitmap SRC to DST.  */
253*e4b17023SJohn Marino 
254*e4b17023SJohn Marino void
sbitmap_copy_n(sbitmap dst,const_sbitmap src,unsigned int n)255*e4b17023SJohn Marino sbitmap_copy_n (sbitmap dst, const_sbitmap src, unsigned int n)
256*e4b17023SJohn Marino {
257*e4b17023SJohn Marino   memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * n);
258*e4b17023SJohn Marino   if (dst->popcount)
259*e4b17023SJohn Marino     memcpy (dst->popcount, src->popcount, sizeof (unsigned char) * n);
260*e4b17023SJohn Marino }
261*e4b17023SJohn Marino 
262*e4b17023SJohn Marino /* Determine if a == b.  */
263*e4b17023SJohn Marino int
sbitmap_equal(const_sbitmap a,const_sbitmap b)264*e4b17023SJohn Marino sbitmap_equal (const_sbitmap a, const_sbitmap b)
265*e4b17023SJohn Marino {
266*e4b17023SJohn Marino   return !memcmp (a->elms, b->elms, sizeof (SBITMAP_ELT_TYPE) * a->size);
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino 
269*e4b17023SJohn Marino /* Return true if the bitmap is empty.  */
270*e4b17023SJohn Marino 
271*e4b17023SJohn Marino bool
sbitmap_empty_p(const_sbitmap bmap)272*e4b17023SJohn Marino sbitmap_empty_p (const_sbitmap bmap)
273*e4b17023SJohn Marino {
274*e4b17023SJohn Marino   unsigned int i;
275*e4b17023SJohn Marino   for (i=0; i<bmap->size; i++)
276*e4b17023SJohn Marino     if (bmap->elms[i])
277*e4b17023SJohn Marino       return false;
278*e4b17023SJohn Marino 
279*e4b17023SJohn Marino   return true;
280*e4b17023SJohn Marino }
281*e4b17023SJohn Marino 
282*e4b17023SJohn Marino /* Return false if any of the N bits are set in MAP starting at
283*e4b17023SJohn Marino    START.  */
284*e4b17023SJohn Marino 
285*e4b17023SJohn Marino bool
sbitmap_range_empty_p(const_sbitmap bmap,unsigned int start,unsigned int n)286*e4b17023SJohn Marino sbitmap_range_empty_p (const_sbitmap bmap, unsigned int start, unsigned int n)
287*e4b17023SJohn Marino {
288*e4b17023SJohn Marino   unsigned int i = start / SBITMAP_ELT_BITS;
289*e4b17023SJohn Marino   SBITMAP_ELT_TYPE elm;
290*e4b17023SJohn Marino   unsigned int shift = start % SBITMAP_ELT_BITS;
291*e4b17023SJohn Marino 
292*e4b17023SJohn Marino   gcc_assert (bmap->n_bits >= start + n);
293*e4b17023SJohn Marino 
294*e4b17023SJohn Marino   elm = bmap->elms[i];
295*e4b17023SJohn Marino   elm = elm >> shift;
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino   if (shift + n <= SBITMAP_ELT_BITS)
298*e4b17023SJohn Marino     {
299*e4b17023SJohn Marino       /* The bits are totally contained in a single element.  */
300*e4b17023SJohn Marino       if (shift + n < SBITMAP_ELT_BITS)
301*e4b17023SJohn Marino         elm &= ((1 << n) - 1);
302*e4b17023SJohn Marino       return (elm == 0);
303*e4b17023SJohn Marino     }
304*e4b17023SJohn Marino 
305*e4b17023SJohn Marino   if (elm)
306*e4b17023SJohn Marino     return false;
307*e4b17023SJohn Marino 
308*e4b17023SJohn Marino   n -= SBITMAP_ELT_BITS - shift;
309*e4b17023SJohn Marino   i++;
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino   /* Deal with full elts.  */
312*e4b17023SJohn Marino   while (n >= SBITMAP_ELT_BITS)
313*e4b17023SJohn Marino     {
314*e4b17023SJohn Marino       if (bmap->elms[i])
315*e4b17023SJohn Marino 	return false;
316*e4b17023SJohn Marino       i++;
317*e4b17023SJohn Marino       n -= SBITMAP_ELT_BITS;
318*e4b17023SJohn Marino     }
319*e4b17023SJohn Marino 
320*e4b17023SJohn Marino   /* The leftover bits.  */
321*e4b17023SJohn Marino   if (n)
322*e4b17023SJohn Marino     {
323*e4b17023SJohn Marino       elm = bmap->elms[i];
324*e4b17023SJohn Marino       elm &= ((1 << n) - 1);
325*e4b17023SJohn Marino       return (elm == 0);
326*e4b17023SJohn Marino     }
327*e4b17023SJohn Marino 
328*e4b17023SJohn Marino   return true;
329*e4b17023SJohn Marino }
330*e4b17023SJohn Marino 
331*e4b17023SJohn Marino 
332*e4b17023SJohn Marino 
333*e4b17023SJohn Marino /* Zero all elements in a bitmap.  */
334*e4b17023SJohn Marino 
335*e4b17023SJohn Marino void
sbitmap_zero(sbitmap bmap)336*e4b17023SJohn Marino sbitmap_zero (sbitmap bmap)
337*e4b17023SJohn Marino {
338*e4b17023SJohn Marino   memset (bmap->elms, 0, SBITMAP_SIZE_BYTES (bmap));
339*e4b17023SJohn Marino   if (bmap->popcount)
340*e4b17023SJohn Marino     memset (bmap->popcount, 0, bmap->size * sizeof (unsigned char));
341*e4b17023SJohn Marino }
342*e4b17023SJohn Marino 
343*e4b17023SJohn Marino /* Set all elements in a bitmap to ones.  */
344*e4b17023SJohn Marino 
345*e4b17023SJohn Marino void
sbitmap_ones(sbitmap bmap)346*e4b17023SJohn Marino sbitmap_ones (sbitmap bmap)
347*e4b17023SJohn Marino {
348*e4b17023SJohn Marino   unsigned int last_bit;
349*e4b17023SJohn Marino 
350*e4b17023SJohn Marino   memset (bmap->elms, -1, SBITMAP_SIZE_BYTES (bmap));
351*e4b17023SJohn Marino   if (bmap->popcount)
352*e4b17023SJohn Marino     memset (bmap->popcount, -1, bmap->size * sizeof (unsigned char));
353*e4b17023SJohn Marino 
354*e4b17023SJohn Marino   last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
355*e4b17023SJohn Marino   if (last_bit)
356*e4b17023SJohn Marino     {
357*e4b17023SJohn Marino       bmap->elms[bmap->size - 1]
358*e4b17023SJohn Marino 	= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
359*e4b17023SJohn Marino       if (bmap->popcount)
360*e4b17023SJohn Marino 	bmap->popcount[bmap->size - 1]
361*e4b17023SJohn Marino 	  = do_popcount (bmap->elms[bmap->size - 1]);
362*e4b17023SJohn Marino     }
363*e4b17023SJohn Marino }
364*e4b17023SJohn Marino 
365*e4b17023SJohn Marino /* Zero a vector of N_VECS bitmaps.  */
366*e4b17023SJohn Marino 
367*e4b17023SJohn Marino void
sbitmap_vector_zero(sbitmap * bmap,unsigned int n_vecs)368*e4b17023SJohn Marino sbitmap_vector_zero (sbitmap *bmap, unsigned int n_vecs)
369*e4b17023SJohn Marino {
370*e4b17023SJohn Marino   unsigned int i;
371*e4b17023SJohn Marino 
372*e4b17023SJohn Marino   for (i = 0; i < n_vecs; i++)
373*e4b17023SJohn Marino     sbitmap_zero (bmap[i]);
374*e4b17023SJohn Marino }
375*e4b17023SJohn Marino 
376*e4b17023SJohn Marino /* Set a vector of N_VECS bitmaps to ones.  */
377*e4b17023SJohn Marino 
378*e4b17023SJohn Marino void
sbitmap_vector_ones(sbitmap * bmap,unsigned int n_vecs)379*e4b17023SJohn Marino sbitmap_vector_ones (sbitmap *bmap, unsigned int n_vecs)
380*e4b17023SJohn Marino {
381*e4b17023SJohn Marino   unsigned int i;
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino   for (i = 0; i < n_vecs; i++)
384*e4b17023SJohn Marino     sbitmap_ones (bmap[i]);
385*e4b17023SJohn Marino }
386*e4b17023SJohn Marino 
387*e4b17023SJohn Marino /* Set DST to be A union (B - C).
388*e4b17023SJohn Marino    DST = A | (B & ~C).
389*e4b17023SJohn Marino    Returns true if any change is made.  */
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino bool
sbitmap_union_of_diff_cg(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)392*e4b17023SJohn Marino sbitmap_union_of_diff_cg (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
393*e4b17023SJohn Marino {
394*e4b17023SJohn Marino   unsigned int i, n = dst->size;
395*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
396*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
397*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
398*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
399*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
400*e4b17023SJohn Marino 
401*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
402*e4b17023SJohn Marino 
403*e4b17023SJohn Marino   for (i = 0; i < n; i++)
404*e4b17023SJohn Marino     {
405*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & ~*cp++);
406*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
407*e4b17023SJohn Marino       *dstp++ = tmp;
408*e4b17023SJohn Marino     }
409*e4b17023SJohn Marino 
410*e4b17023SJohn Marino   return changed != 0;
411*e4b17023SJohn Marino }
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino void
sbitmap_union_of_diff(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)414*e4b17023SJohn Marino sbitmap_union_of_diff (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
415*e4b17023SJohn Marino {
416*e4b17023SJohn Marino   unsigned int i, n = dst->size;
417*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
418*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
419*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
420*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
421*e4b17023SJohn Marino 
422*e4b17023SJohn Marino   gcc_assert (!dst->popcount && !a->popcount
423*e4b17023SJohn Marino 	      && !b->popcount && !c->popcount);
424*e4b17023SJohn Marino 
425*e4b17023SJohn Marino   for (i = 0; i < n; i++)
426*e4b17023SJohn Marino     *dstp++ = *ap++ | (*bp++ & ~*cp++);
427*e4b17023SJohn Marino }
428*e4b17023SJohn Marino 
429*e4b17023SJohn Marino /* Set bitmap DST to the bitwise negation of the bitmap SRC.  */
430*e4b17023SJohn Marino 
431*e4b17023SJohn Marino void
sbitmap_not(sbitmap dst,const_sbitmap src)432*e4b17023SJohn Marino sbitmap_not (sbitmap dst, const_sbitmap src)
433*e4b17023SJohn Marino {
434*e4b17023SJohn Marino   unsigned int i, n = dst->size;
435*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
436*e4b17023SJohn Marino   const_sbitmap_ptr srcp = src->elms;
437*e4b17023SJohn Marino   unsigned int last_bit;
438*e4b17023SJohn Marino 
439*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
440*e4b17023SJohn Marino 
441*e4b17023SJohn Marino   for (i = 0; i < n; i++)
442*e4b17023SJohn Marino     *dstp++ = ~*srcp++;
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   /* Zero all bits past n_bits, by ANDing dst with sbitmap_ones.  */
445*e4b17023SJohn Marino   last_bit = src->n_bits % SBITMAP_ELT_BITS;
446*e4b17023SJohn Marino   if (last_bit)
447*e4b17023SJohn Marino     dst->elms[n-1] = dst->elms[n-1]
448*e4b17023SJohn Marino       & ((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
449*e4b17023SJohn Marino }
450*e4b17023SJohn Marino 
451*e4b17023SJohn Marino /* Set the bits in DST to be the difference between the bits
452*e4b17023SJohn Marino    in A and the bits in B. i.e. dst = a & (~b).  */
453*e4b17023SJohn Marino 
454*e4b17023SJohn Marino void
sbitmap_difference(sbitmap dst,const_sbitmap a,const_sbitmap b)455*e4b17023SJohn Marino sbitmap_difference (sbitmap dst, const_sbitmap a, const_sbitmap b)
456*e4b17023SJohn Marino {
457*e4b17023SJohn Marino   unsigned int i, dst_size = dst->size;
458*e4b17023SJohn Marino   unsigned int min_size = dst->size;
459*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
460*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
461*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
462*e4b17023SJohn Marino 
463*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
464*e4b17023SJohn Marino 
465*e4b17023SJohn Marino   /* A should be at least as large as DEST, to have a defined source.  */
466*e4b17023SJohn Marino   gcc_assert (a->size >= dst_size);
467*e4b17023SJohn Marino   /* If minuend is smaller, we simply pretend it to be zero bits, i.e.
468*e4b17023SJohn Marino      only copy the subtrahend into dest.  */
469*e4b17023SJohn Marino   if (b->size < min_size)
470*e4b17023SJohn Marino     min_size = b->size;
471*e4b17023SJohn Marino   for (i = 0; i < min_size; i++)
472*e4b17023SJohn Marino     *dstp++ = *ap++ & (~*bp++);
473*e4b17023SJohn Marino   /* Now fill the rest of dest from A, if B was too short.
474*e4b17023SJohn Marino      This makes sense only when destination and A differ.  */
475*e4b17023SJohn Marino   if (dst != a && i != dst_size)
476*e4b17023SJohn Marino     for (; i < dst_size; i++)
477*e4b17023SJohn Marino       *dstp++ = *ap++;
478*e4b17023SJohn Marino }
479*e4b17023SJohn Marino 
480*e4b17023SJohn Marino /* Return true if there are any bits set in A are also set in B.
481*e4b17023SJohn Marino    Return false otherwise.  */
482*e4b17023SJohn Marino 
483*e4b17023SJohn Marino bool
sbitmap_any_common_bits(const_sbitmap a,const_sbitmap b)484*e4b17023SJohn Marino sbitmap_any_common_bits (const_sbitmap a, const_sbitmap b)
485*e4b17023SJohn Marino {
486*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
487*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
488*e4b17023SJohn Marino   unsigned int i, n;
489*e4b17023SJohn Marino 
490*e4b17023SJohn Marino   n = MIN (a->size, b->size);
491*e4b17023SJohn Marino   for (i = 0; i < n; i++)
492*e4b17023SJohn Marino     if ((*ap++ & *bp++) != 0)
493*e4b17023SJohn Marino       return true;
494*e4b17023SJohn Marino 
495*e4b17023SJohn Marino   return false;
496*e4b17023SJohn Marino }
497*e4b17023SJohn Marino 
498*e4b17023SJohn Marino /* Set DST to be (A and B).
499*e4b17023SJohn Marino    Return nonzero if any change is made.  */
500*e4b17023SJohn Marino 
501*e4b17023SJohn Marino bool
sbitmap_a_and_b_cg(sbitmap dst,const_sbitmap a,const_sbitmap b)502*e4b17023SJohn Marino sbitmap_a_and_b_cg (sbitmap dst, const_sbitmap a, const_sbitmap b)
503*e4b17023SJohn Marino {
504*e4b17023SJohn Marino   unsigned int i, n = dst->size;
505*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
506*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
507*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
508*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
511*e4b17023SJohn Marino 
512*e4b17023SJohn Marino   for (i = 0; i < n; i++)
513*e4b17023SJohn Marino     {
514*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
515*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
516*e4b17023SJohn Marino       *dstp++ = tmp;
517*e4b17023SJohn Marino     }
518*e4b17023SJohn Marino 
519*e4b17023SJohn Marino   return changed != 0;
520*e4b17023SJohn Marino }
521*e4b17023SJohn Marino 
522*e4b17023SJohn Marino void
sbitmap_a_and_b(sbitmap dst,const_sbitmap a,const_sbitmap b)523*e4b17023SJohn Marino sbitmap_a_and_b (sbitmap dst, const_sbitmap a, const_sbitmap b)
524*e4b17023SJohn Marino {
525*e4b17023SJohn Marino   unsigned int i, n = dst->size;
526*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
527*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
528*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
529*e4b17023SJohn Marino   bool has_popcount = dst->popcount != NULL;
530*e4b17023SJohn Marino   unsigned char *popcountp = dst->popcount;
531*e4b17023SJohn Marino 
532*e4b17023SJohn Marino   for (i = 0; i < n; i++)
533*e4b17023SJohn Marino     {
534*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
535*e4b17023SJohn Marino       if (has_popcount)
536*e4b17023SJohn Marino 	{
537*e4b17023SJohn Marino 	  bool wordchanged = (*dstp ^ tmp) != 0;
538*e4b17023SJohn Marino 	  if (wordchanged)
539*e4b17023SJohn Marino 	    *popcountp = do_popcount (tmp);
540*e4b17023SJohn Marino 	  popcountp++;
541*e4b17023SJohn Marino 	}
542*e4b17023SJohn Marino       *dstp++ = tmp;
543*e4b17023SJohn Marino     }
544*e4b17023SJohn Marino #ifdef BITMAP_DEBUGGING
545*e4b17023SJohn Marino   if (has_popcount)
546*e4b17023SJohn Marino     sbitmap_verify_popcount (dst);
547*e4b17023SJohn Marino #endif
548*e4b17023SJohn Marino }
549*e4b17023SJohn Marino 
550*e4b17023SJohn Marino /* Set DST to be (A xor B)).
551*e4b17023SJohn Marino    Return nonzero if any change is made.  */
552*e4b17023SJohn Marino 
553*e4b17023SJohn Marino bool
sbitmap_a_xor_b_cg(sbitmap dst,const_sbitmap a,const_sbitmap b)554*e4b17023SJohn Marino sbitmap_a_xor_b_cg (sbitmap dst, const_sbitmap a, const_sbitmap b)
555*e4b17023SJohn Marino {
556*e4b17023SJohn Marino   unsigned int i, n = dst->size;
557*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
558*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
559*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
560*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
561*e4b17023SJohn Marino 
562*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
563*e4b17023SJohn Marino 
564*e4b17023SJohn Marino   for (i = 0; i < n; i++)
565*e4b17023SJohn Marino     {
566*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
567*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
568*e4b17023SJohn Marino       *dstp++ = tmp;
569*e4b17023SJohn Marino     }
570*e4b17023SJohn Marino 
571*e4b17023SJohn Marino   return changed != 0;
572*e4b17023SJohn Marino }
573*e4b17023SJohn Marino 
574*e4b17023SJohn Marino void
sbitmap_a_xor_b(sbitmap dst,const_sbitmap a,const_sbitmap b)575*e4b17023SJohn Marino sbitmap_a_xor_b (sbitmap dst, const_sbitmap a, const_sbitmap b)
576*e4b17023SJohn Marino {
577*e4b17023SJohn Marino   unsigned int i, n = dst->size;
578*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
579*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
580*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
581*e4b17023SJohn Marino   bool has_popcount = dst->popcount != NULL;
582*e4b17023SJohn Marino   unsigned char *popcountp = dst->popcount;
583*e4b17023SJohn Marino 
584*e4b17023SJohn Marino   for (i = 0; i < n; i++)
585*e4b17023SJohn Marino     {
586*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
587*e4b17023SJohn Marino       if (has_popcount)
588*e4b17023SJohn Marino 	{
589*e4b17023SJohn Marino 	  bool wordchanged = (*dstp ^ tmp) != 0;
590*e4b17023SJohn Marino 	  if (wordchanged)
591*e4b17023SJohn Marino 	    *popcountp = do_popcount (tmp);
592*e4b17023SJohn Marino 	  popcountp++;
593*e4b17023SJohn Marino 	}
594*e4b17023SJohn Marino       *dstp++ = tmp;
595*e4b17023SJohn Marino     }
596*e4b17023SJohn Marino #ifdef BITMAP_DEBUGGING
597*e4b17023SJohn Marino   if (has_popcount)
598*e4b17023SJohn Marino     sbitmap_verify_popcount (dst);
599*e4b17023SJohn Marino #endif
600*e4b17023SJohn Marino }
601*e4b17023SJohn Marino 
602*e4b17023SJohn Marino /* Set DST to be (A or B)).
603*e4b17023SJohn Marino    Return nonzero if any change is made.  */
604*e4b17023SJohn Marino 
605*e4b17023SJohn Marino bool
sbitmap_a_or_b_cg(sbitmap dst,const_sbitmap a,const_sbitmap b)606*e4b17023SJohn Marino sbitmap_a_or_b_cg (sbitmap dst, const_sbitmap a, const_sbitmap b)
607*e4b17023SJohn Marino {
608*e4b17023SJohn Marino   unsigned int i, n = dst->size;
609*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
610*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
611*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
612*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
615*e4b17023SJohn Marino 
616*e4b17023SJohn Marino   for (i = 0; i < n; i++)
617*e4b17023SJohn Marino     {
618*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
619*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
620*e4b17023SJohn Marino       *dstp++ = tmp;
621*e4b17023SJohn Marino     }
622*e4b17023SJohn Marino 
623*e4b17023SJohn Marino   return changed != 0;
624*e4b17023SJohn Marino }
625*e4b17023SJohn Marino 
626*e4b17023SJohn Marino void
sbitmap_a_or_b(sbitmap dst,const_sbitmap a,const_sbitmap b)627*e4b17023SJohn Marino sbitmap_a_or_b (sbitmap dst, const_sbitmap a, const_sbitmap b)
628*e4b17023SJohn Marino {
629*e4b17023SJohn Marino   unsigned int i, n = dst->size;
630*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
631*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
632*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
633*e4b17023SJohn Marino   bool has_popcount = dst->popcount != NULL;
634*e4b17023SJohn Marino   unsigned char *popcountp = dst->popcount;
635*e4b17023SJohn Marino 
636*e4b17023SJohn Marino   for (i = 0; i < n; i++)
637*e4b17023SJohn Marino     {
638*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
639*e4b17023SJohn Marino       if (has_popcount)
640*e4b17023SJohn Marino 	{
641*e4b17023SJohn Marino 	  bool wordchanged = (*dstp ^ tmp) != 0;
642*e4b17023SJohn Marino 	  if (wordchanged)
643*e4b17023SJohn Marino 	    *popcountp = do_popcount (tmp);
644*e4b17023SJohn Marino 	  popcountp++;
645*e4b17023SJohn Marino 	}
646*e4b17023SJohn Marino       *dstp++ = tmp;
647*e4b17023SJohn Marino     }
648*e4b17023SJohn Marino #ifdef BITMAP_DEBUGGING
649*e4b17023SJohn Marino   if (has_popcount)
650*e4b17023SJohn Marino     sbitmap_verify_popcount (dst);
651*e4b17023SJohn Marino #endif
652*e4b17023SJohn Marino }
653*e4b17023SJohn Marino 
654*e4b17023SJohn Marino /* Return nonzero if A is a subset of B.  */
655*e4b17023SJohn Marino 
656*e4b17023SJohn Marino bool
sbitmap_a_subset_b_p(const_sbitmap a,const_sbitmap b)657*e4b17023SJohn Marino sbitmap_a_subset_b_p (const_sbitmap a, const_sbitmap b)
658*e4b17023SJohn Marino {
659*e4b17023SJohn Marino   unsigned int i, n = a->size;
660*e4b17023SJohn Marino   const_sbitmap_ptr ap, bp;
661*e4b17023SJohn Marino 
662*e4b17023SJohn Marino   for (ap = a->elms, bp = b->elms, i = 0; i < n; i++, ap++, bp++)
663*e4b17023SJohn Marino     if ((*ap | *bp) != *bp)
664*e4b17023SJohn Marino       return false;
665*e4b17023SJohn Marino 
666*e4b17023SJohn Marino   return true;
667*e4b17023SJohn Marino }
668*e4b17023SJohn Marino 
669*e4b17023SJohn Marino /* Set DST to be (A or (B and C)).
670*e4b17023SJohn Marino    Return nonzero if any change is made.  */
671*e4b17023SJohn Marino 
672*e4b17023SJohn Marino bool
sbitmap_a_or_b_and_c_cg(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)673*e4b17023SJohn Marino sbitmap_a_or_b_and_c_cg (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
674*e4b17023SJohn Marino {
675*e4b17023SJohn Marino   unsigned int i, n = dst->size;
676*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
677*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
678*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
679*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
680*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
681*e4b17023SJohn Marino 
682*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
683*e4b17023SJohn Marino 
684*e4b17023SJohn Marino   for (i = 0; i < n; i++)
685*e4b17023SJohn Marino     {
686*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & *cp++);
687*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
688*e4b17023SJohn Marino       *dstp++ = tmp;
689*e4b17023SJohn Marino     }
690*e4b17023SJohn Marino 
691*e4b17023SJohn Marino   return changed != 0;
692*e4b17023SJohn Marino }
693*e4b17023SJohn Marino 
694*e4b17023SJohn Marino void
sbitmap_a_or_b_and_c(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)695*e4b17023SJohn Marino sbitmap_a_or_b_and_c (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
696*e4b17023SJohn Marino {
697*e4b17023SJohn Marino   unsigned int i, n = dst->size;
698*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
699*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
700*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
701*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
702*e4b17023SJohn Marino 
703*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
704*e4b17023SJohn Marino 
705*e4b17023SJohn Marino   for (i = 0; i < n; i++)
706*e4b17023SJohn Marino     *dstp++ = *ap++ | (*bp++ & *cp++);
707*e4b17023SJohn Marino }
708*e4b17023SJohn Marino 
709*e4b17023SJohn Marino /* Set DST to be (A and (B or C)).
710*e4b17023SJohn Marino    Return nonzero if any change is made.  */
711*e4b17023SJohn Marino 
712*e4b17023SJohn Marino bool
sbitmap_a_and_b_or_c_cg(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)713*e4b17023SJohn Marino sbitmap_a_and_b_or_c_cg (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
714*e4b17023SJohn Marino {
715*e4b17023SJohn Marino   unsigned int i, n = dst->size;
716*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
717*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
718*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
719*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
720*e4b17023SJohn Marino   SBITMAP_ELT_TYPE changed = 0;
721*e4b17023SJohn Marino 
722*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
723*e4b17023SJohn Marino 
724*e4b17023SJohn Marino   for (i = 0; i < n; i++)
725*e4b17023SJohn Marino     {
726*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE tmp = *ap++ & (*bp++ | *cp++);
727*e4b17023SJohn Marino       changed |= *dstp ^ tmp;
728*e4b17023SJohn Marino       *dstp++ = tmp;
729*e4b17023SJohn Marino     }
730*e4b17023SJohn Marino 
731*e4b17023SJohn Marino   return changed != 0;
732*e4b17023SJohn Marino }
733*e4b17023SJohn Marino 
734*e4b17023SJohn Marino void
sbitmap_a_and_b_or_c(sbitmap dst,const_sbitmap a,const_sbitmap b,const_sbitmap c)735*e4b17023SJohn Marino sbitmap_a_and_b_or_c (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
736*e4b17023SJohn Marino {
737*e4b17023SJohn Marino   unsigned int i, n = dst->size;
738*e4b17023SJohn Marino   sbitmap_ptr dstp = dst->elms;
739*e4b17023SJohn Marino   const_sbitmap_ptr ap = a->elms;
740*e4b17023SJohn Marino   const_sbitmap_ptr bp = b->elms;
741*e4b17023SJohn Marino   const_sbitmap_ptr cp = c->elms;
742*e4b17023SJohn Marino 
743*e4b17023SJohn Marino   for (i = 0; i < n; i++)
744*e4b17023SJohn Marino     *dstp++ = *ap++ & (*bp++ | *cp++);
745*e4b17023SJohn Marino }
746*e4b17023SJohn Marino 
747*e4b17023SJohn Marino #ifdef IN_GCC
748*e4b17023SJohn Marino /* FIXME: depends on basic-block.h, see comment at start of this file.
749*e4b17023SJohn Marino 
750*e4b17023SJohn Marino    Ironically, the comments before the functions below suggest they do
751*e4b17023SJohn Marino    dataflow using the "new flow graph structures", but that's the *old*
752*e4b17023SJohn Marino    new data structures.  The functions receive basic block numbers and
753*e4b17023SJohn Marino    use BASIC_BLOCK(idx) to get the basic block.  They should receive
754*e4b17023SJohn Marino    the basic block directly,  *sigh*.  */
755*e4b17023SJohn Marino 
756*e4b17023SJohn Marino /* Set the bitmap DST to the intersection of SRC of successors of
757*e4b17023SJohn Marino    block number BB, using the new flow graph structures.  */
758*e4b17023SJohn Marino 
759*e4b17023SJohn Marino void
sbitmap_intersection_of_succs(sbitmap dst,sbitmap * src,int bb)760*e4b17023SJohn Marino sbitmap_intersection_of_succs (sbitmap dst, sbitmap *src, int bb)
761*e4b17023SJohn Marino {
762*e4b17023SJohn Marino   basic_block b = BASIC_BLOCK (bb);
763*e4b17023SJohn Marino   unsigned int set_size = dst->size;
764*e4b17023SJohn Marino   edge e;
765*e4b17023SJohn Marino   unsigned ix;
766*e4b17023SJohn Marino 
767*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
768*e4b17023SJohn Marino 
769*e4b17023SJohn Marino   for (e = NULL, ix = 0; ix < EDGE_COUNT (b->succs); ix++)
770*e4b17023SJohn Marino     {
771*e4b17023SJohn Marino       e = EDGE_SUCC (b, ix);
772*e4b17023SJohn Marino       if (e->dest == EXIT_BLOCK_PTR)
773*e4b17023SJohn Marino 	continue;
774*e4b17023SJohn Marino 
775*e4b17023SJohn Marino       sbitmap_copy (dst, src[e->dest->index]);
776*e4b17023SJohn Marino       break;
777*e4b17023SJohn Marino     }
778*e4b17023SJohn Marino 
779*e4b17023SJohn Marino   if (e == 0)
780*e4b17023SJohn Marino     sbitmap_ones (dst);
781*e4b17023SJohn Marino   else
782*e4b17023SJohn Marino     for (++ix; ix < EDGE_COUNT (b->succs); ix++)
783*e4b17023SJohn Marino       {
784*e4b17023SJohn Marino 	unsigned int i;
785*e4b17023SJohn Marino 	sbitmap_ptr p, r;
786*e4b17023SJohn Marino 
787*e4b17023SJohn Marino 	e = EDGE_SUCC (b, ix);
788*e4b17023SJohn Marino 	if (e->dest == EXIT_BLOCK_PTR)
789*e4b17023SJohn Marino 	  continue;
790*e4b17023SJohn Marino 
791*e4b17023SJohn Marino 	p = src[e->dest->index]->elms;
792*e4b17023SJohn Marino 	r = dst->elms;
793*e4b17023SJohn Marino 	for (i = 0; i < set_size; i++)
794*e4b17023SJohn Marino 	  *r++ &= *p++;
795*e4b17023SJohn Marino       }
796*e4b17023SJohn Marino }
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino /* Set the bitmap DST to the intersection of SRC of predecessors of
799*e4b17023SJohn Marino    block number BB, using the new flow graph structures.  */
800*e4b17023SJohn Marino 
801*e4b17023SJohn Marino void
sbitmap_intersection_of_preds(sbitmap dst,sbitmap * src,int bb)802*e4b17023SJohn Marino sbitmap_intersection_of_preds (sbitmap dst, sbitmap *src, int bb)
803*e4b17023SJohn Marino {
804*e4b17023SJohn Marino   basic_block b = BASIC_BLOCK (bb);
805*e4b17023SJohn Marino   unsigned int set_size = dst->size;
806*e4b17023SJohn Marino   edge e;
807*e4b17023SJohn Marino   unsigned ix;
808*e4b17023SJohn Marino 
809*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
810*e4b17023SJohn Marino 
811*e4b17023SJohn Marino   for (e = NULL, ix = 0; ix < EDGE_COUNT (b->preds); ix++)
812*e4b17023SJohn Marino     {
813*e4b17023SJohn Marino       e = EDGE_PRED (b, ix);
814*e4b17023SJohn Marino       if (e->src == ENTRY_BLOCK_PTR)
815*e4b17023SJohn Marino 	continue;
816*e4b17023SJohn Marino 
817*e4b17023SJohn Marino       sbitmap_copy (dst, src[e->src->index]);
818*e4b17023SJohn Marino       break;
819*e4b17023SJohn Marino     }
820*e4b17023SJohn Marino 
821*e4b17023SJohn Marino   if (e == 0)
822*e4b17023SJohn Marino     sbitmap_ones (dst);
823*e4b17023SJohn Marino   else
824*e4b17023SJohn Marino     for (++ix; ix < EDGE_COUNT (b->preds); ix++)
825*e4b17023SJohn Marino       {
826*e4b17023SJohn Marino 	unsigned int i;
827*e4b17023SJohn Marino 	sbitmap_ptr p, r;
828*e4b17023SJohn Marino 
829*e4b17023SJohn Marino 	e = EDGE_PRED (b, ix);
830*e4b17023SJohn Marino 	if (e->src == ENTRY_BLOCK_PTR)
831*e4b17023SJohn Marino 	  continue;
832*e4b17023SJohn Marino 
833*e4b17023SJohn Marino 	p = src[e->src->index]->elms;
834*e4b17023SJohn Marino 	r = dst->elms;
835*e4b17023SJohn Marino 	for (i = 0; i < set_size; i++)
836*e4b17023SJohn Marino 	  *r++ &= *p++;
837*e4b17023SJohn Marino       }
838*e4b17023SJohn Marino }
839*e4b17023SJohn Marino 
840*e4b17023SJohn Marino /* Set the bitmap DST to the union of SRC of successors of
841*e4b17023SJohn Marino    block number BB, using the new flow graph structures.  */
842*e4b17023SJohn Marino 
843*e4b17023SJohn Marino void
sbitmap_union_of_succs(sbitmap dst,sbitmap * src,int bb)844*e4b17023SJohn Marino sbitmap_union_of_succs (sbitmap dst, sbitmap *src, int bb)
845*e4b17023SJohn Marino {
846*e4b17023SJohn Marino   basic_block b = BASIC_BLOCK (bb);
847*e4b17023SJohn Marino   unsigned int set_size = dst->size;
848*e4b17023SJohn Marino   edge e;
849*e4b17023SJohn Marino   unsigned ix;
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
852*e4b17023SJohn Marino 
853*e4b17023SJohn Marino   for (ix = 0; ix < EDGE_COUNT (b->succs); ix++)
854*e4b17023SJohn Marino     {
855*e4b17023SJohn Marino       e = EDGE_SUCC (b, ix);
856*e4b17023SJohn Marino       if (e->dest == EXIT_BLOCK_PTR)
857*e4b17023SJohn Marino 	continue;
858*e4b17023SJohn Marino 
859*e4b17023SJohn Marino       sbitmap_copy (dst, src[e->dest->index]);
860*e4b17023SJohn Marino       break;
861*e4b17023SJohn Marino     }
862*e4b17023SJohn Marino 
863*e4b17023SJohn Marino   if (ix == EDGE_COUNT (b->succs))
864*e4b17023SJohn Marino     sbitmap_zero (dst);
865*e4b17023SJohn Marino   else
866*e4b17023SJohn Marino     for (ix++; ix < EDGE_COUNT (b->succs); ix++)
867*e4b17023SJohn Marino       {
868*e4b17023SJohn Marino 	unsigned int i;
869*e4b17023SJohn Marino 	sbitmap_ptr p, r;
870*e4b17023SJohn Marino 
871*e4b17023SJohn Marino 	e = EDGE_SUCC (b, ix);
872*e4b17023SJohn Marino 	if (e->dest == EXIT_BLOCK_PTR)
873*e4b17023SJohn Marino 	  continue;
874*e4b17023SJohn Marino 
875*e4b17023SJohn Marino 	p = src[e->dest->index]->elms;
876*e4b17023SJohn Marino 	r = dst->elms;
877*e4b17023SJohn Marino 	for (i = 0; i < set_size; i++)
878*e4b17023SJohn Marino 	  *r++ |= *p++;
879*e4b17023SJohn Marino       }
880*e4b17023SJohn Marino }
881*e4b17023SJohn Marino 
882*e4b17023SJohn Marino /* Set the bitmap DST to the union of SRC of predecessors of
883*e4b17023SJohn Marino    block number BB, using the new flow graph structures.  */
884*e4b17023SJohn Marino 
885*e4b17023SJohn Marino void
sbitmap_union_of_preds(sbitmap dst,sbitmap * src,int bb)886*e4b17023SJohn Marino sbitmap_union_of_preds (sbitmap dst, sbitmap *src, int bb)
887*e4b17023SJohn Marino {
888*e4b17023SJohn Marino   basic_block b = BASIC_BLOCK (bb);
889*e4b17023SJohn Marino   unsigned int set_size = dst->size;
890*e4b17023SJohn Marino   edge e;
891*e4b17023SJohn Marino   unsigned ix;
892*e4b17023SJohn Marino 
893*e4b17023SJohn Marino   gcc_assert (!dst->popcount);
894*e4b17023SJohn Marino 
895*e4b17023SJohn Marino   for (ix = 0; ix < EDGE_COUNT (b->preds); ix++)
896*e4b17023SJohn Marino     {
897*e4b17023SJohn Marino       e = EDGE_PRED (b, ix);
898*e4b17023SJohn Marino       if (e->src== ENTRY_BLOCK_PTR)
899*e4b17023SJohn Marino 	continue;
900*e4b17023SJohn Marino 
901*e4b17023SJohn Marino       sbitmap_copy (dst, src[e->src->index]);
902*e4b17023SJohn Marino       break;
903*e4b17023SJohn Marino     }
904*e4b17023SJohn Marino 
905*e4b17023SJohn Marino   if (ix == EDGE_COUNT (b->preds))
906*e4b17023SJohn Marino     sbitmap_zero (dst);
907*e4b17023SJohn Marino   else
908*e4b17023SJohn Marino     for (ix++; ix < EDGE_COUNT (b->preds); ix++)
909*e4b17023SJohn Marino       {
910*e4b17023SJohn Marino 	unsigned int i;
911*e4b17023SJohn Marino 	sbitmap_ptr p, r;
912*e4b17023SJohn Marino 
913*e4b17023SJohn Marino 	e = EDGE_PRED (b, ix);
914*e4b17023SJohn Marino 	if (e->src == ENTRY_BLOCK_PTR)
915*e4b17023SJohn Marino 	  continue;
916*e4b17023SJohn Marino 
917*e4b17023SJohn Marino 	p = src[e->src->index]->elms;
918*e4b17023SJohn Marino 	r = dst->elms;
919*e4b17023SJohn Marino 	for (i = 0; i < set_size; i++)
920*e4b17023SJohn Marino 	  *r++ |= *p++;
921*e4b17023SJohn Marino       }
922*e4b17023SJohn Marino }
923*e4b17023SJohn Marino #endif
924*e4b17023SJohn Marino 
925*e4b17023SJohn Marino /* Return number of first bit set in the bitmap, -1 if none.  */
926*e4b17023SJohn Marino 
927*e4b17023SJohn Marino int
sbitmap_first_set_bit(const_sbitmap bmap)928*e4b17023SJohn Marino sbitmap_first_set_bit (const_sbitmap bmap)
929*e4b17023SJohn Marino {
930*e4b17023SJohn Marino   unsigned int n = 0;
931*e4b17023SJohn Marino   sbitmap_iterator sbi;
932*e4b17023SJohn Marino 
933*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_SBITMAP (bmap, 0, n, sbi)
934*e4b17023SJohn Marino     return n;
935*e4b17023SJohn Marino   return -1;
936*e4b17023SJohn Marino }
937*e4b17023SJohn Marino 
938*e4b17023SJohn Marino /* Return number of last bit set in the bitmap, -1 if none.  */
939*e4b17023SJohn Marino 
940*e4b17023SJohn Marino int
sbitmap_last_set_bit(const_sbitmap bmap)941*e4b17023SJohn Marino sbitmap_last_set_bit (const_sbitmap bmap)
942*e4b17023SJohn Marino {
943*e4b17023SJohn Marino   int i;
944*e4b17023SJohn Marino   const SBITMAP_ELT_TYPE *const ptr = bmap->elms;
945*e4b17023SJohn Marino 
946*e4b17023SJohn Marino   for (i = bmap->size - 1; i >= 0; i--)
947*e4b17023SJohn Marino     {
948*e4b17023SJohn Marino       const SBITMAP_ELT_TYPE word = ptr[i];
949*e4b17023SJohn Marino 
950*e4b17023SJohn Marino       if (word != 0)
951*e4b17023SJohn Marino 	{
952*e4b17023SJohn Marino 	  unsigned int index = (i + 1) * SBITMAP_ELT_BITS - 1;
953*e4b17023SJohn Marino 	  SBITMAP_ELT_TYPE mask
954*e4b17023SJohn Marino 	    = (SBITMAP_ELT_TYPE) 1 << (SBITMAP_ELT_BITS - 1);
955*e4b17023SJohn Marino 
956*e4b17023SJohn Marino 	  while (1)
957*e4b17023SJohn Marino 	    {
958*e4b17023SJohn Marino 	      if ((word & mask) != 0)
959*e4b17023SJohn Marino 		return index;
960*e4b17023SJohn Marino 
961*e4b17023SJohn Marino 	      mask >>= 1;
962*e4b17023SJohn Marino 	      index--;
963*e4b17023SJohn Marino 	    }
964*e4b17023SJohn Marino 	}
965*e4b17023SJohn Marino     }
966*e4b17023SJohn Marino 
967*e4b17023SJohn Marino   return -1;
968*e4b17023SJohn Marino }
969*e4b17023SJohn Marino 
970*e4b17023SJohn Marino void
dump_sbitmap(FILE * file,const_sbitmap bmap)971*e4b17023SJohn Marino dump_sbitmap (FILE *file, const_sbitmap bmap)
972*e4b17023SJohn Marino {
973*e4b17023SJohn Marino   unsigned int i, n, j;
974*e4b17023SJohn Marino   unsigned int set_size = bmap->size;
975*e4b17023SJohn Marino   unsigned int total_bits = bmap->n_bits;
976*e4b17023SJohn Marino 
977*e4b17023SJohn Marino   fprintf (file, "  ");
978*e4b17023SJohn Marino   for (i = n = 0; i < set_size && n < total_bits; i++)
979*e4b17023SJohn Marino     for (j = 0; j < SBITMAP_ELT_BITS && n < total_bits; j++, n++)
980*e4b17023SJohn Marino       {
981*e4b17023SJohn Marino 	if (n != 0 && n % 10 == 0)
982*e4b17023SJohn Marino 	  fprintf (file, " ");
983*e4b17023SJohn Marino 
984*e4b17023SJohn Marino 	fprintf (file, "%d",
985*e4b17023SJohn Marino 		 (bmap->elms[i] & ((SBITMAP_ELT_TYPE) 1 << j)) != 0);
986*e4b17023SJohn Marino       }
987*e4b17023SJohn Marino 
988*e4b17023SJohn Marino   fprintf (file, "\n");
989*e4b17023SJohn Marino }
990*e4b17023SJohn Marino 
991*e4b17023SJohn Marino void
dump_sbitmap_file(FILE * file,const_sbitmap bmap)992*e4b17023SJohn Marino dump_sbitmap_file (FILE *file, const_sbitmap bmap)
993*e4b17023SJohn Marino {
994*e4b17023SJohn Marino   unsigned int i, pos;
995*e4b17023SJohn Marino 
996*e4b17023SJohn Marino   fprintf (file, "n_bits = %d, set = {", bmap->n_bits);
997*e4b17023SJohn Marino 
998*e4b17023SJohn Marino   for (pos = 30, i = 0; i < bmap->n_bits; i++)
999*e4b17023SJohn Marino     if (TEST_BIT (bmap, i))
1000*e4b17023SJohn Marino       {
1001*e4b17023SJohn Marino 	if (pos > 70)
1002*e4b17023SJohn Marino 	  {
1003*e4b17023SJohn Marino 	    fprintf (file, "\n  ");
1004*e4b17023SJohn Marino 	    pos = 0;
1005*e4b17023SJohn Marino 	  }
1006*e4b17023SJohn Marino 
1007*e4b17023SJohn Marino 	fprintf (file, "%d ", i);
1008*e4b17023SJohn Marino 	pos += 2 + (i >= 10) + (i >= 100) + (i >= 1000);
1009*e4b17023SJohn Marino       }
1010*e4b17023SJohn Marino 
1011*e4b17023SJohn Marino   fprintf (file, "}\n");
1012*e4b17023SJohn Marino }
1013*e4b17023SJohn Marino 
1014*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_sbitmap(const_sbitmap bmap)1015*e4b17023SJohn Marino debug_sbitmap (const_sbitmap bmap)
1016*e4b17023SJohn Marino {
1017*e4b17023SJohn Marino   dump_sbitmap_file (stderr, bmap);
1018*e4b17023SJohn Marino }
1019*e4b17023SJohn Marino 
1020*e4b17023SJohn Marino void
dump_sbitmap_vector(FILE * file,const char * title,const char * subtitle,sbitmap * bmaps,int n_maps)1021*e4b17023SJohn Marino dump_sbitmap_vector (FILE *file, const char *title, const char *subtitle,
1022*e4b17023SJohn Marino 		     sbitmap *bmaps, int n_maps)
1023*e4b17023SJohn Marino {
1024*e4b17023SJohn Marino   int bb;
1025*e4b17023SJohn Marino 
1026*e4b17023SJohn Marino   fprintf (file, "%s\n", title);
1027*e4b17023SJohn Marino   for (bb = 0; bb < n_maps; bb++)
1028*e4b17023SJohn Marino     {
1029*e4b17023SJohn Marino       fprintf (file, "%s %d\n", subtitle, bb);
1030*e4b17023SJohn Marino       dump_sbitmap (file, bmaps[bb]);
1031*e4b17023SJohn Marino     }
1032*e4b17023SJohn Marino 
1033*e4b17023SJohn Marino   fprintf (file, "\n");
1034*e4b17023SJohn Marino }
1035*e4b17023SJohn Marino 
1036*e4b17023SJohn Marino #if GCC_VERSION < 3400
1037*e4b17023SJohn Marino /* Table of number of set bits in a character, indexed by value of char.  */
1038*e4b17023SJohn Marino static const unsigned char popcount_table[] =
1039*e4b17023SJohn Marino {
1040*e4b17023SJohn Marino     0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1041*e4b17023SJohn Marino     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1042*e4b17023SJohn Marino     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1043*e4b17023SJohn Marino     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1044*e4b17023SJohn Marino     1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1045*e4b17023SJohn Marino     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1046*e4b17023SJohn Marino     2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1047*e4b17023SJohn Marino     3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
1048*e4b17023SJohn Marino };
1049*e4b17023SJohn Marino 
1050*e4b17023SJohn Marino /* Count the bits in an SBITMAP element A.  */
1051*e4b17023SJohn Marino 
1052*e4b17023SJohn Marino static unsigned long
sbitmap_elt_popcount(SBITMAP_ELT_TYPE a)1053*e4b17023SJohn Marino sbitmap_elt_popcount (SBITMAP_ELT_TYPE a)
1054*e4b17023SJohn Marino {
1055*e4b17023SJohn Marino   unsigned long ret = 0;
1056*e4b17023SJohn Marino   unsigned i;
1057*e4b17023SJohn Marino 
1058*e4b17023SJohn Marino   if (a == 0)
1059*e4b17023SJohn Marino     return 0;
1060*e4b17023SJohn Marino 
1061*e4b17023SJohn Marino   /* Just do this the table way for now  */
1062*e4b17023SJohn Marino   for (i = 0; i < SBITMAP_ELT_BITS; i += 8)
1063*e4b17023SJohn Marino     ret += popcount_table[(a >> i) & 0xff];
1064*e4b17023SJohn Marino   return ret;
1065*e4b17023SJohn Marino }
1066*e4b17023SJohn Marino #endif
1067*e4b17023SJohn Marino 
1068*e4b17023SJohn Marino /* Count the number of bits in SBITMAP a, up to bit MAXBIT.  */
1069*e4b17023SJohn Marino 
1070*e4b17023SJohn Marino unsigned long
sbitmap_popcount(const_sbitmap a,unsigned long maxbit)1071*e4b17023SJohn Marino sbitmap_popcount (const_sbitmap a, unsigned long maxbit)
1072*e4b17023SJohn Marino {
1073*e4b17023SJohn Marino   unsigned long count = 0;
1074*e4b17023SJohn Marino   unsigned ix;
1075*e4b17023SJohn Marino   unsigned int lastword;
1076*e4b17023SJohn Marino 
1077*e4b17023SJohn Marino   if (maxbit == 0)
1078*e4b17023SJohn Marino     return 0;
1079*e4b17023SJohn Marino 
1080*e4b17023SJohn Marino   if (maxbit >= a->n_bits)
1081*e4b17023SJohn Marino     maxbit = a->n_bits;
1082*e4b17023SJohn Marino 
1083*e4b17023SJohn Marino   /* Count the bits in the full word.  */
1084*e4b17023SJohn Marino   lastword = MIN (a->size, SBITMAP_SET_SIZE (maxbit + 1) - 1);
1085*e4b17023SJohn Marino   for (ix = 0; ix < lastword; ix++)
1086*e4b17023SJohn Marino     {
1087*e4b17023SJohn Marino       if (a->popcount)
1088*e4b17023SJohn Marino 	{
1089*e4b17023SJohn Marino 	  count += a->popcount[ix];
1090*e4b17023SJohn Marino #ifdef BITMAP_DEBUGGING
1091*e4b17023SJohn Marino 	  gcc_assert (a->popcount[ix] == do_popcount (a->elms[ix]));
1092*e4b17023SJohn Marino #endif
1093*e4b17023SJohn Marino 	}
1094*e4b17023SJohn Marino       else
1095*e4b17023SJohn Marino 	count += do_popcount (a->elms[ix]);
1096*e4b17023SJohn Marino     }
1097*e4b17023SJohn Marino 
1098*e4b17023SJohn Marino   /* Count the remaining bits.  */
1099*e4b17023SJohn Marino   if (lastword < a->size)
1100*e4b17023SJohn Marino     {
1101*e4b17023SJohn Marino       unsigned int bitindex;
1102*e4b17023SJohn Marino       SBITMAP_ELT_TYPE theword = a->elms[lastword];
1103*e4b17023SJohn Marino 
1104*e4b17023SJohn Marino       bitindex = maxbit % SBITMAP_ELT_BITS;
1105*e4b17023SJohn Marino       if (bitindex != 0)
1106*e4b17023SJohn Marino 	{
1107*e4b17023SJohn Marino 	  theword &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - bitindex);
1108*e4b17023SJohn Marino 	  count += do_popcount (theword);
1109*e4b17023SJohn Marino 	}
1110*e4b17023SJohn Marino     }
1111*e4b17023SJohn Marino   return count;
1112*e4b17023SJohn Marino }
1113*e4b17023SJohn Marino 
1114