* data/glr.c (yyuserMerge, yyreportAmbiguity, yyreportSyntaxError):
[bison.git] / lib / abitset.c
blobec5bf6a0f1f5ea18c1536bba90e73af9d44e01ce
1 /* Array bitsets.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include "abitset.h"
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <string.h>
29 /* This file implements fixed size bitsets stored as an array
30 of words. Any unused bits in the last word must be zero. */
32 #define ABITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
33 #define ABITSET_WORDS(X) ((X)->a.words)
36 static bitset_bindex
37 abitset_resize (bitset src ATTRIBUTE_UNUSED,
38 bitset_bindex size ATTRIBUTE_UNUSED)
40 if (BITSET_SIZE_ (src) == size)
41 return size;
43 /* These bitsets have a fixed size. */
44 abort ();
47 /* Find list of up to NUM bits set in BSET starting from and including
48 *NEXT and store in array LIST. Return with actual number of bits
49 found and with *NEXT indicating where search stopped. */
50 static bitset_bindex
51 abitset_small_list (bitset src, bitset_bindex *list,
52 bitset_bindex num, bitset_bindex *next)
54 bitset_bindex bitno;
55 bitset_bindex count;
56 bitset_windex size;
57 bitset_word word;
59 word = ABITSET_WORDS (src)[0];
61 /* Short circuit common case. */
62 if (!word)
63 return 0;
65 size = BITSET_SIZE_ (src);
66 bitno = *next;
67 if (bitno >= size)
68 return 0;
70 word >>= bitno;
72 /* If num is 1, we could speed things up with a binary search
73 of the word of interest. */
75 if (num >= BITSET_WORD_BITS)
77 for (count = 0; word; bitno++)
79 if (word & 1)
80 list[count++] = bitno;
81 word >>= 1;
84 else
86 for (count = 0; word; bitno++)
88 if (word & 1)
90 list[count++] = bitno;
91 if (count >= num)
93 bitno++;
94 break;
97 word >>= 1;
101 *next = bitno;
102 return count;
106 /* Set bit BITNO in bitset DST. */
107 static void
108 abitset_set (bitset dst ATTRIBUTE_UNUSED, bitset_bindex bitno ATTRIBUTE_UNUSED)
110 /* This should never occur for abitsets since we should always hit
111 the cache. It is likely someone is trying to access outside the
112 bounds of the bitset. */
113 abort ();
117 /* Reset bit BITNO in bitset DST. */
118 static void
119 abitset_reset (bitset dst ATTRIBUTE_UNUSED,
120 bitset_bindex bitno ATTRIBUTE_UNUSED)
122 /* This should never occur for abitsets since we should always hit
123 the cache. It is likely someone is trying to access outside the
124 bounds of the bitset. Since the bit is zero anyway, let it pass. */
128 /* Test bit BITNO in bitset SRC. */
129 static bool
130 abitset_test (bitset src ATTRIBUTE_UNUSED,
131 bitset_bindex bitno ATTRIBUTE_UNUSED)
133 /* This should never occur for abitsets since we should always
134 hit the cache. */
135 return false;
139 /* Find list of up to NUM bits set in BSET in reverse order, starting
140 from and including NEXT and store in array LIST. Return with
141 actual number of bits found and with *NEXT indicating where search
142 stopped. */
143 static bitset_bindex
144 abitset_list_reverse (bitset src, bitset_bindex *list,
145 bitset_bindex num, bitset_bindex *next)
147 bitset_bindex bitno;
148 bitset_bindex rbitno;
149 bitset_bindex count;
150 bitset_windex windex;
151 unsigned int bitcnt;
152 bitset_bindex bitoff;
153 bitset_word *srcp = ABITSET_WORDS (src);
154 bitset_bindex n_bits = BITSET_SIZE_ (src);
156 rbitno = *next;
158 /* If num is 1, we could speed things up with a binary search
159 of the word of interest. */
161 if (rbitno >= n_bits)
162 return 0;
164 count = 0;
166 bitno = n_bits - (rbitno + 1);
168 windex = bitno / BITSET_WORD_BITS;
169 bitcnt = bitno % BITSET_WORD_BITS;
170 bitoff = windex * BITSET_WORD_BITS;
174 bitset_word word;
176 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
177 for (; word; bitcnt--)
179 if (word & BITSET_MSB)
181 list[count++] = bitoff + bitcnt;
182 if (count >= num)
184 *next = n_bits - (bitoff + bitcnt);
185 return count;
188 word <<= 1;
190 bitoff -= BITSET_WORD_BITS;
191 bitcnt = BITSET_WORD_BITS - 1;
193 while (windex--);
195 *next = n_bits - (bitoff + 1);
196 return count;
200 /* Find list of up to NUM bits set in BSET starting from and including
201 *NEXT and store in array LIST. Return with actual number of bits
202 found and with *NEXT indicating where search stopped. */
203 static bitset_bindex
204 abitset_list (bitset src, bitset_bindex *list,
205 bitset_bindex num, bitset_bindex *next)
207 bitset_bindex bitno;
208 bitset_bindex count;
209 bitset_windex windex;
210 bitset_bindex bitoff;
211 bitset_windex size = src->b.csize;
212 bitset_word *srcp = ABITSET_WORDS (src);
213 bitset_word word;
215 bitno = *next;
217 count = 0;
218 if (!bitno)
220 /* Many bitsets are zero, so make this common case fast. */
221 for (windex = 0; windex < size && !srcp[windex]; windex++)
222 continue;
223 if (windex >= size)
224 return 0;
226 /* If num is 1, we could speed things up with a binary search
227 of the current word. */
229 bitoff = windex * BITSET_WORD_BITS;
231 else
233 if (bitno >= BITSET_SIZE_ (src))
234 return 0;
236 windex = bitno / BITSET_WORD_BITS;
237 bitno = bitno % BITSET_WORD_BITS;
239 if (bitno)
241 /* Handle the case where we start within a word.
242 Most often, this is executed with large bitsets
243 with many set bits where we filled the array
244 on the previous call to this function. */
246 bitoff = windex * BITSET_WORD_BITS;
247 word = srcp[windex] >> bitno;
248 for (bitno = bitoff + bitno; word; bitno++)
250 if (word & 1)
252 list[count++] = bitno;
253 if (count >= num)
255 *next = bitno + 1;
256 return count;
259 word >>= 1;
261 windex++;
263 bitoff = windex * BITSET_WORD_BITS;
266 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
268 if (!(word = srcp[windex]))
269 continue;
271 if ((count + BITSET_WORD_BITS) < num)
273 for (bitno = bitoff; word; bitno++)
275 if (word & 1)
276 list[count++] = bitno;
277 word >>= 1;
280 else
282 for (bitno = bitoff; word; bitno++)
284 if (word & 1)
286 list[count++] = bitno;
287 if (count >= num)
289 *next = bitno + 1;
290 return count;
293 word >>= 1;
298 *next = bitoff;
299 return count;
303 /* Ensure that any unused bits within the last word are clear. */
304 static inline void
305 abitset_unused_clear (bitset dst)
307 unsigned int last_bit;
309 last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
310 if (last_bit)
311 ABITSET_WORDS (dst)[dst->b.csize - 1] &=
312 ((bitset_word) 1 << last_bit) - 1;
316 static void
317 abitset_ones (bitset dst)
319 bitset_word *dstp = ABITSET_WORDS (dst);
320 size_t bytes;
322 bytes = sizeof (bitset_word) * dst->b.csize;
324 memset (dstp, -1, bytes);
325 abitset_unused_clear (dst);
329 static void
330 abitset_zero (bitset dst)
332 bitset_word *dstp = ABITSET_WORDS (dst);
333 size_t bytes;
335 bytes = sizeof (bitset_word) * dst->b.csize;
337 memset (dstp, 0, bytes);
341 static bool
342 abitset_empty_p (bitset dst)
344 bitset_windex i;
345 bitset_word *dstp = ABITSET_WORDS (dst);
347 for (i = 0; i < dst->b.csize; i++)
348 if (dstp[i])
349 return false;
351 return true;
355 static void
356 abitset_copy1 (bitset dst, bitset src)
358 bitset_word *srcp = ABITSET_WORDS (src);
359 bitset_word *dstp = ABITSET_WORDS (dst);
360 bitset_windex size = dst->b.csize;
362 if (srcp == dstp)
363 return;
364 memcpy (dstp, srcp, sizeof (bitset_word) * size);
368 static void
369 abitset_not (bitset dst, bitset src)
371 bitset_windex i;
372 bitset_word *srcp = ABITSET_WORDS (src);
373 bitset_word *dstp = ABITSET_WORDS (dst);
374 bitset_windex size = dst->b.csize;
376 for (i = 0; i < size; i++)
377 *dstp++ = ~(*srcp++);
378 abitset_unused_clear (dst);
382 static bool
383 abitset_equal_p (bitset dst, bitset src)
385 bitset_windex i;
386 bitset_word *srcp = ABITSET_WORDS (src);
387 bitset_word *dstp = ABITSET_WORDS (dst);
388 bitset_windex size = dst->b.csize;
390 for (i = 0; i < size; i++)
391 if (*srcp++ != *dstp++)
392 return false;
393 return true;
397 static bool
398 abitset_subset_p (bitset dst, bitset src)
400 bitset_windex i;
401 bitset_word *srcp = ABITSET_WORDS (src);
402 bitset_word *dstp = ABITSET_WORDS (dst);
403 bitset_windex size = dst->b.csize;
405 for (i = 0; i < size; i++, dstp++, srcp++)
406 if (*dstp != (*srcp | *dstp))
407 return false;
408 return true;
412 static bool
413 abitset_disjoint_p (bitset dst, bitset src)
415 bitset_windex i;
416 bitset_word *srcp = ABITSET_WORDS (src);
417 bitset_word *dstp = ABITSET_WORDS (dst);
418 bitset_windex size = dst->b.csize;
420 for (i = 0; i < size; i++)
421 if (*srcp++ & *dstp++)
422 return false;
424 return true;
428 static void
429 abitset_and (bitset dst, bitset src1, bitset src2)
431 bitset_windex i;
432 bitset_word *src1p = ABITSET_WORDS (src1);
433 bitset_word *src2p = ABITSET_WORDS (src2);
434 bitset_word *dstp = ABITSET_WORDS (dst);
435 bitset_windex size = dst->b.csize;
437 for (i = 0; i < size; i++)
438 *dstp++ = *src1p++ & *src2p++;
442 static bool
443 abitset_and_cmp (bitset dst, bitset src1, bitset src2)
445 bitset_windex i;
446 bool changed = false;
447 bitset_word *src1p = ABITSET_WORDS (src1);
448 bitset_word *src2p = ABITSET_WORDS (src2);
449 bitset_word *dstp = ABITSET_WORDS (dst);
450 bitset_windex size = dst->b.csize;
452 for (i = 0; i < size; i++, dstp++)
454 bitset_word tmp = *src1p++ & *src2p++;
456 if (*dstp != tmp)
458 changed = true;
459 *dstp = tmp;
462 return changed;
466 static void
467 abitset_andn (bitset dst, bitset src1, bitset src2)
469 bitset_windex i;
470 bitset_word *src1p = ABITSET_WORDS (src1);
471 bitset_word *src2p = ABITSET_WORDS (src2);
472 bitset_word *dstp = ABITSET_WORDS (dst);
473 bitset_windex size = dst->b.csize;
475 for (i = 0; i < size; i++)
476 *dstp++ = *src1p++ & ~(*src2p++);
480 static bool
481 abitset_andn_cmp (bitset dst, bitset src1, bitset src2)
483 bitset_windex i;
484 bool changed = false;
485 bitset_word *src1p = ABITSET_WORDS (src1);
486 bitset_word *src2p = ABITSET_WORDS (src2);
487 bitset_word *dstp = ABITSET_WORDS (dst);
488 bitset_windex size = dst->b.csize;
490 for (i = 0; i < size; i++, dstp++)
492 bitset_word tmp = *src1p++ & ~(*src2p++);
494 if (*dstp != tmp)
496 changed = true;
497 *dstp = tmp;
500 return changed;
504 static void
505 abitset_or (bitset dst, bitset src1, bitset src2)
507 bitset_windex i;
508 bitset_word *src1p = ABITSET_WORDS (src1);
509 bitset_word *src2p = ABITSET_WORDS (src2);
510 bitset_word *dstp = ABITSET_WORDS (dst);
511 bitset_windex size = dst->b.csize;
513 for (i = 0; i < size; i++)
514 *dstp++ = *src1p++ | *src2p++;
518 static bool
519 abitset_or_cmp (bitset dst, bitset src1, bitset src2)
521 bitset_windex i;
522 bool changed = false;
523 bitset_word *src1p = ABITSET_WORDS (src1);
524 bitset_word *src2p = ABITSET_WORDS (src2);
525 bitset_word *dstp = ABITSET_WORDS (dst);
526 bitset_windex size = dst->b.csize;
528 for (i = 0; i < size; i++, dstp++)
530 bitset_word tmp = *src1p++ | *src2p++;
532 if (*dstp != tmp)
534 changed = true;
535 *dstp = tmp;
538 return changed;
542 static void
543 abitset_xor (bitset dst, bitset src1, bitset src2)
545 bitset_windex i;
546 bitset_word *src1p = ABITSET_WORDS (src1);
547 bitset_word *src2p = ABITSET_WORDS (src2);
548 bitset_word *dstp = ABITSET_WORDS (dst);
549 bitset_windex size = dst->b.csize;
551 for (i = 0; i < size; i++)
552 *dstp++ = *src1p++ ^ *src2p++;
556 static bool
557 abitset_xor_cmp (bitset dst, bitset src1, bitset src2)
559 bitset_windex i;
560 bool changed = false;
561 bitset_word *src1p = ABITSET_WORDS (src1);
562 bitset_word *src2p = ABITSET_WORDS (src2);
563 bitset_word *dstp = ABITSET_WORDS (dst);
564 bitset_windex size = dst->b.csize;
566 for (i = 0; i < size; i++, dstp++)
568 bitset_word tmp = *src1p++ ^ *src2p++;
570 if (*dstp != tmp)
572 changed = true;
573 *dstp = tmp;
576 return changed;
580 static void
581 abitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
583 bitset_windex i;
584 bitset_word *src1p = ABITSET_WORDS (src1);
585 bitset_word *src2p = ABITSET_WORDS (src2);
586 bitset_word *src3p = ABITSET_WORDS (src3);
587 bitset_word *dstp = ABITSET_WORDS (dst);
588 bitset_windex size = dst->b.csize;
590 for (i = 0; i < size; i++)
591 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
595 static bool
596 abitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
598 bitset_windex i;
599 bool changed = false;
600 bitset_word *src1p = ABITSET_WORDS (src1);
601 bitset_word *src2p = ABITSET_WORDS (src2);
602 bitset_word *src3p = ABITSET_WORDS (src3);
603 bitset_word *dstp = ABITSET_WORDS (dst);
604 bitset_windex size = dst->b.csize;
606 for (i = 0; i < size; i++, dstp++)
608 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
610 if (*dstp != tmp)
612 changed = true;
613 *dstp = tmp;
616 return changed;
620 static void
621 abitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
623 bitset_windex i;
624 bitset_word *src1p = ABITSET_WORDS (src1);
625 bitset_word *src2p = ABITSET_WORDS (src2);
626 bitset_word *src3p = ABITSET_WORDS (src3);
627 bitset_word *dstp = ABITSET_WORDS (dst);
628 bitset_windex size = dst->b.csize;
630 for (i = 0; i < size; i++)
631 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
635 static bool
636 abitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
638 bitset_windex i;
639 bool changed = false;
640 bitset_word *src1p = ABITSET_WORDS (src1);
641 bitset_word *src2p = ABITSET_WORDS (src2);
642 bitset_word *src3p = ABITSET_WORDS (src3);
643 bitset_word *dstp = ABITSET_WORDS (dst);
644 bitset_windex size = dst->b.csize;
646 for (i = 0; i < size; i++, dstp++)
648 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
650 if (*dstp != tmp)
652 changed = true;
653 *dstp = tmp;
656 return changed;
660 static void
661 abitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
663 bitset_windex i;
664 bitset_word *src1p = ABITSET_WORDS (src1);
665 bitset_word *src2p = ABITSET_WORDS (src2);
666 bitset_word *src3p = ABITSET_WORDS (src3);
667 bitset_word *dstp = ABITSET_WORDS (dst);
668 bitset_windex size = dst->b.csize;
670 for (i = 0; i < size; i++)
671 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
675 static bool
676 abitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
678 bitset_windex i;
679 bool changed = false;
680 bitset_word *src1p = ABITSET_WORDS (src1);
681 bitset_word *src2p = ABITSET_WORDS (src2);
682 bitset_word *src3p = ABITSET_WORDS (src3);
683 bitset_word *dstp = ABITSET_WORDS (dst);
684 bitset_windex size = dst->b.csize;
686 for (i = 0; i < size; i++, dstp++)
688 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
690 if (*dstp != tmp)
692 changed = true;
693 *dstp = tmp;
696 return changed;
700 static void
701 abitset_copy (bitset dst, bitset src)
703 if (BITSET_COMPATIBLE_ (dst, src))
704 abitset_copy1 (dst, src);
705 else
706 bitset_copy_ (dst, src);
710 /* Vector of operations for single word bitsets. */
711 struct bitset_vtable abitset_small_vtable = {
712 abitset_set,
713 abitset_reset,
714 bitset_toggle_,
715 abitset_test,
716 abitset_resize,
717 bitset_size_,
718 bitset_count_,
719 abitset_empty_p,
720 abitset_ones,
721 abitset_zero,
722 abitset_copy,
723 abitset_disjoint_p,
724 abitset_equal_p,
725 abitset_not,
726 abitset_subset_p,
727 abitset_and,
728 abitset_and_cmp,
729 abitset_andn,
730 abitset_andn_cmp,
731 abitset_or,
732 abitset_or_cmp,
733 abitset_xor,
734 abitset_xor_cmp,
735 abitset_and_or,
736 abitset_and_or_cmp,
737 abitset_andn_or,
738 abitset_andn_or_cmp,
739 abitset_or_and,
740 abitset_or_and_cmp,
741 abitset_small_list,
742 abitset_list_reverse,
743 NULL,
744 BITSET_ARRAY
748 /* Vector of operations for multiple word bitsets. */
749 struct bitset_vtable abitset_vtable = {
750 abitset_set,
751 abitset_reset,
752 bitset_toggle_,
753 abitset_test,
754 abitset_resize,
755 bitset_size_,
756 bitset_count_,
757 abitset_empty_p,
758 abitset_ones,
759 abitset_zero,
760 abitset_copy,
761 abitset_disjoint_p,
762 abitset_equal_p,
763 abitset_not,
764 abitset_subset_p,
765 abitset_and,
766 abitset_and_cmp,
767 abitset_andn,
768 abitset_andn_cmp,
769 abitset_or,
770 abitset_or_cmp,
771 abitset_xor,
772 abitset_xor_cmp,
773 abitset_and_or,
774 abitset_and_or_cmp,
775 abitset_andn_or,
776 abitset_andn_or_cmp,
777 abitset_or_and,
778 abitset_or_and_cmp,
779 abitset_list,
780 abitset_list_reverse,
781 NULL,
782 BITSET_ARRAY
786 size_t
787 abitset_bytes (bitset_bindex n_bits)
789 bitset_windex size;
790 size_t bytes;
791 size_t header_size = offsetof (union bitset_union, a.words);
792 struct bitset_align_struct { char a; union bitset_union b; };
793 size_t bitset_alignment = offsetof (struct bitset_align_struct, b);
795 size = ABITSET_N_WORDS (n_bits);
796 bytes = header_size + size * sizeof (bitset_word);
798 /* Align the size properly for a vector of abitset objects. */
799 if (header_size % bitset_alignment != 0
800 || sizeof (bitset_word) % bitset_alignment != 0)
802 bytes += bitset_alignment - 1;
803 bytes -= bytes % bitset_alignment;
806 return bytes;
810 bitset
811 abitset_init (bitset bset, bitset_bindex n_bits)
813 bitset_windex size;
815 size = ABITSET_N_WORDS (n_bits);
816 BITSET_NBITS_ (bset) = n_bits;
818 /* Use optimized routines if bitset fits within a single word.
819 There is probably little merit if using caching since
820 the small bitset will always fit in the cache. */
821 if (size == 1)
822 bset->b.vtable = &abitset_small_vtable;
823 else
824 bset->b.vtable = &abitset_vtable;
826 bset->b.cindex = 0;
827 bset->b.csize = size;
828 bset->b.cdata = ABITSET_WORDS (bset);
829 return bset;