]> git.saurik.com Git - bison.git/blame - lib/ebitset.c
Update from TP.
[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
345cea78
AD
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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
ef017502 40 be zero.
7086e707
AD
41
42 The bitset cache can be disabled either by setting cindex to
ef017502 43 some large number or by setting csize to 0. Here
7086e707 44 we use the former approach since cindex needs to be updated whenever
ef017502 45 cdata is changed.
7086e707
AD
46*/
47
ef017502
AD
48
49/* Number of words to use for each element. */
50
51#ifndef EBITSET_ELT_WORDS
52#define EBITSET_ELT_WORDS 2
53#endif
54
55/* Number of bits stored in each element. */
56#define EBITSET_ELT_BITS \
57 ((unsigned) (EBITSET_ELT_WORDS * BITSET_WORD_BITS))
58
59/* Ebitset element. We use an array of bits. */
60typedef struct ebitset_elt_struct
61{
62 union
63 {
64 bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */
65 struct ebitset_elt_struct *next;
66 }
67 u;
68}
69ebitset_elt;
70
71
72typedef ebitset_elt *ebitset_elts;
73
74/* Head of ebitset linked list. */
75typedef struct ebitset_struct
76{
77 unsigned int size; /* Number of elements. */
78 ebitset_elts *elts; /* Expanding array of pointers to elements. */
79}
80*ebitset;
81
82
7086e707 83/* Number of elements to initially allocate. */
ef017502 84
7086e707
AD
85#ifndef EBITSET_INITIAL_SIZE
86#define EBITSET_INITIAL_SIZE 2
87#endif
88
89/* Minimum number of elements to grow table. */
ef017502 90
7086e707
AD
91#ifndef EBITSET_GROW_SIZE
92#define EBITSET_GROW_SIZE 4
93#endif
94
ef017502
AD
95struct bitset_struct
96{
97 struct bbitset_struct b;
98 struct ebitset_struct e;
99};
7086e707 100
ef017502
AD
101enum ebitset_find_mode
102 { EBITSET_FIND, EBITSET_CREATE, EBITSET_SUBST };
7086e707
AD
103
104static ebitset_elt ebitset_zero_elts[1]; /* Elements of all zero bits. */
105
106/* Obstack to allocate bitset elements from. */
107static struct obstack ebitset_obstack;
108static int ebitset_obstack_init = 0;
ef017502 109static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */
7086e707
AD
110
111static void ebitset_elts_grow PARAMS ((bitset, unsigned int));
112static ebitset_elt *ebitset_elt_alloc PARAMS ((void));
113static ebitset_elt *ebitset_elt_calloc PARAMS ((void));
114static void ebitset_elt_add PARAMS ((bitset, ebitset_elt *, unsigned int));
115static void ebitset_elt_remove PARAMS ((bitset, unsigned int));
116static void ebitset_elt_free PARAMS ((ebitset_elt *));
117static ebitset_elt *ebitset_elt_find PARAMS ((bitset, bitset_windex,
118 enum ebitset_find_mode));
119static ebitset_elt *ebitset_elt_last PARAMS ((bitset));
120static int ebitset_elt_zero_p PARAMS ((ebitset_elt *));
121
122static int ebitset_weed PARAMS ((bitset));
ef017502
AD
123static void ebitset_zero PARAMS ((bitset));
124static int ebitset_equal_p PARAMS ((bitset, bitset));
125static void ebitset_copy PARAMS ((bitset, bitset));
126static int ebitset_copy_compare PARAMS ((bitset, bitset));
127static void ebitset_set PARAMS ((bitset, bitset_bindex));
128static void ebitset_reset PARAMS ((bitset, bitset_bindex));
129static int ebitset_test PARAMS ((bitset, bitset_bindex));
130static int ebitset_size PARAMS ((bitset));
131static int ebitset_op1 PARAMS ((bitset, enum bitset_ops));
132static int ebitset_op2 PARAMS ((bitset, bitset, enum bitset_ops));
133static int ebitset_op3 PARAMS ((bitset, bitset, bitset, enum bitset_ops));
134static int ebitset_list PARAMS ((bitset, bitset_bindex *, bitset_bindex,
135 bitset_bindex *));
136static int ebitset_reverse_list
137PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
138static void ebitset_free PARAMS ((bitset));
139
140#define EBITSET_ELTS(BSET) ((BSET)->e.elts)
141#define EBITSET_SIZE(BSET) ((BSET)->e.size)
7086e707
AD
142
143#define EBITSET_NEXT(ELT) ((ELT)->u.next)
144#define EBITSET_WORDS(ELT) ((ELT)->u.words)
145
146/* Disable bitset cache and mark BSET as being zero. */
ef017502
AD
147#define EBITSET_OP_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_INDEX_MAX, \
148 (BSET)->b.cdata = 0)
7086e707 149
ef017502 150#define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_INDEX_MAX)
7086e707
AD
151
152/* Disable bitset cache and mark BSET as being possibly non-zero. */
153#define EBITSET_NONZERO_SET(BSET) \
ef017502 154 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0)
7086e707
AD
155
156/* A conservative estimate of whether the bitset is zero.
157 This is non-zero only if we know for sure that the bitset is zero. */
ef017502 158#define EBITSET_OP_ZERO_P(BSET) ((BSET)->b.cdata == 0)
7086e707 159
ef017502 160/* Enable cache to point to element with table index EINDEX.
7086e707
AD
161 The element must exist. */
162#define EBITSET_CACHE_SET(BSET, EINDEX) \
ef017502
AD
163 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \
164 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX]))
7086e707
AD
165
166
167/* Grow the expandable table for BSET by SIZE elements. */
168static void
169ebitset_elts_grow (bset, size)
ef017502
AD
170 bitset bset;
171 unsigned int size;
7086e707
AD
172{
173 unsigned int oldsize;
174 unsigned int newsize;
175
176 oldsize = EBITSET_SIZE (bset);
177 newsize = oldsize + size;
178
179 EBITSET_ELTS (bset) = xrealloc (EBITSET_ELTS (bset),
ef017502 180 newsize * sizeof (ebitset_elt *));
7086e707
AD
181 EBITSET_SIZE (bset) = newsize;
182
183 memset (EBITSET_ELTS (bset) + oldsize, 0, size * sizeof (ebitset_elt *));
184}
185
186
187/* Allocate a ebitset element. The bits are not cleared. */
188static inline ebitset_elt *
189ebitset_elt_alloc ()
190{
191 ebitset_elt *elt;
192
193 if (ebitset_free_list != 0)
194 {
195 elt = ebitset_free_list;
196 ebitset_free_list = EBITSET_NEXT (elt);
197 }
198 else
199 {
200 /* We can't use gcc_obstack_init to initialize the obstack since
201 print-rtl.c now calls bitset functions, and bitset is linked
202 into the gen* functions. */
203 if (!ebitset_obstack_init)
204 {
205 ebitset_obstack_init = 1;
206
207 /* Let particular systems override the size of a chunk. */
ef017502 208
7086e707
AD
209#ifndef OBSTACK_CHUNK_SIZE
210#define OBSTACK_CHUNK_SIZE 0
211#endif
ef017502 212
7086e707 213 /* Let them override the alloc and free routines too. */
ef017502 214
7086e707
AD
215#ifndef OBSTACK_CHUNK_ALLOC
216#define OBSTACK_CHUNK_ALLOC xmalloc
217#endif
ef017502 218
7086e707
AD
219#ifndef OBSTACK_CHUNK_FREE
220#define OBSTACK_CHUNK_FREE free
221#endif
222
223#if !defined(__GNUC__) || (__GNUC__ < 2)
224#define __alignof__(type) 0
225#endif
226
227 obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE,
228 __alignof__ (ebitset_elt),
ef017502
AD
229 (void *(*)PARAMS ((long)))
230 OBSTACK_CHUNK_ALLOC,
231 (void (*)PARAMS ((void *)))
232 OBSTACK_CHUNK_FREE);
7086e707
AD
233 }
234
235 /* Perhaps we should add a number of new elements to the free
ef017502 236 list. */
7086e707
AD
237 elt = (ebitset_elt *) obstack_alloc (&ebitset_obstack,
238 sizeof (ebitset_elt));
239 }
240
241 return elt;
242}
243
244
245/* Allocate a ebitset element. The bits are not cleared. */
246static inline ebitset_elt *
247ebitset_elt_calloc ()
248{
249 ebitset_elt *elt;
250
251 elt = ebitset_elt_alloc ();
252 memset (EBITSET_WORDS (elt), 0, sizeof (EBITSET_WORDS (elt)));
253 return elt;
254}
255
256
257static inline void
258ebitset_elt_free (elt)
259 ebitset_elt *elt;
260{
261 EBITSET_NEXT (elt) = ebitset_free_list;
262 ebitset_free_list = elt;
263}
264
265
266/* Remove element with index EINDEX from bitset BSET. */
267static inline void
268ebitset_elt_remove (bset, eindex)
269 bitset bset;
270 unsigned int eindex;
271{
272 ebitset_elts *elts;
273 ebitset_elt *elt;
274
275 elts = EBITSET_ELTS (bset);
276
277 elt = elts[eindex];
278
279 elts[eindex] = 0;
280 ebitset_elt_free (elt);
281}
282
283
284/* Add ELT into elts at index EINDEX of bitset BSET. */
285static inline void
286ebitset_elt_add (bset, elt, eindex)
287 bitset bset;
288 ebitset_elt *elt;
289 unsigned int eindex;
290{
291 ebitset_elts *elts;
292
293 elts = EBITSET_ELTS (bset);
294 /* Assume that the elts entry not allocated. */
295 elts[eindex] = elt;
296}
297
298
299/* Return nonzero if all bits in an element are zero. */
300static inline int
301ebitset_elt_zero_p (elt)
302 ebitset_elt *elt;
303{
304 int i;
305
306 for (i = 0; i < EBITSET_ELT_WORDS; i++)
307 if (EBITSET_WORDS (elt)[i])
308 return 0;
309
310 return 1;
311}
312
313
314static ebitset_elt *
345cea78 315ebitset_elt_find (bset, windex, mode)
7086e707 316 bitset bset;
345cea78 317 bitset_windex windex;
7086e707
AD
318 enum ebitset_find_mode mode;
319{
320 ebitset_elt *elt;
321 bitset_windex size;
322 unsigned int eindex;
323 ebitset_elts *elts;
324
345cea78 325 eindex = windex / EBITSET_ELT_WORDS;
7086e707
AD
326
327 elts = EBITSET_ELTS (bset);
328 size = EBITSET_SIZE (bset);
329
330 if (eindex < size)
331 {
7086e707
AD
332 if ((elt = elts[eindex]))
333 {
ef017502 334 if (EBITSET_WORDS (elt) == bset->b.cdata)
7086e707
AD
335 return elt;
336
337 EBITSET_CACHE_SET (bset, eindex);
338 return elt;
339 }
340 }
341
342 /* The element could not be found. */
343
344 switch (mode)
345 {
346 case EBITSET_FIND:
347 return 0;
348
349 case EBITSET_CREATE:
350 if (eindex >= size)
351 {
352 unsigned int extra;
353
354 extra = eindex - size + 1;
355
356 /* We need to expand the table by EXTRA elements. It may be
357 better with large bitsets to grow the number of
358 elements by some fraction of the current size otherwise
359 we can spend a lot of time slowly increasing the size of the
360 bitset. */
361 if (extra < EBITSET_GROW_SIZE)
362 extra = EBITSET_GROW_SIZE;
363
364 ebitset_elts_grow (bset, extra);
365 }
366
367 /* Create a new element. */
368 elt = ebitset_elt_calloc ();
369 ebitset_elt_add (bset, elt, eindex);
370 EBITSET_CACHE_SET (bset, eindex);
371 return elt;
372
373 case EBITSET_SUBST:
374 return &ebitset_zero_elts[0];
375
376 default:
377 abort ();
378 }
379}
380
381
382static inline ebitset_elt *
383ebitset_elt_last (bset)
384 bitset bset;
385{
386 ebitset_elts *elts;
387
388 elts = EBITSET_ELTS (bset);
389
390 /* Assume that have at least one element in elts. */
391 return elts[EBITSET_SIZE (bset) - 1];
392}
393
394
395/* Weed out the zero elements from the elts. */
396static inline int
397ebitset_weed (bset)
398 bitset bset;
399{
400 ebitset_elts *elts;
401 bitset_windex j;
402 int count;
403
ef017502 404 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
405 return 0;
406
407 elts = EBITSET_ELTS (bset);
408 count = 0;
409 for (j = 0; j < EBITSET_SIZE (bset); j++)
410 {
411 ebitset_elt *elt = elts[j];
412
413 if (elt)
414 {
415 if (elt && ebitset_elt_zero_p (elt))
416 {
417 ebitset_elt_remove (bset, j);
418 count++;
419 }
420 }
421 else
422 count++;
423 }
424
425 count = j - count;
426 if (!count)
427 {
ef017502 428 /* All the bits are zero. We could shrink the elts.
7086e707 429 For now just mark BSET as known to be zero. */
ef017502 430 EBITSET_OP_ZERO_SET (bset);
7086e707
AD
431 }
432 else
433 EBITSET_NONZERO_SET (bset);
434
ef017502 435 return count;
7086e707
AD
436}
437
438
439/* Set all bits in the bitset to zero. */
440static inline void
441ebitset_zero (bset)
442 bitset bset;
443{
444 ebitset_elts *elts;
445 bitset_windex j;
446
ef017502 447 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
448 return;
449
450 elts = EBITSET_ELTS (bset);
451 for (j = 0; j < EBITSET_SIZE (bset); j++)
452 {
453 ebitset_elt *elt = elts[j];
454
455 if (elt)
456 ebitset_elt_remove (bset, j);
457 }
458
ef017502 459 /* All the bits are zero. We could shrink the elts.
7086e707 460 For now just mark BSET as known to be zero. */
ef017502 461 EBITSET_OP_ZERO_SET (bset);
7086e707
AD
462}
463
464
465static inline int
466ebitset_equal_p (dst, src)
467 bitset dst;
468 bitset src;
469{
470 ebitset_elts *selts;
471 ebitset_elts *delts;
472 bitset_windex j;
473
474 if (src == dst)
475 return 1;
476
477 ebitset_weed (dst);
478 ebitset_weed (src);
479
480 if (EBITSET_SIZE (src) != EBITSET_SIZE (dst))
481 return 0;
482
483 selts = EBITSET_ELTS (src);
484 delts = EBITSET_ELTS (dst);
485
486 for (j = 0; j < EBITSET_SIZE (src); j++)
487 {
488 unsigned int i;
489 ebitset_elt *selt = selts[j];
490 ebitset_elt *delt = delts[j];
491
ef017502 492 if (!selt && !delt)
7086e707 493 continue;
ef017502 494 if ((selt && !delt) || (!selt && delt))
7086e707
AD
495 return 0;
496
497 for (i = 0; i < EBITSET_ELT_WORDS; i++)
498 if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i])
499 return 0;
500 }
501 return 1;
502}
503
504
505/* Copy bits from bitset SRC to bitset DST. */
506static inline void
507ebitset_copy (dst, src)
508 bitset dst;
509 bitset src;
510{
511 ebitset_elts *selts;
512 ebitset_elts *delts;
513 bitset_windex j;
514
515 if (src == dst)
516 return;
517
518 ebitset_zero (dst);
519
520 if (EBITSET_SIZE (dst) < EBITSET_SIZE (src))
521 ebitset_elts_grow (dst, EBITSET_SIZE (src) - EBITSET_SIZE (dst));
522
523 selts = EBITSET_ELTS (src);
524 delts = EBITSET_ELTS (dst);
525 for (j = 0; j < EBITSET_SIZE (src); j++)
526 {
527 ebitset_elt *selt = selts[j];
528
529 if (selt)
530 {
531 ebitset_elt *tmp;
532
533 tmp = ebitset_elt_alloc ();
534 delts[j] = tmp;
535 memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt),
536 sizeof (EBITSET_WORDS (selt)));
537 }
538 }
539 EBITSET_NONZERO_SET (dst);
540}
541
542
543/* Copy bits from bitset SRC to bitset DST. Return non-zero if
544 bitsets different. */
545static inline int
546ebitset_copy_compare (dst, src)
547 bitset dst;
548 bitset src;
549{
550 if (src == dst)
551 return 0;
552
ef017502 553 if (EBITSET_OP_ZERO_P (dst))
7086e707
AD
554 {
555 ebitset_copy (dst, src);
ef017502 556 return !EBITSET_OP_ZERO_P (src);
7086e707
AD
557 }
558
559 if (ebitset_equal_p (dst, src))
560 return 0;
561
562 ebitset_copy (dst, src);
563 return 1;
564}
565
566
567/* Return size in bits of bitset SRC. */
568static int
569ebitset_size (src)
570 bitset src;
571{
572 /* Return current size of bitset in bits. */
573 return EBITSET_SIZE (src) * EBITSET_ELT_BITS;
574}
575
576
577/* Set bit BITNO in bitset DST. */
578static void
579ebitset_set (dst, bitno)
580 bitset dst;
581 bitset_bindex bitno;
582{
345cea78 583 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 584
345cea78 585 ebitset_elt_find (dst, windex, EBITSET_CREATE);
7086e707 586
345cea78 587 dst->b.cdata[windex - dst->b.cindex] |= (1 << (bitno % BITSET_WORD_BITS));
7086e707
AD
588}
589
590
591/* Reset bit BITNO in bitset DST. */
592static void
593ebitset_reset (dst, bitno)
594 bitset dst;
595 bitset_bindex bitno;
596{
345cea78 597 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 598
345cea78 599 if (!ebitset_elt_find (dst, windex, EBITSET_FIND))
ef017502 600 return;
7086e707 601
345cea78 602 dst->b.cdata[windex - dst->b.cindex] &= ~(1 << (bitno % BITSET_WORD_BITS));
7086e707 603
ef017502 604 /* If all the data is zero, perhaps we should remove it now...
345cea78 605 However, there is a good chance that the element will be needed
7086e707
AD
606 again soon. */
607}
608
609
610/* Test bit BITNO in bitset SRC. */
611static int
612ebitset_test (src, bitno)
613 bitset src;
614 bitset_bindex bitno;
615{
345cea78 616 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 617
345cea78 618 if (!ebitset_elt_find (src, windex, EBITSET_FIND))
7086e707
AD
619 return 0;
620
ef017502 621 return (src->b.
345cea78 622 cdata[windex - src->b.cindex] >> (bitno % BITSET_WORD_BITS)) & 1;
7086e707
AD
623}
624
625
626static void
627ebitset_free (bset)
628 bitset bset;
629{
630 ebitset_zero (bset);
631 free (EBITSET_ELTS (bset));
632}
633
634
635/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
636 *NEXT and store in array LIST. Return with actual number of bits
637 found and with *NEXT indicating where search stopped. */
7086e707
AD
638static int
639ebitset_reverse_list (bset, list, num, next)
640 bitset bset;
641 bitset_bindex *list;
642 bitset_bindex num;
643 bitset_bindex *next;
644{
645 bitset_bindex n_bits;
646 bitset_bindex bitno;
647 bitset_bindex rbitno;
345cea78
AD
648 unsigned int bcount;
649 bitset_bindex boffset;
7086e707 650 bitset_windex windex;
345cea78
AD
651 unsigned int eindex;
652 bitset_windex woffset;
7086e707
AD
653 bitset_bindex count;
654 bitset_windex size;
655 bitset_word word;
656 ebitset_elts *elts;
657
ef017502 658 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
659 return 0;
660
661 size = EBITSET_SIZE (bset);
662 n_bits = size * EBITSET_ELT_BITS;
663 rbitno = *next;
664
665 if (rbitno >= n_bits)
ef017502 666 return 0;
7086e707
AD
667
668 elts = EBITSET_ELTS (bset);
669
670 bitno = n_bits - (rbitno + 1);
671
345cea78 672 windex = bitno / BITSET_WORD_BITS;
7086e707 673 eindex = bitno / EBITSET_ELT_BITS;
345cea78 674 woffset = windex - eindex * EBITSET_ELT_WORDS;
7086e707
AD
675
676 /* If num is 1, we could speed things up with a binary search
677 of the word of interest. */
678
679 count = 0;
345cea78
AD
680 bcount = bitno % BITSET_WORD_BITS;
681 boffset = windex * BITSET_WORD_BITS;
7086e707 682
345cea78
AD
683 for (; eindex != ~0U;
684 boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS, eindex--)
7086e707
AD
685 {
686 ebitset_elt *elt;
687 bitset_word *srcp;
688
689 elt = elts[eindex];
690 if (!elt)
691 continue;
692
693 srcp = EBITSET_WORDS (elt);
694
345cea78
AD
695 for (; woffset != ~0U; woffset--, boffset -= BITSET_WORD_BITS,
696 bcount = BITSET_WORD_BITS - 1)
7086e707 697 {
345cea78 698 word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount);
7086e707 699
345cea78 700 for (; word; bcount--)
7086e707
AD
701 {
702 if (word & BITSET_MSB)
703 {
345cea78 704 list[count++] = boffset + bcount;
7086e707
AD
705 if (count >= num)
706 {
345cea78 707 *next = n_bits - (boffset + bcount);
7086e707
AD
708 return count;
709 }
710 }
711 word <<= 1;
712 }
713 }
714
345cea78 715 woffset = EBITSET_ELT_WORDS;
7086e707
AD
716 }
717
345cea78 718 *next = n_bits - (boffset + 1);
7086e707
AD
719 return count;
720}
721
722
723/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
724 *NEXT and store in array LIST. Return with actual number of bits
725 found and with *NEXT indicating where search stopped. */
7086e707
AD
726static int
727ebitset_list (bset, list, num, next)
728 bitset bset;
729 bitset_bindex *list;
730 bitset_bindex num;
731 bitset_bindex *next;
732{
733 bitset_bindex bitno;
345cea78 734 bitset_windex windex;
7086e707
AD
735 unsigned int eindex;
736 bitset_bindex count;
737 bitset_windex size;
738 ebitset_elt *elt;
739 bitset_word word;
740 ebitset_elts *elts;
741
ef017502 742 if (EBITSET_OP_ZERO_P (bset))
7086e707
AD
743 return 0;
744
745 bitno = *next;
746 count = 0;
747
748 elts = EBITSET_ELTS (bset);
749 size = EBITSET_SIZE (bset);
750 eindex = bitno / EBITSET_ELT_BITS;
751
752 if (bitno % EBITSET_ELT_BITS)
753 {
754 /* We need to start within an element. This is not very common. */
755
756 elt = elts[eindex];
757 if (elt)
758 {
345cea78 759 bitset_windex woffset;
7086e707
AD
760 bitset_word *srcp = EBITSET_WORDS (elt);
761
345cea78
AD
762 windex = bitno / BITSET_WORD_BITS;
763 woffset = eindex / EBITSET_ELT_WORDS;
7086e707 764
345cea78 765 for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++)
7086e707 766 {
345cea78 767 word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS);
7086e707
AD
768
769 for (; word; bitno++)
770 {
771 if (word & 1)
772 {
773 list[count++] = bitno;
774 if (count >= num)
775 {
776 *next = bitno + 1;
777 return count;
778 }
779 }
780 word >>= 1;
781 }
345cea78 782 bitno = (windex + 1) * BITSET_WORD_BITS;
7086e707
AD
783 }
784 }
785
786 /* Skip to next element. */
787 eindex++;
788 }
789
790 /* If num is 1, we could speed things up with a binary search
791 of the word of interest. */
792
793 for (; eindex < size; eindex++)
794 {
795 int i;
7086e707
AD
796 bitset_word *srcp;
797
798 elt = elts[eindex];
799 if (!elt)
800 continue;
801
802 srcp = EBITSET_WORDS (elt);
345cea78 803 windex = eindex * EBITSET_ELT_WORDS;
7086e707
AD
804
805 if ((count + EBITSET_ELT_BITS) < num)
806 {
807 /* The coast is clear, plant boot! */
808
345cea78 809 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 810 {
345cea78 811 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
812
813 word = srcp[i];
814 if (word)
815 {
ef017502 816 if (!(word & 0xffff))
7086e707
AD
817 {
818 word >>= 16;
819 bitno += 16;
820 }
ef017502 821 if (!(word & 0xff))
7086e707
AD
822 {
823 word >>= 8;
824 bitno += 8;
825 }
826 for (; word; bitno++)
827 {
828 if (word & 1)
829 list[count++] = bitno;
830 word >>= 1;
831 }
832 }
833 }
834 }
835 else
836 {
837 /* Tread more carefully since we need to check
838 if array overflows. */
839
345cea78 840 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++)
7086e707 841 {
345cea78 842 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
843
844 for (word = srcp[i]; word; bitno++)
845 {
846 if (word & 1)
847 {
848 list[count++] = bitno;
849 if (count >= num)
850 {
851 *next = bitno + 1;
852 return count;
853 }
854 }
855 word >>= 1;
856 }
857 }
858 }
859 }
860
861 *next = bitno;
862 return count;
863}
864
865
866static int
867ebitset_op1 (dst, op)
868 bitset dst;
869 enum bitset_ops op;
870{
871 bitset_windex j;
872 ebitset_elt *elt;
873
874 switch (op)
875 {
ef017502 876 case BITSET_OP_ZERO:
7086e707
AD
877 ebitset_zero (dst);
878 return 1;
879
ef017502 880 case BITSET_OP_ONES:
7086e707
AD
881 for (j = 0; j < EBITSET_SIZE (dst); j++)
882 {
883 /* Create new elements if they cannot be found. Perhaps
ef017502
AD
884 we should just add pointers to a ones element. */
885 elt =
886 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
7086e707
AD
887 memset (EBITSET_WORDS (elt), ~0, sizeof (EBITSET_WORDS (elt)));
888 }
889 break;
890
ef017502
AD
891 case BITSET_OP_EMPTY_P:
892 return !ebitset_weed (dst);
7086e707
AD
893
894 default:
895 abort ();
896 }
897
898 EBITSET_NONZERO_SET (dst);
899 return 1;
900}
901
902
903static int
904ebitset_op2 (dst, src, op)
905 bitset dst;
906 bitset src;
907 enum bitset_ops op;
908{
909 ebitset_elt *selt;
910 ebitset_elt *delt;
911 unsigned int i;
912 bitset_windex j;
913
914 switch (op)
915 {
ef017502 916 case BITSET_OP_COPY:
7086e707
AD
917 ebitset_copy (dst, src);
918 break;
919
ef017502 920 case BITSET_OP_NOT:
7086e707
AD
921 for (j = 0; j < EBITSET_SIZE (src); j++)
922 {
923 /* Create new elements for dst if they cannot be found
924 or substitute zero elements if src elements not found. */
ef017502
AD
925 selt =
926 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_SUBST);
927 delt =
928 ebitset_elt_find (dst, j * EBITSET_ELT_WORDS, EBITSET_CREATE);
7086e707
AD
929
930 for (i = 0; i < EBITSET_ELT_WORDS; i++)
931 EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i];
932 }
933 break;
934
ef017502
AD
935 /* Return 1 if DST == SRC. */
936 case BITSET_OP_EQUAL_P:
7086e707
AD
937 return ebitset_equal_p (dst, src);
938
939 /* Return 1 if DST == DST | SRC. */
ef017502 940 case BITSET_OP_SUBSET_P:
7086e707
AD
941 {
942 ebitset_elts *selts;
943 ebitset_elts *delts;
944 bitset_windex ssize;
945 bitset_windex dsize;
946
947 selts = EBITSET_ELTS (src);
948 delts = EBITSET_ELTS (dst);
949
950 ssize = EBITSET_SIZE (src);
951 dsize = EBITSET_SIZE (dst);
952
953 for (j = 0; j < ssize; j++)
954 {
7086e707
AD
955 selt = j < ssize ? selts[j] : 0;
956 delt = j < dsize ? delts[j] : 0;
957
ef017502 958 if (!selt && !delt)
7086e707
AD
959 continue;
960
961 if (!selt)
962 selt = &ebitset_zero_elts[0];
963 if (!delt)
964 delt = &ebitset_zero_elts[0];
965
966 for (i = 0; i < EBITSET_ELT_WORDS; i++)
967 if (EBITSET_WORDS (delt)[i]
968 != (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i]))
969 return 0;
970 }
971 return 1;
972 }
973 break;
974
ef017502
AD
975 /* Return 1 if DST & SRC == 0. */
976 case BITSET_OP_DISJOINT_P:
977 {
978 ebitset_elts *selts;
979 ebitset_elts *delts;
980 bitset_windex ssize;
981 bitset_windex dsize;
982
983 selts = EBITSET_ELTS (src);
984 delts = EBITSET_ELTS (dst);
985
986 ssize = EBITSET_SIZE (src);
987 dsize = EBITSET_SIZE (dst);
988
989 for (j = 0; j < ssize; j++)
990 {
ef017502
AD
991 selt = j < ssize ? selts[j] : 0;
992 delt = j < dsize ? delts[j] : 0;
993
345cea78 994 if (!selt || !delt)
ef017502
AD
995 continue;
996
ef017502
AD
997 for (i = 0; i < EBITSET_ELT_WORDS; i++)
998 if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i]))
999 return 0;
1000 }
1001 return 1;
1002 }
1003 break;
1004
7086e707
AD
1005 default:
1006 abort ();
1007 }
1008
1009 EBITSET_NONZERO_SET (dst);
1010 return 1;
1011}
1012
1013
1014static int
1015ebitset_op3 (dst, src1, src2, op)
1016 bitset dst;
1017 bitset src1;
1018 bitset src2;
1019 enum bitset_ops op;
1020{
1021 bitset_windex ssize1;
1022 bitset_windex ssize2;
1023 bitset_windex dsize;
1024 bitset_windex size;
1025 ebitset_elts *selts1;
1026 ebitset_elts *selts2;
1027 ebitset_elts *delts;
1028 bitset_word *srcp1;
1029 bitset_word *srcp2;
1030 bitset_word *dstp;
1031 int changed = 0;
1032 unsigned int i;
1033 bitset_windex j;
1034
1035 /* Fast track common, simple cases. */
ef017502 1036 if (EBITSET_OP_ZERO_P (src2))
7086e707 1037 {
ef017502 1038 if (op == BITSET_OP_AND)
7086e707
AD
1039 {
1040 ebitset_weed (dst);
ef017502 1041 changed = EBITSET_OP_ZERO_P (dst);
7086e707
AD
1042 ebitset_zero (dst);
1043 return changed;
1044 }
ef017502
AD
1045 else if (op == BITSET_OP_ANDN || op == BITSET_OP_OR
1046 || op == BITSET_OP_XOR)
7086e707
AD
1047 {
1048 return ebitset_copy_compare (dst, src1);
1049 }
1050 }
ef017502 1051 else if (EBITSET_OP_ZERO_P (src1))
7086e707 1052 {
ef017502 1053 if (op == BITSET_OP_AND || op == BITSET_OP_ANDN)
7086e707
AD
1054 {
1055 ebitset_weed (dst);
ef017502 1056 changed = EBITSET_OP_ZERO_P (dst);
7086e707
AD
1057 ebitset_zero (dst);
1058 return changed;
1059 }
ef017502 1060 else if (op == BITSET_OP_OR || op == BITSET_OP_XOR)
7086e707
AD
1061 {
1062 return ebitset_copy_compare (dst, src2);
1063 }
1064 }
1065
1066 ssize1 = EBITSET_SIZE (src1);
1067 ssize2 = EBITSET_SIZE (src2);
1068 dsize = EBITSET_SIZE (dst);
1069 size = ssize1;
1070 if (size < ssize2)
1071 size = ssize2;
1072
1073 if (size > dsize)
ef017502 1074 ebitset_elts_grow (dst, size - dsize);
7086e707
AD
1075
1076 selts1 = EBITSET_ELTS (src1);
1077 selts2 = EBITSET_ELTS (src2);
1078 delts = EBITSET_ELTS (dst);
1079
1080 for (j = 0; j < size; j++)
1081 {
1082 ebitset_elt *selt1;
1083 ebitset_elt *selt2;
1084 ebitset_elt *delt;
1085
1086 selt1 = j < ssize1 ? selts1[j] : 0;
1087 selt2 = j < ssize2 ? selts2[j] : 0;
1088 delt = j < dsize ? delts[j] : 0;
1089
ef017502 1090 if (!selt1 && !selt2)
7086e707
AD
1091 {
1092 if (delt)
1093 {
1094 changed = 1;
1095 ebitset_elt_remove (dst, j);
1096 }
1097 continue;
1098 }
1099
1100 if (!selt1)
1101 selt1 = &ebitset_zero_elts[0];
1102 if (!selt2)
1103 selt2 = &ebitset_zero_elts[0];
1104 if (!delt)
1105 delt = ebitset_elt_calloc ();
1106 else
1107 delts[j] = 0;
1108
1109 srcp1 = EBITSET_WORDS (selt1);
1110 srcp2 = EBITSET_WORDS (selt2);
1111 dstp = EBITSET_WORDS (delt);
1112 switch (op)
1113 {
ef017502 1114 case BITSET_OP_OR:
7086e707
AD
1115 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1116 {
1117 bitset_word tmp = *srcp1++ | *srcp2++;
1118
1119 if (*dstp != tmp)
1120 {
1121 changed = 1;
1122 *dstp = tmp;
1123 }
1124 }
1125 break;
1126
ef017502 1127 case BITSET_OP_AND:
7086e707
AD
1128 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1129 {
1130 bitset_word tmp = *srcp1++ & *srcp2++;
1131
1132 if (*dstp != tmp)
1133 {
1134 changed = 1;
1135 *dstp = tmp;
1136 }
1137 }
1138 break;
1139
ef017502 1140 case BITSET_OP_XOR:
7086e707
AD
1141 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1142 {
1143 bitset_word tmp = *srcp1++ ^ *srcp2++;
1144
1145 if (*dstp != tmp)
1146 {
1147 changed = 1;
1148 *dstp = tmp;
1149 }
1150 }
1151 break;
1152
ef017502 1153 case BITSET_OP_ANDN:
7086e707
AD
1154 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++)
1155 {
1156 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1157
1158 if (*dstp != tmp)
1159 {
1160 changed = 1;
1161 *dstp = tmp;
1162 }
1163 }
1164 break;
1165
7086e707
AD
1166 default:
1167 abort ();
1168 }
1169
ef017502 1170 if (!ebitset_elt_zero_p (delt))
7086e707
AD
1171 {
1172 ebitset_elt_add (dst, delt, j);
1173 }
1174 else
1175 {
1176 ebitset_elt_free (delt);
1177 }
1178 }
1179
1180 /* If we have elements of DST left over, free them all. */
1181 for (; j < dsize; j++)
1182 {
1183 ebitset_elt *delt;
1184
1185 changed = 1;
1186
1187 delt = delts[j];
1188
1189 if (delt)
1190 ebitset_elt_remove (dst, j);
1191 }
1192
1193 EBITSET_NONZERO_SET (dst);
1194 return changed;
1195}
1196
1197
7086e707 1198/* Vector of operations for linked-list bitsets. */
ef017502
AD
1199struct bitset_ops_struct ebitset_ops = {
1200 ebitset_set,
1201 ebitset_reset,
1202 ebitset_test,
1203 ebitset_size,
1204 ebitset_op1,
1205 ebitset_op2,
1206 ebitset_op3,
1207 bitset_op4,
1208 ebitset_list,
1209 ebitset_reverse_list,
1210 ebitset_free,
1211 BITSET_TABLE
1212};
7086e707
AD
1213
1214
1215/* Return size of initial structure. */
1216int
1217ebitset_bytes (n_bits)
1218 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1219{
1220 return sizeof (struct bitset_struct);
1221}
1222
1223
1224/* Initialize a bitset. */
1225
1226bitset
1227ebitset_init (bset, n_bits)
1228 bitset bset;
1229 bitset_bindex n_bits;
1230{
1231 unsigned int size;
1232
ef017502 1233 bset->b.ops = &ebitset_ops;
7086e707 1234
ef017502 1235 bset->b.csize = EBITSET_ELT_WORDS;
7086e707 1236
ef017502 1237 EBITSET_OP_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
1251ebitset_release_memory ()
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}