1 /* Functions to support expandable bitsets.
3 Copyright (C) 2002-2006, 2009-2015, 2018-2020 Free Software Foundation, Inc.
5 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <https://www.gnu.org/licenses/>. */
22 #include "bitset/table.h"
30 /* This file implements expandable bitsets. These bitsets can be of
31 arbitrary length and are more efficient than arrays of bits for
34 Empty elements are represented by a NULL pointer in the table of
35 element pointers. An alternative is to point to a special zero
36 element. Similarly, we could represent an all 1's element with
37 another special ones element pointer.
39 Bitsets are commonly empty so we need to ensure that this special
40 case is fast. A zero bitset is indicated when cdata is 0. This is
41 conservative since cdata may be non zero and the bitset may still
44 The bitset cache can be disabled either by setting cindex to
45 BITSET_WINDEX_MAX or by setting csize to 0. Here
46 we use the former approach since cindex needs to be updated whenever
51 /* Number of words to use for each element. */
52 #define TBITSET_ELT_WORDS 2
54 /* Number of bits stored in each element. */
55 #define TBITSET_ELT_BITS \
56 ((unsigned) (TBITSET_ELT_WORDS * BITSET_WORD_BITS))
58 /* Tbitset element. We use an array of bits. */
59 typedef struct tbitset_elt_struct
63 bitset_word words
[TBITSET_ELT_WORDS
]; /* Bits that are set. */
64 struct tbitset_elt_struct
*next
;
71 typedef tbitset_elt
*tbitset_elts
;
74 /* Number of elements to initially allocate. */
76 #ifndef TBITSET_INITIAL_SIZE
77 # define TBITSET_INITIAL_SIZE 2
81 enum tbitset_find_mode
82 { TBITSET_FIND
, TBITSET_CREATE
, TBITSET_SUBST
};
84 static tbitset_elt tbitset_zero_elts
[1]; /* Elements of all zero bits. */
86 /* Obstack to allocate bitset elements from. */
87 static struct obstack tbitset_obstack
;
88 static bool tbitset_obstack_init
= false;
89 static tbitset_elt
*tbitset_free_list
; /* Free list of bitset elements. */
91 #define TBITSET_N_ELTS(N) (((N) + TBITSET_ELT_BITS - 1) / TBITSET_ELT_BITS)
92 #define TBITSET_ELTS(BSET) ((BSET)->e.elts)
93 #define TBITSET_SIZE(BSET) TBITSET_N_ELTS (BITSET_NBITS_ (BSET))
94 #define TBITSET_ASIZE(BSET) ((BSET)->e.size)
96 #define TBITSET_NEXT(ELT) ((ELT)->u.next)
97 #define TBITSET_WORDS(ELT) ((ELT)->u.words)
99 /* Disable bitset cache and mark BSET as being zero. */
100 #define TBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
103 #define TBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
105 /* Disable bitset cache and mark BSET as being possibly non-zero. */
106 #define TBITSET_NONZERO_SET(BSET) \
107 (TBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
109 /* A conservative estimate of whether the bitset is zero.
110 This is non-zero only if we know for sure that the bitset is zero. */
111 #define TBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0)
113 /* Enable cache to point to element with table index EINDEX.
114 The element must exist. */
115 #define TBITSET_CACHE_SET(BSET, EINDEX) \
116 ((BSET)->b.cindex = (EINDEX) * TBITSET_ELT_WORDS, \
117 (BSET)->b.cdata = TBITSET_WORDS (TBITSET_ELTS (BSET) [EINDEX]))
121 #define min(a, b) ((a) > (b) ? (b) : (a))
122 #define max(a, b) ((a) > (b) ? (a) : (b))
125 tbitset_resize (bitset src
, bitset_bindex n_bits
)
127 if (n_bits
== BITSET_NBITS_ (src
))
130 bitset_windex oldsize
= TBITSET_SIZE (src
);
131 bitset_windex newsize
= TBITSET_N_ELTS (n_bits
);
133 if (oldsize
< newsize
)
135 /* The bitset needs to grow. If we already have enough memory
136 allocated, then just zero what we need. */
137 if (newsize
> TBITSET_ASIZE (src
))
139 /* We need to allocate more memory. When oldsize is
140 non-zero this means that we are changing the size, so
141 grow the bitset 25% larger than requested to reduce
142 number of reallocations. */
144 bitset_windex size
= oldsize
== 0 ? newsize
: newsize
+ newsize
/ 4;
146 = xrealloc (TBITSET_ELTS (src
), size
* sizeof (tbitset_elt
*));
147 TBITSET_ASIZE (src
) = size
;
150 memset (TBITSET_ELTS (src
) + oldsize
, 0,
151 (newsize
- oldsize
) * sizeof (tbitset_elt
*));
155 /* The bitset needs to shrink. There's no point deallocating
156 the memory unless it is shrinking by a reasonable amount. */
157 if ((oldsize
- newsize
) >= oldsize
/ 2)
160 = realloc (TBITSET_ELTS (src
), newsize
* sizeof (tbitset_elt
*));
163 TBITSET_ELTS (src
) = p
;
164 TBITSET_ASIZE (src
) = newsize
;
168 /* Need to prune any excess bits. FIXME. */
171 BITSET_NBITS_ (src
) = n_bits
;
176 /* Allocate a tbitset element. The bits are not cleared. */
177 static inline tbitset_elt
*
178 tbitset_elt_alloc (void)
182 if (tbitset_free_list
!= 0)
184 elt
= tbitset_free_list
;
185 tbitset_free_list
= TBITSET_NEXT (elt
);
189 if (!tbitset_obstack_init
)
191 tbitset_obstack_init
= true;
193 /* Let particular systems override the size of a chunk. */
195 #ifndef OBSTACK_CHUNK_SIZE
196 # define OBSTACK_CHUNK_SIZE 0
199 /* Let them override the alloc and free routines too. */
201 #ifndef OBSTACK_CHUNK_ALLOC
202 # define OBSTACK_CHUNK_ALLOC xmalloc
205 #ifndef OBSTACK_CHUNK_FREE
206 # define OBSTACK_CHUNK_FREE free
209 #if !(defined __GNUC__ || defined __clang__)
210 # define __alignof__(type) 0
213 obstack_specify_allocation (&tbitset_obstack
, OBSTACK_CHUNK_SIZE
,
214 __alignof__ (tbitset_elt
),
219 /* Perhaps we should add a number of new elements to the free
221 elt
= (tbitset_elt
*) obstack_alloc (&tbitset_obstack
,
222 sizeof (tbitset_elt
));
229 /* Allocate a tbitset element. The bits are cleared. */
230 static inline tbitset_elt
*
231 tbitset_elt_calloc (void)
233 tbitset_elt
*elt
= tbitset_elt_alloc ();
234 memset (TBITSET_WORDS (elt
), 0, sizeof (TBITSET_WORDS (elt
)));
240 tbitset_elt_free (tbitset_elt
*elt
)
242 TBITSET_NEXT (elt
) = tbitset_free_list
;
243 tbitset_free_list
= elt
;
247 /* Remove element with index EINDEX from bitset BSET. */
249 tbitset_elt_remove (bitset bset
, bitset_windex eindex
)
251 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
252 tbitset_elt
*elt
= elts
[eindex
];
255 tbitset_elt_free (elt
);
259 /* Add ELT into elts at index EINDEX of bitset BSET. */
261 tbitset_elt_add (bitset bset
, tbitset_elt
*elt
, bitset_windex eindex
)
263 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
264 /* Assume that the elts entry not allocated. */
269 /* Are all bits in an element zero? */
271 tbitset_elt_zero_p (tbitset_elt
*elt
)
273 for (int i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
274 if (TBITSET_WORDS (elt
)[i
])
281 tbitset_elt_find (bitset bset
, bitset_bindex bindex
,
282 enum tbitset_find_mode mode
)
284 bitset_windex eindex
= bindex
/ TBITSET_ELT_BITS
;
286 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
287 bitset_windex size
= TBITSET_SIZE (bset
);
291 tbitset_elt
*elt
= elts
[eindex
];
294 if (TBITSET_WORDS (elt
) != bset
->b
.cdata
)
295 TBITSET_CACHE_SET (bset
, eindex
);
300 /* The element could not be found. */
312 tbitset_resize (bset
, bindex
);
314 /* Create a new element. */
316 tbitset_elt
*elt
= tbitset_elt_calloc ();
317 tbitset_elt_add (bset
, elt
, eindex
);
318 TBITSET_CACHE_SET (bset
, eindex
);
323 return &tbitset_zero_elts
[0];
328 /* Weed out the zero elements from the elts. */
329 static inline bitset_windex
330 tbitset_weed (bitset bset
)
332 if (TBITSET_ZERO_P (bset
))
335 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
336 bitset_windex count
= 0;
338 for (j
= 0; j
< TBITSET_SIZE (bset
); j
++)
340 tbitset_elt
*elt
= elts
[j
];
344 if (tbitset_elt_zero_p (elt
))
346 tbitset_elt_remove (bset
, j
);
357 /* All the bits are zero. We could shrink the elts.
358 For now just mark BSET as known to be zero. */
359 TBITSET_ZERO_SET (bset
);
362 TBITSET_NONZERO_SET (bset
);
368 /* Set all bits in the bitset to zero. */
370 tbitset_zero (bitset bset
)
372 if (TBITSET_ZERO_P (bset
))
375 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
376 for (bitset_windex j
= 0; j
< TBITSET_SIZE (bset
); j
++)
378 tbitset_elt
*elt
= elts
[j
];
380 tbitset_elt_remove (bset
, j
);
383 /* All the bits are zero. We could shrink the elts.
384 For now just mark BSET as known to be zero. */
385 TBITSET_ZERO_SET (bset
);
390 tbitset_equal_p (bitset dst
, bitset src
)
398 if (TBITSET_SIZE (src
) != TBITSET_SIZE (dst
))
401 tbitset_elts
*selts
= TBITSET_ELTS (src
);
402 tbitset_elts
*delts
= TBITSET_ELTS (dst
);
404 for (bitset_windex j
= 0; j
< TBITSET_SIZE (src
); j
++)
406 tbitset_elt
*selt
= selts
[j
];
407 tbitset_elt
*delt
= delts
[j
];
411 if ((selt
&& !delt
) || (!selt
&& delt
))
414 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
415 if (TBITSET_WORDS (selt
)[i
] != TBITSET_WORDS (delt
)[i
])
422 /* Copy bits from bitset SRC to bitset DST. */
424 tbitset_copy_ (bitset dst
, bitset src
)
431 if (BITSET_NBITS_ (dst
) != BITSET_NBITS_ (src
))
432 tbitset_resize (dst
, BITSET_NBITS_ (src
));
434 tbitset_elts
*selts
= TBITSET_ELTS (src
);
435 tbitset_elts
*delts
= TBITSET_ELTS (dst
);
436 for (bitset_windex j
= 0; j
< TBITSET_SIZE (src
); j
++)
438 tbitset_elt
*selt
= selts
[j
];
441 tbitset_elt
*tmp
= tbitset_elt_alloc ();
443 memcpy (TBITSET_WORDS (tmp
), TBITSET_WORDS (selt
),
444 sizeof (TBITSET_WORDS (selt
)));
447 TBITSET_NONZERO_SET (dst
);
451 /* Copy bits from bitset SRC to bitset DST. Return true if
452 bitsets different. */
454 tbitset_copy_cmp (bitset dst
, bitset src
)
459 if (TBITSET_ZERO_P (dst
))
461 tbitset_copy_ (dst
, src
);
462 return !TBITSET_ZERO_P (src
);
465 if (tbitset_equal_p (dst
, src
))
468 tbitset_copy_ (dst
, src
);
473 /* Set bit BITNO in bitset DST. */
475 tbitset_set (bitset dst
, bitset_bindex bitno
)
477 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
479 tbitset_elt_find (dst
, bitno
, TBITSET_CREATE
);
481 dst
->b
.cdata
[windex
- dst
->b
.cindex
] |=
482 (bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
);
486 /* Reset bit BITNO in bitset DST. */
488 tbitset_reset (bitset dst
, bitset_bindex bitno
)
490 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
492 if (!tbitset_elt_find (dst
, bitno
, TBITSET_FIND
))
495 dst
->b
.cdata
[windex
- dst
->b
.cindex
] &=
496 ~((bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
));
498 /* If all the data is zero, perhaps we should remove it now...
499 However, there is a good chance that the element will be needed
504 /* Test bit BITNO in bitset SRC. */
506 tbitset_test (bitset src
, bitset_bindex bitno
)
508 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
510 return (tbitset_elt_find (src
, bitno
, TBITSET_FIND
)
511 && ((src
->b
.cdata
[windex
- src
->b
.cindex
]
512 >> (bitno
% BITSET_WORD_BITS
))
518 tbitset_free (bitset bset
)
521 free (TBITSET_ELTS (bset
));
525 /* Find list of up to NUM bits set in BSET starting from and including
526 *NEXT and store in array LIST. Return with actual number of bits
527 found and with *NEXT indicating where search stopped. */
529 tbitset_list_reverse (bitset bset
, bitset_bindex
*list
,
530 bitset_bindex num
, bitset_bindex
*next
)
532 if (TBITSET_ZERO_P (bset
))
535 bitset_windex size
= TBITSET_SIZE (bset
);
536 bitset_bindex n_bits
= size
* TBITSET_ELT_BITS
;
537 bitset_bindex rbitno
= *next
;
539 if (rbitno
>= n_bits
)
542 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
544 bitset_bindex bitno
= n_bits
- (rbitno
+ 1);
546 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
547 bitset_windex eindex
= bitno
/ TBITSET_ELT_BITS
;
548 bitset_windex woffset
= windex
- eindex
* TBITSET_ELT_WORDS
;
550 /* If num is 1, we could speed things up with a binary search
551 of the word of interest. */
552 bitset_bindex count
= 0;
553 unsigned bitcnt
= bitno
% BITSET_WORD_BITS
;
554 bitset_bindex bitoff
= windex
* BITSET_WORD_BITS
;
558 tbitset_elt
*elt
= elts
[eindex
];
561 bitset_word
*srcp
= TBITSET_WORDS (elt
);
565 bitset_word word
= srcp
[woffset
];
566 if (bitcnt
+ 1 < BITSET_WORD_BITS
)
567 /* We're starting in the middle of a word: smash bits to ignore. */
568 word
&= ((bitset_word
) 1 << (bitcnt
+ 1)) - 1;
569 BITSET_FOR_EACH_BIT_REVERSE(pos
, word
)
571 list
[count
++] = bitoff
+ pos
;
574 *next
= n_bits
- (bitoff
+ pos
);
578 bitoff
-= BITSET_WORD_BITS
;
579 bitcnt
= BITSET_WORD_BITS
- 1;
584 woffset
= TBITSET_ELT_WORDS
- 1;
585 bitoff
= eindex
* TBITSET_ELT_BITS
- BITSET_WORD_BITS
;
589 *next
= n_bits
- (bitoff
+ 1);
594 /* Find list of up to NUM bits set in BSET starting from and including
595 *NEXT and store in array LIST. Return with actual number of bits
596 found and with *NEXT indicating where search stopped. */
598 tbitset_list (bitset bset
, bitset_bindex
*list
,
599 bitset_bindex num
, bitset_bindex
*next
)
601 if (TBITSET_ZERO_P (bset
))
604 bitset_bindex bitno
= *next
;
605 bitset_bindex count
= 0;
607 tbitset_elts
*elts
= TBITSET_ELTS (bset
);
608 bitset_windex size
= TBITSET_SIZE (bset
);
609 bitset_windex eindex
= bitno
/ TBITSET_ELT_BITS
;
611 if (bitno
% TBITSET_ELT_BITS
)
613 /* We need to start within an element. This is not very common. */
614 tbitset_elt
*elt
= elts
[eindex
];
617 bitset_word
*srcp
= TBITSET_WORDS (elt
);
618 bitset_windex woffset
= eindex
* TBITSET_ELT_WORDS
;
620 for (bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
621 (windex
- woffset
) < TBITSET_ELT_WORDS
; windex
++)
623 bitset_word word
= srcp
[windex
- woffset
] >> (bitno
% BITSET_WORD_BITS
);
625 BITSET_FOR_EACH_BIT (pos
, word
)
627 list
[count
++] = bitno
+ pos
;
630 *next
= bitno
+ pos
+ 1;
634 bitno
= (windex
+ 1) * BITSET_WORD_BITS
;
638 /* Skip to next element. */
642 /* If num is 1, we could speed things up with a binary search
643 of the word of interest. */
645 for (; eindex
< size
; eindex
++)
647 tbitset_elt
*elt
= elts
[eindex
];
651 bitset_word
*srcp
= TBITSET_WORDS (elt
);
652 bitset_windex windex
= eindex
* TBITSET_ELT_WORDS
;
653 bitno
= windex
* BITSET_WORD_BITS
;
655 /* Is there enough room to avoid checking in each iteration? */
656 if ((count
+ TBITSET_ELT_BITS
) < num
)
658 /* The coast is clear, plant boot! */
660 #if TBITSET_ELT_WORDS == 2
661 bitset_word word
= srcp
[0];
663 BITSET_FOR_EACH_BIT (pos
, word
)
664 list
[count
++] = bitno
+ pos
;
666 bitno
= windex
* BITSET_WORD_BITS
;
670 BITSET_FOR_EACH_BIT (pos
, word
)
671 list
[count
++] = bitno
+ pos
;
673 bitno
= windex
* BITSET_WORD_BITS
;
675 for (int i
= 0; i
< TBITSET_ELT_WORDS
; i
++, windex
++)
677 bitset_word word
= srcp
[i
];
679 BITSET_FOR_EACH_BIT (pos
, word
)
680 list
[count
++] = bitno
+ pos
;
681 bitno
= windex
* BITSET_WORD_BITS
;
687 /* Tread more carefully since we need to check
688 if array overflows. */
689 for (int i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
691 bitset_word word
= srcp
[i
];
693 BITSET_FOR_EACH_BIT (pos
, word
)
695 list
[count
++] = bitno
+ pos
;
698 *next
= bitno
+ pos
+ 1;
703 bitno
= windex
* BITSET_WORD_BITS
;
713 /* Ensure that any unused bits within the last element are clear. */
715 tbitset_unused_clear (bitset dst
)
717 bitset_bindex n_bits
= BITSET_NBITS_ (dst
);
718 unsigned last_bit
= n_bits
% TBITSET_ELT_BITS
;
722 tbitset_elts
*elts
= TBITSET_ELTS (dst
);
724 bitset_windex eindex
= n_bits
/ TBITSET_ELT_BITS
;
726 tbitset_elt
*elt
= elts
[eindex
];
729 bitset_word
*srcp
= TBITSET_WORDS (elt
);
731 bitset_windex windex
= n_bits
/ BITSET_WORD_BITS
;
732 bitset_windex woffset
= eindex
* TBITSET_ELT_WORDS
;
734 srcp
[windex
- woffset
]
735 &= ((bitset_word
) 1 << (last_bit
% BITSET_WORD_BITS
)) - 1;
737 for (; (windex
- woffset
) < TBITSET_ELT_WORDS
; windex
++)
738 srcp
[windex
- woffset
] = 0;
745 tbitset_ones (bitset dst
)
747 for (bitset_windex j
= 0; j
< TBITSET_SIZE (dst
); j
++)
749 /* Create new elements if they cannot be found. Perhaps
750 we should just add pointers to a ones element? */
752 tbitset_elt_find (dst
, j
* TBITSET_ELT_BITS
, TBITSET_CREATE
);
753 memset (TBITSET_WORDS (elt
), -1, sizeof (TBITSET_WORDS (elt
)));
755 TBITSET_NONZERO_SET (dst
);
756 tbitset_unused_clear (dst
);
761 tbitset_empty_p (bitset dst
)
763 if (TBITSET_ZERO_P (dst
))
766 tbitset_elts
*elts
= TBITSET_ELTS (dst
);
767 for (bitset_windex j
= 0; j
< TBITSET_SIZE (dst
); j
++)
769 tbitset_elt
*elt
= elts
[j
];
773 if (!tbitset_elt_zero_p (elt
))
775 /* Do some weeding as we go. */
776 tbitset_elt_remove (dst
, j
);
780 /* All the bits are zero. We could shrink the elts.
781 For now just mark DST as known to be zero. */
782 TBITSET_ZERO_SET (dst
);
788 tbitset_not (bitset dst
, bitset src
)
790 tbitset_resize (dst
, BITSET_NBITS_ (src
));
792 for (bitset_windex j
= 0; j
< TBITSET_SIZE (src
); j
++)
794 /* Create new elements for dst if they cannot be found
795 or substitute zero elements if src elements not found. */
797 tbitset_elt_find (src
, j
* TBITSET_ELT_BITS
, TBITSET_SUBST
);
799 tbitset_elt_find (dst
, j
* TBITSET_ELT_BITS
, TBITSET_CREATE
);
801 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
802 TBITSET_WORDS (delt
)[i
] = ~TBITSET_WORDS (selt
)[i
];
804 TBITSET_NONZERO_SET (dst
);
805 tbitset_unused_clear (dst
);
809 /* Is DST == DST | SRC? */
811 tbitset_subset_p (bitset dst
, bitset src
)
813 tbitset_elts
*selts
= TBITSET_ELTS (src
);
814 tbitset_elts
*delts
= TBITSET_ELTS (dst
);
816 bitset_windex ssize
= TBITSET_SIZE (src
);
817 bitset_windex dsize
= TBITSET_SIZE (dst
);
819 for (bitset_windex j
= 0; j
< ssize
; j
++)
821 tbitset_elt
*selt
= j
< ssize
? selts
[j
] : 0;
822 tbitset_elt
*delt
= j
< dsize
? delts
[j
] : 0;
828 selt
= &tbitset_zero_elts
[0];
830 delt
= &tbitset_zero_elts
[0];
832 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
833 if (TBITSET_WORDS (delt
)[i
]
834 != (TBITSET_WORDS (selt
)[i
] | TBITSET_WORDS (delt
)[i
]))
841 /* Is DST & SRC == 0? */
843 tbitset_disjoint_p (bitset dst
, bitset src
)
845 tbitset_elts
*selts
= TBITSET_ELTS (src
);
846 tbitset_elts
*delts
= TBITSET_ELTS (dst
);
848 bitset_windex ssize
= TBITSET_SIZE (src
);
849 bitset_windex dsize
= TBITSET_SIZE (dst
);
851 for (bitset_windex j
= 0; j
< ssize
; j
++)
853 tbitset_elt
*selt
= j
< ssize
? selts
[j
] : 0;
854 tbitset_elt
*delt
= j
< dsize
? delts
[j
] : 0;
859 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++)
860 if ((TBITSET_WORDS (selt
)[i
] & TBITSET_WORDS (delt
)[i
]))
869 tbitset_op3_cmp (bitset dst
, bitset src1
, bitset src2
, enum bitset_ops op
)
871 bool changed
= false;
873 tbitset_resize (dst
, max (BITSET_NBITS_ (src1
), BITSET_NBITS_ (src2
)));
875 bitset_windex ssize1
= TBITSET_SIZE (src1
);
876 bitset_windex ssize2
= TBITSET_SIZE (src2
);
877 bitset_windex dsize
= TBITSET_SIZE (dst
);
878 bitset_windex size
= ssize1
;
882 tbitset_elts
*selts1
= TBITSET_ELTS (src1
);
883 tbitset_elts
*selts2
= TBITSET_ELTS (src2
);
884 tbitset_elts
*delts
= TBITSET_ELTS (dst
);
887 for (j
= 0; j
< size
; j
++)
889 tbitset_elt
*selt1
= j
< ssize1
? selts1
[j
] : 0;
890 tbitset_elt
*selt2
= j
< ssize2
? selts2
[j
] : 0;
891 tbitset_elt
*delt
= j
< dsize
? delts
[j
] : 0;
893 if (!selt1
&& !selt2
)
898 tbitset_elt_remove (dst
, j
);
904 selt1
= &tbitset_zero_elts
[0];
906 selt2
= &tbitset_zero_elts
[0];
908 delt
= tbitset_elt_calloc ();
912 bitset_word
*srcp1
= TBITSET_WORDS (selt1
);
913 bitset_word
*srcp2
= TBITSET_WORDS (selt2
);
914 bitset_word
*dstp
= TBITSET_WORDS (delt
);
921 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++, dstp
++)
923 bitset_word tmp
= *srcp1
++ | *srcp2
++;
934 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++, dstp
++)
936 bitset_word tmp
= *srcp1
++ & *srcp2
++;
947 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++, dstp
++)
949 bitset_word tmp
= *srcp1
++ ^ *srcp2
++;
960 for (unsigned i
= 0; i
< TBITSET_ELT_WORDS
; i
++, dstp
++)
962 bitset_word tmp
= *srcp1
++ & ~(*srcp2
++);
973 if (!tbitset_elt_zero_p (delt
))
974 tbitset_elt_add (dst
, delt
, j
);
976 tbitset_elt_free (delt
);
979 /* If we have elements of DST left over, free them all. */
980 for (; j
< dsize
; j
++)
984 tbitset_elt
*delt
= delts
[j
];
986 tbitset_elt_remove (dst
, j
);
989 TBITSET_NONZERO_SET (dst
);
995 tbitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
997 if (TBITSET_ZERO_P (src2
))
1000 bool changed
= TBITSET_ZERO_P (dst
);
1004 else if (TBITSET_ZERO_P (src1
))
1007 bool changed
= TBITSET_ZERO_P (dst
);
1012 return tbitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_AND
);
1017 tbitset_and (bitset dst
, bitset src1
, bitset src2
)
1019 tbitset_and_cmp (dst
, src1
, src2
);
1024 tbitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
1026 if (TBITSET_ZERO_P (src2
))
1027 return tbitset_copy_cmp (dst
, src1
);
1028 else if (TBITSET_ZERO_P (src1
))
1031 bool changed
= TBITSET_ZERO_P (dst
);
1036 return tbitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_ANDN
);
1041 tbitset_andn (bitset dst
, bitset src1
, bitset src2
)
1043 tbitset_andn_cmp (dst
, src1
, src2
);
1048 tbitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
1050 if (TBITSET_ZERO_P (src2
))
1051 return tbitset_copy_cmp (dst
, src1
);
1052 else if (TBITSET_ZERO_P (src1
))
1053 return tbitset_copy_cmp (dst
, src2
);
1055 return tbitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_OR
);
1060 tbitset_or (bitset dst
, bitset src1
, bitset src2
)
1062 tbitset_or_cmp (dst
, src1
, src2
);
1067 tbitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
1069 if (TBITSET_ZERO_P (src2
))
1070 return tbitset_copy_cmp (dst
, src1
);
1071 else if (TBITSET_ZERO_P (src1
))
1072 return tbitset_copy_cmp (dst
, src2
);
1074 return tbitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_XOR
);
1079 tbitset_xor (bitset dst
, bitset src1
, bitset src2
)
1081 tbitset_xor_cmp (dst
, src1
, src2
);
1086 tbitset_copy (bitset dst
, bitset src
)
1088 if (BITSET_COMPATIBLE_ (dst
, src
))
1089 tbitset_copy_ (dst
, src
);
1091 bitset_copy_ (dst
, src
);
1095 /* Vector of operations for linked-list bitsets. */
1096 struct bitset_vtable tbitset_vtable
= {
1123 bitset_andn_or_cmp_
,
1127 tbitset_list_reverse
,
1133 /* Return size of initial structure. */
1135 tbitset_bytes (bitset_bindex n_bits MAYBE_UNUSED
)
1137 return sizeof (struct tbitset_struct
);
1141 /* Initialize a bitset. */
1144 tbitset_init (bitset bset
, bitset_bindex n_bits
)
1146 bset
->b
.vtable
= &tbitset_vtable
;
1148 bset
->b
.csize
= TBITSET_ELT_WORDS
;
1150 TBITSET_ZERO_SET (bset
);
1152 TBITSET_ASIZE (bset
) = 0;
1153 TBITSET_ELTS (bset
) = 0;
1154 tbitset_resize (bset
, n_bits
);
1161 tbitset_release_memory (void)
1163 tbitset_free_list
= 0;
1164 if (tbitset_obstack_init
)
1166 tbitset_obstack_init
= false;
1167 obstack_free (&tbitset_obstack
, NULL
);