1 /* Functions to support expandable bitsets.
2 Copyright (C) 2002 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.
28 /* This file implements expandable bitsets. These bitsets can be of
29 arbitrary length and are more efficient than arrays of bits for
32 Empty elements are represented by a NULL pointer in the table of
33 element pointers. An alternative is to point to a special zero
34 element. Similarly, we could represent an all 1's element with
35 another special ones element pointer.
37 Bitsets are commonly empty so we need to ensure that this special
38 case is fast. A zero bitset is indicated when cdata is 0. This is
39 conservative since cdata may be non zero and the bitset may still
42 The bitset cache can be disabled either by setting cindex to
43 BITSET_WINDEX_MAX or by setting csize to 0. Here
44 we use the former approach since cindex needs to be updated whenever
49 /* Number of words to use for each element. */
50 #define EBITSET_ELT_WORDS 2
52 /* Number of bits stored in each element. */
53 #define EBITSET_ELT_BITS \
54 ((unsigned) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
56 /* Ebitset element. We use an array of bits. */
57 typedef struct ebitset_elt_struct
61 bitset_word words
[EBITSET_ELT_WORDS
]; /* Bits that are set. */
62 struct ebitset_elt_struct
*next
;
69 typedef ebitset_elt
*ebitset_elts
;
72 /* Number of elements to initially allocate. */
74 #ifndef EBITSET_INITIAL_SIZE
75 #define EBITSET_INITIAL_SIZE 2
78 /* Minimum number of elements to grow table. */
80 #ifndef EBITSET_GROW_SIZE
81 #define EBITSET_GROW_SIZE 4
84 enum ebitset_find_mode
85 { EBITSET_FIND
, EBITSET_CREATE
, EBITSET_SUBST
};
86 typedef int enum_ebitset_find_mode
;
88 static ebitset_elt ebitset_zero_elts
[1]; /* Elements of all zero bits. */
90 /* Obstack to allocate bitset elements from. */
91 static struct obstack ebitset_obstack
;
92 static int ebitset_obstack_init
= 0;
93 static ebitset_elt
*ebitset_free_list
; /* Free list of bitset elements. */
95 static void ebitset_elts_grow
PARAMS ((bitset
, bitset_windex
));
96 static ebitset_elt
*ebitset_elt_alloc
PARAMS ((void));
97 static ebitset_elt
*ebitset_elt_calloc
PARAMS ((void));
98 static void ebitset_elt_add
PARAMS ((bitset
, ebitset_elt
*, bitset_windex
));
99 static void ebitset_elt_remove
PARAMS ((bitset
, bitset_windex
));
100 static void ebitset_elt_free
PARAMS ((ebitset_elt
*));
101 static ebitset_elt
*ebitset_elt_find
PARAMS ((bitset
, bitset_windex
,
102 enum_ebitset_find_mode
));
103 static ebitset_elt
*ebitset_elt_last
PARAMS ((bitset
));
104 static int ebitset_elt_zero_p
PARAMS ((ebitset_elt
*));
106 static bitset_windex ebitset_weed
PARAMS ((bitset
));
107 static void ebitset_zero
PARAMS ((bitset
));
108 static void ebitset_copy_
PARAMS ((bitset
, bitset
));
109 static int ebitset_copy_cmp
PARAMS ((bitset
, bitset
));
110 static void ebitset_set
PARAMS ((bitset
, bitset_bindex
));
111 static void ebitset_reset
PARAMS ((bitset
, bitset_bindex
));
112 static int ebitset_test
PARAMS ((bitset
, bitset_bindex
));
113 static bitset_bindex ebitset_size
PARAMS ((bitset
));
114 static int ebitset_disjoint_p
PARAMS ((bitset
, bitset
));
115 static int ebitset_equal_p
PARAMS ((bitset
, bitset
));
116 static void ebitset_not
PARAMS ((bitset
, bitset
));
117 static int ebitset_subset_p
PARAMS ((bitset
, bitset
));
118 static int ebitset_op3_cmp
PARAMS ((bitset
, bitset
, bitset
, enum_bitset_ops
));
119 static void ebitset_and
PARAMS ((bitset
, bitset
, bitset
));
120 static int ebitset_and_cmp
PARAMS ((bitset
, bitset
, bitset
));
121 static void ebitset_andn
PARAMS ((bitset
, bitset
, bitset
));
122 static int ebitset_andn_cmp
PARAMS ((bitset
, bitset
, bitset
));
123 static void ebitset_or
PARAMS ((bitset
, bitset
, bitset
));
124 static int ebitset_or_cmp
PARAMS ((bitset
, bitset
, bitset
));
125 static void ebitset_xor
PARAMS ((bitset
, bitset
, bitset
));
126 static int ebitset_xor_cmp
PARAMS ((bitset
, bitset
, bitset
));
127 static void ebitset_copy
PARAMS ((bitset
, bitset
));
128 static bitset_bindex ebitset_list
PARAMS ((bitset
, bitset_bindex
*,
129 bitset_bindex
, bitset_bindex
*));
130 static bitset_bindex ebitset_list_reverse
131 PARAMS ((bitset
, bitset_bindex
*, bitset_bindex
, bitset_bindex
*));
132 static void ebitset_ones
PARAMS ((bitset
));
133 static int ebitset_empty_p
PARAMS ((bitset
));
134 static void ebitset_free
PARAMS ((bitset
));
136 #define EBITSET_ELTS(BSET) ((BSET)->e.elts)
137 #define EBITSET_SIZE(BSET) ((BSET)->e.size)
139 #define EBITSET_NEXT(ELT) ((ELT)->u.next)
140 #define EBITSET_WORDS(ELT) ((ELT)->u.words)
142 /* Disable bitset cache and mark BSET as being zero. */
143 #define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
146 #define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
148 /* Disable bitset cache and mark BSET as being possibly non-zero. */
149 #define EBITSET_NONZERO_SET(BSET) \
150 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
152 /* A conservative estimate of whether the bitset is zero.
153 This is non-zero only if we know for sure that the bitset is zero. */
154 #define EBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0)
156 /* Enable cache to point to element with table index EINDEX.
157 The element must exist. */
158 #define EBITSET_CACHE_SET(BSET, EINDEX) \
159 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \
160 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX]))
163 /* Grow the expandable table for BSET by SIZE elements. */
165 ebitset_elts_grow (bset
, size
)
169 bitset_windex oldsize
;
170 bitset_windex newsize
;
172 oldsize
= EBITSET_SIZE (bset
);
173 newsize
= oldsize
+ size
;
175 if (BITSET_SIZE_MAX
/ sizeof (ebitset_elt
*) < newsize
)
178 EBITSET_ELTS (bset
) = xrealloc (EBITSET_ELTS (bset
),
179 newsize
* sizeof (ebitset_elt
*));
180 EBITSET_SIZE (bset
) = newsize
;
182 memset (EBITSET_ELTS (bset
) + oldsize
, 0, size
* sizeof (ebitset_elt
*));
186 /* Allocate a ebitset element. The bits are not cleared. */
187 static inline ebitset_elt
*
192 if (ebitset_free_list
!= 0)
194 elt
= ebitset_free_list
;
195 ebitset_free_list
= EBITSET_NEXT (elt
);
199 if (!ebitset_obstack_init
)
201 ebitset_obstack_init
= 1;
203 /* Let particular systems override the size of a chunk. */
205 #ifndef OBSTACK_CHUNK_SIZE
206 #define OBSTACK_CHUNK_SIZE 0
209 /* Let them override the alloc and free routines too. */
211 #ifndef OBSTACK_CHUNK_ALLOC
212 #define OBSTACK_CHUNK_ALLOC xmalloc
215 #ifndef OBSTACK_CHUNK_FREE
216 #define OBSTACK_CHUNK_FREE free
219 #if !defined(__GNUC__) || (__GNUC__ < 2)
220 #define __alignof__(type) 0
223 obstack_specify_allocation (&ebitset_obstack
, OBSTACK_CHUNK_SIZE
,
224 __alignof__ (ebitset_elt
),
225 (void *(*)PARAMS ((long)))
227 (void (*)PARAMS ((void *)))
231 /* Perhaps we should add a number of new elements to the free
233 elt
= (ebitset_elt
*) obstack_alloc (&ebitset_obstack
,
234 sizeof (ebitset_elt
));
241 /* Allocate a ebitset element. The bits are cleared. */
242 static inline ebitset_elt
*
243 ebitset_elt_calloc ()
247 elt
= ebitset_elt_alloc ();
248 memset (EBITSET_WORDS (elt
), 0, sizeof (EBITSET_WORDS (elt
)));
254 ebitset_elt_free (elt
)
257 EBITSET_NEXT (elt
) = ebitset_free_list
;
258 ebitset_free_list
= elt
;
262 /* Remove element with index EINDEX from bitset BSET. */
264 ebitset_elt_remove (bset
, eindex
)
266 bitset_windex eindex
;
271 elts
= EBITSET_ELTS (bset
);
276 ebitset_elt_free (elt
);
280 /* Add ELT into elts at index EINDEX of bitset BSET. */
282 ebitset_elt_add (bset
, elt
, eindex
)
285 bitset_windex eindex
;
289 elts
= EBITSET_ELTS (bset
);
290 /* Assume that the elts entry not allocated. */
295 /* Return nonzero if all bits in an element are zero. */
297 ebitset_elt_zero_p (elt
)
302 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
303 if (EBITSET_WORDS (elt
)[i
])
311 ebitset_elt_find (bset
, windex
, mode
)
313 bitset_windex windex
;
314 enum_ebitset_find_mode mode
;
318 bitset_windex eindex
;
321 eindex
= windex
/ EBITSET_ELT_WORDS
;
323 elts
= EBITSET_ELTS (bset
);
324 size
= EBITSET_SIZE (bset
);
328 if ((elt
= elts
[eindex
]))
330 if (EBITSET_WORDS (elt
) == bset
->b
.cdata
)
333 EBITSET_CACHE_SET (bset
, eindex
);
338 /* The element could not be found. */
350 extra
= eindex
- size
+ 1;
352 /* We need to expand the table by EXTRA elements. It may be
353 better with large bitsets to grow the number of
354 elements by some fraction of the current size otherwise
355 we can spend a lot of time slowly increasing the size of the
357 if (extra
< EBITSET_GROW_SIZE
)
358 extra
= EBITSET_GROW_SIZE
;
360 ebitset_elts_grow (bset
, extra
);
363 /* Create a new element. */
364 elt
= ebitset_elt_calloc ();
365 ebitset_elt_add (bset
, elt
, eindex
);
366 EBITSET_CACHE_SET (bset
, eindex
);
370 return &ebitset_zero_elts
[0];
378 static inline ebitset_elt
*
379 ebitset_elt_last (bset
)
384 elts
= EBITSET_ELTS (bset
);
386 /* Assume that have at least one element in elts. */
387 return elts
[EBITSET_SIZE (bset
) - 1];
391 /* Weed out the zero elements from the elts. */
392 static inline bitset_windex
400 if (EBITSET_ZERO_P (bset
))
403 elts
= EBITSET_ELTS (bset
);
405 for (j
= 0; j
< EBITSET_SIZE (bset
); j
++)
407 ebitset_elt
*elt
= elts
[j
];
411 if (elt
&& ebitset_elt_zero_p (elt
))
413 ebitset_elt_remove (bset
, j
);
424 /* All the bits are zero. We could shrink the elts.
425 For now just mark BSET as known to be zero. */
426 EBITSET_ZERO_SET (bset
);
429 EBITSET_NONZERO_SET (bset
);
435 /* Set all bits in the bitset to zero. */
443 if (EBITSET_ZERO_P (bset
))
446 elts
= EBITSET_ELTS (bset
);
447 for (j
= 0; j
< EBITSET_SIZE (bset
); j
++)
449 ebitset_elt
*elt
= elts
[j
];
452 ebitset_elt_remove (bset
, j
);
455 /* All the bits are zero. We could shrink the elts.
456 For now just mark BSET as known to be zero. */
457 EBITSET_ZERO_SET (bset
);
462 ebitset_equal_p (dst
, src
)
476 if (EBITSET_SIZE (src
) != EBITSET_SIZE (dst
))
479 selts
= EBITSET_ELTS (src
);
480 delts
= EBITSET_ELTS (dst
);
482 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
485 ebitset_elt
*selt
= selts
[j
];
486 ebitset_elt
*delt
= delts
[j
];
490 if ((selt
&& !delt
) || (!selt
&& delt
))
493 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
494 if (EBITSET_WORDS (selt
)[i
] != EBITSET_WORDS (delt
)[i
])
501 /* Copy bits from bitset SRC to bitset DST. */
503 ebitset_copy_ (dst
, src
)
516 if (EBITSET_SIZE (dst
) < EBITSET_SIZE (src
))
517 ebitset_elts_grow (dst
, EBITSET_SIZE (src
) - EBITSET_SIZE (dst
));
519 selts
= EBITSET_ELTS (src
);
520 delts
= EBITSET_ELTS (dst
);
521 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
523 ebitset_elt
*selt
= selts
[j
];
529 tmp
= ebitset_elt_alloc ();
531 memcpy (EBITSET_WORDS (tmp
), EBITSET_WORDS (selt
),
532 sizeof (EBITSET_WORDS (selt
)));
535 EBITSET_NONZERO_SET (dst
);
539 /* Copy bits from bitset SRC to bitset DST. Return non-zero if
540 bitsets different. */
542 ebitset_copy_cmp (dst
, src
)
549 if (EBITSET_ZERO_P (dst
))
551 ebitset_copy_ (dst
, src
);
552 return !EBITSET_ZERO_P (src
);
555 if (ebitset_equal_p (dst
, src
))
558 ebitset_copy_ (dst
, src
);
563 /* Return size in bits of bitset SRC. */
568 /* Return current size of bitset in bits. */
569 return EBITSET_SIZE (src
) * EBITSET_ELT_BITS
;
573 /* Set bit BITNO in bitset DST. */
575 ebitset_set (dst
, bitno
)
579 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
581 ebitset_elt_find (dst
, windex
, EBITSET_CREATE
);
583 dst
->b
.cdata
[windex
- dst
->b
.cindex
] |=
584 (bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
);
588 /* Reset bit BITNO in bitset DST. */
590 ebitset_reset (dst
, bitno
)
594 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
596 if (!ebitset_elt_find (dst
, windex
, EBITSET_FIND
))
599 dst
->b
.cdata
[windex
- dst
->b
.cindex
] &=
600 ~((bitset_word
) 1 << (bitno
% BITSET_WORD_BITS
));
602 /* If all the data is zero, perhaps we should remove it now...
603 However, there is a good chance that the element will be needed
608 /* Test bit BITNO in bitset SRC. */
610 ebitset_test (src
, bitno
)
614 bitset_windex windex
= bitno
/ BITSET_WORD_BITS
;
616 if (!ebitset_elt_find (src
, windex
, EBITSET_FIND
))
620 cdata
[windex
- src
->b
.cindex
] >> (bitno
% BITSET_WORD_BITS
)) & 1;
629 free (EBITSET_ELTS (bset
));
633 /* Find list of up to NUM bits set in BSET starting from and including
634 *NEXT and store in array LIST. Return with actual number of bits
635 found and with *NEXT indicating where search stopped. */
637 ebitset_list_reverse (bset
, list
, num
, next
)
643 bitset_bindex n_bits
;
645 bitset_bindex rbitno
;
647 bitset_bindex boffset
;
648 bitset_windex windex
;
649 bitset_windex eindex
;
650 bitset_windex woffset
;
655 if (EBITSET_ZERO_P (bset
))
658 size
= EBITSET_SIZE (bset
);
659 n_bits
= size
* EBITSET_ELT_BITS
;
662 if (rbitno
>= n_bits
)
665 elts
= EBITSET_ELTS (bset
);
667 bitno
= n_bits
- (rbitno
+ 1);
669 windex
= bitno
/ BITSET_WORD_BITS
;
670 eindex
= bitno
/ EBITSET_ELT_BITS
;
671 woffset
= windex
- eindex
* EBITSET_ELT_WORDS
;
673 /* If num is 1, we could speed things up with a binary search
674 of the word of interest. */
677 bcount
= bitno
% BITSET_WORD_BITS
;
678 boffset
= windex
* BITSET_WORD_BITS
;
688 srcp
= EBITSET_WORDS (elt
);
694 word
= srcp
[woffset
] << (BITSET_WORD_BITS
- 1 - bcount
);
696 for (; word
; bcount
--)
698 if (word
& BITSET_MSB
)
700 list
[count
++] = boffset
+ bcount
;
703 *next
= n_bits
- (boffset
+ bcount
);
709 boffset
-= BITSET_WORD_BITS
;
710 bcount
= BITSET_WORD_BITS
- 1;
715 woffset
= EBITSET_ELT_WORDS
- 1;
716 boffset
= eindex
* EBITSET_ELT_BITS
- BITSET_WORD_BITS
;
720 *next
= n_bits
- (boffset
+ 1);
725 /* Find list of up to NUM bits set in BSET starting from and including
726 *NEXT and store in array LIST. Return with actual number of bits
727 found and with *NEXT indicating where search stopped. */
729 ebitset_list (bset
, list
, num
, next
)
736 bitset_windex windex
;
737 bitset_windex eindex
;
744 if (EBITSET_ZERO_P (bset
))
750 elts
= EBITSET_ELTS (bset
);
751 size
= EBITSET_SIZE (bset
);
752 eindex
= bitno
/ EBITSET_ELT_BITS
;
754 if (bitno
% EBITSET_ELT_BITS
)
756 /* We need to start within an element. This is not very common. */
761 bitset_windex woffset
;
762 bitset_word
*srcp
= EBITSET_WORDS (elt
);
764 windex
= bitno
/ BITSET_WORD_BITS
;
765 woffset
= eindex
* EBITSET_ELT_WORDS
;
767 for (; (windex
- woffset
) < EBITSET_ELT_WORDS
; windex
++)
769 word
= srcp
[windex
- woffset
] >> (bitno
% BITSET_WORD_BITS
);
771 for (; word
; bitno
++)
775 list
[count
++] = bitno
;
784 bitno
= (windex
+ 1) * BITSET_WORD_BITS
;
788 /* Skip to next element. */
792 /* If num is 1, we could speed things up with a binary search
793 of the word of interest. */
795 for (; eindex
< size
; eindex
++)
804 srcp
= EBITSET_WORDS (elt
);
805 windex
= eindex
* EBITSET_ELT_WORDS
;
807 if ((count
+ EBITSET_ELT_BITS
) < num
)
809 /* The coast is clear, plant boot! */
811 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, windex
++)
813 bitno
= windex
* BITSET_WORD_BITS
;
818 if (!(word
& 0xffff))
828 for (; word
; bitno
++)
831 list
[count
++] = bitno
;
839 /* Tread more carefully since we need to check
840 if array overflows. */
842 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, windex
++)
844 bitno
= windex
* BITSET_WORD_BITS
;
846 for (word
= srcp
[i
]; word
; bitno
++)
850 list
[count
++] = bitno
;
876 for (j
= 0; j
< EBITSET_SIZE (dst
); j
++)
878 /* Create new elements if they cannot be found. Perhaps
879 we should just add pointers to a ones element. */
881 ebitset_elt_find (dst
, j
* EBITSET_ELT_WORDS
, EBITSET_CREATE
);
882 memset (EBITSET_WORDS (elt
), -1, sizeof (EBITSET_WORDS (elt
)));
884 EBITSET_NONZERO_SET (dst
);
889 ebitset_empty_p (dst
)
892 return !ebitset_weed (dst
);
897 ebitset_not (dst
, src
)
906 for (j
= 0; j
< EBITSET_SIZE (src
); j
++)
908 /* Create new elements for dst if they cannot be found
909 or substitute zero elements if src elements not found. */
911 ebitset_elt_find (dst
, j
* EBITSET_ELT_WORDS
, EBITSET_SUBST
);
913 ebitset_elt_find (dst
, j
* EBITSET_ELT_WORDS
, EBITSET_CREATE
);
915 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
916 EBITSET_WORDS (delt
)[i
] = ~EBITSET_WORDS (selt
)[i
];
918 EBITSET_NONZERO_SET (dst
);
922 /* Return 1 if DST == DST | SRC. */
924 ebitset_subset_p (dst
, src
)
934 selts
= EBITSET_ELTS (src
);
935 delts
= EBITSET_ELTS (dst
);
937 ssize
= EBITSET_SIZE (src
);
938 dsize
= EBITSET_SIZE (dst
);
940 for (j
= 0; j
< ssize
; j
++)
946 selt
= j
< ssize
? selts
[j
] : 0;
947 delt
= j
< dsize
? delts
[j
] : 0;
953 selt
= &ebitset_zero_elts
[0];
955 delt
= &ebitset_zero_elts
[0];
957 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
958 if (EBITSET_WORDS (delt
)[i
]
959 != (EBITSET_WORDS (selt
)[i
] | EBITSET_WORDS (delt
)[i
]))
966 /* Return 1 if DST & SRC == 0. */
968 ebitset_disjoint_p (dst
, src
)
978 selts
= EBITSET_ELTS (src
);
979 delts
= EBITSET_ELTS (dst
);
981 ssize
= EBITSET_SIZE (src
);
982 dsize
= EBITSET_SIZE (dst
);
984 for (j
= 0; j
< ssize
; j
++)
990 selt
= j
< ssize
? selts
[j
] : 0;
991 delt
= j
< dsize
? delts
[j
] : 0;
996 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++)
997 if ((EBITSET_WORDS (selt
)[i
] & EBITSET_WORDS (delt
)[i
]))
1006 ebitset_op3_cmp (dst
, src1
, src2
, op
)
1012 bitset_windex ssize1
;
1013 bitset_windex ssize2
;
1014 bitset_windex dsize
;
1016 ebitset_elts
*selts1
;
1017 ebitset_elts
*selts2
;
1018 ebitset_elts
*delts
;
1026 ssize1
= EBITSET_SIZE (src1
);
1027 ssize2
= EBITSET_SIZE (src2
);
1028 dsize
= EBITSET_SIZE (dst
);
1034 ebitset_elts_grow (dst
, size
- dsize
);
1036 selts1
= EBITSET_ELTS (src1
);
1037 selts2
= EBITSET_ELTS (src2
);
1038 delts
= EBITSET_ELTS (dst
);
1040 for (j
= 0; j
< size
; j
++)
1046 selt1
= j
< ssize1
? selts1
[j
] : 0;
1047 selt2
= j
< ssize2
? selts2
[j
] : 0;
1048 delt
= j
< dsize
? delts
[j
] : 0;
1050 if (!selt1
&& !selt2
)
1055 ebitset_elt_remove (dst
, j
);
1061 selt1
= &ebitset_zero_elts
[0];
1063 selt2
= &ebitset_zero_elts
[0];
1065 delt
= ebitset_elt_calloc ();
1069 srcp1
= EBITSET_WORDS (selt1
);
1070 srcp2
= EBITSET_WORDS (selt2
);
1071 dstp
= EBITSET_WORDS (delt
);
1075 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1077 bitset_word tmp
= *srcp1
++ | *srcp2
++;
1088 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1090 bitset_word tmp
= *srcp1
++ & *srcp2
++;
1101 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1103 bitset_word tmp
= *srcp1
++ ^ *srcp2
++;
1113 case BITSET_OP_ANDN
:
1114 for (i
= 0; i
< EBITSET_ELT_WORDS
; i
++, dstp
++)
1116 bitset_word tmp
= *srcp1
++ & ~(*srcp2
++);
1130 if (!ebitset_elt_zero_p (delt
))
1132 ebitset_elt_add (dst
, delt
, j
);
1136 ebitset_elt_free (delt
);
1140 /* If we have elements of DST left over, free them all. */
1141 for (; j
< dsize
; j
++)
1150 ebitset_elt_remove (dst
, j
);
1153 EBITSET_NONZERO_SET (dst
);
1159 ebitset_and (dst
, src1
, src2
)
1164 ebitset_and_cmp (dst
, src1
, src2
);
1169 ebitset_and_cmp (dst
, src1
, src2
)
1176 if (EBITSET_ZERO_P (src2
))
1179 changed
= EBITSET_ZERO_P (dst
);
1183 else if (EBITSET_ZERO_P (src1
))
1186 changed
= EBITSET_ZERO_P (dst
);
1190 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_AND
);
1195 ebitset_andn (dst
, src1
, src2
)
1200 ebitset_andn_cmp (dst
, src1
, src2
);
1205 ebitset_andn_cmp (dst
, src1
, 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_or (dst
, src1
, src2
)
1233 ebitset_or_cmp (dst
, src1
, src2
);
1238 ebitset_or_cmp (dst
, src1
, src2
)
1243 if (EBITSET_ZERO_P (src2
))
1245 return ebitset_copy_cmp (dst
, src1
);
1247 else if (EBITSET_ZERO_P (src1
))
1249 return ebitset_copy_cmp (dst
, src2
);
1251 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_OR
);
1256 ebitset_xor (dst
, src1
, src2
)
1261 ebitset_xor_cmp (dst
, src1
, src2
);
1266 ebitset_xor_cmp (dst
, src1
, src2
)
1271 if (EBITSET_ZERO_P (src2
))
1273 return ebitset_copy_cmp (dst
, src1
);
1275 else if (EBITSET_ZERO_P (src1
))
1277 return ebitset_copy_cmp (dst
, src2
);
1279 return ebitset_op3_cmp (dst
, src1
, src2
, BITSET_OP_XOR
);
1284 ebitset_copy (dst
, src
)
1288 if (BITSET_COMPATIBLE_ (dst
, src
))
1289 ebitset_copy_ (dst
, src
);
1291 bitset_copy_ (dst
, src
);
1295 /* Vector of operations for linked-list bitsets. */
1296 struct bitset_vtable ebitset_vtable
= {
1322 bitset_andn_or_cmp_
,
1326 ebitset_list_reverse
,
1332 /* Return size of initial structure. */
1334 ebitset_bytes (n_bits
)
1335 bitset_bindex n_bits ATTRIBUTE_UNUSED
;
1337 return sizeof (struct ebitset_struct
);
1341 /* Initialize a bitset. */
1344 ebitset_init (bset
, n_bits
)
1346 bitset_bindex n_bits
;
1350 bset
->b
.vtable
= &ebitset_vtable
;
1352 bset
->b
.csize
= EBITSET_ELT_WORDS
;
1354 EBITSET_ZERO_SET (bset
);
1356 size
= n_bits
? (n_bits
+ EBITSET_ELT_BITS
- 1) / EBITSET_ELT_BITS
1357 : EBITSET_INITIAL_SIZE
;
1359 EBITSET_SIZE (bset
) = 0;
1360 EBITSET_ELTS (bset
) = 0;
1361 ebitset_elts_grow (bset
, size
);
1368 ebitset_release_memory ()
1370 ebitset_free_list
= 0;
1371 if (ebitset_obstack_init
)
1373 ebitset_obstack_init
= 0;
1374 obstack_free (&ebitset_obstack
, NULL
);