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