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