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