* tree-ssa-reassoc.c (reassociate_bb): Clarify code slighly.
[official-gcc.git] / gcc / sbitmap.c
blobbaef4d05f0d33ada852d1f8d9cc9bcea130dd3ca
1 /* Simple bitmaps.
2 Copyright (C) 1999-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "sbitmap.h"
24 #include "selftest.h"
26 typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
27 typedef const SBITMAP_ELT_TYPE *const_sbitmap_ptr;
29 /* Return the size in bytes of a bitmap MAP. */
31 static inline unsigned int sbitmap_size_bytes (const_sbitmap map)
33 return map->size * sizeof (SBITMAP_ELT_TYPE);
37 /* Bitmap manipulation routines. */
39 /* Allocate a simple bitmap of N_ELMS bits. */
41 sbitmap
42 sbitmap_alloc (unsigned int n_elms)
44 unsigned int bytes, size, amt;
45 sbitmap bmap;
47 size = SBITMAP_SET_SIZE (n_elms);
48 bytes = size * sizeof (SBITMAP_ELT_TYPE);
49 amt = (sizeof (struct simple_bitmap_def)
50 + bytes - sizeof (SBITMAP_ELT_TYPE));
51 bmap = (sbitmap) xmalloc (amt);
52 bmap->n_bits = n_elms;
53 bmap->size = size;
54 return bmap;
57 /* Resize a simple bitmap BMAP to N_ELMS bits. If increasing the
58 size of BMAP, clear the new bits to zero if the DEF argument
59 is zero, and set them to one otherwise. */
61 sbitmap
62 sbitmap_resize (sbitmap bmap, unsigned int n_elms, int def)
64 unsigned int bytes, size, amt;
65 unsigned int last_bit;
67 size = SBITMAP_SET_SIZE (n_elms);
68 bytes = size * sizeof (SBITMAP_ELT_TYPE);
69 if (bytes > sbitmap_size_bytes (bmap))
71 amt = (sizeof (struct simple_bitmap_def)
72 + bytes - sizeof (SBITMAP_ELT_TYPE));
73 bmap = (sbitmap) xrealloc (bmap, amt);
76 if (n_elms > bmap->n_bits)
78 if (def)
80 memset (bmap->elms + bmap->size, -1,
81 bytes - sbitmap_size_bytes (bmap));
83 /* Set the new bits if the original last element. */
84 last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
85 if (last_bit)
86 bmap->elms[bmap->size - 1]
87 |= ~((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
89 /* Clear the unused bit in the new last element. */
90 last_bit = n_elms % SBITMAP_ELT_BITS;
91 if (last_bit)
92 bmap->elms[size - 1]
93 &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
95 else
96 memset (bmap->elms + bmap->size, 0, bytes - sbitmap_size_bytes (bmap));
98 else if (n_elms < bmap->n_bits)
100 /* Clear the surplus bits in the last word. */
101 last_bit = n_elms % SBITMAP_ELT_BITS;
102 if (last_bit)
103 bmap->elms[size - 1]
104 &= (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
107 bmap->n_bits = n_elms;
108 bmap->size = size;
109 return bmap;
112 /* Re-allocate a simple bitmap of N_ELMS bits. New storage is uninitialized. */
114 sbitmap
115 sbitmap_realloc (sbitmap src, unsigned int n_elms)
117 unsigned int bytes, size, amt;
118 sbitmap bmap;
120 size = SBITMAP_SET_SIZE (n_elms);
121 bytes = size * sizeof (SBITMAP_ELT_TYPE);
122 amt = (sizeof (struct simple_bitmap_def)
123 + bytes - sizeof (SBITMAP_ELT_TYPE));
125 if (sbitmap_size_bytes (src) >= bytes)
127 src->n_bits = n_elms;
128 return src;
131 bmap = (sbitmap) xrealloc (src, amt);
132 bmap->n_bits = n_elms;
133 bmap->size = size;
134 return bmap;
137 /* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
139 sbitmap *
140 sbitmap_vector_alloc (unsigned int n_vecs, unsigned int n_elms)
142 unsigned int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
143 sbitmap *bitmap_vector;
145 size = SBITMAP_SET_SIZE (n_elms);
146 bytes = size * sizeof (SBITMAP_ELT_TYPE);
147 elm_bytes = (sizeof (struct simple_bitmap_def)
148 + bytes - sizeof (SBITMAP_ELT_TYPE));
149 vector_bytes = n_vecs * sizeof (sbitmap *);
151 /* Round up `vector_bytes' to account for the alignment requirements
152 of an sbitmap. One could allocate the vector-table and set of sbitmaps
153 separately, but that requires maintaining two pointers or creating
154 a cover struct to hold both pointers (so our result is still just
155 one pointer). Neither is a bad idea, but this is simpler for now. */
157 /* Based on DEFAULT_ALIGNMENT computation in obstack.c. */
158 struct { char x; SBITMAP_ELT_TYPE y; } align;
159 int alignment = (char *) & align.y - & align.x;
160 vector_bytes = (vector_bytes + alignment - 1) & ~ (alignment - 1);
163 amt = vector_bytes + (n_vecs * elm_bytes);
164 bitmap_vector = (sbitmap *) xmalloc (amt);
166 for (i = 0, offset = vector_bytes; i < n_vecs; i++, offset += elm_bytes)
168 sbitmap b = (sbitmap) ((char *) bitmap_vector + offset);
170 bitmap_vector[i] = b;
171 b->n_bits = n_elms;
172 b->size = size;
175 return bitmap_vector;
178 /* Copy sbitmap SRC to DST. */
180 void
181 bitmap_copy (sbitmap dst, const_sbitmap src)
183 memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
186 /* Determine if a == b. */
188 bitmap_equal_p (const_sbitmap a, const_sbitmap b)
190 return !memcmp (a->elms, b->elms, sizeof (SBITMAP_ELT_TYPE) * a->size);
193 /* Return true if the bitmap is empty. */
195 bool
196 bitmap_empty_p (const_sbitmap bmap)
198 unsigned int i;
199 for (i=0; i<bmap->size; i++)
200 if (bmap->elms[i])
201 return false;
203 return true;
206 /* Clear COUNT bits from START in BMAP. */
208 void
209 bitmap_clear_range (sbitmap bmap, unsigned int start, unsigned int count)
211 if (count == 0)
212 return;
214 unsigned int start_word = start / SBITMAP_ELT_BITS;
215 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
217 /* Clearing less than a full word, starting at the beginning of a word. */
218 if (start_bitno == 0 && count < SBITMAP_ELT_BITS)
220 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
221 bmap->elms[start_word] &= ~mask;
222 return;
225 unsigned int end_word = (start + count) / SBITMAP_ELT_BITS;
226 unsigned int end_bitno = (start + count) % SBITMAP_ELT_BITS;
228 /* Clearing starts somewhere in the middle of the first word. Clear up to
229 the end of the first word or the end of the requested region, whichever
230 comes first. */
231 if (start_bitno != 0)
233 unsigned int nbits = ((start_word == end_word)
234 ? end_bitno - start_bitno
235 : SBITMAP_ELT_BITS - start_bitno);
236 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << nbits) - 1;
237 mask <<= start_bitno;
238 bmap->elms[start_word] &= ~mask;
239 start_word++;
240 count -= nbits;
243 if (count == 0)
244 return;
246 /* Now clear words at a time until we hit a partial word. */
247 unsigned int nwords = (end_word - start_word);
248 if (nwords)
250 memset (&bmap->elms[start_word], 0, nwords * sizeof (SBITMAP_ELT_TYPE));
251 count -= nwords * sizeof (SBITMAP_ELT_TYPE) * BITS_PER_UNIT;
252 start_word += nwords;
255 if (count == 0)
256 return;
258 /* Now handle residuals in the last word. */
259 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
260 bmap->elms[start_word] &= ~mask;
263 /* Set COUNT bits from START in BMAP. */
264 void
265 bitmap_set_range (sbitmap bmap, unsigned int start, unsigned int count)
267 if (count == 0)
268 return;
270 unsigned int start_word = start / SBITMAP_ELT_BITS;
271 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
273 /* Setting less than a full word, starting at the beginning of a word. */
274 if (start_bitno == 0 && count < SBITMAP_ELT_BITS)
276 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
277 bmap->elms[start_word] |= mask;
278 return;
281 unsigned int end_word = (start + count) / SBITMAP_ELT_BITS;
282 unsigned int end_bitno = (start + count) % SBITMAP_ELT_BITS;
284 /* Setting starts somewhere in the middle of the first word. Set up to
285 the end of the first word or the end of the requested region, whichever
286 comes first. */
287 if (start_bitno != 0)
289 unsigned int nbits = ((start_word == end_word)
290 ? end_bitno - start_bitno
291 : SBITMAP_ELT_BITS - start_bitno);
292 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << nbits) - 1;
293 mask <<= start_bitno;
294 bmap->elms[start_word] |= mask;
295 start_word++;
296 count -= nbits;
299 if (count == 0)
300 return;
302 /* Now set words at a time until we hit a partial word. */
303 unsigned int nwords = (end_word - start_word);
304 if (nwords)
306 memset (&bmap->elms[start_word], 0xff,
307 nwords * sizeof (SBITMAP_ELT_TYPE));
308 count -= nwords * sizeof (SBITMAP_ELT_TYPE) * BITS_PER_UNIT;
309 start_word += nwords;
312 if (count == 0)
313 return;
315 /* Now handle residuals in the last word. */
316 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
317 bmap->elms[start_word] |= mask;
320 /* Return TRUE if any bit between START and END inclusive is set within
321 the simple bitmap BMAP. Return FALSE otherwise. */
323 bool
324 bitmap_bit_in_range_p (const_sbitmap bmap, unsigned int start, unsigned int end)
326 gcc_checking_assert (start <= end);
327 unsigned int start_word = start / SBITMAP_ELT_BITS;
328 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
330 unsigned int end_word = end / SBITMAP_ELT_BITS;
331 unsigned int end_bitno = end % SBITMAP_ELT_BITS;
333 /* Check beginning of first word if different from zero. */
334 if (start_bitno != 0)
336 SBITMAP_ELT_TYPE high_mask = ~(SBITMAP_ELT_TYPE)0;
337 if (start_word == end_word && end_bitno + 1 < SBITMAP_ELT_BITS)
338 high_mask = ((SBITMAP_ELT_TYPE)1 << (end_bitno + 1)) - 1;
340 SBITMAP_ELT_TYPE low_mask = ((SBITMAP_ELT_TYPE)1 << start_bitno) - 1;
341 SBITMAP_ELT_TYPE mask = high_mask - low_mask;
342 if (bmap->elms[start_word] & mask)
343 return true;
344 start_word++;
347 if (start_word > end_word)
348 return false;
350 /* Now test words at a time until we hit a partial word. */
351 unsigned int nwords = (end_word - start_word);
352 while (nwords)
354 if (bmap->elms[start_word])
355 return true;
356 start_word++;
357 nwords--;
360 /* Now handle residuals in the last word. */
361 SBITMAP_ELT_TYPE mask = ~(SBITMAP_ELT_TYPE)0;
362 if (end_bitno + 1 < SBITMAP_ELT_BITS)
363 mask = ((SBITMAP_ELT_TYPE)1 << (end_bitno + 1)) - 1;
364 return (bmap->elms[start_word] & mask) != 0;
367 #if GCC_VERSION < 3400
368 /* Table of number of set bits in a character, indexed by value of char. */
369 static const unsigned char popcount_table[] =
371 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,
372 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,
373 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,
374 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,
375 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,
376 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,
377 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,
378 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,
381 static unsigned long
382 sbitmap_popcount (SBITMAP_ELT_TYPE a)
384 unsigned long ret = 0;
385 unsigned i;
387 /* Just do this the table way for now */
388 for (i = 0; i < HOST_BITS_PER_WIDEST_FAST_INT; i += 8)
389 ret += popcount_table[(a >> i) & 0xff];
390 return ret;
392 #endif
394 /* Count and return the number of bits set in the bitmap BMAP. */
396 unsigned int
397 bitmap_count_bits (const_sbitmap bmap)
399 unsigned int count = 0;
400 for (unsigned int i = 0; i < bmap->size; i++)
401 if (bmap->elms[i])
403 #if GCC_VERSION < 3400
404 count += sbitmap_popcount (bmap->elms[i]);
405 #else
406 # if HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONG
407 count += __builtin_popcountl (bmap->elms[i]);
408 # elif HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONGLONG
409 count += __builtin_popcountll (bmap->elms[i]);
410 # else
411 count += __builtin_popcount (bmap->elms[i]);
412 # endif
413 #endif
415 return count;
418 /* Zero all elements in a bitmap. */
420 void
421 bitmap_clear (sbitmap bmap)
423 memset (bmap->elms, 0, sbitmap_size_bytes (bmap));
426 /* Set all elements in a bitmap to ones. */
428 void
429 bitmap_ones (sbitmap bmap)
431 unsigned int last_bit;
433 memset (bmap->elms, -1, sbitmap_size_bytes (bmap));
435 last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
436 if (last_bit)
437 bmap->elms[bmap->size - 1]
438 = (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
441 /* Zero a vector of N_VECS bitmaps. */
443 void
444 bitmap_vector_clear (sbitmap *bmap, unsigned int n_vecs)
446 unsigned int i;
448 for (i = 0; i < n_vecs; i++)
449 bitmap_clear (bmap[i]);
452 /* Set a vector of N_VECS bitmaps to ones. */
454 void
455 bitmap_vector_ones (sbitmap *bmap, unsigned int n_vecs)
457 unsigned int i;
459 for (i = 0; i < n_vecs; i++)
460 bitmap_ones (bmap[i]);
463 /* Set DST to be A union (B - C).
464 DST = A | (B & ~C).
465 Returns true if any change is made. */
467 bool
468 bitmap_ior_and_compl (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
470 unsigned int i, n = dst->size;
471 sbitmap_ptr dstp = dst->elms;
472 const_sbitmap_ptr ap = a->elms;
473 const_sbitmap_ptr bp = b->elms;
474 const_sbitmap_ptr cp = c->elms;
475 SBITMAP_ELT_TYPE changed = 0;
477 for (i = 0; i < n; i++)
479 const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & ~*cp++);
480 changed |= *dstp ^ tmp;
481 *dstp++ = tmp;
484 return changed != 0;
487 /* Set bitmap DST to the bitwise negation of the bitmap SRC. */
489 void
490 bitmap_not (sbitmap dst, const_sbitmap src)
492 unsigned int i, n = dst->size;
493 sbitmap_ptr dstp = dst->elms;
494 const_sbitmap_ptr srcp = src->elms;
495 unsigned int last_bit;
497 for (i = 0; i < n; i++)
498 *dstp++ = ~*srcp++;
500 /* Zero all bits past n_bits, by ANDing dst with bitmap_ones. */
501 last_bit = src->n_bits % SBITMAP_ELT_BITS;
502 if (last_bit)
503 dst->elms[n-1] = dst->elms[n-1]
504 & ((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
507 /* Set the bits in DST to be the difference between the bits
508 in A and the bits in B. i.e. dst = a & (~b). */
510 void
511 bitmap_and_compl (sbitmap dst, const_sbitmap a, const_sbitmap b)
513 unsigned int i, dst_size = dst->size;
514 unsigned int min_size = dst->size;
515 sbitmap_ptr dstp = dst->elms;
516 const_sbitmap_ptr ap = a->elms;
517 const_sbitmap_ptr bp = b->elms;
519 /* A should be at least as large as DEST, to have a defined source. */
520 gcc_assert (a->size >= dst_size);
521 /* If minuend is smaller, we simply pretend it to be zero bits, i.e.
522 only copy the subtrahend into dest. */
523 if (b->size < min_size)
524 min_size = b->size;
525 for (i = 0; i < min_size; i++)
526 *dstp++ = *ap++ & (~*bp++);
527 /* Now fill the rest of dest from A, if B was too short.
528 This makes sense only when destination and A differ. */
529 if (dst != a && i != dst_size)
530 for (; i < dst_size; i++)
531 *dstp++ = *ap++;
534 /* Return true if there are any bits set in A are also set in B.
535 Return false otherwise. */
537 bool
538 bitmap_intersect_p (const_sbitmap a, const_sbitmap b)
540 const_sbitmap_ptr ap = a->elms;
541 const_sbitmap_ptr bp = b->elms;
542 unsigned int i, n;
544 n = MIN (a->size, b->size);
545 for (i = 0; i < n; i++)
546 if ((*ap++ & *bp++) != 0)
547 return true;
549 return false;
552 /* Set DST to be (A and B).
553 Return nonzero if any change is made. */
555 bool
556 bitmap_and (sbitmap dst, const_sbitmap a, const_sbitmap b)
558 unsigned int i, n = dst->size;
559 sbitmap_ptr dstp = dst->elms;
560 const_sbitmap_ptr ap = a->elms;
561 const_sbitmap_ptr bp = b->elms;
562 SBITMAP_ELT_TYPE changed = 0;
564 for (i = 0; i < n; i++)
566 const SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
567 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
568 *dstp++ = tmp;
569 changed |= wordchanged;
571 return changed != 0;
574 /* Set DST to be (A xor B)).
575 Return nonzero if any change is made. */
577 bool
578 bitmap_xor (sbitmap dst, const_sbitmap a, const_sbitmap b)
580 unsigned int i, n = dst->size;
581 sbitmap_ptr dstp = dst->elms;
582 const_sbitmap_ptr ap = a->elms;
583 const_sbitmap_ptr bp = b->elms;
584 SBITMAP_ELT_TYPE changed = 0;
586 for (i = 0; i < n; i++)
588 const SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
589 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
590 *dstp++ = tmp;
591 changed |= wordchanged;
593 return changed != 0;
596 /* Set DST to be (A or B)).
597 Return nonzero if any change is made. */
599 bool
600 bitmap_ior (sbitmap dst, const_sbitmap a, const_sbitmap b)
602 unsigned int i, n = dst->size;
603 sbitmap_ptr dstp = dst->elms;
604 const_sbitmap_ptr ap = a->elms;
605 const_sbitmap_ptr bp = b->elms;
606 SBITMAP_ELT_TYPE changed = 0;
608 for (i = 0; i < n; i++)
610 const SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
611 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
612 *dstp++ = tmp;
613 changed |= wordchanged;
615 return changed != 0;
618 /* Return nonzero if A is a subset of B. */
620 bool
621 bitmap_subset_p (const_sbitmap a, const_sbitmap b)
623 unsigned int i, n = a->size;
624 const_sbitmap_ptr ap, bp;
626 for (ap = a->elms, bp = b->elms, i = 0; i < n; i++, ap++, bp++)
627 if ((*ap | *bp) != *bp)
628 return false;
630 return true;
633 /* Set DST to be (A or (B and C)).
634 Return nonzero if any change is made. */
636 bool
637 bitmap_or_and (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
639 unsigned int i, n = dst->size;
640 sbitmap_ptr dstp = dst->elms;
641 const_sbitmap_ptr ap = a->elms;
642 const_sbitmap_ptr bp = b->elms;
643 const_sbitmap_ptr cp = c->elms;
644 SBITMAP_ELT_TYPE changed = 0;
646 for (i = 0; i < n; i++)
648 const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & *cp++);
649 changed |= *dstp ^ tmp;
650 *dstp++ = tmp;
653 return changed != 0;
656 /* Set DST to be (A and (B or C)).
657 Return nonzero if any change is made. */
659 bool
660 bitmap_and_or (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
662 unsigned int i, n = dst->size;
663 sbitmap_ptr dstp = dst->elms;
664 const_sbitmap_ptr ap = a->elms;
665 const_sbitmap_ptr bp = b->elms;
666 const_sbitmap_ptr cp = c->elms;
667 SBITMAP_ELT_TYPE changed = 0;
669 for (i = 0; i < n; i++)
671 const SBITMAP_ELT_TYPE tmp = *ap++ & (*bp++ | *cp++);
672 changed |= *dstp ^ tmp;
673 *dstp++ = tmp;
676 return changed != 0;
679 /* Return number of first bit set in the bitmap, -1 if none. */
682 bitmap_first_set_bit (const_sbitmap bmap)
684 unsigned int n = 0;
685 sbitmap_iterator sbi;
687 EXECUTE_IF_SET_IN_BITMAP (bmap, 0, n, sbi)
688 return n;
689 return -1;
692 /* Return number of last bit set in the bitmap, -1 if none. */
695 bitmap_last_set_bit (const_sbitmap bmap)
697 int i;
698 const SBITMAP_ELT_TYPE *const ptr = bmap->elms;
700 for (i = bmap->size - 1; i >= 0; i--)
702 const SBITMAP_ELT_TYPE word = ptr[i];
704 if (word != 0)
706 unsigned int index = (i + 1) * SBITMAP_ELT_BITS - 1;
707 SBITMAP_ELT_TYPE mask
708 = (SBITMAP_ELT_TYPE) 1 << (SBITMAP_ELT_BITS - 1);
710 while (1)
712 if ((word & mask) != 0)
713 return index;
715 mask >>= 1;
716 index--;
721 return -1;
724 void
725 dump_bitmap (FILE *file, const_sbitmap bmap)
727 unsigned int i, n, j;
728 unsigned int set_size = bmap->size;
729 unsigned int total_bits = bmap->n_bits;
731 fprintf (file, " ");
732 for (i = n = 0; i < set_size && n < total_bits; i++)
733 for (j = 0; j < SBITMAP_ELT_BITS && n < total_bits; j++, n++)
735 if (n != 0 && n % 10 == 0)
736 fprintf (file, " ");
738 fprintf (file, "%d",
739 (bmap->elms[i] & ((SBITMAP_ELT_TYPE) 1 << j)) != 0);
742 fprintf (file, "\n");
745 DEBUG_FUNCTION void
746 debug_raw (simple_bitmap_def &ref)
748 dump_bitmap (stderr, &ref);
751 DEBUG_FUNCTION void
752 debug_raw (simple_bitmap_def *ptr)
754 if (ptr)
755 debug_raw (*ptr);
756 else
757 fprintf (stderr, "<nil>\n");
760 void
761 dump_bitmap_file (FILE *file, const_sbitmap bmap)
763 unsigned int i, pos;
765 fprintf (file, "n_bits = %d, set = {", bmap->n_bits);
767 for (pos = 30, i = 0; i < bmap->n_bits; i++)
768 if (bitmap_bit_p (bmap, i))
770 if (pos > 70)
772 fprintf (file, "\n ");
773 pos = 0;
776 fprintf (file, "%d ", i);
777 pos += 2 + (i >= 10) + (i >= 100) + (i >= 1000);
780 fprintf (file, "}\n");
783 DEBUG_FUNCTION void
784 debug_bitmap (const_sbitmap bmap)
786 dump_bitmap_file (stderr, bmap);
789 DEBUG_FUNCTION void
790 debug (simple_bitmap_def &ref)
792 dump_bitmap_file (stderr, &ref);
795 DEBUG_FUNCTION void
796 debug (simple_bitmap_def *ptr)
798 if (ptr)
799 debug (*ptr);
800 else
801 fprintf (stderr, "<nil>\n");
804 void
805 dump_bitmap_vector (FILE *file, const char *title, const char *subtitle,
806 sbitmap *bmaps, int n_maps)
808 int i;
810 fprintf (file, "%s\n", title);
811 for (i = 0; i < n_maps; i++)
813 fprintf (file, "%s %d\n", subtitle, i);
814 dump_bitmap (file, bmaps[i]);
817 fprintf (file, "\n");
820 #if CHECKING_P
822 namespace selftest {
824 /* Selftests for sbitmaps. */
827 /* Verify range functions for sbitmap. */
829 static void
830 test_range_functions ()
832 sbitmap s = sbitmap_alloc (1024);
833 bitmap_clear (s);
835 ASSERT_FALSE (bitmap_bit_in_range_p (s, 512, 1023));
836 bitmap_set_bit (s, 100);
838 ASSERT_FALSE (bitmap_bit_in_range_p (s, 512, 1023));
839 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 99));
840 ASSERT_FALSE (bitmap_bit_in_range_p (s, 101, 1023));
841 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 100));
842 ASSERT_TRUE (bitmap_bit_in_range_p (s, 64, 100));
843 ASSERT_TRUE (bitmap_bit_in_range_p (s, 100, 100));
844 ASSERT_TRUE (bitmap_bit_p (s, 100));
846 s = sbitmap_alloc (64);
847 bitmap_clear (s);
848 bitmap_set_bit (s, 63);
849 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 63));
850 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 63));
851 ASSERT_TRUE (bitmap_bit_in_range_p (s, 63, 63));
852 ASSERT_TRUE (bitmap_bit_p (s, 63));
854 s = sbitmap_alloc (1024);
855 bitmap_clear (s);
856 bitmap_set_bit (s, 128);
857 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 127));
858 ASSERT_FALSE (bitmap_bit_in_range_p (s, 129, 1023));
860 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 128));
861 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 128));
862 ASSERT_TRUE (bitmap_bit_in_range_p (s, 128, 255));
863 ASSERT_TRUE (bitmap_bit_in_range_p (s, 128, 254));
864 ASSERT_TRUE (bitmap_bit_p (s, 128));
866 bitmap_clear (s);
867 bitmap_set_bit (s, 8);
868 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 8));
869 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 12));
870 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 63));
871 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 127));
872 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 512));
873 ASSERT_TRUE (bitmap_bit_in_range_p (s, 8, 8));
874 ASSERT_TRUE (bitmap_bit_p (s, 8));
876 bitmap_clear (s);
877 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 0));
878 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 8));
879 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 63));
880 ASSERT_FALSE (bitmap_bit_in_range_p (s, 1, 63));
881 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 256));
883 bitmap_set_bit (s, 0);
884 bitmap_set_bit (s, 16);
885 bitmap_set_bit (s, 32);
886 bitmap_set_bit (s, 48);
887 bitmap_set_bit (s, 64);
888 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 0));
889 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 16));
890 ASSERT_TRUE (bitmap_bit_in_range_p (s, 48, 63));
891 ASSERT_TRUE (bitmap_bit_in_range_p (s, 64, 64));
892 ASSERT_FALSE (bitmap_bit_in_range_p (s, 1, 15));
893 ASSERT_FALSE (bitmap_bit_in_range_p (s, 17, 31));
894 ASSERT_FALSE (bitmap_bit_in_range_p (s, 49, 63));
895 ASSERT_FALSE (bitmap_bit_in_range_p (s, 65, 1023));
898 /* Run all of the selftests within this file. */
900 void
901 sbitmap_c_tests ()
903 test_range_functions ();
906 } // namespace selftest
907 #endif /* CHECKING_P */