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