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