]> git.saurik.com Git - bison.git/blame - lib/ebitset.c
(libbison_a_SOURCES): Add mbswidth.h, mbswidth.c.
[bison.git] / lib / ebitset.c
CommitLineData
ef017502 1/* Functions to support expandable bitsets.
7086e707
AD
2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
ef017502
AD
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
7086e707 9
ef017502
AD
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
7086e707 14
ef017502
AD
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
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>
27
ef017502 28/* This file implements expandable bitsets. These bitsets can be of
7086e707
AD
29 arbitrary length and are more efficient than arrays of bits for
30 large sparse sets.
31
7086e707
AD
32 Empty elements are represented by a NULL pointer in the table of
33 element pointers. An alternative is to point to a special zero
34 element. Similarly, we could represent an all 1's element with
35 another special ones element pointer.
36
37 Bitsets are commonly empty so we need to ensure that this special
38 case is fast. A zero bitset is indicated when cdata is 0. This is
39 conservative since cdata may be non zero and the bitset may still
75f10004 40 be zero.
7086e707
AD
41
42 The bitset cache can be disabled either by setting cindex to
75f10004 43 BITSET_WINDEX_MAX or by setting csize to 0. Here
7086e707 44 we use the former approach since cindex needs to be updated whenever
75f10004 45 cdata is changed.
7086e707
AD
46*/
47
ef017502
AD
48
49/* Number of words to use for each element. */
ef017502 50#define EBITSET_ELT_WORDS 2
ef017502
AD
51
52/* Number of bits stored in each element. */
53#define EBITSET_ELT_BITS \
54 ((unsigned) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
55
56/* Ebitset element. We use an array of bits. */
57typedef struct ebitset_elt_struct
58{
59 union
60 {
61 bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */
62 struct ebitset_elt_struct *next;
63 }
64 u;
65}
66ebitset_elt;
67
68
69typedef ebitset_elt *ebitset_elts;
70
6aa452a6 71
7086e707 72/* Number of elements to initially allocate. */
ef017502 73
7086e707
AD
74#ifndef EBITSET_INITIAL_SIZE
75#define EBITSET_INITIAL_SIZE 2
76#endif
77
78/* Minimum number of elements to grow table. */
ef017502 79
7086e707
AD
80#ifndef EBITSET_GROW_SIZE
81#define EBITSET_GROW_SIZE 4
82#endif
83
ef017502
AD
84enum ebitset_find_mode
85 { EBITSET_FIND, EBITSET_CREATE, EBITSET_SUBST };
7086e707
AD
86
87static ebitset_elt ebitset_zero_elts[1]; /* Elements of all zero bits. */
88
89/* Obstack to allocate bitset elements from. */
90static struct obstack ebitset_obstack;
91static int ebitset_obstack_init = 0;
ef017502 92static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
7086e707 93
ef017502
AD
94#define EBITSET_ELTS(BSET) ((BSET)->e.elts)
95#define EBITSET_SIZE(BSET) ((BSET)->e.size)
7086e707
AD
96
97#define EBITSET_NEXT(ELT) ((ELT)->u.next)
98#define EBITSET_WORDS(ELT) ((ELT)->u.words)
99
100/* Disable bitset cache and mark BSET as being zero. */
52f8da14 101#define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \
75f10004 102 (BSET)->b.cdata = 0)
7086e707 103
52f8da14 104#define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX)
7086e707
AD
105
106/* Disable bitset cache and mark BSET as being possibly non-zero. */
107#define EBITSET_NONZERO_SET(BSET) \
ef017502 108 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
7086e707
AD
109
110/* A conservative estimate of whether the bitset is zero.
111 This is non-zero only if we know for sure that the bitset is zero. */
6aa452a6 112#define EBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0)
7086e707 113
75f10004 114/* Enable cache to point to element with table index EINDEX.
7086e707
AD
115 The element must exist. */
116#define EBITSET_CACHE_SET(BSET, EINDEX) \
ef017502
AD
117 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \
118 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX]))
7086e707
AD
119
120
121/* Grow the expandable table for BSET by SIZE elements. */
122static void
75f10004 123ebitset_elts_grow (bitset bset, bitset_windex size)
7086e707 124{
52f8da14
PE
125 bitset_windex oldsize;
126 bitset_windex newsize;
7086e707
AD
127
128 oldsize = EBITSET_SIZE (bset);
129 newsize = oldsize + size;
130
52f8da14
PE
131 if (BITSET_SIZE_MAX / sizeof (ebitset_elt *) < newsize)
132 xalloc_die ();
133
7086e707 134 EBITSET_ELTS (bset) = xrealloc (EBITSET_ELTS (bset),
ef017502 135 newsize * sizeof (ebitset_elt *));
7086e707
AD
136 EBITSET_SIZE (bset) = newsize;
137
138 memset (EBITSET_ELTS (bset) + oldsize, 0, size * sizeof (ebitset_elt *));
139}
140
141
142/* Allocate a ebitset element. The bits are not cleared. */
143static inline ebitset_elt *
75f10004 144ebitset_elt_alloc (void)
7086e707
AD
145{
146 ebitset_elt *elt;
147
148 if (ebitset_free_list != 0)
149 {
150 elt = ebitset_free_list;
151 ebitset_free_list = EBITSET_NEXT (elt);
152 }
153 else
154 {
7086e707
AD
155 if (!ebitset_obstack_init)
156 {
157 ebitset_obstack_init = 1;
158
159 /* Let particular systems override the size of a chunk. */
ef017502 160
7086e707
AD
161#ifndef OBSTACK_CHUNK_SIZE
162#define OBSTACK_CHUNK_SIZE 0
163#endif
ef017502 164
7086e707 165 /* Let them override the alloc and free routines too. */
ef017502 166
7086e707
AD
167#ifndef OBSTACK_CHUNK_ALLOC
168#define OBSTACK_CHUNK_ALLOC xmalloc
169#endif
ef017502 170
7086e707
AD
171#ifndef OBSTACK_CHUNK_FREE
172#define OBSTACK_CHUNK_FREE free
173#endif
174
175#if !defined(__GNUC__) || (__GNUC__ < 2)
176#define __alignof__(type) 0
177#endif
178
179 obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE,
180 __alignof__ (ebitset_elt),
ef017502
AD
181 (void *(*)PARAMS ((long)))
182 OBSTACK_CHUNK_ALLOC,
183 (void (*)PARAMS ((void *)))
184 OBSTACK_CHUNK_FREE);
7086e707
AD
185 }
186
187 /* Perhaps we should add a number of new elements to the free
ef017502 188 list. */
7086e707
AD
189 elt = (ebitset_elt *) obstack_alloc (&ebitset_obstack,
190 sizeof (ebitset_elt));
191 }
192
193 return elt;
194}
195
196
613f5e1a 197/* Allocate a ebitset element. The bits are cleared. */
7086e707 198static inline ebitset_elt *
75f10004 199ebitset_elt_calloc (void)
7086e707
AD
200{
201 ebitset_elt *elt;
202
203 elt = ebitset_elt_alloc ();
204 memset (EBITSET_WORDS (elt), 0, sizeof (EBITSET_WORDS (elt)));
205 return elt;
206}
207
208
209static inline void
75f10004 210ebitset_elt_free (ebitset_elt *elt)
7086e707
AD
211{
212 EBITSET_NEXT (elt) = ebitset_free_list;
213 ebitset_free_list = elt;
214}
215
216
217/* Remove element with index EINDEX from bitset BSET. */
218static inline void
75f10004 219ebitset_elt_remove (bitset bset, bitset_windex eindex)
7086e707
AD
220{
221 ebitset_elts *elts;
222 ebitset_elt *elt;
223
224 elts = EBITSET_ELTS (bset);
225
226 elt = elts[eindex];
227
228 elts[eindex] = 0;
229 ebitset_elt_free (elt);
230}
231
232
233/* Add ELT into elts at index EINDEX of bitset BSET. */
234static inline void
75f10004 235ebitset_elt_add (bitset bset, ebitset_elt *elt, bitset_windex eindex)
7086e707
AD
236{
237 ebitset_elts *elts;
238
239 elts = EBITSET_ELTS (bset);
240 /* Assume that the elts entry not allocated. */
241 elts[eindex] = elt;
242}
243
244
245/* Return nonzero if all bits in an element are zero. */
246static inline int
75f10004 247ebitset_elt_zero_p (ebitset_elt *elt)
7086e707
AD
248{
249 int i;
250
251 for (i = 0; i < EBITSET_ELT_WORDS; i++)
252 if (EBITSET_WORDS (elt)[i])
253 return 0;
254
255 return 1;
256}
257
258
259static ebitset_elt *
75f10004
PE
260ebitset_elt_find (bitset bset, bitset_windex windex,
261 enum ebitset_find_mode mode)
7086e707
AD
262{
263 ebitset_elt *elt;
264 bitset_windex size;
52f8da14 265 bitset_windex eindex;
7086e707
AD
266 ebitset_elts *elts;
267
345cea78 268 eindex = windex / EBITSET_ELT_WORDS;
7086e707
AD
269
270 elts = EBITSET_ELTS (bset);
271 size = EBITSET_SIZE (bset);
272
273 if (eindex < size)
274 {
7086e707
AD
275 if ((elt = elts[eindex]))
276 {
ef017502 277 if (EBITSET_WORDS (elt) == bset->b.cdata)
7086e707
AD
278 return elt;
279
280 EBITSET_CACHE_SET (bset, eindex);
281 return elt;
282 }
283 }
284
285 /* The element could not be found. */
286
287 switch (mode)
288 {
289 case EBITSET_FIND:
290 return 0;
291
292 case EBITSET_CREATE:
293 if (eindex >= size)
294 {
52f8da14 295 bitset_windex extra;
7086e707
AD
296
297 extra = eindex - size + 1;
298
299 /* We need to expand the table by EXTRA elements. It may be
300 better with large bitsets to grow the number of
301 elements by some fraction of the current size otherwise
302 we can spend a lot of time slowly increasing the size of the
303 bitset. */
304 if (extra < EBITSET_GROW_SIZE)
305 extra = EBITSET_GROW_SIZE;
306
307 ebitset_elts_grow (bset, extra);
308 }
309
310 /* Create a new element. */
311 elt = ebitset_elt_calloc ();
312 ebitset_elt_add (bset, elt, eindex);
313 EBITSET_CACHE_SET (bset, eindex);
314 return elt;
315
316 case EBITSET_SUBST:
317 return &ebitset_zero_elts[0];
318
319 default:
320 abort ();
321 }
322}
323
324
325static inline ebitset_elt *
75f10004 326ebitset_elt_last (bitset bset)
7086e707
AD
327{
328 ebitset_elts *elts;
329
330 elts = EBITSET_ELTS (bset);
331
332 /* Assume that have at least one element in elts. */
333 return elts[EBITSET_SIZE (bset) - 1];
334}
335
336
337/* Weed out the zero elements from the elts. */
52f8da14 338static inline bitset_windex
75f10004 339ebitset_weed (bitset bset)
7086e707
AD
340{
341 ebitset_elts *elts;
342 bitset_windex j;
52f8da14 343 bitset_windex count;
7086e707 344
6aa452a6 345 if (EBITSET_ZERO_P (bset))
7086e707
AD
346 return 0;
347
348 elts = EBITSET_ELTS (bset);
349 count = 0;
350 for (j = 0; j < EBITSET_SIZE (bset); j++)
351 {
352 ebitset_elt *elt = elts[j];
353
354 if (elt)
355 {
356 if (elt && ebitset_elt_zero_p (elt))
357 {
358 ebitset_elt_remove (bset, j);
359 count++;
360 }
361 }
362 else
363 count++;
364 }
365
366 count = j - count;
367 if (!count)
368 {
75f10004 369 /* All the bits are zero. We could shrink the elts.
7086e707 370 For now just mark BSET as known to be zero. */
6aa452a6 371 EBITSET_ZERO_SET (bset);
7086e707
AD
372 }
373 else
374 EBITSET_NONZERO_SET (bset);
375
ef017502 376 return count;
7086e707
AD
377}
378
379
380/* Set all bits in the bitset to zero. */
381static inline void
75f10004 382ebitset_zero (bitset bset)
7086e707
AD
383{
384 ebitset_elts *elts;
385 bitset_windex j;
386
6aa452a6 387 if (EBITSET_ZERO_P (bset))
7086e707
AD
388 return;
389
390 elts = EBITSET_ELTS (bset);
391 for (j = 0; j < EBITSET_SIZE (bset); j++)
392 {
393 ebitset_elt *elt = elts[j];
394
395 if (elt)
396 ebitset_elt_remove (bset, j);
397 }
398
75f10004 399 /* All the bits are zero. We could shrink the elts.
7086e707 400 For now just mark BSET as known to be zero. */
6aa452a6 401 EBITSET_ZERO_SET (bset);
7086e707
AD
402}
403
404
405static inline int
75f10004 406ebitset_equal_p (bitset dst, bitset src)
7086e707
AD
407{
408 ebitset_elts *selts;
409 ebitset_elts *delts;
410 bitset_windex j;
411
412 if (src == dst)
413 return 1;
414
415 ebitset_weed (dst);
416 ebitset_weed (src);
417
418 if (EBITSET_SIZE (src) != EBITSET_SIZE (dst))
419 return 0;
420
421 selts = EBITSET_ELTS (src);
422 delts = EBITSET_ELTS (dst);
423
424 for (j = 0; j < EBITSET_SIZE (src); j++)
425 {
426 unsigned int i;
427 ebitset_elt *selt = selts[j];
428 ebitset_elt *delt = delts[j];
429
ef017502 430 if (!selt && !delt)
7086e707 431 continue;
ef017502 432 if ((selt && !delt) || (!selt && delt))
7086e707
AD
433 return 0;
434
435 for (i = 0; i < EBITSET_ELT_WORDS; i++)
436 if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
437 return 0;
438 }
439 return 1;
440}
441
442
443/* Copy bits from bitset SRC to bitset DST. */
444static inline void
75f10004 445ebitset_copy_ (bitset dst, bitset src)
7086e707
AD
446{
447 ebitset_elts *selts;
448 ebitset_elts *delts;
449 bitset_windex j;
450
451 if (src == dst)
452 return;
453
454 ebitset_zero (dst);
455
456 if (EBITSET_SIZE (dst) < EBITSET_SIZE (src))
457 ebitset_elts_grow (dst, EBITSET_SIZE (src) - EBITSET_SIZE (dst));
458
459 selts = EBITSET_ELTS (src);
460 delts = EBITSET_ELTS (dst);
461 for (j = 0; j < EBITSET_SIZE (src); j++)
462 {
463 ebitset_elt *selt = selts[j];
464
465 if (selt)
466 {
467 ebitset_elt *tmp;
468
469 tmp = ebitset_elt_alloc ();
470 delts[j] = tmp;
471 memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
472 sizeof (EBITSET_WORDS (selt)));
473 }
474 }
475 EBITSET_NONZERO_SET (dst);
476}
477
478
479/* Copy bits from bitset SRC to bitset DST. Return non-zero if
480 bitsets different. */
481static inline int
75f10004 482ebitset_copy_cmp (bitset dst, bitset src)
7086e707
AD
483{
484 if (src == dst)
485 return 0;
486
6aa452a6 487 if (EBITSET_ZERO_P (dst))
7086e707 488 {
6aa452a6
AD
489 ebitset_copy_ (dst, src);
490 return !EBITSET_ZERO_P (src);
7086e707
AD
491 }
492
493 if (ebitset_equal_p (dst, src))
494 return 0;
495
6aa452a6 496 ebitset_copy_ (dst, src);
7086e707
AD
497 return 1;
498}
499
500
501/* Return size in bits of bitset SRC. */
52f8da14 502static bitset_bindex
75f10004 503ebitset_size (bitset src)
7086e707
AD
504{
505 /* Return current size of bitset in bits. */
506 return EBITSET_SIZE (src) * EBITSET_ELT_BITS;
507}
508
509
510/* Set bit BITNO in bitset DST. */
511static void
75f10004 512ebitset_set (bitset dst, bitset_bindex bitno)
7086e707 513{
345cea78 514 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 515
345cea78 516 ebitset_elt_find (dst, windex, EBITSET_CREATE);
7086e707 517
c837b828
PE
518 dst->b.cdata[windex - dst->b.cindex] |=
519 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
7086e707
AD
520}
521
522
523/* Reset bit BITNO in bitset DST. */
524static void
75f10004 525ebitset_reset (bitset dst, bitset_bindex bitno)
7086e707 526{
345cea78 527 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 528
345cea78 529 if (!ebitset_elt_find (dst, windex, EBITSET_FIND))
ef017502 530 return;
7086e707 531
c837b828
PE
532 dst->b.cdata[windex - dst->b.cindex] &=
533 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707 534
75f10004 535 /* If all the data is zero, perhaps we should remove it now...
345cea78 536 However, there is a good chance that the element will be needed
7086e707
AD
537 again soon. */
538}
539
540
541/* Test bit BITNO in bitset SRC. */
542static int
75f10004 543ebitset_test (bitset src, bitset_bindex bitno)
7086e707 544{
345cea78 545 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 546
345cea78 547 if (!ebitset_elt_find (src, windex, EBITSET_FIND))
7086e707
AD
548 return 0;
549
ef017502 550 return (src->b.
345cea78 551 cdata[windex - src->b.cindex] >> (bitno % BITSET_WORD_BITS)) & 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
345cea78 735 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 736 {
345cea78 737 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
738
739 word = srcp[i];
740 if (word)
741 {
ef017502 742 if (!(word & 0xffff))
7086e707
AD
743 {
744 word >>= 16;
745 bitno += 16;
746 }
ef017502 747 if (!(word & 0xff))
7086e707
AD
748 {
749 word >>= 8;
750 bitno += 8;
751 }
752 for (; word; bitno++)
753 {
754 if (word & 1)
755 list[count++] = bitno;
756 word >>= 1;
757 }
758 }
759 }
760 }
761 else
762 {
763 /* Tread more carefully since we need to check
764 if array overflows. */
765
345cea78 766 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 767 {
345cea78 768 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
769
770 for (word = srcp[i]; word; bitno++)
771 {
772 if (word & 1)
773 {
774 list[count++] = bitno;
775 if (count >= num)
776 {
777 *next = bitno + 1;
778 return count;
779 }
780 }
781 word >>= 1;
782 }
783 }
784 }
785 }
786
787 *next = bitno;
788 return count;
789}
790
791
6aa452a6 792static void
75f10004 793ebitset_ones (bitset dst)
7086e707
AD
794{
795 bitset_windex j;
796 ebitset_elt *elt;
797
7086e707 798
6aa452a6
AD
799 for (j = 0; j < EBITSET_SIZE (dst); j++)
800 {
801 /* Create new elements if they cannot be found. Perhaps
802 we should just add pointers to a ones element. */
803 elt =
804 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
805 memset (EBITSET_WORDS (elt), -1, sizeof (EBITSET_WORDS (elt)));
7086e707 806 }
7086e707 807 EBITSET_NONZERO_SET (dst);
7086e707
AD
808}
809
810
811static int
75f10004 812ebitset_empty_p (bitset dst)
6aa452a6
AD
813{
814 return !ebitset_weed (dst);
815}
816
817
818static void
75f10004 819ebitset_not (bitset dst, bitset src)
7086e707 820{
6aa452a6 821 unsigned int i;
7086e707
AD
822 ebitset_elt *selt;
823 ebitset_elt *delt;
7086e707
AD
824 bitset_windex j;
825
6aa452a6 826 for (j = 0; j < EBITSET_SIZE (src); j++)
7086e707 827 {
6aa452a6 828 /* Create new elements for dst if they cannot be found
7086e707 829 or substitute zero elements if src elements not found. */
6aa452a6
AD
830 selt =
831 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_SUBST);
832 delt =
833 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
7086e707 834
6aa452a6
AD
835 for (i = 0; i < EBITSET_ELT_WORDS; i++)
836 EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
837 }
838 EBITSET_NONZERO_SET (dst);
75f10004 839}
ef017502 840
6aa452a6
AD
841
842/* Return 1 if DST == DST | SRC. */
843static int
75f10004 844ebitset_subset_p (bitset dst, bitset src)
6aa452a6
AD
845{
846 bitset_windex j;
847 ebitset_elts *selts;
848 ebitset_elts *delts;
849 bitset_windex ssize;
850 bitset_windex dsize;
75f10004 851
6aa452a6
AD
852 selts = EBITSET_ELTS (src);
853 delts = EBITSET_ELTS (dst);
75f10004 854
6aa452a6
AD
855 ssize = EBITSET_SIZE (src);
856 dsize = EBITSET_SIZE (dst);
75f10004 857
6aa452a6
AD
858 for (j = 0; j < ssize; j++)
859 {
860 unsigned int i;
861 ebitset_elt *selt;
862 ebitset_elt *delt;
863
864 selt = j < ssize ? selts[j] : 0;
865 delt = j < dsize ? delts[j] : 0;
75f10004 866
6aa452a6
AD
867 if (!selt && !delt)
868 continue;
75f10004 869
6aa452a6
AD
870 if (!selt)
871 selt = &ebitset_zero_elts[0];
872 if (!delt)
873 delt = &ebitset_zero_elts[0];
75f10004 874
6aa452a6
AD
875 for (i = 0; i < EBITSET_ELT_WORDS; i++)
876 if (EBITSET_WORDS (delt)[i]
877 != (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
878 return 0;
7086e707 879 }
6aa452a6
AD
880 return 1;
881}
7086e707 882
6aa452a6
AD
883
884/* Return 1 if DST & SRC == 0. */
885static int
75f10004 886ebitset_disjoint_p (bitset dst, bitset src)
6aa452a6
AD
887{
888 bitset_windex j;
889 ebitset_elts *selts;
890 ebitset_elts *delts;
891 bitset_windex ssize;
892 bitset_windex dsize;
75f10004 893
6aa452a6
AD
894 selts = EBITSET_ELTS (src);
895 delts = EBITSET_ELTS (dst);
75f10004 896
6aa452a6
AD
897 ssize = EBITSET_SIZE (src);
898 dsize = EBITSET_SIZE (dst);
75f10004 899
6aa452a6
AD
900 for (j = 0; j < ssize; j++)
901 {
902 unsigned int i;
903 ebitset_elt *selt;
904 ebitset_elt *delt;
905
906 selt = j < ssize ? selts[j] : 0;
907 delt = j < dsize ? delts[j] : 0;
75f10004 908
6aa452a6
AD
909 if (!selt || !delt)
910 continue;
75f10004 911
6aa452a6
AD
912 for (i = 0; i < EBITSET_ELT_WORDS; i++)
913 if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
914 return 0;
915 }
7086e707
AD
916 return 1;
917}
918
919
6aa452a6 920
7086e707 921static int
75f10004 922ebitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
7086e707
AD
923{
924 bitset_windex ssize1;
925 bitset_windex ssize2;
926 bitset_windex dsize;
927 bitset_windex size;
928 ebitset_elts *selts1;
929 ebitset_elts *selts2;
930 ebitset_elts *delts;
931 bitset_word *srcp1;
932 bitset_word *srcp2;
933 bitset_word *dstp;
934 int changed = 0;
935 unsigned int i;
936 bitset_windex j;
937
7086e707
AD
938 ssize1 = EBITSET_SIZE (src1);
939 ssize2 = EBITSET_SIZE (src2);
940 dsize = EBITSET_SIZE (dst);
941 size = ssize1;
942 if (size < ssize2)
943 size = ssize2;
944
945 if (size > dsize)
ef017502 946 ebitset_elts_grow (dst, size - dsize);
7086e707
AD
947
948 selts1 = EBITSET_ELTS (src1);
949 selts2 = EBITSET_ELTS (src2);
950 delts = EBITSET_ELTS (dst);
951
952 for (j = 0; j < size; j++)
953 {
954 ebitset_elt *selt1;
955 ebitset_elt *selt2;
956 ebitset_elt *delt;
957
958 selt1 = j < ssize1 ? selts1[j] : 0;
959 selt2 = j < ssize2 ? selts2[j] : 0;
960 delt = j < dsize ? delts[j] : 0;
961
ef017502 962 if (!selt1 && !selt2)
7086e707
AD
963 {
964 if (delt)
965 {
966 changed = 1;
967 ebitset_elt_remove (dst, j);
968 }
969 continue;
970 }
971
972 if (!selt1)
973 selt1 = &ebitset_zero_elts[0];
974 if (!selt2)
975 selt2 = &ebitset_zero_elts[0];
976 if (!delt)
977 delt = ebitset_elt_calloc ();
978 else
979 delts[j] = 0;
980
981 srcp1 = EBITSET_WORDS (selt1);
982 srcp2 = EBITSET_WORDS (selt2);
983 dstp = EBITSET_WORDS (delt);
984 switch (op)
985 {
ef017502 986 case BITSET_OP_OR:
7086e707
AD
987 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
988 {
989 bitset_word tmp = *srcp1++ | *srcp2++;
990
991 if (*dstp != tmp)
992 {
993 changed = 1;
994 *dstp = tmp;
995 }
996 }
997 break;
998
ef017502 999 case BITSET_OP_AND:
7086e707
AD
1000 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1001 {
1002 bitset_word tmp = *srcp1++ & *srcp2++;
1003
1004 if (*dstp != tmp)
1005 {
1006 changed = 1;
1007 *dstp = tmp;
1008 }
1009 }
1010 break;
1011
ef017502 1012 case BITSET_OP_XOR:
7086e707
AD
1013 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1014 {
1015 bitset_word tmp = *srcp1++ ^ *srcp2++;
1016
1017 if (*dstp != tmp)
1018 {
1019 changed = 1;
1020 *dstp = tmp;
1021 }
1022 }
1023 break;
1024
ef017502 1025 case BITSET_OP_ANDN:
7086e707
AD
1026 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1027 {
1028 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1029
1030 if (*dstp != tmp)
1031 {
1032 changed = 1;
1033 *dstp = tmp;
1034 }
1035 }
1036 break;
1037
7086e707
AD
1038 default:
1039 abort ();
1040 }
1041
ef017502 1042 if (!ebitset_elt_zero_p (delt))
7086e707
AD
1043 {
1044 ebitset_elt_add (dst, delt, j);
1045 }
1046 else
1047 {
1048 ebitset_elt_free (delt);
1049 }
1050 }
1051
1052 /* If we have elements of DST left over, free them all. */
1053 for (; j < dsize; j++)
1054 {
1055 ebitset_elt *delt;
1056
1057 changed = 1;
1058
1059 delt = delts[j];
1060
1061 if (delt)
1062 ebitset_elt_remove (dst, j);
1063 }
1064
1065 EBITSET_NONZERO_SET (dst);
1066 return changed;
1067}
1068
1069
6aa452a6 1070static int
75f10004 1071ebitset_and_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1072{
1073 int changed;
1074
1075 if (EBITSET_ZERO_P (src2))
1076 {
1077 ebitset_weed (dst);
1078 changed = EBITSET_ZERO_P (dst);
1079 ebitset_zero (dst);
1080 return changed;
1081 }
1082 else if (EBITSET_ZERO_P (src1))
1083 {
1084 ebitset_weed (dst);
1085 changed = EBITSET_ZERO_P (dst);
1086 ebitset_zero (dst);
1087 return changed;
1088 }
1089 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_AND);
1090}
1091
1092
3e0a8627 1093static void
75f10004 1094ebitset_and (bitset dst, bitset src1, bitset src2)
3e0a8627 1095{
75f10004 1096 ebitset_and_cmp (dst, src1, src2);
3e0a8627
PE
1097}
1098
1099
6aa452a6 1100static int
75f10004 1101ebitset_andn_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1102{
1103 int changed;
1104
1105 if (EBITSET_ZERO_P (src2))
1106 {
1107 return ebitset_copy_cmp (dst, src1);
1108 }
1109 else if (EBITSET_ZERO_P (src1))
1110 {
1111 ebitset_weed (dst);
1112 changed = EBITSET_ZERO_P (dst);
1113 ebitset_zero (dst);
1114 return changed;
1115 }
1116 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_ANDN);
1117}
1118
1119
3e0a8627 1120static void
75f10004 1121ebitset_andn (bitset dst, bitset src1, bitset src2)
3e0a8627 1122{
75f10004 1123 ebitset_andn_cmp (dst, src1, src2);
3e0a8627
PE
1124}
1125
1126
6aa452a6 1127static int
75f10004 1128ebitset_or_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1129{
1130 if (EBITSET_ZERO_P (src2))
1131 {
1132 return ebitset_copy_cmp (dst, src1);
1133 }
1134 else if (EBITSET_ZERO_P (src1))
1135 {
1136 return ebitset_copy_cmp (dst, src2);
1137 }
1138 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_OR);
1139}
1140
1141
3e0a8627 1142static void
75f10004 1143ebitset_or (bitset dst, bitset src1, bitset src2)
3e0a8627 1144{
75f10004 1145 ebitset_or_cmp (dst, src1, src2);
3e0a8627
PE
1146}
1147
1148
6aa452a6 1149static int
75f10004 1150ebitset_xor_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1151{
1152 if (EBITSET_ZERO_P (src2))
1153 {
1154 return ebitset_copy_cmp (dst, src1);
1155 }
1156 else if (EBITSET_ZERO_P (src1))
1157 {
1158 return ebitset_copy_cmp (dst, src2);
1159 }
1160 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_XOR);
1161}
1162
1163
1164static void
75f10004
PE
1165ebitset_xor (bitset dst, bitset src1, bitset src2)
1166{
1167 ebitset_xor_cmp (dst, src1, src2);
1168}
1169
1170
1171static void
1172ebitset_copy (bitset dst, bitset src)
6aa452a6
AD
1173{
1174 if (BITSET_COMPATIBLE_ (dst, src))
1175 ebitset_copy_ (dst, src);
1176 else
1177 bitset_copy_ (dst, src);
1178}
1179
1180
7086e707 1181/* Vector of operations for linked-list bitsets. */
6aa452a6 1182struct bitset_vtable ebitset_vtable = {
ef017502
AD
1183 ebitset_set,
1184 ebitset_reset,
6aa452a6 1185 bitset_toggle_,
ef017502
AD
1186 ebitset_test,
1187 ebitset_size,
6aa452a6
AD
1188 bitset_count_,
1189 ebitset_empty_p,
1190 ebitset_ones,
1191 ebitset_zero,
1192 ebitset_copy,
1193 ebitset_disjoint_p,
1194 ebitset_equal_p,
1195 ebitset_not,
1196 ebitset_subset_p,
3e0a8627 1197 ebitset_and,
6aa452a6 1198 ebitset_and_cmp,
3e0a8627 1199 ebitset_andn,
6aa452a6 1200 ebitset_andn_cmp,
3e0a8627 1201 ebitset_or,
6aa452a6 1202 ebitset_or_cmp,
3e0a8627 1203 ebitset_xor,
6aa452a6 1204 ebitset_xor_cmp,
3e0a8627 1205 bitset_and_or_,
6aa452a6 1206 bitset_and_or_cmp_,
3e0a8627 1207 bitset_andn_or_,
6aa452a6 1208 bitset_andn_or_cmp_,
3e0a8627 1209 bitset_or_and_,
6aa452a6 1210 bitset_or_and_cmp_,
ef017502 1211 ebitset_list,
6aa452a6 1212 ebitset_list_reverse,
ef017502
AD
1213 ebitset_free,
1214 BITSET_TABLE
1215};
7086e707
AD
1216
1217
1218/* Return size of initial structure. */
52f8da14 1219size_t
75f10004 1220ebitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED)
7086e707 1221{
3e0a8627 1222 return sizeof (struct ebitset_struct);
7086e707
AD
1223}
1224
1225
1226/* Initialize a bitset. */
1227
1228bitset
75f10004 1229ebitset_init (bitset bset, bitset_bindex n_bits)
7086e707 1230{
52f8da14 1231 bitset_windex size;
7086e707 1232
6aa452a6 1233 bset->b.vtable = &ebitset_vtable;
7086e707 1234
ef017502 1235 bset->b.csize = EBITSET_ELT_WORDS;
7086e707 1236
6aa452a6 1237 EBITSET_ZERO_SET (bset);
7086e707
AD
1238
1239 size = n_bits ? (n_bits + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS
1240 : EBITSET_INITIAL_SIZE;
1241
1242 EBITSET_SIZE (bset) = 0;
1243 EBITSET_ELTS (bset) = 0;
1244 ebitset_elts_grow (bset, size);
1245
1246 return bset;
1247}
1248
1249
1250void
75f10004 1251ebitset_release_memory (void)
7086e707
AD
1252{
1253 ebitset_free_list = 0;
1254 if (ebitset_obstack_init)
1255 {
1256 ebitset_obstack_init = 0;
1257 obstack_free (&ebitset_obstack, NULL);
1258 }
1259}