]> git.saurik.com Git - bison.git/blame - lib/ebitset.c
Typo.
[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
c837b828
PE
581 dst->b.cdata[windex - dst->b.cindex] |=
582 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
7086e707
AD
583}
584
585
586/* Reset bit BITNO in bitset DST. */
587static void
588ebitset_reset (dst, bitno)
589 bitset dst;
590 bitset_bindex bitno;
591{
345cea78 592 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 593
345cea78 594 if (!ebitset_elt_find (dst, windex, EBITSET_FIND))
ef017502 595 return;
7086e707 596
c837b828
PE
597 dst->b.cdata[windex - dst->b.cindex] &=
598 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707 599
ef017502 600 /* If all the data is zero, perhaps we should remove it now...
345cea78 601 However, there is a good chance that the element will be needed
7086e707
AD
602 again soon. */
603}
604
605
606/* Test bit BITNO in bitset SRC. */
607static int
608ebitset_test (src, bitno)
609 bitset src;
610 bitset_bindex bitno;
611{
345cea78 612 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 613
345cea78 614 if (!ebitset_elt_find (src, windex, EBITSET_FIND))
7086e707
AD
615 return 0;
616
ef017502 617 return (src->b.
345cea78 618 cdata[windex - src->b.cindex] >> (bitno % BITSET_WORD_BITS)) & 1;
7086e707
AD
619}
620
621
622static void
623ebitset_free (bset)
624 bitset bset;
625{
626 ebitset_zero (bset);
627 free (EBITSET_ELTS (bset));
628}
629
630
631/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
632 *NEXT and store in array LIST. Return with actual number of bits
633 found and with *NEXT indicating where search stopped. */
7086e707
AD
634static int
635ebitset_reverse_list (bset, list, num, next)
636 bitset bset;
637 bitset_bindex *list;
638 bitset_bindex num;
639 bitset_bindex *next;
640{
641 bitset_bindex n_bits;
642 bitset_bindex bitno;
643 bitset_bindex rbitno;
345cea78
AD
644 unsigned int bcount;
645 bitset_bindex boffset;
7086e707 646 bitset_windex windex;
345cea78
AD
647 unsigned int eindex;
648 bitset_windex woffset;
7086e707
AD
649 bitset_bindex count;
650 bitset_windex size;
7086e707
AD
651 ebitset_elts *elts;
652
ef017502 653 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
654 return 0;
655
656 size = EBITSET_SIZE (bset);
657 n_bits = size * EBITSET_ELT_BITS;
658 rbitno = *next;
659
660 if (rbitno >= n_bits)
ef017502 661 return 0;
7086e707
AD
662
663 elts = EBITSET_ELTS (bset);
664
665 bitno = n_bits - (rbitno + 1);
666
345cea78 667 windex = bitno / BITSET_WORD_BITS;
7086e707 668 eindex = bitno / EBITSET_ELT_BITS;
345cea78 669 woffset = windex - eindex * EBITSET_ELT_WORDS;
7086e707
AD
670
671 /* If num is 1, we could speed things up with a binary search
672 of the word of interest. */
673
674 count = 0;
345cea78
AD
675 bcount = bitno % BITSET_WORD_BITS;
676 boffset = windex * BITSET_WORD_BITS;
7086e707 677
c837b828 678 do
7086e707
AD
679 {
680 ebitset_elt *elt;
7086e707
AD
681
682 elt = elts[eindex];
c837b828 683 if (elt)
7086e707 684 {
c837b828
PE
685 bitset_word *srcp;
686
687 srcp = EBITSET_WORDS (elt);
7086e707 688
c837b828 689 do
7086e707 690 {
c837b828
PE
691 bitset_word word;
692
693 word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
694
695 for (; word; bcount--)
7086e707 696 {
c837b828 697 if (word & BITSET_MSB)
7086e707 698 {
c837b828
PE
699 list[count++] = boffset + bcount;
700 if (count >= num)
701 {
702 *next = n_bits - (boffset + bcount);
703 return count;
704 }
7086e707 705 }
c837b828 706 word <<= 1;
7086e707 707 }
c837b828
PE
708
709 boffset -= BITSET_WORD_BITS;
710 bcount = BITSET_WORD_BITS - 1;
7086e707 711 }
c837b828
PE
712 while (woffset--);
713
714 woffset = EBITSET_ELT_WORDS;
7086e707
AD
715 }
716
c837b828 717 boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS;
7086e707 718 }
c837b828 719 while (eindex--);
7086e707 720
345cea78 721 *next = n_bits - (boffset + 1);
7086e707
AD
722 return count;
723}
724
725
726/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
727 *NEXT and store in array LIST. Return with actual number of bits
728 found and with *NEXT indicating where search stopped. */
7086e707
AD
729static int
730ebitset_list (bset, list, num, next)
731 bitset bset;
732 bitset_bindex *list;
733 bitset_bindex num;
734 bitset_bindex *next;
735{
736 bitset_bindex bitno;
345cea78 737 bitset_windex windex;
7086e707
AD
738 unsigned int eindex;
739 bitset_bindex count;
740 bitset_windex size;
741 ebitset_elt *elt;
742 bitset_word word;
743 ebitset_elts *elts;
744
ef017502 745 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
746 return 0;
747
748 bitno = *next;
749 count = 0;
750
751 elts = EBITSET_ELTS (bset);
752 size = EBITSET_SIZE (bset);
753 eindex = bitno / EBITSET_ELT_BITS;
754
755 if (bitno % EBITSET_ELT_BITS)
756 {
757 /* We need to start within an element. This is not very common. */
758
759 elt = elts[eindex];
760 if (elt)
761 {
345cea78 762 bitset_windex woffset;
7086e707
AD
763 bitset_word *srcp = EBITSET_WORDS (elt);
764
345cea78
AD
765 windex = bitno / BITSET_WORD_BITS;
766 woffset = eindex / EBITSET_ELT_WORDS;
7086e707 767
345cea78 768 for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
7086e707 769 {
345cea78 770 word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);
7086e707
AD
771
772 for (; word; bitno++)
773 {
774 if (word & 1)
775 {
776 list[count++] = bitno;
777 if (count >= num)
778 {
779 *next = bitno + 1;
780 return count;
781 }
782 }
783 word >>= 1;
784 }
345cea78 785 bitno = (windex + 1) * BITSET_WORD_BITS;
7086e707
AD
786 }
787 }
788
789 /* Skip to next element. */
790 eindex++;
791 }
792
793 /* If num is 1, we could speed things up with a binary search
794 of the word of interest. */
795
796 for (; eindex < size; eindex++)
797 {
798 int i;
7086e707
AD
799 bitset_word *srcp;
800
801 elt = elts[eindex];
802 if (!elt)
803 continue;
804
805 srcp = EBITSET_WORDS (elt);
345cea78 806 windex = eindex * EBITSET_ELT_WORDS;
7086e707
AD
807
808 if ((count + EBITSET_ELT_BITS) < num)
809 {
810 /* The coast is clear, plant boot! */
811
345cea78 812 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 813 {
345cea78 814 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
815
816 word = srcp[i];
817 if (word)
818 {
ef017502 819 if (!(word & 0xffff))
7086e707
AD
820 {
821 word >>= 16;
822 bitno += 16;
823 }
ef017502 824 if (!(word & 0xff))
7086e707
AD
825 {
826 word >>= 8;
827 bitno += 8;
828 }
829 for (; word; bitno++)
830 {
831 if (word & 1)
832 list[count++] = bitno;
833 word >>= 1;
834 }
835 }
836 }
837 }
838 else
839 {
840 /* Tread more carefully since we need to check
841 if array overflows. */
842
345cea78 843 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 844 {
345cea78 845 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
846
847 for (word = srcp[i]; word; bitno++)
848 {
849 if (word & 1)
850 {
851 list[count++] = bitno;
852 if (count >= num)
853 {
854 *next = bitno + 1;
855 return count;
856 }
857 }
858 word >>= 1;
859 }
860 }
861 }
862 }
863
864 *next = bitno;
865 return count;
866}
867
868
869static int
870ebitset_op1 (dst, op)
871 bitset dst;
872 enum bitset_ops op;
873{
874 bitset_windex j;
875 ebitset_elt *elt;
876
877 switch (op)
878 {
ef017502 879 case BITSET_OP_ZERO:
7086e707
AD
880 ebitset_zero (dst);
881 return 1;
882
ef017502 883 case BITSET_OP_ONES:
7086e707
AD
884 for (j = 0; j < EBITSET_SIZE (dst); j++)
885 {
886 /* Create new elements if they cannot be found. Perhaps
ef017502
AD
887 we should just add pointers to a ones element. */
888 elt =
889 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
c837b828 890 memset (EBITSET_WORDS (elt), -1, sizeof (EBITSET_WORDS (elt)));
7086e707
AD
891 }
892 break;
893
ef017502
AD
894 case BITSET_OP_EMPTY_P:
895 return !ebitset_weed (dst);
7086e707
AD
896
897 default:
898 abort ();
899 }
900
901 EBITSET_NONZERO_SET (dst);
902 return 1;
903}
904
905
906static int
907ebitset_op2 (dst, src, op)
908 bitset dst;
909 bitset src;
910 enum bitset_ops op;
911{
912 ebitset_elt *selt;
913 ebitset_elt *delt;
914 unsigned int i;
915 bitset_windex j;
916
917 switch (op)
918 {
ef017502 919 case BITSET_OP_COPY:
7086e707
AD
920 ebitset_copy (dst, src);
921 break;
922
ef017502 923 case BITSET_OP_NOT:
7086e707
AD
924 for (j = 0; j < EBITSET_SIZE (src); j++)
925 {
926 /* Create new elements for dst if they cannot be found
927 or substitute zero elements if src elements not found. */
ef017502
AD
928 selt =
929 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_SUBST);
930 delt =
931 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
7086e707
AD
932
933 for (i = 0; i < EBITSET_ELT_WORDS; i++)
934 EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
935 }
936 break;
937
ef017502
AD
938 /* Return 1 if DST == SRC. */
939 case BITSET_OP_EQUAL_P:
7086e707
AD
940 return ebitset_equal_p (dst, src);
941
942 /* Return 1 if DST == DST | SRC. */
ef017502 943 case BITSET_OP_SUBSET_P:
7086e707
AD
944 {
945 ebitset_elts *selts;
946 ebitset_elts *delts;
947 bitset_windex ssize;
948 bitset_windex dsize;
949
950 selts = EBITSET_ELTS (src);
951 delts = EBITSET_ELTS (dst);
952
953 ssize = EBITSET_SIZE (src);
954 dsize = EBITSET_SIZE (dst);
955
956 for (j = 0; j < ssize; j++)
957 {
7086e707
AD
958 selt = j < ssize ? selts[j] : 0;
959 delt = j < dsize ? delts[j] : 0;
960
ef017502 961 if (!selt && !delt)
7086e707
AD
962 continue;
963
964 if (!selt)
965 selt = &ebitset_zero_elts[0];
966 if (!delt)
967 delt = &ebitset_zero_elts[0];
968
969 for (i = 0; i < EBITSET_ELT_WORDS; i++)
970 if (EBITSET_WORDS (delt)[i]
971 != (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
972 return 0;
973 }
974 return 1;
975 }
976 break;
977
ef017502
AD
978 /* Return 1 if DST & SRC == 0. */
979 case BITSET_OP_DISJOINT_P:
980 {
981 ebitset_elts *selts;
982 ebitset_elts *delts;
983 bitset_windex ssize;
984 bitset_windex dsize;
985
986 selts = EBITSET_ELTS (src);
987 delts = EBITSET_ELTS (dst);
988
989 ssize = EBITSET_SIZE (src);
990 dsize = EBITSET_SIZE (dst);
991
992 for (j = 0; j < ssize; j++)
993 {
ef017502
AD
994 selt = j < ssize ? selts[j] : 0;
995 delt = j < dsize ? delts[j] : 0;
996
345cea78 997 if (!selt || !delt)
ef017502
AD
998 continue;
999
ef017502
AD
1000 for (i = 0; i < EBITSET_ELT_WORDS; i++)
1001 if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
1002 return 0;
1003 }
1004 return 1;
1005 }
1006 break;
1007
7086e707
AD
1008 default:
1009 abort ();
1010 }
1011
1012 EBITSET_NONZERO_SET (dst);
1013 return 1;
1014}
1015
1016
1017static int
1018ebitset_op3 (dst, src1, src2, op)
1019 bitset dst;
1020 bitset src1;
1021 bitset src2;
1022 enum bitset_ops op;
1023{
1024 bitset_windex ssize1;
1025 bitset_windex ssize2;
1026 bitset_windex dsize;
1027 bitset_windex size;
1028 ebitset_elts *selts1;
1029 ebitset_elts *selts2;
1030 ebitset_elts *delts;
1031 bitset_word *srcp1;
1032 bitset_word *srcp2;
1033 bitset_word *dstp;
1034 int changed = 0;
1035 unsigned int i;
1036 bitset_windex j;
1037
1038 /* Fast track common, simple cases. */
ef017502 1039 if (EBITSET_OP_ZERO_P (src2))
7086e707 1040 {
ef017502 1041 if (op == BITSET_OP_AND)
7086e707
AD
1042 {
1043 ebitset_weed (dst);
ef017502 1044 changed = EBITSET_OP_ZERO_P (dst);
7086e707
AD
1045 ebitset_zero (dst);
1046 return changed;
1047 }
ef017502
AD
1048 else if (op == BITSET_OP_ANDN || op == BITSET_OP_OR
1049 || op == BITSET_OP_XOR)
7086e707
AD
1050 {
1051 return ebitset_copy_compare (dst, src1);
1052 }
1053 }
ef017502 1054 else if (EBITSET_OP_ZERO_P (src1))
7086e707 1055 {
ef017502 1056 if (op == BITSET_OP_AND || op == BITSET_OP_ANDN)
7086e707
AD
1057 {
1058 ebitset_weed (dst);
ef017502 1059 changed = EBITSET_OP_ZERO_P (dst);
7086e707
AD
1060 ebitset_zero (dst);
1061 return changed;
1062 }
ef017502 1063 else if (op == BITSET_OP_OR || op == BITSET_OP_XOR)
7086e707
AD
1064 {
1065 return ebitset_copy_compare (dst, src2);
1066 }
1067 }
1068
1069 ssize1 = EBITSET_SIZE (src1);
1070 ssize2 = EBITSET_SIZE (src2);
1071 dsize = EBITSET_SIZE (dst);
1072 size = ssize1;
1073 if (size < ssize2)
1074 size = ssize2;
1075
1076 if (size > dsize)
ef017502 1077 ebitset_elts_grow (dst, size - dsize);
7086e707
AD
1078
1079 selts1 = EBITSET_ELTS (src1);
1080 selts2 = EBITSET_ELTS (src2);
1081 delts = EBITSET_ELTS (dst);
1082
1083 for (j = 0; j < size; j++)
1084 {
1085 ebitset_elt *selt1;
1086 ebitset_elt *selt2;
1087 ebitset_elt *delt;
1088
1089 selt1 = j < ssize1 ? selts1[j] : 0;
1090 selt2 = j < ssize2 ? selts2[j] : 0;
1091 delt = j < dsize ? delts[j] : 0;
1092
ef017502 1093 if (!selt1 && !selt2)
7086e707
AD
1094 {
1095 if (delt)
1096 {
1097 changed = 1;
1098 ebitset_elt_remove (dst, j);
1099 }
1100 continue;
1101 }
1102
1103 if (!selt1)
1104 selt1 = &ebitset_zero_elts[0];
1105 if (!selt2)
1106 selt2 = &ebitset_zero_elts[0];
1107 if (!delt)
1108 delt = ebitset_elt_calloc ();
1109 else
1110 delts[j] = 0;
1111
1112 srcp1 = EBITSET_WORDS (selt1);
1113 srcp2 = EBITSET_WORDS (selt2);
1114 dstp = EBITSET_WORDS (delt);
1115 switch (op)
1116 {
ef017502 1117 case BITSET_OP_OR:
7086e707
AD
1118 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1119 {
1120 bitset_word tmp = *srcp1++ | *srcp2++;
1121
1122 if (*dstp != tmp)
1123 {
1124 changed = 1;
1125 *dstp = tmp;
1126 }
1127 }
1128 break;
1129
ef017502 1130 case BITSET_OP_AND:
7086e707
AD
1131 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1132 {
1133 bitset_word tmp = *srcp1++ & *srcp2++;
1134
1135 if (*dstp != tmp)
1136 {
1137 changed = 1;
1138 *dstp = tmp;
1139 }
1140 }
1141 break;
1142
ef017502 1143 case BITSET_OP_XOR:
7086e707
AD
1144 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1145 {
1146 bitset_word tmp = *srcp1++ ^ *srcp2++;
1147
1148 if (*dstp != tmp)
1149 {
1150 changed = 1;
1151 *dstp = tmp;
1152 }
1153 }
1154 break;
1155
ef017502 1156 case BITSET_OP_ANDN:
7086e707
AD
1157 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1158 {
1159 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1160
1161 if (*dstp != tmp)
1162 {
1163 changed = 1;
1164 *dstp = tmp;
1165 }
1166 }
1167 break;
1168
7086e707
AD
1169 default:
1170 abort ();
1171 }
1172
ef017502 1173 if (!ebitset_elt_zero_p (delt))
7086e707
AD
1174 {
1175 ebitset_elt_add (dst, delt, j);
1176 }
1177 else
1178 {
1179 ebitset_elt_free (delt);
1180 }
1181 }
1182
1183 /* If we have elements of DST left over, free them all. */
1184 for (; j < dsize; j++)
1185 {
1186 ebitset_elt *delt;
1187
1188 changed = 1;
1189
1190 delt = delts[j];
1191
1192 if (delt)
1193 ebitset_elt_remove (dst, j);
1194 }
1195
1196 EBITSET_NONZERO_SET (dst);
1197 return changed;
1198}
1199
1200
7086e707 1201/* Vector of operations for linked-list bitsets. */
ef017502
AD
1202struct bitset_ops_struct ebitset_ops = {
1203 ebitset_set,
1204 ebitset_reset,
1205 ebitset_test,
1206 ebitset_size,
1207 ebitset_op1,
1208 ebitset_op2,
1209 ebitset_op3,
1210 bitset_op4,
1211 ebitset_list,
1212 ebitset_reverse_list,
1213 ebitset_free,
1214 BITSET_TABLE
1215};
7086e707
AD
1216
1217
1218/* Return size of initial structure. */
1219int
1220ebitset_bytes (n_bits)
1221 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1222{
1223 return sizeof (struct bitset_struct);
1224}
1225
1226
1227/* Initialize a bitset. */
1228
1229bitset
1230ebitset_init (bset, n_bits)
1231 bitset bset;
1232 bitset_bindex n_bits;
1233{
1234 unsigned int size;
1235
ef017502 1236 bset->b.ops = &ebitset_ops;
7086e707 1237
ef017502 1238 bset->b.csize = EBITSET_ELT_WORDS;
7086e707 1239
ef017502 1240 EBITSET_OP_ZERO_SET (bset);
7086e707
AD
1241
1242 size = n_bits ? (n_bits + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS
1243 : EBITSET_INITIAL_SIZE;
1244
1245 EBITSET_SIZE (bset) = 0;
1246 EBITSET_ELTS (bset) = 0;
1247 ebitset_elts_grow (bset, size);
1248
1249 return bset;
1250}
1251
1252
1253void
1254ebitset_release_memory ()
1255{
1256 ebitset_free_list = 0;
1257 if (ebitset_obstack_init)
1258 {
1259 ebitset_obstack_init = 0;
1260 obstack_free (&ebitset_obstack, NULL);
1261 }
1262}