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