]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/sbitmap.c
PR translation/79183
[thirdparty/gcc.git] / gcc / sbitmap.c
1 /* Simple bitmaps.
2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
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.
10
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.
15
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/>. */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "sbitmap.h"
24 #include "selftest.h"
25
26 typedef SBITMAP_ELT_TYPE *sbitmap_ptr;
27 typedef const SBITMAP_ELT_TYPE *const_sbitmap_ptr;
28
29 /* Return the size in bytes of a bitmap MAP. */
30
31 static inline unsigned int sbitmap_size_bytes (const_sbitmap map)
32 {
33 return map->size * sizeof (SBITMAP_ELT_TYPE);
34 }
35
36
37 /* Bitmap manipulation routines. */
38
39 /* Allocate a simple bitmap of N_ELMS bits. */
40
41 sbitmap
42 sbitmap_alloc (unsigned int n_elms)
43 {
44 unsigned int bytes, size, amt;
45 sbitmap bmap;
46
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;
55 }
56
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. */
60
61 sbitmap
62 sbitmap_resize (sbitmap bmap, unsigned int n_elms, int def)
63 {
64 unsigned int bytes, size, amt;
65 unsigned int last_bit;
66
67 size = SBITMAP_SET_SIZE (n_elms);
68 bytes = size * sizeof (SBITMAP_ELT_TYPE);
69 if (bytes > sbitmap_size_bytes (bmap))
70 {
71 amt = (sizeof (struct simple_bitmap_def)
72 + bytes - sizeof (SBITMAP_ELT_TYPE));
73 bmap = (sbitmap) xrealloc (bmap, amt);
74 }
75
76 if (n_elms > bmap->n_bits)
77 {
78 if (def)
79 {
80 memset (bmap->elms + bmap->size, -1,
81 bytes - sbitmap_size_bytes (bmap));
82
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));
88
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);
94 }
95 else
96 memset (bmap->elms + bmap->size, 0, bytes - sbitmap_size_bytes (bmap));
97 }
98 else if (n_elms < bmap->n_bits)
99 {
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);
105 }
106
107 bmap->n_bits = n_elms;
108 bmap->size = size;
109 return bmap;
110 }
111
112 /* Re-allocate a simple bitmap of N_ELMS bits. New storage is uninitialized. */
113
114 sbitmap
115 sbitmap_realloc (sbitmap src, unsigned int n_elms)
116 {
117 unsigned int bytes, size, amt;
118 sbitmap bmap;
119
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));
124
125 if (sbitmap_size_bytes (src) >= bytes)
126 {
127 src->n_bits = n_elms;
128 return src;
129 }
130
131 bmap = (sbitmap) xrealloc (src, amt);
132 bmap->n_bits = n_elms;
133 bmap->size = size;
134 return bmap;
135 }
136
137 /* Allocate a vector of N_VECS bitmaps of N_ELMS bits. */
138
139 sbitmap *
140 sbitmap_vector_alloc (unsigned int n_vecs, unsigned int n_elms)
141 {
142 unsigned int i, bytes, offset, elm_bytes, size, amt, vector_bytes;
143 sbitmap *bitmap_vector;
144
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 *);
150
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. */
156 {
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);
161 }
162
163 amt = vector_bytes + (n_vecs * elm_bytes);
164 bitmap_vector = (sbitmap *) xmalloc (amt);
165
166 for (i = 0, offset = vector_bytes; i < n_vecs; i++, offset += elm_bytes)
167 {
168 sbitmap b = (sbitmap) ((char *) bitmap_vector + offset);
169
170 bitmap_vector[i] = b;
171 b->n_bits = n_elms;
172 b->size = size;
173 }
174
175 return bitmap_vector;
176 }
177
178 /* Copy sbitmap SRC to DST. */
179
180 void
181 bitmap_copy (sbitmap dst, const_sbitmap src)
182 {
183 gcc_checking_assert (src->size <= dst->size);
184
185 memcpy (dst->elms, src->elms, sizeof (SBITMAP_ELT_TYPE) * dst->size);
186 }
187
188 /* Determine if a == b. */
189 int
190 bitmap_equal_p (const_sbitmap a, const_sbitmap b)
191 {
192 bitmap_check_sizes (a, b);
193
194 return !memcmp (a->elms, b->elms, sizeof (SBITMAP_ELT_TYPE) * a->size);
195 }
196
197 /* Return true if the bitmap is empty. */
198
199 bool
200 bitmap_empty_p (const_sbitmap bmap)
201 {
202 unsigned int i;
203 for (i=0; i<bmap->size; i++)
204 if (bmap->elms[i])
205 return false;
206
207 return true;
208 }
209
210 /* Clear COUNT bits from START in BMAP. */
211
212 void
213 bitmap_clear_range (sbitmap bmap, unsigned int start, unsigned int count)
214 {
215 if (count == 0)
216 return;
217
218 bitmap_check_index (bmap, start + count - 1);
219
220 unsigned int start_word = start / SBITMAP_ELT_BITS;
221 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
222
223 /* Clearing less than a full word, starting at the beginning of a word. */
224 if (start_bitno == 0 && count < SBITMAP_ELT_BITS)
225 {
226 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
227 bmap->elms[start_word] &= ~mask;
228 return;
229 }
230
231 unsigned int end_word = (start + count) / SBITMAP_ELT_BITS;
232 unsigned int end_bitno = (start + count) % SBITMAP_ELT_BITS;
233
234 /* Clearing starts somewhere in the middle of the first word. Clear up to
235 the end of the first word or the end of the requested region, whichever
236 comes first. */
237 if (start_bitno != 0)
238 {
239 unsigned int nbits = ((start_word == end_word)
240 ? end_bitno - start_bitno
241 : SBITMAP_ELT_BITS - start_bitno);
242 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << nbits) - 1;
243 mask <<= start_bitno;
244 bmap->elms[start_word] &= ~mask;
245 start_word++;
246 count -= nbits;
247 }
248
249 if (count == 0)
250 return;
251
252 /* Now clear words at a time until we hit a partial word. */
253 unsigned int nwords = (end_word - start_word);
254 if (nwords)
255 {
256 memset (&bmap->elms[start_word], 0, nwords * sizeof (SBITMAP_ELT_TYPE));
257 count -= nwords * sizeof (SBITMAP_ELT_TYPE) * BITS_PER_UNIT;
258 start_word += nwords;
259 }
260
261 if (count == 0)
262 return;
263
264 /* Now handle residuals in the last word. */
265 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
266 bmap->elms[start_word] &= ~mask;
267 }
268
269 /* Set COUNT bits from START in BMAP. */
270 void
271 bitmap_set_range (sbitmap bmap, unsigned int start, unsigned int count)
272 {
273 if (count == 0)
274 return;
275
276 bitmap_check_index (bmap, start + count - 1);
277
278 unsigned int start_word = start / SBITMAP_ELT_BITS;
279 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
280
281 /* Setting less than a full word, starting at the beginning of a word. */
282 if (start_bitno == 0 && count < SBITMAP_ELT_BITS)
283 {
284 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
285 bmap->elms[start_word] |= mask;
286 return;
287 }
288
289 unsigned int end_word = (start + count) / SBITMAP_ELT_BITS;
290 unsigned int end_bitno = (start + count) % SBITMAP_ELT_BITS;
291
292 /* Setting starts somewhere in the middle of the first word. Set up to
293 the end of the first word or the end of the requested region, whichever
294 comes first. */
295 if (start_bitno != 0)
296 {
297 unsigned int nbits = ((start_word == end_word)
298 ? end_bitno - start_bitno
299 : SBITMAP_ELT_BITS - start_bitno);
300 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << nbits) - 1;
301 mask <<= start_bitno;
302 bmap->elms[start_word] |= mask;
303 start_word++;
304 count -= nbits;
305 }
306
307 if (count == 0)
308 return;
309
310 /* Now set words at a time until we hit a partial word. */
311 unsigned int nwords = (end_word - start_word);
312 if (nwords)
313 {
314 memset (&bmap->elms[start_word], 0xff,
315 nwords * sizeof (SBITMAP_ELT_TYPE));
316 count -= nwords * sizeof (SBITMAP_ELT_TYPE) * BITS_PER_UNIT;
317 start_word += nwords;
318 }
319
320 if (count == 0)
321 return;
322
323 /* Now handle residuals in the last word. */
324 SBITMAP_ELT_TYPE mask = ((SBITMAP_ELT_TYPE)1 << count) - 1;
325 bmap->elms[start_word] |= mask;
326 }
327
328 /* Return TRUE if any bit between START and END inclusive is set within
329 the simple bitmap BMAP. Return FALSE otherwise. */
330
331 bool
332 bitmap_bit_in_range_p (const_sbitmap bmap, unsigned int start, unsigned int end)
333 {
334 gcc_checking_assert (start <= end);
335 bitmap_check_index (bmap, end);
336
337 unsigned int start_word = start / SBITMAP_ELT_BITS;
338 unsigned int start_bitno = start % SBITMAP_ELT_BITS;
339
340 unsigned int end_word = end / SBITMAP_ELT_BITS;
341 unsigned int end_bitno = end % SBITMAP_ELT_BITS;
342
343 /* Check beginning of first word if different from zero. */
344 if (start_bitno != 0)
345 {
346 SBITMAP_ELT_TYPE high_mask = ~(SBITMAP_ELT_TYPE)0;
347 if (start_word == end_word && end_bitno + 1 < SBITMAP_ELT_BITS)
348 high_mask = ((SBITMAP_ELT_TYPE)1 << (end_bitno + 1)) - 1;
349
350 SBITMAP_ELT_TYPE low_mask = ((SBITMAP_ELT_TYPE)1 << start_bitno) - 1;
351 SBITMAP_ELT_TYPE mask = high_mask - low_mask;
352 if (bmap->elms[start_word] & mask)
353 return true;
354 start_word++;
355 }
356
357 if (start_word > end_word)
358 return false;
359
360 /* Now test words at a time until we hit a partial word. */
361 unsigned int nwords = (end_word - start_word);
362 while (nwords)
363 {
364 if (bmap->elms[start_word])
365 return true;
366 start_word++;
367 nwords--;
368 }
369
370 /* Now handle residuals in the last word. */
371 SBITMAP_ELT_TYPE mask = ~(SBITMAP_ELT_TYPE)0;
372 if (end_bitno + 1 < SBITMAP_ELT_BITS)
373 mask = ((SBITMAP_ELT_TYPE)1 << (end_bitno + 1)) - 1;
374 return (bmap->elms[start_word] & mask) != 0;
375 }
376
377 #if GCC_VERSION < 3400
378 /* Table of number of set bits in a character, indexed by value of char. */
379 static const unsigned char popcount_table[] =
380 {
381 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,
382 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,
383 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,
384 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,
385 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,
386 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,
387 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,
388 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,
389 };
390
391 static unsigned long
392 sbitmap_popcount (SBITMAP_ELT_TYPE a)
393 {
394 unsigned long ret = 0;
395 unsigned i;
396
397 /* Just do this the table way for now */
398 for (i = 0; i < HOST_BITS_PER_WIDEST_FAST_INT; i += 8)
399 ret += popcount_table[(a >> i) & 0xff];
400 return ret;
401 }
402 #endif
403
404 /* Count and return the number of bits set in the bitmap BMAP. */
405
406 unsigned int
407 bitmap_count_bits (const_sbitmap bmap)
408 {
409 unsigned int count = 0;
410 for (unsigned int i = 0; i < bmap->size; i++)
411 if (bmap->elms[i])
412 {
413 #if GCC_VERSION < 3400
414 count += sbitmap_popcount (bmap->elms[i]);
415 #else
416 # if HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONG
417 count += __builtin_popcountl (bmap->elms[i]);
418 # elif HOST_BITS_PER_WIDEST_FAST_INT == HOST_BITS_PER_LONGLONG
419 count += __builtin_popcountll (bmap->elms[i]);
420 # else
421 count += __builtin_popcount (bmap->elms[i]);
422 # endif
423 #endif
424 }
425 return count;
426 }
427
428 /* Zero all elements in a bitmap. */
429
430 void
431 bitmap_clear (sbitmap bmap)
432 {
433 memset (bmap->elms, 0, sbitmap_size_bytes (bmap));
434 }
435
436 /* Set all elements in a bitmap to ones. */
437
438 void
439 bitmap_ones (sbitmap bmap)
440 {
441 unsigned int last_bit;
442
443 memset (bmap->elms, -1, sbitmap_size_bytes (bmap));
444
445 last_bit = bmap->n_bits % SBITMAP_ELT_BITS;
446 if (last_bit)
447 bmap->elms[bmap->size - 1]
448 = (SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit);
449 }
450
451 /* Zero a vector of N_VECS bitmaps. */
452
453 void
454 bitmap_vector_clear (sbitmap *bmap, unsigned int n_vecs)
455 {
456 unsigned int i;
457
458 for (i = 0; i < n_vecs; i++)
459 bitmap_clear (bmap[i]);
460 }
461
462 /* Set a vector of N_VECS bitmaps to ones. */
463
464 void
465 bitmap_vector_ones (sbitmap *bmap, unsigned int n_vecs)
466 {
467 unsigned int i;
468
469 for (i = 0; i < n_vecs; i++)
470 bitmap_ones (bmap[i]);
471 }
472
473 /* Set DST to be A union (B - C).
474 DST = A | (B & ~C).
475 Returns true if any change is made. */
476
477 bool
478 bitmap_ior_and_compl (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
479 {
480 bitmap_check_sizes (a, b);
481 bitmap_check_sizes (b, c);
482
483 unsigned int i, n = dst->size;
484 sbitmap_ptr dstp = dst->elms;
485 const_sbitmap_ptr ap = a->elms;
486 const_sbitmap_ptr bp = b->elms;
487 const_sbitmap_ptr cp = c->elms;
488 SBITMAP_ELT_TYPE changed = 0;
489
490 for (i = 0; i < n; i++)
491 {
492 const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & ~*cp++);
493 changed |= *dstp ^ tmp;
494 *dstp++ = tmp;
495 }
496
497 return changed != 0;
498 }
499
500 /* Set bitmap DST to the bitwise negation of the bitmap SRC. */
501
502 void
503 bitmap_not (sbitmap dst, const_sbitmap src)
504 {
505 bitmap_check_sizes (src, dst);
506
507 unsigned int i, n = dst->size;
508 sbitmap_ptr dstp = dst->elms;
509 const_sbitmap_ptr srcp = src->elms;
510 unsigned int last_bit;
511
512 for (i = 0; i < n; i++)
513 *dstp++ = ~*srcp++;
514
515 /* Zero all bits past n_bits, by ANDing dst with bitmap_ones. */
516 last_bit = src->n_bits % SBITMAP_ELT_BITS;
517 if (last_bit)
518 dst->elms[n-1] = dst->elms[n-1]
519 & ((SBITMAP_ELT_TYPE)-1 >> (SBITMAP_ELT_BITS - last_bit));
520 }
521
522 /* Set the bits in DST to be the difference between the bits
523 in A and the bits in B. i.e. dst = a & (~b). */
524
525 void
526 bitmap_and_compl (sbitmap dst, const_sbitmap a, const_sbitmap b)
527 {
528 bitmap_check_sizes (a, b);
529 bitmap_check_sizes (b, dst);
530
531 unsigned int i, dst_size = dst->size;
532 unsigned int min_size = dst->size;
533 sbitmap_ptr dstp = dst->elms;
534 const_sbitmap_ptr ap = a->elms;
535 const_sbitmap_ptr bp = b->elms;
536
537 /* A should be at least as large as DEST, to have a defined source. */
538 gcc_assert (a->size >= dst_size);
539 /* If minuend is smaller, we simply pretend it to be zero bits, i.e.
540 only copy the subtrahend into dest. */
541 if (b->size < min_size)
542 min_size = b->size;
543 for (i = 0; i < min_size; i++)
544 *dstp++ = *ap++ & (~*bp++);
545 /* Now fill the rest of dest from A, if B was too short.
546 This makes sense only when destination and A differ. */
547 if (dst != a && i != dst_size)
548 for (; i < dst_size; i++)
549 *dstp++ = *ap++;
550 }
551
552 /* Return true if there are any bits set in A are also set in B.
553 Return false otherwise. */
554
555 bool
556 bitmap_intersect_p (const_sbitmap a, const_sbitmap b)
557 {
558 bitmap_check_sizes (a, b);
559
560 const_sbitmap_ptr ap = a->elms;
561 const_sbitmap_ptr bp = b->elms;
562 unsigned int i, n;
563
564 n = MIN (a->size, b->size);
565 for (i = 0; i < n; i++)
566 if ((*ap++ & *bp++) != 0)
567 return true;
568
569 return false;
570 }
571
572 /* Set DST to be (A and B).
573 Return nonzero if any change is made. */
574
575 bool
576 bitmap_and (sbitmap dst, const_sbitmap a, const_sbitmap b)
577 {
578 bitmap_check_sizes (a, b);
579 bitmap_check_sizes (b, dst);
580
581 unsigned int i, n = dst->size;
582 sbitmap_ptr dstp = dst->elms;
583 const_sbitmap_ptr ap = a->elms;
584 const_sbitmap_ptr bp = b->elms;
585 SBITMAP_ELT_TYPE changed = 0;
586
587 for (i = 0; i < n; i++)
588 {
589 const SBITMAP_ELT_TYPE tmp = *ap++ & *bp++;
590 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
591 *dstp++ = tmp;
592 changed |= wordchanged;
593 }
594 return changed != 0;
595 }
596
597 /* Set DST to be (A xor B)).
598 Return nonzero if any change is made. */
599
600 bool
601 bitmap_xor (sbitmap dst, const_sbitmap a, const_sbitmap b)
602 {
603 bitmap_check_sizes (a, b);
604 bitmap_check_sizes (b, dst);
605
606 unsigned int i, n = dst->size;
607 sbitmap_ptr dstp = dst->elms;
608 const_sbitmap_ptr ap = a->elms;
609 const_sbitmap_ptr bp = b->elms;
610 SBITMAP_ELT_TYPE changed = 0;
611
612 for (i = 0; i < n; i++)
613 {
614 const SBITMAP_ELT_TYPE tmp = *ap++ ^ *bp++;
615 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
616 *dstp++ = tmp;
617 changed |= wordchanged;
618 }
619 return changed != 0;
620 }
621
622 /* Set DST to be (A or B)).
623 Return nonzero if any change is made. */
624
625 bool
626 bitmap_ior (sbitmap dst, const_sbitmap a, const_sbitmap b)
627 {
628 bitmap_check_sizes (a, b);
629 bitmap_check_sizes (b, dst);
630
631 unsigned int i, n = dst->size;
632 sbitmap_ptr dstp = dst->elms;
633 const_sbitmap_ptr ap = a->elms;
634 const_sbitmap_ptr bp = b->elms;
635 SBITMAP_ELT_TYPE changed = 0;
636
637 for (i = 0; i < n; i++)
638 {
639 const SBITMAP_ELT_TYPE tmp = *ap++ | *bp++;
640 SBITMAP_ELT_TYPE wordchanged = *dstp ^ tmp;
641 *dstp++ = tmp;
642 changed |= wordchanged;
643 }
644 return changed != 0;
645 }
646
647 /* Return nonzero if A is a subset of B. */
648
649 bool
650 bitmap_subset_p (const_sbitmap a, const_sbitmap b)
651 {
652 bitmap_check_sizes (a, b);
653
654 unsigned int i, n = a->size;
655 const_sbitmap_ptr ap, bp;
656
657 for (ap = a->elms, bp = b->elms, i = 0; i < n; i++, ap++, bp++)
658 if ((*ap | *bp) != *bp)
659 return false;
660
661 return true;
662 }
663
664 /* Set DST to be (A or (B and C)).
665 Return nonzero if any change is made. */
666
667 bool
668 bitmap_or_and (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
669 {
670 bitmap_check_sizes (a, b);
671 bitmap_check_sizes (b, c);
672 bitmap_check_sizes (c, dst);
673
674 unsigned int i, n = dst->size;
675 sbitmap_ptr dstp = dst->elms;
676 const_sbitmap_ptr ap = a->elms;
677 const_sbitmap_ptr bp = b->elms;
678 const_sbitmap_ptr cp = c->elms;
679 SBITMAP_ELT_TYPE changed = 0;
680
681 for (i = 0; i < n; i++)
682 {
683 const SBITMAP_ELT_TYPE tmp = *ap++ | (*bp++ & *cp++);
684 changed |= *dstp ^ tmp;
685 *dstp++ = tmp;
686 }
687
688 return changed != 0;
689 }
690
691 /* Set DST to be (A and (B or C)).
692 Return nonzero if any change is made. */
693
694 bool
695 bitmap_and_or (sbitmap dst, const_sbitmap a, const_sbitmap b, const_sbitmap c)
696 {
697 bitmap_check_sizes (a, b);
698 bitmap_check_sizes (b, c);
699 bitmap_check_sizes (c, dst);
700
701 unsigned int i, n = dst->size;
702 sbitmap_ptr dstp = dst->elms;
703 const_sbitmap_ptr ap = a->elms;
704 const_sbitmap_ptr bp = b->elms;
705 const_sbitmap_ptr cp = c->elms;
706 SBITMAP_ELT_TYPE changed = 0;
707
708 for (i = 0; i < n; i++)
709 {
710 const SBITMAP_ELT_TYPE tmp = *ap++ & (*bp++ | *cp++);
711 changed |= *dstp ^ tmp;
712 *dstp++ = tmp;
713 }
714
715 return changed != 0;
716 }
717
718 /* Return number of first bit set in the bitmap, -1 if none. */
719
720 int
721 bitmap_first_set_bit (const_sbitmap bmap)
722 {
723 unsigned int n = 0;
724 sbitmap_iterator sbi;
725
726 EXECUTE_IF_SET_IN_BITMAP (bmap, 0, n, sbi)
727 return n;
728 return -1;
729 }
730
731 /* Return number of last bit set in the bitmap, -1 if none. */
732
733 int
734 bitmap_last_set_bit (const_sbitmap bmap)
735 {
736 int i;
737 const SBITMAP_ELT_TYPE *const ptr = bmap->elms;
738
739 for (i = bmap->size - 1; i >= 0; i--)
740 {
741 const SBITMAP_ELT_TYPE word = ptr[i];
742
743 if (word != 0)
744 {
745 unsigned int index = (i + 1) * SBITMAP_ELT_BITS - 1;
746 SBITMAP_ELT_TYPE mask
747 = (SBITMAP_ELT_TYPE) 1 << (SBITMAP_ELT_BITS - 1);
748
749 while (1)
750 {
751 if ((word & mask) != 0)
752 return index;
753
754 mask >>= 1;
755 index--;
756 }
757 }
758 }
759
760 return -1;
761 }
762
763 void
764 dump_bitmap (FILE *file, const_sbitmap bmap)
765 {
766 unsigned int i, n, j;
767 unsigned int set_size = bmap->size;
768 unsigned int total_bits = bmap->n_bits;
769
770 fprintf (file, " ");
771 for (i = n = 0; i < set_size && n < total_bits; i++)
772 for (j = 0; j < SBITMAP_ELT_BITS && n < total_bits; j++, n++)
773 {
774 if (n != 0 && n % 10 == 0)
775 fprintf (file, " ");
776
777 fprintf (file, "%d",
778 (bmap->elms[i] & ((SBITMAP_ELT_TYPE) 1 << j)) != 0);
779 }
780
781 fprintf (file, "\n");
782 }
783
784 DEBUG_FUNCTION void
785 debug_raw (simple_bitmap_def &ref)
786 {
787 dump_bitmap (stderr, &ref);
788 }
789
790 DEBUG_FUNCTION void
791 debug_raw (simple_bitmap_def *ptr)
792 {
793 if (ptr)
794 debug_raw (*ptr);
795 else
796 fprintf (stderr, "<nil>\n");
797 }
798
799 void
800 dump_bitmap_file (FILE *file, const_sbitmap bmap)
801 {
802 unsigned int i, pos;
803
804 fprintf (file, "n_bits = %d, set = {", bmap->n_bits);
805
806 for (pos = 30, i = 0; i < bmap->n_bits; i++)
807 if (bitmap_bit_p (bmap, i))
808 {
809 if (pos > 70)
810 {
811 fprintf (file, "\n ");
812 pos = 0;
813 }
814
815 fprintf (file, "%d ", i);
816 pos += 2 + (i >= 10) + (i >= 100) + (i >= 1000);
817 }
818
819 fprintf (file, "}\n");
820 }
821
822 DEBUG_FUNCTION void
823 debug_bitmap (const_sbitmap bmap)
824 {
825 dump_bitmap_file (stderr, bmap);
826 }
827
828 DEBUG_FUNCTION void
829 debug (simple_bitmap_def &ref)
830 {
831 dump_bitmap_file (stderr, &ref);
832 }
833
834 DEBUG_FUNCTION void
835 debug (simple_bitmap_def *ptr)
836 {
837 if (ptr)
838 debug (*ptr);
839 else
840 fprintf (stderr, "<nil>\n");
841 }
842
843 void
844 dump_bitmap_vector (FILE *file, const char *title, const char *subtitle,
845 sbitmap *bmaps, int n_maps)
846 {
847 int i;
848
849 fprintf (file, "%s\n", title);
850 for (i = 0; i < n_maps; i++)
851 {
852 fprintf (file, "%s %d\n", subtitle, i);
853 dump_bitmap (file, bmaps[i]);
854 }
855
856 fprintf (file, "\n");
857 }
858
859 #if CHECKING_P
860
861 namespace selftest {
862
863 /* Selftests for sbitmaps. */
864
865 /* Checking function that uses both bitmap_bit_in_range_p and
866 loop of bitmap_bit_p and verifies consistent results. */
867
868 static bool
869 bitmap_bit_in_range_p_checking (sbitmap s, unsigned int start,
870 unsigned end)
871 {
872 bool r1 = bitmap_bit_in_range_p (s, start, end);
873 bool r2 = false;
874
875 for (unsigned int i = start; i <= end; i++)
876 if (bitmap_bit_p (s, i))
877 {
878 r2 = true;
879 break;
880 }
881
882 ASSERT_EQ (r1, r2);
883 return r1;
884 }
885
886 /* Verify bitmap_set_range functions for sbitmap. */
887
888 static void
889 test_set_range ()
890 {
891 sbitmap s = sbitmap_alloc (16);
892 bitmap_clear (s);
893
894 bitmap_set_range (s, 0, 1);
895 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 0, 0));
896 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 1, 15));
897 bitmap_set_range (s, 15, 1);
898 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 1, 14));
899 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 15, 15));
900 sbitmap_free (s);
901
902 s = sbitmap_alloc (1024);
903 bitmap_clear (s);
904 bitmap_set_range (s, 512, 1);
905 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 0, 511));
906 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 513, 1023));
907 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 512, 512));
908 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 508, 512));
909 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 508, 513));
910 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 508, 511));
911
912 bitmap_clear (s);
913 bitmap_set_range (s, 512, 64);
914 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 0, 511));
915 ASSERT_FALSE (bitmap_bit_in_range_p_checking (s, 512 + 64, 1023));
916 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 512, 512));
917 ASSERT_TRUE (bitmap_bit_in_range_p_checking (s, 512 + 63, 512 + 63));
918 sbitmap_free (s);
919 }
920
921 /* Verify bitmap_bit_in_range_p functions for sbitmap. */
922
923 static void
924 test_bit_in_range ()
925 {
926 sbitmap s = sbitmap_alloc (1024);
927 bitmap_clear (s);
928
929 ASSERT_FALSE (bitmap_bit_in_range_p (s, 512, 1023));
930 bitmap_set_bit (s, 100);
931
932 ASSERT_FALSE (bitmap_bit_in_range_p (s, 512, 1023));
933 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 99));
934 ASSERT_FALSE (bitmap_bit_in_range_p (s, 101, 1023));
935 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 100));
936 ASSERT_TRUE (bitmap_bit_in_range_p (s, 64, 100));
937 ASSERT_TRUE (bitmap_bit_in_range_p (s, 100, 100));
938 ASSERT_TRUE (bitmap_bit_p (s, 100));
939
940 sbitmap_free (s);
941
942 s = sbitmap_alloc (64);
943 bitmap_clear (s);
944 bitmap_set_bit (s, 63);
945 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 63));
946 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 63));
947 ASSERT_TRUE (bitmap_bit_in_range_p (s, 63, 63));
948 ASSERT_TRUE (bitmap_bit_p (s, 63));
949 sbitmap_free (s);
950
951 s = sbitmap_alloc (1024);
952 bitmap_clear (s);
953 bitmap_set_bit (s, 128);
954 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 127));
955 ASSERT_FALSE (bitmap_bit_in_range_p (s, 129, 1023));
956
957 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 128));
958 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 128));
959 ASSERT_TRUE (bitmap_bit_in_range_p (s, 128, 255));
960 ASSERT_TRUE (bitmap_bit_in_range_p (s, 128, 254));
961 ASSERT_TRUE (bitmap_bit_p (s, 128));
962
963 bitmap_clear (s);
964 bitmap_set_bit (s, 8);
965 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 8));
966 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 12));
967 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 63));
968 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 127));
969 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 512));
970 ASSERT_TRUE (bitmap_bit_in_range_p (s, 8, 8));
971 ASSERT_TRUE (bitmap_bit_p (s, 8));
972
973 bitmap_clear (s);
974 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 0));
975 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 8));
976 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 63));
977 ASSERT_FALSE (bitmap_bit_in_range_p (s, 1, 63));
978 ASSERT_FALSE (bitmap_bit_in_range_p (s, 0, 256));
979
980 bitmap_set_bit (s, 0);
981 bitmap_set_bit (s, 16);
982 bitmap_set_bit (s, 32);
983 bitmap_set_bit (s, 48);
984 bitmap_set_bit (s, 64);
985 ASSERT_TRUE (bitmap_bit_in_range_p (s, 0, 0));
986 ASSERT_TRUE (bitmap_bit_in_range_p (s, 1, 16));
987 ASSERT_TRUE (bitmap_bit_in_range_p (s, 48, 63));
988 ASSERT_TRUE (bitmap_bit_in_range_p (s, 64, 64));
989 ASSERT_FALSE (bitmap_bit_in_range_p (s, 1, 15));
990 ASSERT_FALSE (bitmap_bit_in_range_p (s, 17, 31));
991 ASSERT_FALSE (bitmap_bit_in_range_p (s, 49, 63));
992 ASSERT_FALSE (bitmap_bit_in_range_p (s, 65, 1023));
993 sbitmap_free (s);
994 }
995
996 /* Run all of the selftests within this file. */
997
998 void
999 sbitmap_c_tests ()
1000 {
1001 test_set_range ();
1002 test_bit_in_range ();
1003 }
1004
1005 } // namespace selftest
1006 #endif /* CHECKING_P */