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