1 /* Functions to support expandable bitsets.
2 Copyright (C) 2002, 2003, 2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 /* This file implements expandable bitsets. These bitsets can be of
30 arbitrary length and are more efficient than arrays of bits for
33 Empty elements are represented by a NULL pointer in the table of
34 element pointers. An alternative is to point to a special zero
35 element. Similarly, we could represent an all 1's element with
36 another special ones element pointer.
38 Bitsets are commonly empty so we need to ensure that this special
39 case is fast. A zero bitset is indicated when cdata is 0. This is
40 conservative since cdata may be non zero and the bitset may still
43 The bitset cache can be disabled either by setting cindex to
44 BITSET_WINDEX_MAX or by setting csize to 0. Here
45 we use the former approach since cindex needs to be updated whenever
50 /* Number of words to use for each element. */
51 #define EBITSET_ELT_WORDS 2
53 /* Number of bits stored in each element. */
54 #define EBITSET_ELT_BITS \
55 ((unsigned int) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
57 /* Ebitset element. We use an array of bits. */
58 typedef struct ebitset_elt_struct
62 bitset_word words
[EBITSET_ELT_WORDS
]; /* Bits that are set. */
63 struct ebitset_elt_struct
*next
;
70 typedef ebitset_elt
*ebitset_elts
;
73 /* Number of elements to initially allocate. */
75 #ifndef EBITSET_INITIAL_SIZE
76 #define EBITSET_INITIAL_SIZE 2
80 enum ebitset_find_mode
81 { EBITSET_FIND
, EBITSET_CREATE
, EBITSET_SUBST
};
83 static ebitset_elt ebitset_zero_elts
[1]; /* Elements of all zero bits. */
85 /* Obstack to allocate bitset elements from. */
86 static struct obstack ebitset_obstack
;
87 static bool ebitset_obstack_init
= false;
88 static ebitset_elt
*ebitset_free_list
; /* Free list of bitset elements. */
90 #define EBITSET_N_ELTS(N) (((N) + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS)
91 #define EBITSET_ELTS(BSET) ((BSET)->e.elts)
92 #define EBITSET_SIZE(BSET) EBITSET_N_ELTS (BITSET_NBITS_ (BSET))
93 #define EBITSET_ASIZE(BSET) ((BSET)->e.size)
95 #define EBITSET_NEXT(ELT) ((ELT)->u.next)
96 #define EBITSET_WORDS(ELT) ((ELT)->u.words)
98 /* Disable bitset cache and mark BSET as being zero. */
99 #define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
102 #define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
104 /* Disable bitset cache and mark BSET as being possibly non-zero. */
105 #define EBITSET_NONZERO_SET(BSET) \
106 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
108 /* A conservative estimate of whether the bitset is zero.
109 This is non-zero only if we know for sure that the bitset is zero. */
110 #define EBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0)
112 /* Enable cache to point to element with table index EINDEX.
113 The element must exist. */
114 #define EBITSET_CACHE_SET(BSET, EINDEX) \
115 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \
116 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX]))
119 #define min(a, b) ((a) > (b) ? (b) : (a))
120 #define max(a, b) ((a) > (b) ? (a) : (b))
124 ebitset_resize (bitset src
, bitset_bindex n_bits
)
126 bitset_windex oldsize
;
127 bitset_windex newsize
;
129 if (n_bits
== BITSET_NBITS_ (src
))
132 oldsize
= EBITSET_SIZE (src
);
133 newsize
= EBITSET_N_ELTS (n_bits
);
135 if (oldsize
< newsize
)
139 /* The bitset needs to grow. If we already have enough memory
140 allocated, then just zero what we need. */
141 if (newsize
> EBITSET_ASIZE (src
))
143 /* We need to allocate more memory. When oldsize is
144 non-zero this means that we are changing the size, so
145 grow the bitset 25% larger than requested to reduce
146 number of reallocations. */
151 size
= newsize
+ newsize
/ 4;
154 = realloc (EBITSET_ELTS (src
), size
* sizeof (ebitset_elt
*));
155 EBITSET_ASIZE (src
) = size
;
158 memset (EBITSET_ELTS (src
) + oldsize
, 0,
159 (newsize
- oldsize
) * sizeof (ebitset_elt
*));
163 /* The bitset needs to shrink. There's no point deallocating
164 the memory unless it is shrinking by a reasonable amount. */
165 if ((oldsize
- newsize
) >= oldsize
/ 2)
168 = realloc (EBITSET_ELTS (src
), newsize
* sizeof (ebitset_elt
*));
169 EBITSET_ASIZE (src
) = newsize
;
172 /* Need to prune any excess bits. FIXME. */
175 BITSET_NBITS_ (src
) = n_bits
;
180 /* Allocate a ebitset element. The bits are not cleared. */
181 static inline ebitset_elt
*
182 ebitset_elt_alloc (void)
186 if (ebitset_free_list
!= 0)
188 elt
= ebitset_free_list
;
189 ebitset_free_list
= EBITSET_NEXT (elt
);
193 if (!ebitset_obstack_init
)
195 ebitset_obstack_init
= true;
197 /* Let particular systems override the size of a chunk. */
199 #ifndef OBSTACK_CHUNK_SIZE
200 #define OBSTACK_CHUNK_SIZE 0
203 /* Let them override the alloc and free routines too. */
205 #ifndef OBSTACK_CHUNK_ALLOC
206 #define OBSTACK_CHUNK_ALLOC xmalloc
209 #ifndef OBSTACK_CHUNK_FREE
210 #define OBSTACK_CHUNK_FREE free
213 #if !defined(__GNUC__) || (__GNUC__ < 2)
214 #define __alignof__(type) 0
217 obstack_specify_allocation (&ebitset_obstack
, OBSTACK_CHUNK_SIZE
,
218 __alignof__ (ebitset_elt
),
223 /* Perhaps we should add a number of new elements to the free
225 elt
= (ebitset_elt
*) obstack_alloc (&ebitset_obstack
,
226 sizeof (ebitset_elt
));
233 /* Allocate a ebitset element. The bits are cleared. */
234 static inline ebitset_elt
*
235 ebitset_elt_calloc (void)
239 elt
= ebitset_elt_alloc ();
240 memset (EBITSET_WORDS (elt
), 0, sizeof (EBITSET_WORDS (elt
)));
246 ebitset_elt_free (ebitset_elt
*elt
)
248 EBITSET_NEXT (elt
) = ebitset_free_list
;
249 ebitset_free_list
= elt
;
253 /* Remove element with index EINDEX from bitset BSET. */
255 ebitset_elt_remove (bitset bset
, bitset_windex eindex
)
260 elts
= EBITSET_ELTS (bset
);
265 ebitset_elt_free (elt
);
269 /* Add ELT into elts at index EINDEX of bitset BSET. */
271 ebitset_elt_add (bitset bset
, ebitset_elt
*elt
, bitset_windex eindex
)
275 elts
= EBITSET_ELTS (bset
);
276 /* Assume that the elts entry not allocated. */
281 /* Are all bits in an element zero? */
283 ebitset_elt_zero_p (ebitset_elt
*elt
)
287 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
288 if (EBITSET_WORDS (elt
)[i
])
296 ebitset_elt_find (bitset bset
, bitset_bindex bindex
,
297 enum ebitset_find_mode mode
)
301 bitset_windex eindex
;
304 eindex
= bindex
/ EBITSET_ELT_BITS
;
306 elts
= EBITSET_ELTS (bset
);
307 size
= EBITSET_SIZE (bset
);
311 if ((elt
= elts
[eindex
]))
313 if (EBITSET_WORDS (elt
) == bset
->b
.cdata
)
316 EBITSET_CACHE_SET (bset
, eindex
);
321 /* The element could not be found. */
330 ebitset_resize (bset
, bindex
);
332 /* Create a new element. */
333 elt
= ebitset_elt_calloc ();
334 ebitset_elt_add (bset
, elt
, eindex
);
335 EBITSET_CACHE_SET (bset
, eindex
);
339 return &ebitset_zero_elts
[0];
347 /* Weed out the zero elements from the elts. */
348 static inline bitset_windex
349 ebitset_weed (bitset bset
)
355 if (EBITSET_ZERO_P (bset
))
358 elts
= EBITSET_ELTS (bset
);
360 for (j
= 0; j
< EBITSET_SIZE (bset
); j
++)
362 ebitset_elt
*elt
= elts
[j
];
366 if (ebitset_elt_zero_p (elt
))
368 ebitset_elt_remove (bset
, j
);
379 /* All the bits are zero. We could shrink the elts.
380 For now just mark BSET as known to be zero. */
381 EBITSET_ZERO_SET (bset
);
384 EBITSET_NONZERO_SET (bset
);
390 /* Set all bits in the bitset to zero. */
392 ebitset_zero (bitset bset
)
397 if (EBITSET_ZERO_P (bset
))
400 elts
= EBITSET_ELTS (bset
);
401 for (j
= 0; j
< EBITSET_SIZE (bset
); j
++)
403 ebitset_elt
*elt
= elts
[j
];
406 ebitset_elt_remove (bset
, j
);
409 /* All the bits are zero. We could shrink the elts.
410 For now just mark BSET as known to be zero. */
411 EBITSET_ZERO_SET (bset
);
416 ebitset_equal_p (bitset dst
, bitset src
)
428 if (EBITSET_SIZE (src
) != EBITSET_SIZE (dst
))
431 selts
= EBITSET_ELTS (src
);
432 delts
= EBITSET_ELTS (dst
);
434 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
437 ebitset_elt
*selt
= selts
[j
];
438 ebitset_elt
*delt
= delts
[j
];
442 if ((selt
&& !delt
) || (!selt
&& delt
))
445 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
446 if (EBITSET_WORDS (selt
)[i
] != EBITSET_WORDS (delt
)[i
])
453 /* Copy bits from bitset SRC to bitset DST. */
455 ebitset_copy_ (bitset dst
, bitset src
)
466 if (BITSET_NBITS_ (dst
) != BITSET_NBITS_ (src
))
467 ebitset_resize (dst
, BITSET_NBITS_ (src
));
469 selts
= EBITSET_ELTS (src
);
470 delts
= EBITSET_ELTS (dst
);
471 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
473 ebitset_elt
*selt
= selts
[j
];
479 tmp
= ebitset_elt_alloc ();
481 memcpy (EBITSET_WORDS (tmp
), EBITSET_WORDS (selt
),
482 sizeof (EBITSET_WORDS (selt
)));
485 EBITSET_NONZERO_SET (dst
);
489 /* Copy bits from bitset SRC to bitset DST. Return true if
490 bitsets different. */
492 ebitset_copy_cmp (bitset dst
, bitset src
)
497 if (EBITSET_ZERO_P (dst
))
499 ebitset_copy_ (dst
, src
);
500 return !EBITSET_ZERO_P (src
);
503 if (ebitset_equal_p (dst
, src
))
506 ebitset_copy_ (dst
, src
);
511 /* Set bit BITNO in bitset DST. */
513 ebitset_set (bitset dst
, bitset_bindex bitno
)
515 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
517 ebitset_elt_find (dst
, bitno
, EBITSET_CREATE
);
519 dst
->b
.cdata
[windex
- dst
->b
.cindex
] |=
520 (bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
);
524 /* Reset bit BITNO in bitset DST. */
526 ebitset_reset (bitset dst
, bitset_bindex bitno
)
528 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
530 if (!ebitset_elt_find (dst
, bitno
, EBITSET_FIND
))
533 dst
->b
.cdata
[windex
- dst
->b
.cindex
] &=
534 ~((bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
));
536 /* If all the data is zero, perhaps we should remove it now...
537 However, there is a good chance that the element will be needed
542 /* Test bit BITNO in bitset SRC. */
544 ebitset_test (bitset src
, bitset_bindex bitno
)
546 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
548 return (ebitset_elt_find (src
, bitno
, EBITSET_FIND
)
549 && ((src
->b
.cdata
[windex
- src
->b
.cindex
]
550 >> (bitno
% BITSET_WORD_BITS
))
556 ebitset_free (bitset bset
)
559 free (EBITSET_ELTS (bset
));
563 /* Find list of up to NUM bits set in BSET starting from and including
564 *NEXT and store in array LIST. Return with actual number of bits
565 found and with *NEXT indicating where search stopped. */
567 ebitset_list_reverse (bitset bset
, bitset_bindex
*list
,
568 bitset_bindex num
, bitset_bindex
*next
)
570 bitset_bindex n_bits
;
572 bitset_bindex rbitno
;
574 bitset_bindex boffset
;
575 bitset_windex windex
;
576 bitset_windex eindex
;
577 bitset_windex woffset
;
582 if (EBITSET_ZERO_P (bset
))
585 size
= EBITSET_SIZE (bset
);
586 n_bits
= size
* EBITSET_ELT_BITS
;
589 if (rbitno
>= n_bits
)
592 elts
= EBITSET_ELTS (bset
);
594 bitno
= n_bits
- (rbitno
+ 1);
596 windex
= bitno
/ BITSET_WORD_BITS
;
597 eindex
= bitno
/ EBITSET_ELT_BITS
;
598 woffset
= windex
- eindex
* EBITSET_ELT_WORDS
;
600 /* If num is 1, we could speed things up with a binary search
601 of the word of interest. */
604 bcount
= bitno
% BITSET_WORD_BITS
;
605 boffset
= windex
* BITSET_WORD_BITS
;
615 srcp
= EBITSET_WORDS (elt
);
621 word
= srcp
[woffset
] << (BITSET_WORD_BITS
- 1 - bcount
);
623 for (; word
; bcount
--)
625 if (word
& BITSET_MSB
)
627 list
[count
++] = boffset
+ bcount
;
630 *next
= n_bits
- (boffset
+ bcount
);
636 boffset
-= BITSET_WORD_BITS
;
637 bcount
= BITSET_WORD_BITS
- 1;
642 woffset
= EBITSET_ELT_WORDS
- 1;
643 boffset
= eindex
* EBITSET_ELT_BITS
- BITSET_WORD_BITS
;
647 *next
= n_bits
- (boffset
+ 1);
652 /* Find list of up to NUM bits set in BSET starting from and including
653 *NEXT and store in array LIST. Return with actual number of bits
654 found and with *NEXT indicating where search stopped. */
656 ebitset_list (bitset bset
, bitset_bindex
*list
,
657 bitset_bindex num
, bitset_bindex
*next
)
660 bitset_windex windex
;
661 bitset_windex eindex
;
668 if (EBITSET_ZERO_P (bset
))
674 elts
= EBITSET_ELTS (bset
);
675 size
= EBITSET_SIZE (bset
);
676 eindex
= bitno
/ EBITSET_ELT_BITS
;
678 if (bitno
% EBITSET_ELT_BITS
)
680 /* We need to start within an element. This is not very common. */
685 bitset_windex woffset
;
686 bitset_word
*srcp
= EBITSET_WORDS (elt
);
688 windex
= bitno
/ BITSET_WORD_BITS
;
689 woffset
= eindex
* EBITSET_ELT_WORDS
;
691 for (; (windex
- woffset
) < EBITSET_ELT_WORDS
; windex
++)
693 word
= srcp
[windex
- woffset
] >> (bitno
% BITSET_WORD_BITS
);
695 for (; word
; bitno
++)
699 list
[count
++] = bitno
;
708 bitno
= (windex
+ 1) * BITSET_WORD_BITS
;
712 /* Skip to next element. */
716 /* If num is 1, we could speed things up with a binary search
717 of the word of interest. */
719 for (; eindex
< size
; eindex
++)
728 srcp
= EBITSET_WORDS (elt
);
729 windex
= eindex
* EBITSET_ELT_WORDS
;
731 if ((count
+ EBITSET_ELT_BITS
) < num
)
733 /* The coast is clear, plant boot! */
735 #if EBITSET_ELT_WORDS == 2
739 if (!(word
& 0xffff))
749 for (; word
; bitno
++)
752 list
[count
++] = bitno
;
757 bitno
= windex
* BITSET_WORD_BITS
;
762 if (!(word
& 0xffff))
767 for (; word
; bitno
++)
770 list
[count
++] = bitno
;
775 bitno
= windex
* BITSET_WORD_BITS
;
777 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, windex
++)
779 bitno
= windex
* BITSET_WORD_BITS
;
784 if (!(word
& 0xffff))
794 for (; word
; bitno
++)
797 list
[count
++] = bitno
;
806 /* Tread more carefully since we need to check
807 if array overflows. */
809 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, windex
++)
811 bitno
= windex
* BITSET_WORD_BITS
;
813 for (word
= srcp
[i
]; word
; bitno
++)
817 list
[count
++] = bitno
;
835 /* Ensure that any unused bits within the last element are clear. */
837 ebitset_unused_clear (bitset dst
)
839 unsigned int last_bit
;
840 bitset_bindex n_bits
;
842 n_bits
= BITSET_NBITS_ (dst
);
843 last_bit
= n_bits
% EBITSET_ELT_BITS
;
847 bitset_windex eindex
;
851 elts
= EBITSET_ELTS (dst
);
853 eindex
= n_bits
/ EBITSET_ELT_BITS
;
858 bitset_windex windex
;
859 bitset_windex woffset
;
860 bitset_word
*srcp
= EBITSET_WORDS (elt
);
862 windex
= n_bits
/ BITSET_WORD_BITS
;
863 woffset
= eindex
* EBITSET_ELT_WORDS
;
865 srcp
[windex
- woffset
] &= ((bitset_word
) 1 << last_bit
) - 1;
867 for (; (windex
- woffset
) < EBITSET_ELT_WORDS
; windex
++)
868 srcp
[windex
- woffset
] = 0;
875 ebitset_ones (bitset dst
)
880 for (j
= 0; j
< EBITSET_SIZE (dst
); j
++)
882 /* Create new elements if they cannot be found. Perhaps
883 we should just add pointers to a ones element? */
885 ebitset_elt_find (dst
, j
* EBITSET_ELT_BITS
, EBITSET_CREATE
);
886 memset (EBITSET_WORDS (elt
), -1, sizeof (EBITSET_WORDS (elt
)));
888 EBITSET_NONZERO_SET (dst
);
889 ebitset_unused_clear (dst
);
894 ebitset_empty_p (bitset dst
)
899 if (EBITSET_ZERO_P (dst
))
902 elts
= EBITSET_ELTS (dst
);
903 for (j
= 0; j
< EBITSET_SIZE (dst
); j
++)
905 ebitset_elt
*elt
= elts
[j
];
909 if (!ebitset_elt_zero_p (elt
))
911 /* Do some weeding as we go. */
912 ebitset_elt_remove (dst
, j
);
916 /* All the bits are zero. We could shrink the elts.
917 For now just mark DST as known to be zero. */
918 EBITSET_ZERO_SET (dst
);
924 ebitset_not (bitset dst
, bitset src
)
931 ebitset_resize (dst
, BITSET_NBITS_ (src
));
933 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
935 /* Create new elements for dst if they cannot be found
936 or substitute zero elements if src elements not found. */
938 ebitset_elt_find (dst
, j
* EBITSET_ELT_BITS
, EBITSET_SUBST
);
940 ebitset_elt_find (dst
, j
* EBITSET_ELT_BITS
, EBITSET_CREATE
);
942 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
943 EBITSET_WORDS (delt
)[i
] = ~EBITSET_WORDS (selt
)[i
];
945 EBITSET_NONZERO_SET (dst
);
946 ebitset_unused_clear (dst
);
950 /* Is DST == DST | SRC? */
952 ebitset_subset_p (bitset dst
, bitset src
)
960 selts
= EBITSET_ELTS (src
);
961 delts
= EBITSET_ELTS (dst
);
963 ssize
= EBITSET_SIZE (src
);
964 dsize
= EBITSET_SIZE (dst
);
966 for (j
= 0; j
< ssize
; j
++)
972 selt
= j
< ssize
? selts
[j
] : 0;
973 delt
= j
< dsize
? delts
[j
] : 0;
979 selt
= &ebitset_zero_elts
[0];
981 delt
= &ebitset_zero_elts
[0];
983 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
984 if (EBITSET_WORDS (delt
)[i
]
985 != (EBITSET_WORDS (selt
)[i
] | EBITSET_WORDS (delt
)[i
]))
992 /* Is DST & SRC == 0? */
994 ebitset_disjoint_p (bitset dst
, bitset src
)
1000 bitset_windex dsize
;
1002 selts
= EBITSET_ELTS (src
);
1003 delts
= EBITSET_ELTS (dst
);
1005 ssize
= EBITSET_SIZE (src
);
1006 dsize
= EBITSET_SIZE (dst
);
1008 for (j
= 0; j
< ssize
; j
++)
1014 selt
= j
< ssize
? selts
[j
] : 0;
1015 delt
= j
< dsize
? delts
[j
] : 0;
1020 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
1021 if ((EBITSET_WORDS (selt
)[i
] & EBITSET_WORDS (delt
)[i
]))
1030 ebitset_op3_cmp (bitset dst
, bitset src1
, bitset src2
, enum bitset_ops op
)
1032 bitset_windex ssize1
;
1033 bitset_windex ssize2
;
1034 bitset_windex dsize
;
1036 ebitset_elts
*selts1
;
1037 ebitset_elts
*selts2
;
1038 ebitset_elts
*delts
;
1042 bool changed
= false;
1046 ebitset_resize (dst
, max (BITSET_NBITS_ (src1
), BITSET_NBITS_ (src2
)));
1048 ssize1
= EBITSET_SIZE (src1
);
1049 ssize2
= EBITSET_SIZE (src2
);
1050 dsize
= EBITSET_SIZE (dst
);
1055 selts1
= EBITSET_ELTS (src1
);
1056 selts2
= EBITSET_ELTS (src2
);
1057 delts
= EBITSET_ELTS (dst
);
1059 for (j
= 0; j
< size
; j
++)
1065 selt1
= j
< ssize1
? selts1
[j
] : 0;
1066 selt2
= j
< ssize2
? selts2
[j
] : 0;
1067 delt
= j
< dsize
? delts
[j
] : 0;
1069 if (!selt1
&& !selt2
)
1074 ebitset_elt_remove (dst
, j
);
1080 selt1
= &ebitset_zero_elts
[0];
1082 selt2
= &ebitset_zero_elts
[0];
1084 delt
= ebitset_elt_calloc ();
1088 srcp1
= EBITSET_WORDS (selt1
);
1089 srcp2
= EBITSET_WORDS (selt2
);
1090 dstp
= EBITSET_WORDS (delt
);
1094 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1096 bitset_word tmp
= *srcp1
++ | *srcp2
++;
1107 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1109 bitset_word tmp
= *srcp1
++ & *srcp2
++;
1120 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1122 bitset_word tmp
= *srcp1
++ ^ *srcp2
++;
1132 case BITSET_OP_ANDN
:
1133 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1135 bitset_word tmp
= *srcp1
++ & ~(*srcp2
++);
1149 if (!ebitset_elt_zero_p (delt
))
1151 ebitset_elt_add (dst
, delt
, j
);
1155 ebitset_elt_free (delt
);
1159 /* If we have elements of DST left over, free them all. */
1160 for (; j
< dsize
; j
++)
1169 ebitset_elt_remove (dst
, j
);
1172 EBITSET_NONZERO_SET (dst
);
1178 ebitset_and_cmp (bitset dst
, bitset src1
, bitset src2
)
1182 if (EBITSET_ZERO_P (src2
))
1185 changed
= EBITSET_ZERO_P (dst
);
1189 else if (EBITSET_ZERO_P (src1
))
1192 changed
= EBITSET_ZERO_P (dst
);
1196 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_AND
);
1201 ebitset_and (bitset dst
, bitset src1
, bitset src2
)
1203 ebitset_and_cmp (dst
, src1
, src2
);
1208 ebitset_andn_cmp (bitset dst
, bitset src1
, bitset src2
)
1212 if (EBITSET_ZERO_P (src2
))
1214 return ebitset_copy_cmp (dst
, src1
);
1216 else if (EBITSET_ZERO_P (src1
))
1219 changed
= EBITSET_ZERO_P (dst
);
1223 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_ANDN
);
1228 ebitset_andn (bitset dst
, bitset src1
, bitset src2
)
1230 ebitset_andn_cmp (dst
, src1
, src2
);
1235 ebitset_or_cmp (bitset dst
, bitset src1
, bitset src2
)
1237 if (EBITSET_ZERO_P (src2
))
1239 return ebitset_copy_cmp (dst
, src1
);
1241 else if (EBITSET_ZERO_P (src1
))
1243 return ebitset_copy_cmp (dst
, src2
);
1245 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_OR
);
1250 ebitset_or (bitset dst
, bitset src1
, bitset src2
)
1252 ebitset_or_cmp (dst
, src1
, src2
);
1257 ebitset_xor_cmp (bitset dst
, bitset src1
, bitset src2
)
1259 if (EBITSET_ZERO_P (src2
))
1261 return ebitset_copy_cmp (dst
, src1
);
1263 else if (EBITSET_ZERO_P (src1
))
1265 return ebitset_copy_cmp (dst
, src2
);
1267 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_XOR
);
1272 ebitset_xor (bitset dst
, bitset src1
, bitset src2
)
1274 ebitset_xor_cmp (dst
, src1
, src2
);
1279 ebitset_copy (bitset dst
, bitset src
)
1281 if (BITSET_COMPATIBLE_ (dst
, src
))
1282 ebitset_copy_ (dst
, src
);
1284 bitset_copy_ (dst
, src
);
1288 /* Vector of operations for linked-list bitsets. */
1289 struct bitset_vtable ebitset_vtable
= {
1316 bitset_andn_or_cmp_
,
1320 ebitset_list_reverse
,
1326 /* Return size of initial structure. */
1328 ebitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED
)
1330 return sizeof (struct ebitset_struct
);
1334 /* Initialize a bitset. */
1337 ebitset_init (bitset bset
, bitset_bindex n_bits
)
1341 bset
->b
.vtable
= &ebitset_vtable
;
1343 bset
->b
.csize
= EBITSET_ELT_WORDS
;
1345 EBITSET_ZERO_SET (bset
);
1347 size
= n_bits
? (n_bits
+ EBITSET_ELT_BITS
- 1) / EBITSET_ELT_BITS
1348 : EBITSET_INITIAL_SIZE
;
1350 EBITSET_ASIZE (bset
) = 0;
1351 EBITSET_ELTS (bset
) = 0;
1352 ebitset_resize (bset
, n_bits
);
1359 ebitset_release_memory (void)
1361 ebitset_free_list
= 0;
1362 if (ebitset_obstack_init
)
1364 ebitset_obstack_init
= false;
1365 obstack_free (&ebitset_obstack
, NULL
);