]> git.saurik.com Git - bison.git/blame - lib/ebitset.c
(bitset_stats_init): enum_bitset_type -> enum bitset_type.
[bison.git] / lib / ebitset.c
CommitLineData
ef017502 1/* Functions to support expandable bitsets.
7086e707
AD
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
ef017502
AD
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.
7086e707 9
ef017502
AD
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.
7086e707 14
ef017502
AD
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
345cea78
AD
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18*/
7086e707
AD
19
20#ifdef HAVE_CONFIG_H
21#include "config.h"
22#endif
23
345cea78 24#include "ebitset.h"
7086e707
AD
25#include "obstack.h"
26#include <stdlib.h>
27
ef017502 28/* This file implements expandable bitsets. These bitsets can be of
7086e707
AD
29 arbitrary length and are more efficient than arrays of bits for
30 large sparse sets.
31
7086e707
AD
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.
36
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
ef017502 40 be zero.
7086e707
AD
41
42 The bitset cache can be disabled either by setting cindex to
52f8da14 43 BITSET_WINDEX_MAX or by setting csize to 0. Here
7086e707 44 we use the former approach since cindex needs to be updated whenever
ef017502 45 cdata is changed.
7086e707
AD
46*/
47
ef017502
AD
48
49/* Number of words to use for each element. */
ef017502 50#define EBITSET_ELT_WORDS 2
ef017502
AD
51
52/* Number of bits stored in each element. */
53#define EBITSET_ELT_BITS \
54 ((unsigned) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
55
56/* Ebitset element. We use an array of bits. */
57typedef struct ebitset_elt_struct
58{
59 union
60 {
61 bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */
62 struct ebitset_elt_struct *next;
63 }
64 u;
65}
66ebitset_elt;
67
68
69typedef ebitset_elt *ebitset_elts;
70
6aa452a6 71
7086e707 72/* Number of elements to initially allocate. */
ef017502 73
7086e707
AD
74#ifndef EBITSET_INITIAL_SIZE
75#define EBITSET_INITIAL_SIZE 2
76#endif
77
78/* Minimum number of elements to grow table. */
ef017502 79
7086e707
AD
80#ifndef EBITSET_GROW_SIZE
81#define EBITSET_GROW_SIZE 4
82#endif
83
ef017502
AD
84enum ebitset_find_mode
85 { EBITSET_FIND, EBITSET_CREATE, EBITSET_SUBST };
3e0a8627 86typedef int enum_ebitset_find_mode;
7086e707
AD
87
88static ebitset_elt ebitset_zero_elts[1]; /* Elements of all zero bits. */
89
90/* Obstack to allocate bitset elements from. */
91static struct obstack ebitset_obstack;
92static int ebitset_obstack_init = 0;
ef017502 93static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
7086e707 94
52f8da14 95static void ebitset_elts_grow PARAMS ((bitset, bitset_windex));
7086e707
AD
96static ebitset_elt *ebitset_elt_alloc PARAMS ((void));
97static ebitset_elt *ebitset_elt_calloc PARAMS ((void));
52f8da14
PE
98static void ebitset_elt_add PARAMS ((bitset, ebitset_elt *, bitset_windex));
99static void ebitset_elt_remove PARAMS ((bitset, bitset_windex));
7086e707
AD
100static void ebitset_elt_free PARAMS ((ebitset_elt *));
101static ebitset_elt *ebitset_elt_find PARAMS ((bitset, bitset_windex,
3e0a8627 102 enum_ebitset_find_mode));
7086e707
AD
103static ebitset_elt *ebitset_elt_last PARAMS ((bitset));
104static int ebitset_elt_zero_p PARAMS ((ebitset_elt *));
105
52f8da14 106static bitset_windex ebitset_weed PARAMS ((bitset));
ef017502 107static void ebitset_zero PARAMS ((bitset));
6aa452a6
AD
108static void ebitset_copy_ PARAMS ((bitset, bitset));
109static int ebitset_copy_cmp PARAMS ((bitset, bitset));
ef017502
AD
110static void ebitset_set PARAMS ((bitset, bitset_bindex));
111static void ebitset_reset PARAMS ((bitset, bitset_bindex));
112static int ebitset_test PARAMS ((bitset, bitset_bindex));
52f8da14 113static bitset_bindex ebitset_size PARAMS ((bitset));
6aa452a6
AD
114static int ebitset_disjoint_p PARAMS ((bitset, bitset));
115static int ebitset_equal_p PARAMS ((bitset, bitset));
116static void ebitset_not PARAMS ((bitset, bitset));
117static int ebitset_subset_p PARAMS ((bitset, bitset));
3e0a8627
PE
118static int ebitset_op3_cmp PARAMS ((bitset, bitset, bitset, enum_bitset_ops));
119static void ebitset_and PARAMS ((bitset, bitset, bitset));
6aa452a6 120static int ebitset_and_cmp PARAMS ((bitset, bitset, bitset));
3e0a8627 121static void ebitset_andn PARAMS ((bitset, bitset, bitset));
6aa452a6 122static int ebitset_andn_cmp PARAMS ((bitset, bitset, bitset));
3e0a8627 123static void ebitset_or PARAMS ((bitset, bitset, bitset));
6aa452a6 124static int ebitset_or_cmp PARAMS ((bitset, bitset, bitset));
3e0a8627 125static void ebitset_xor PARAMS ((bitset, bitset, bitset));
6aa452a6 126static int ebitset_xor_cmp PARAMS ((bitset, bitset, bitset));
3e0a8627 127static void ebitset_copy PARAMS ((bitset, bitset));
52f8da14
PE
128static bitset_bindex ebitset_list PARAMS ((bitset, bitset_bindex *,
129 bitset_bindex, bitset_bindex *));
130static bitset_bindex ebitset_list_reverse
ef017502 131PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
3e0a8627
PE
132static void ebitset_ones PARAMS ((bitset));
133static int ebitset_empty_p PARAMS ((bitset));
ef017502
AD
134static void ebitset_free PARAMS ((bitset));
135
136#define EBITSET_ELTS(BSET) ((BSET)->e.elts)
137#define EBITSET_SIZE(BSET) ((BSET)->e.size)
7086e707
AD
138
139#define EBITSET_NEXT(ELT) ((ELT)->u.next)
140#define EBITSET_WORDS(ELT) ((ELT)->u.words)
141
142/* Disable bitset cache and mark BSET as being zero. */
52f8da14 143#define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
ef017502 144 (BSET)->b.cdata = 0)
7086e707 145
52f8da14 146#define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
7086e707
AD
147
148/* Disable bitset cache and mark BSET as being possibly non-zero. */
149#define EBITSET_NONZERO_SET(BSET) \
ef017502 150 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
7086e707
AD
151
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. */
6aa452a6 154#define EBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0)
7086e707 155
ef017502 156/* Enable cache to point to element with table index EINDEX.
7086e707
AD
157 The element must exist. */
158#define EBITSET_CACHE_SET(BSET, EINDEX) \
ef017502
AD
159 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \
160 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX]))
7086e707
AD
161
162
163/* Grow the expandable table for BSET by SIZE elements. */
164static void
165ebitset_elts_grow (bset, size)
ef017502 166 bitset bset;
52f8da14 167 bitset_windex size;
7086e707 168{
52f8da14
PE
169 bitset_windex oldsize;
170 bitset_windex newsize;
7086e707
AD
171
172 oldsize = EBITSET_SIZE (bset);
173 newsize = oldsize + size;
174
52f8da14
PE
175 if (BITSET_SIZE_MAX / sizeof (ebitset_elt *) < newsize)
176 xalloc_die ();
177
7086e707 178 EBITSET_ELTS (bset) = xrealloc (EBITSET_ELTS (bset),
ef017502 179 newsize * sizeof (ebitset_elt *));
7086e707
AD
180 EBITSET_SIZE (bset) = newsize;
181
182 memset (EBITSET_ELTS (bset) + oldsize, 0, size * sizeof (ebitset_elt *));
183}
184
185
186/* Allocate a ebitset element. The bits are not cleared. */
187static inline ebitset_elt *
188ebitset_elt_alloc ()
189{
190 ebitset_elt *elt;
191
192 if (ebitset_free_list != 0)
193 {
194 elt = ebitset_free_list;
195 ebitset_free_list = EBITSET_NEXT (elt);
196 }
197 else
198 {
7086e707
AD
199 if (!ebitset_obstack_init)
200 {
201 ebitset_obstack_init = 1;
202
203 /* Let particular systems override the size of a chunk. */
ef017502 204
7086e707
AD
205#ifndef OBSTACK_CHUNK_SIZE
206#define OBSTACK_CHUNK_SIZE 0
207#endif
ef017502 208
7086e707 209 /* Let them override the alloc and free routines too. */
ef017502 210
7086e707
AD
211#ifndef OBSTACK_CHUNK_ALLOC
212#define OBSTACK_CHUNK_ALLOC xmalloc
213#endif
ef017502 214
7086e707
AD
215#ifndef OBSTACK_CHUNK_FREE
216#define OBSTACK_CHUNK_FREE free
217#endif
218
219#if !defined(__GNUC__) || (__GNUC__ < 2)
220#define __alignof__(type) 0
221#endif
222
223 obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE,
224 __alignof__ (ebitset_elt),
ef017502
AD
225 (void *(*)PARAMS ((long)))
226 OBSTACK_CHUNK_ALLOC,
227 (void (*)PARAMS ((void *)))
228 OBSTACK_CHUNK_FREE);
7086e707
AD
229 }
230
231 /* Perhaps we should add a number of new elements to the free
ef017502 232 list. */
7086e707
AD
233 elt = (ebitset_elt *) obstack_alloc (&ebitset_obstack,
234 sizeof (ebitset_elt));
235 }
236
237 return elt;
238}
239
240
613f5e1a 241/* Allocate a ebitset element. The bits are cleared. */
7086e707
AD
242static inline ebitset_elt *
243ebitset_elt_calloc ()
244{
245 ebitset_elt *elt;
246
247 elt = ebitset_elt_alloc ();
248 memset (EBITSET_WORDS (elt), 0, sizeof (EBITSET_WORDS (elt)));
249 return elt;
250}
251
252
253static inline void
254ebitset_elt_free (elt)
255 ebitset_elt *elt;
256{
257 EBITSET_NEXT (elt) = ebitset_free_list;
258 ebitset_free_list = elt;
259}
260
261
262/* Remove element with index EINDEX from bitset BSET. */
263static inline void
264ebitset_elt_remove (bset, eindex)
265 bitset bset;
52f8da14 266 bitset_windex eindex;
7086e707
AD
267{
268 ebitset_elts *elts;
269 ebitset_elt *elt;
270
271 elts = EBITSET_ELTS (bset);
272
273 elt = elts[eindex];
274
275 elts[eindex] = 0;
276 ebitset_elt_free (elt);
277}
278
279
280/* Add ELT into elts at index EINDEX of bitset BSET. */
281static inline void
282ebitset_elt_add (bset, elt, eindex)
283 bitset bset;
284 ebitset_elt *elt;
52f8da14 285 bitset_windex eindex;
7086e707
AD
286{
287 ebitset_elts *elts;
288
289 elts = EBITSET_ELTS (bset);
290 /* Assume that the elts entry not allocated. */
291 elts[eindex] = elt;
292}
293
294
295/* Return nonzero if all bits in an element are zero. */
296static inline int
297ebitset_elt_zero_p (elt)
298 ebitset_elt *elt;
299{
300 int i;
301
302 for (i = 0; i < EBITSET_ELT_WORDS; i++)
303 if (EBITSET_WORDS (elt)[i])
304 return 0;
305
306 return 1;
307}
308
309
310static ebitset_elt *
345cea78 311ebitset_elt_find (bset, windex, mode)
7086e707 312 bitset bset;
345cea78 313 bitset_windex windex;
3e0a8627 314 enum_ebitset_find_mode mode;
7086e707
AD
315{
316 ebitset_elt *elt;
317 bitset_windex size;
52f8da14 318 bitset_windex eindex;
7086e707
AD
319 ebitset_elts *elts;
320
345cea78 321 eindex = windex / EBITSET_ELT_WORDS;
7086e707
AD
322
323 elts = EBITSET_ELTS (bset);
324 size = EBITSET_SIZE (bset);
325
326 if (eindex < size)
327 {
7086e707
AD
328 if ((elt = elts[eindex]))
329 {
ef017502 330 if (EBITSET_WORDS (elt) == bset->b.cdata)
7086e707
AD
331 return elt;
332
333 EBITSET_CACHE_SET (bset, eindex);
334 return elt;
335 }
336 }
337
338 /* The element could not be found. */
339
340 switch (mode)
341 {
342 case EBITSET_FIND:
343 return 0;
344
345 case EBITSET_CREATE:
346 if (eindex >= size)
347 {
52f8da14 348 bitset_windex extra;
7086e707
AD
349
350 extra = eindex - size + 1;
351
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
356 bitset. */
357 if (extra < EBITSET_GROW_SIZE)
358 extra = EBITSET_GROW_SIZE;
359
360 ebitset_elts_grow (bset, extra);
361 }
362
363 /* Create a new element. */
364 elt = ebitset_elt_calloc ();
365 ebitset_elt_add (bset, elt, eindex);
366 EBITSET_CACHE_SET (bset, eindex);
367 return elt;
368
369 case EBITSET_SUBST:
370 return &ebitset_zero_elts[0];
371
372 default:
373 abort ();
374 }
375}
376
377
378static inline ebitset_elt *
379ebitset_elt_last (bset)
380 bitset bset;
381{
382 ebitset_elts *elts;
383
384 elts = EBITSET_ELTS (bset);
385
386 /* Assume that have at least one element in elts. */
387 return elts[EBITSET_SIZE (bset) - 1];
388}
389
390
391/* Weed out the zero elements from the elts. */
52f8da14 392static inline bitset_windex
7086e707
AD
393ebitset_weed (bset)
394 bitset bset;
395{
396 ebitset_elts *elts;
397 bitset_windex j;
52f8da14 398 bitset_windex count;
7086e707 399
6aa452a6 400 if (EBITSET_ZERO_P (bset))
7086e707
AD
401 return 0;
402
403 elts = EBITSET_ELTS (bset);
404 count = 0;
405 for (j = 0; j < EBITSET_SIZE (bset); j++)
406 {
407 ebitset_elt *elt = elts[j];
408
409 if (elt)
410 {
411 if (elt && ebitset_elt_zero_p (elt))
412 {
413 ebitset_elt_remove (bset, j);
414 count++;
415 }
416 }
417 else
418 count++;
419 }
420
421 count = j - count;
422 if (!count)
423 {
ef017502 424 /* All the bits are zero. We could shrink the elts.
7086e707 425 For now just mark BSET as known to be zero. */
6aa452a6 426 EBITSET_ZERO_SET (bset);
7086e707
AD
427 }
428 else
429 EBITSET_NONZERO_SET (bset);
430
ef017502 431 return count;
7086e707
AD
432}
433
434
435/* Set all bits in the bitset to zero. */
436static inline void
437ebitset_zero (bset)
438 bitset bset;
439{
440 ebitset_elts *elts;
441 bitset_windex j;
442
6aa452a6 443 if (EBITSET_ZERO_P (bset))
7086e707
AD
444 return;
445
446 elts = EBITSET_ELTS (bset);
447 for (j = 0; j < EBITSET_SIZE (bset); j++)
448 {
449 ebitset_elt *elt = elts[j];
450
451 if (elt)
452 ebitset_elt_remove (bset, j);
453 }
454
ef017502 455 /* All the bits are zero. We could shrink the elts.
7086e707 456 For now just mark BSET as known to be zero. */
6aa452a6 457 EBITSET_ZERO_SET (bset);
7086e707
AD
458}
459
460
461static inline int
462ebitset_equal_p (dst, src)
463 bitset dst;
464 bitset src;
465{
466 ebitset_elts *selts;
467 ebitset_elts *delts;
468 bitset_windex j;
469
470 if (src == dst)
471 return 1;
472
473 ebitset_weed (dst);
474 ebitset_weed (src);
475
476 if (EBITSET_SIZE (src) != EBITSET_SIZE (dst))
477 return 0;
478
479 selts = EBITSET_ELTS (src);
480 delts = EBITSET_ELTS (dst);
481
482 for (j = 0; j < EBITSET_SIZE (src); j++)
483 {
484 unsigned int i;
485 ebitset_elt *selt = selts[j];
486 ebitset_elt *delt = delts[j];
487
ef017502 488 if (!selt && !delt)
7086e707 489 continue;
ef017502 490 if ((selt && !delt) || (!selt && delt))
7086e707
AD
491 return 0;
492
493 for (i = 0; i < EBITSET_ELT_WORDS; i++)
494 if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
495 return 0;
496 }
497 return 1;
498}
499
500
501/* Copy bits from bitset SRC to bitset DST. */
502static inline void
6aa452a6 503ebitset_copy_ (dst, src)
7086e707
AD
504 bitset dst;
505 bitset src;
506{
507 ebitset_elts *selts;
508 ebitset_elts *delts;
509 bitset_windex j;
510
511 if (src == dst)
512 return;
513
514 ebitset_zero (dst);
515
516 if (EBITSET_SIZE (dst) < EBITSET_SIZE (src))
517 ebitset_elts_grow (dst, EBITSET_SIZE (src) - EBITSET_SIZE (dst));
518
519 selts = EBITSET_ELTS (src);
520 delts = EBITSET_ELTS (dst);
521 for (j = 0; j < EBITSET_SIZE (src); j++)
522 {
523 ebitset_elt *selt = selts[j];
524
525 if (selt)
526 {
527 ebitset_elt *tmp;
528
529 tmp = ebitset_elt_alloc ();
530 delts[j] = tmp;
531 memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
532 sizeof (EBITSET_WORDS (selt)));
533 }
534 }
535 EBITSET_NONZERO_SET (dst);
536}
537
538
539/* Copy bits from bitset SRC to bitset DST. Return non-zero if
540 bitsets different. */
541static inline int
6aa452a6 542ebitset_copy_cmp (dst, src)
7086e707
AD
543 bitset dst;
544 bitset src;
545{
546 if (src == dst)
547 return 0;
548
6aa452a6 549 if (EBITSET_ZERO_P (dst))
7086e707 550 {
6aa452a6
AD
551 ebitset_copy_ (dst, src);
552 return !EBITSET_ZERO_P (src);
7086e707
AD
553 }
554
555 if (ebitset_equal_p (dst, src))
556 return 0;
557
6aa452a6 558 ebitset_copy_ (dst, src);
7086e707
AD
559 return 1;
560}
561
562
563/* Return size in bits of bitset SRC. */
52f8da14 564static bitset_bindex
7086e707
AD
565ebitset_size (src)
566 bitset src;
567{
568 /* Return current size of bitset in bits. */
569 return EBITSET_SIZE (src) * EBITSET_ELT_BITS;
570}
571
572
573/* Set bit BITNO in bitset DST. */
574static void
575ebitset_set (dst, bitno)
576 bitset dst;
577 bitset_bindex bitno;
578{
345cea78 579 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 580
345cea78 581 ebitset_elt_find (dst, windex, EBITSET_CREATE);
7086e707 582
c837b828
PE
583 dst->b.cdata[windex - dst->b.cindex] |=
584 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
7086e707
AD
585}
586
587
588/* Reset bit BITNO in bitset DST. */
589static void
590ebitset_reset (dst, bitno)
591 bitset dst;
592 bitset_bindex bitno;
593{
345cea78 594 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 595
345cea78 596 if (!ebitset_elt_find (dst, windex, EBITSET_FIND))
ef017502 597 return;
7086e707 598
c837b828
PE
599 dst->b.cdata[windex - dst->b.cindex] &=
600 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707 601
ef017502 602 /* If all the data is zero, perhaps we should remove it now...
345cea78 603 However, there is a good chance that the element will be needed
7086e707
AD
604 again soon. */
605}
606
607
608/* Test bit BITNO in bitset SRC. */
609static int
610ebitset_test (src, bitno)
611 bitset src;
612 bitset_bindex bitno;
613{
345cea78 614 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 615
345cea78 616 if (!ebitset_elt_find (src, windex, EBITSET_FIND))
7086e707
AD
617 return 0;
618
ef017502 619 return (src->b.
345cea78 620 cdata[windex - src->b.cindex] >> (bitno % BITSET_WORD_BITS)) & 1;
7086e707
AD
621}
622
623
624static void
625ebitset_free (bset)
626 bitset bset;
627{
628 ebitset_zero (bset);
629 free (EBITSET_ELTS (bset));
630}
631
632
633/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
634 *NEXT and store in array LIST. Return with actual number of bits
635 found and with *NEXT indicating where search stopped. */
52f8da14 636static bitset_bindex
6aa452a6 637ebitset_list_reverse (bset, list, num, next)
7086e707
AD
638 bitset bset;
639 bitset_bindex *list;
640 bitset_bindex num;
641 bitset_bindex *next;
642{
643 bitset_bindex n_bits;
644 bitset_bindex bitno;
645 bitset_bindex rbitno;
345cea78
AD
646 unsigned int bcount;
647 bitset_bindex boffset;
7086e707 648 bitset_windex windex;
52f8da14 649 bitset_windex eindex;
345cea78 650 bitset_windex woffset;
7086e707
AD
651 bitset_bindex count;
652 bitset_windex size;
7086e707
AD
653 ebitset_elts *elts;
654
6aa452a6 655 if (EBITSET_ZERO_P (bset))
7086e707
AD
656 return 0;
657
658 size = EBITSET_SIZE (bset);
659 n_bits = size * EBITSET_ELT_BITS;
660 rbitno = *next;
661
662 if (rbitno >= n_bits)
ef017502 663 return 0;
7086e707
AD
664
665 elts = EBITSET_ELTS (bset);
666
667 bitno = n_bits - (rbitno + 1);
668
345cea78 669 windex = bitno / BITSET_WORD_BITS;
7086e707 670 eindex = bitno / EBITSET_ELT_BITS;
345cea78 671 woffset = windex - eindex * EBITSET_ELT_WORDS;
7086e707
AD
672
673 /* If num is 1, we could speed things up with a binary search
674 of the word of interest. */
675
676 count = 0;
345cea78
AD
677 bcount = bitno % BITSET_WORD_BITS;
678 boffset = windex * BITSET_WORD_BITS;
7086e707 679
c837b828 680 do
7086e707
AD
681 {
682 ebitset_elt *elt;
6aa452a6
AD
683 bitset_word *srcp;
684
7086e707 685 elt = elts[eindex];
c837b828 686 if (elt)
6aa452a6 687 {
c837b828 688 srcp = EBITSET_WORDS (elt);
6aa452a6 689
c837b828 690 do
7086e707 691 {
c837b828 692 bitset_word word;
6aa452a6 693
c837b828 694 word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
6aa452a6 695
c837b828 696 for (; word; bcount--)
7086e707 697 {
c837b828 698 if (word & BITSET_MSB)
7086e707 699 {
c837b828
PE
700 list[count++] = boffset + bcount;
701 if (count >= num)
702 {
703 *next = n_bits - (boffset + bcount);
704 return count;
705 }
7086e707 706 }
c837b828 707 word <<= 1;
7086e707 708 }
c837b828 709 boffset -= BITSET_WORD_BITS;
6aa452a6 710 bcount = BITSET_WORD_BITS - 1;
7086e707 711 }
c837b828 712 while (woffset--);
7086e707
AD
713 }
714
6aa452a6 715 woffset = EBITSET_ELT_WORDS - 1;
c837b828 716 boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS;
7086e707 717 }
c837b828 718 while (eindex--);
7086e707 719
345cea78 720 *next = n_bits - (boffset + 1);
7086e707
AD
721 return count;
722}
723
724
725/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
726 *NEXT and store in array LIST. Return with actual number of bits
727 found and with *NEXT indicating where search stopped. */
52f8da14 728static bitset_bindex
7086e707
AD
729ebitset_list (bset, list, num, next)
730 bitset bset;
731 bitset_bindex *list;
732 bitset_bindex num;
733 bitset_bindex *next;
734{
735 bitset_bindex bitno;
345cea78 736 bitset_windex windex;
52f8da14 737 bitset_windex eindex;
7086e707
AD
738 bitset_bindex count;
739 bitset_windex size;
740 ebitset_elt *elt;
741 bitset_word word;
742 ebitset_elts *elts;
743
6aa452a6 744 if (EBITSET_ZERO_P (bset))
7086e707
AD
745 return 0;
746
747 bitno = *next;
748 count = 0;
749
750 elts = EBITSET_ELTS (bset);
751 size = EBITSET_SIZE (bset);
752 eindex = bitno / EBITSET_ELT_BITS;
753
754 if (bitno % EBITSET_ELT_BITS)
755 {
756 /* We need to start within an element. This is not very common. */
757
758 elt = elts[eindex];
759 if (elt)
760 {
345cea78 761 bitset_windex woffset;
7086e707
AD
762 bitset_word *srcp = EBITSET_WORDS (elt);
763
345cea78 764 windex = bitno / BITSET_WORD_BITS;
5beedd9b 765 woffset = eindex * EBITSET_ELT_WORDS;
7086e707 766
345cea78 767 for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
7086e707 768 {
345cea78 769 word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);
7086e707
AD
770
771 for (; word; bitno++)
772 {
773 if (word & 1)
774 {
775 list[count++] = bitno;
776 if (count >= num)
777 {
778 *next = bitno + 1;
779 return count;
780 }
781 }
782 word >>= 1;
783 }
345cea78 784 bitno = (windex + 1) * BITSET_WORD_BITS;
7086e707
AD
785 }
786 }
787
788 /* Skip to next element. */
789 eindex++;
790 }
791
792 /* If num is 1, we could speed things up with a binary search
793 of the word of interest. */
794
795 for (; eindex < size; eindex++)
796 {
797 int i;
7086e707
AD
798 bitset_word *srcp;
799
800 elt = elts[eindex];
801 if (!elt)
802 continue;
803
804 srcp = EBITSET_WORDS (elt);
345cea78 805 windex = eindex * EBITSET_ELT_WORDS;
7086e707
AD
806
807 if ((count + EBITSET_ELT_BITS) < num)
808 {
809 /* The coast is clear, plant boot! */
810
345cea78 811 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 812 {
345cea78 813 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
814
815 word = srcp[i];
816 if (word)
817 {
ef017502 818 if (!(word & 0xffff))
7086e707
AD
819 {
820 word >>= 16;
821 bitno += 16;
822 }
ef017502 823 if (!(word & 0xff))
7086e707
AD
824 {
825 word >>= 8;
826 bitno += 8;
827 }
828 for (; word; bitno++)
829 {
830 if (word & 1)
831 list[count++] = bitno;
832 word >>= 1;
833 }
834 }
835 }
836 }
837 else
838 {
839 /* Tread more carefully since we need to check
840 if array overflows. */
841
345cea78 842 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 843 {
345cea78 844 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
845
846 for (word = srcp[i]; word; bitno++)
847 {
848 if (word & 1)
849 {
850 list[count++] = bitno;
851 if (count >= num)
852 {
853 *next = bitno + 1;
854 return count;
855 }
856 }
857 word >>= 1;
858 }
859 }
860 }
861 }
862
863 *next = bitno;
864 return count;
865}
866
867
6aa452a6
AD
868static void
869ebitset_ones (dst)
7086e707 870 bitset dst;
7086e707
AD
871{
872 bitset_windex j;
873 ebitset_elt *elt;
874
7086e707 875
6aa452a6
AD
876 for (j = 0; j < EBITSET_SIZE (dst); j++)
877 {
878 /* Create new elements if they cannot be found. Perhaps
879 we should just add pointers to a ones element. */
880 elt =
881 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
882 memset (EBITSET_WORDS (elt), -1, sizeof (EBITSET_WORDS (elt)));
7086e707 883 }
7086e707 884 EBITSET_NONZERO_SET (dst);
7086e707
AD
885}
886
887
888static int
6aa452a6
AD
889ebitset_empty_p (dst)
890 bitset dst;
891{
892 return !ebitset_weed (dst);
893}
894
895
896static void
897ebitset_not (dst, src)
7086e707
AD
898 bitset dst;
899 bitset src;
7086e707 900{
6aa452a6 901 unsigned int i;
7086e707
AD
902 ebitset_elt *selt;
903 ebitset_elt *delt;
7086e707
AD
904 bitset_windex j;
905
6aa452a6 906 for (j = 0; j < EBITSET_SIZE (src); j++)
7086e707 907 {
6aa452a6 908 /* Create new elements for dst if they cannot be found
7086e707 909 or substitute zero elements if src elements not found. */
6aa452a6
AD
910 selt =
911 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_SUBST);
912 delt =
913 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
7086e707 914
6aa452a6
AD
915 for (i = 0; i < EBITSET_ELT_WORDS; i++)
916 EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
917 }
918 EBITSET_NONZERO_SET (dst);
919}
ef017502 920
6aa452a6
AD
921
922/* Return 1 if DST == DST | SRC. */
923static int
924ebitset_subset_p (dst, src)
925 bitset dst;
926 bitset src;
927{
928 bitset_windex j;
929 ebitset_elts *selts;
930 ebitset_elts *delts;
931 bitset_windex ssize;
932 bitset_windex dsize;
933
934 selts = EBITSET_ELTS (src);
935 delts = EBITSET_ELTS (dst);
936
937 ssize = EBITSET_SIZE (src);
938 dsize = EBITSET_SIZE (dst);
939
940 for (j = 0; j < ssize; j++)
941 {
942 unsigned int i;
943 ebitset_elt *selt;
944 ebitset_elt *delt;
945
946 selt = j < ssize ? selts[j] : 0;
947 delt = j < dsize ? delts[j] : 0;
948
949 if (!selt && !delt)
950 continue;
951
952 if (!selt)
953 selt = &ebitset_zero_elts[0];
954 if (!delt)
955 delt = &ebitset_zero_elts[0];
956
957 for (i = 0; i < EBITSET_ELT_WORDS; i++)
958 if (EBITSET_WORDS (delt)[i]
959 != (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
960 return 0;
7086e707 961 }
6aa452a6
AD
962 return 1;
963}
7086e707 964
6aa452a6
AD
965
966/* Return 1 if DST & SRC == 0. */
967static int
968ebitset_disjoint_p (dst, src)
969 bitset dst;
970 bitset src;
971{
972 bitset_windex j;
973 ebitset_elts *selts;
974 ebitset_elts *delts;
975 bitset_windex ssize;
976 bitset_windex dsize;
977
978 selts = EBITSET_ELTS (src);
979 delts = EBITSET_ELTS (dst);
980
981 ssize = EBITSET_SIZE (src);
982 dsize = EBITSET_SIZE (dst);
983
984 for (j = 0; j < ssize; j++)
985 {
986 unsigned int i;
987 ebitset_elt *selt;
988 ebitset_elt *delt;
989
990 selt = j < ssize ? selts[j] : 0;
991 delt = j < dsize ? delts[j] : 0;
992
993 if (!selt || !delt)
994 continue;
995
996 for (i = 0; i < EBITSET_ELT_WORDS; i++)
997 if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
998 return 0;
999 }
7086e707
AD
1000 return 1;
1001}
1002
1003
6aa452a6 1004
7086e707 1005static int
6aa452a6 1006ebitset_op3_cmp (dst, src1, src2, op)
7086e707
AD
1007 bitset dst;
1008 bitset src1;
1009 bitset src2;
3e0a8627 1010 enum_bitset_ops op;
7086e707
AD
1011{
1012 bitset_windex ssize1;
1013 bitset_windex ssize2;
1014 bitset_windex dsize;
1015 bitset_windex size;
1016 ebitset_elts *selts1;
1017 ebitset_elts *selts2;
1018 ebitset_elts *delts;
1019 bitset_word *srcp1;
1020 bitset_word *srcp2;
1021 bitset_word *dstp;
1022 int changed = 0;
1023 unsigned int i;
1024 bitset_windex j;
1025
7086e707
AD
1026 ssize1 = EBITSET_SIZE (src1);
1027 ssize2 = EBITSET_SIZE (src2);
1028 dsize = EBITSET_SIZE (dst);
1029 size = ssize1;
1030 if (size < ssize2)
1031 size = ssize2;
1032
1033 if (size > dsize)
ef017502 1034 ebitset_elts_grow (dst, size - dsize);
7086e707
AD
1035
1036 selts1 = EBITSET_ELTS (src1);
1037 selts2 = EBITSET_ELTS (src2);
1038 delts = EBITSET_ELTS (dst);
1039
1040 for (j = 0; j < size; j++)
1041 {
1042 ebitset_elt *selt1;
1043 ebitset_elt *selt2;
1044 ebitset_elt *delt;
1045
1046 selt1 = j < ssize1 ? selts1[j] : 0;
1047 selt2 = j < ssize2 ? selts2[j] : 0;
1048 delt = j < dsize ? delts[j] : 0;
1049
ef017502 1050 if (!selt1 && !selt2)
7086e707
AD
1051 {
1052 if (delt)
1053 {
1054 changed = 1;
1055 ebitset_elt_remove (dst, j);
1056 }
1057 continue;
1058 }
1059
1060 if (!selt1)
1061 selt1 = &ebitset_zero_elts[0];
1062 if (!selt2)
1063 selt2 = &ebitset_zero_elts[0];
1064 if (!delt)
1065 delt = ebitset_elt_calloc ();
1066 else
1067 delts[j] = 0;
1068
1069 srcp1 = EBITSET_WORDS (selt1);
1070 srcp2 = EBITSET_WORDS (selt2);
1071 dstp = EBITSET_WORDS (delt);
1072 switch (op)
1073 {
ef017502 1074 case BITSET_OP_OR:
7086e707
AD
1075 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1076 {
1077 bitset_word tmp = *srcp1++ | *srcp2++;
1078
1079 if (*dstp != tmp)
1080 {
1081 changed = 1;
1082 *dstp = tmp;
1083 }
1084 }
1085 break;
1086
ef017502 1087 case BITSET_OP_AND:
7086e707
AD
1088 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1089 {
1090 bitset_word tmp = *srcp1++ & *srcp2++;
1091
1092 if (*dstp != tmp)
1093 {
1094 changed = 1;
1095 *dstp = tmp;
1096 }
1097 }
1098 break;
1099
ef017502 1100 case BITSET_OP_XOR:
7086e707
AD
1101 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1102 {
1103 bitset_word tmp = *srcp1++ ^ *srcp2++;
1104
1105 if (*dstp != tmp)
1106 {
1107 changed = 1;
1108 *dstp = tmp;
1109 }
1110 }
1111 break;
1112
ef017502 1113 case BITSET_OP_ANDN:
7086e707
AD
1114 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1115 {
1116 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1117
1118 if (*dstp != tmp)
1119 {
1120 changed = 1;
1121 *dstp = tmp;
1122 }
1123 }
1124 break;
1125
7086e707
AD
1126 default:
1127 abort ();
1128 }
1129
ef017502 1130 if (!ebitset_elt_zero_p (delt))
7086e707
AD
1131 {
1132 ebitset_elt_add (dst, delt, j);
1133 }
1134 else
1135 {
1136 ebitset_elt_free (delt);
1137 }
1138 }
1139
1140 /* If we have elements of DST left over, free them all. */
1141 for (; j < dsize; j++)
1142 {
1143 ebitset_elt *delt;
1144
1145 changed = 1;
1146
1147 delt = delts[j];
1148
1149 if (delt)
1150 ebitset_elt_remove (dst, j);
1151 }
1152
1153 EBITSET_NONZERO_SET (dst);
1154 return changed;
1155}
1156
1157
3e0a8627
PE
1158static void
1159ebitset_and (dst, src1, src2)
1160 bitset dst;
1161 bitset src1;
1162 bitset src2;
1163{
1164 ebitset_and_cmp (dst, src1, src2);
1165}
1166
1167
6aa452a6
AD
1168static int
1169ebitset_and_cmp (dst, src1, src2)
1170 bitset dst;
1171 bitset src1;
1172 bitset src2;
1173{
1174 int changed;
1175
1176 if (EBITSET_ZERO_P (src2))
1177 {
1178 ebitset_weed (dst);
1179 changed = EBITSET_ZERO_P (dst);
1180 ebitset_zero (dst);
1181 return changed;
1182 }
1183 else if (EBITSET_ZERO_P (src1))
1184 {
1185 ebitset_weed (dst);
1186 changed = EBITSET_ZERO_P (dst);
1187 ebitset_zero (dst);
1188 return changed;
1189 }
1190 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_AND);
1191}
1192
1193
3e0a8627
PE
1194static void
1195ebitset_andn (dst, src1, src2)
1196 bitset dst;
1197 bitset src1;
1198 bitset src2;
1199{
1200 ebitset_andn_cmp (dst, src1, src2);
1201}
1202
1203
6aa452a6
AD
1204static int
1205ebitset_andn_cmp (dst, src1, src2)
1206 bitset dst;
1207 bitset src1;
1208 bitset src2;
1209{
1210 int changed;
1211
1212 if (EBITSET_ZERO_P (src2))
1213 {
1214 return ebitset_copy_cmp (dst, src1);
1215 }
1216 else if (EBITSET_ZERO_P (src1))
1217 {
1218 ebitset_weed (dst);
1219 changed = EBITSET_ZERO_P (dst);
1220 ebitset_zero (dst);
1221 return changed;
1222 }
1223 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_ANDN);
1224}
1225
1226
3e0a8627
PE
1227static void
1228ebitset_or (dst, src1, src2)
1229 bitset dst;
1230 bitset src1;
1231 bitset src2;
1232{
1233 ebitset_or_cmp (dst, src1, src2);
1234}
1235
1236
6aa452a6
AD
1237static int
1238ebitset_or_cmp (dst, src1, src2)
1239 bitset dst;
1240 bitset src1;
1241 bitset src2;
1242{
1243 if (EBITSET_ZERO_P (src2))
1244 {
1245 return ebitset_copy_cmp (dst, src1);
1246 }
1247 else if (EBITSET_ZERO_P (src1))
1248 {
1249 return ebitset_copy_cmp (dst, src2);
1250 }
1251 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_OR);
1252}
1253
1254
3e0a8627
PE
1255static void
1256ebitset_xor (dst, src1, src2)
1257 bitset dst;
1258 bitset src1;
1259 bitset src2;
1260{
1261 ebitset_xor_cmp (dst, src1, src2);
1262}
1263
1264
6aa452a6
AD
1265static int
1266ebitset_xor_cmp (dst, src1, src2)
1267 bitset dst;
1268 bitset src1;
1269 bitset src2;
1270{
1271 if (EBITSET_ZERO_P (src2))
1272 {
1273 return ebitset_copy_cmp (dst, src1);
1274 }
1275 else if (EBITSET_ZERO_P (src1))
1276 {
1277 return ebitset_copy_cmp (dst, src2);
1278 }
1279 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_XOR);
1280}
1281
1282
1283static void
1284ebitset_copy (dst, src)
1285 bitset dst;
1286 bitset src;
1287{
1288 if (BITSET_COMPATIBLE_ (dst, src))
1289 ebitset_copy_ (dst, src);
1290 else
1291 bitset_copy_ (dst, src);
1292}
1293
1294
7086e707 1295/* Vector of operations for linked-list bitsets. */
6aa452a6 1296struct bitset_vtable ebitset_vtable = {
ef017502
AD
1297 ebitset_set,
1298 ebitset_reset,
6aa452a6 1299 bitset_toggle_,
ef017502
AD
1300 ebitset_test,
1301 ebitset_size,
6aa452a6
AD
1302 bitset_count_,
1303 ebitset_empty_p,
1304 ebitset_ones,
1305 ebitset_zero,
1306 ebitset_copy,
1307 ebitset_disjoint_p,
1308 ebitset_equal_p,
1309 ebitset_not,
1310 ebitset_subset_p,
3e0a8627 1311 ebitset_and,
6aa452a6 1312 ebitset_and_cmp,
3e0a8627 1313 ebitset_andn,
6aa452a6 1314 ebitset_andn_cmp,
3e0a8627 1315 ebitset_or,
6aa452a6 1316 ebitset_or_cmp,
3e0a8627 1317 ebitset_xor,
6aa452a6 1318 ebitset_xor_cmp,
3e0a8627 1319 bitset_and_or_,
6aa452a6 1320 bitset_and_or_cmp_,
3e0a8627 1321 bitset_andn_or_,
6aa452a6 1322 bitset_andn_or_cmp_,
3e0a8627 1323 bitset_or_and_,
6aa452a6 1324 bitset_or_and_cmp_,
ef017502 1325 ebitset_list,
6aa452a6 1326 ebitset_list_reverse,
ef017502
AD
1327 ebitset_free,
1328 BITSET_TABLE
1329};
7086e707
AD
1330
1331
1332/* Return size of initial structure. */
52f8da14 1333size_t
7086e707
AD
1334ebitset_bytes (n_bits)
1335 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1336{
3e0a8627 1337 return sizeof (struct ebitset_struct);
7086e707
AD
1338}
1339
1340
1341/* Initialize a bitset. */
1342
1343bitset
1344ebitset_init (bset, n_bits)
1345 bitset bset;
1346 bitset_bindex n_bits;
1347{
52f8da14 1348 bitset_windex size;
7086e707 1349
6aa452a6 1350 bset->b.vtable = &ebitset_vtable;
7086e707 1351
ef017502 1352 bset->b.csize = EBITSET_ELT_WORDS;
7086e707 1353
6aa452a6 1354 EBITSET_ZERO_SET (bset);
7086e707
AD
1355
1356 size = n_bits ? (n_bits + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS
1357 : EBITSET_INITIAL_SIZE;
1358
1359 EBITSET_SIZE (bset) = 0;
1360 EBITSET_ELTS (bset) = 0;
1361 ebitset_elts_grow (bset, size);
1362
1363 return bset;
1364}
1365
1366
1367void
1368ebitset_release_memory ()
1369{
1370 ebitset_free_list = 0;
1371 if (ebitset_obstack_init)
1372 {
1373 ebitset_obstack_init = 0;
1374 obstack_free (&ebitset_obstack, NULL);
1375 }
1376}