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