]> git.saurik.com Git - bison.git/blame - lib/lbitset.c
Import of 2003-06-08 libbitset <http://mail.gnu.org/archive/html/bison-patches/2003...
[bison.git] / lib / lbitset.c
CommitLineData
7086e707 1/* Functions to support link list 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
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 "lbitset.h"
7086e707 25#include "obstack.h"
ef5da920 26#include <stddef.h>
7086e707 27#include <stdlib.h>
6aa452a6 28#include <stdio.h>
65d5286c 29#include <string.h>
7086e707 30
7086e707
AD
31/* This file implements linked-list bitsets. These bitsets can be of
32 arbitrary length and are more efficient than arrays of bits for
33 large sparse sets.
34
ef017502
AD
35 Usually if all the bits in an element are zero we remove the element
36 from the list. However, a side effect of the bit caching is that we
37 do not always notice when an element becomes zero. Hence the
38 lbitset_weed function which removes zero elements. */
39
40
41/* Number of words to use for each element. The larger the value the
42 greater the size of the cache and the shorter the time to find a given bit
43 but the more memory wasted for sparse bitsets and the longer the time
65d5286c
PE
44 to search for set bits.
45
46 The routines that dominate timing profiles are lbitset_elt_find
47 and lbitset_elt_link, especially when accessing the bits randomly. */
ef017502 48
ef017502 49#define LBITSET_ELT_WORDS 2
ef017502
AD
50
51typedef bitset_word lbitset_word;
52
53#define LBITSET_WORD_BITS BITSET_WORD_BITS
54
55/* Number of bits stored in each element. */
56#define LBITSET_ELT_BITS \
57 ((unsigned) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
58
59/* Lbitset element. We use an array of bits for each element.
60 These are linked together in a doubly-linked list. */
61typedef struct lbitset_elt_struct
62{
63 struct lbitset_elt_struct *next; /* Next element. */
64 struct lbitset_elt_struct *prev; /* Previous element. */
65 bitset_windex index; /* bitno / BITSET_WORD_BITS. */
66 bitset_word words[LBITSET_ELT_WORDS]; /* Bits that are set. */
67}
68lbitset_elt;
69
70
ef017502
AD
71enum lbitset_find_mode
72 { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
73
345cea78 74static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits. */
7086e707
AD
75
76/* Obstack to allocate bitset elements from. */
77static struct obstack lbitset_obstack;
d0829076 78static bool lbitset_obstack_init = false;
ef017502 79static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */
7086e707 80
ef5da920 81extern void debug_lbitset PARAMS ((bitset));
7086e707 82
ef5da920
PE
83#define LBITSET_CURRENT1(X) \
84 ((lbitset_elt *) (void *) ((char *) (X) - offsetof (lbitset_elt, words)))
7086e707 85
ef017502 86#define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->b.cdata)
7086e707 87
ef017502
AD
88#define LBITSET_HEAD(X) ((X)->l.head)
89#define LBITSET_TAIL(X) ((X)->l.tail)
7086e707
AD
90
91/* Allocate a lbitset element. The bits are not cleared. */
92static inline lbitset_elt *
829f74d2 93lbitset_elt_alloc (void)
7086e707
AD
94{
95 lbitset_elt *elt;
96
97 if (lbitset_free_list != 0)
98 {
99 elt = lbitset_free_list;
100 lbitset_free_list = elt->next;
101 }
102 else
103 {
7086e707
AD
104 if (!lbitset_obstack_init)
105 {
d0829076 106 lbitset_obstack_init = true;
7086e707
AD
107
108 /* Let particular systems override the size of a chunk. */
ef017502 109
7086e707
AD
110#ifndef OBSTACK_CHUNK_SIZE
111#define OBSTACK_CHUNK_SIZE 0
112#endif
ef017502 113
7086e707 114 /* Let them override the alloc and free routines too. */
ef017502 115
7086e707
AD
116#ifndef OBSTACK_CHUNK_ALLOC
117#define OBSTACK_CHUNK_ALLOC xmalloc
118#endif
ef017502 119
7086e707
AD
120#ifndef OBSTACK_CHUNK_FREE
121#define OBSTACK_CHUNK_FREE free
122#endif
123
124#if !defined(__GNUC__) || (__GNUC__ < 2)
125#define __alignof__(type) 0
126#endif
127
128 obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
129 __alignof__ (lbitset_elt),
ef017502
AD
130 (void *(*)PARAMS ((long)))
131 OBSTACK_CHUNK_ALLOC,
132 (void (*)PARAMS ((void *)))
133 OBSTACK_CHUNK_FREE);
7086e707
AD
134 }
135
136 /* Perhaps we should add a number of new elements to the free
ef017502 137 list. */
7086e707
AD
138 elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack,
139 sizeof (lbitset_elt));
140 }
141
142 return elt;
143}
144
145
613f5e1a 146/* Allocate a lbitset element. The bits are cleared. */
7086e707 147static inline lbitset_elt *
829f74d2 148lbitset_elt_calloc (void)
7086e707
AD
149{
150 lbitset_elt *elt;
151
152 elt = lbitset_elt_alloc ();
153 memset (elt->words, 0, sizeof (elt->words));
154 return elt;
155}
156
157
158static inline void
829f74d2 159lbitset_elt_free (lbitset_elt *elt)
7086e707
AD
160{
161 elt->next = lbitset_free_list;
162 lbitset_free_list = elt;
163}
164
165
166/* Unlink element ELT from bitset BSET. */
167static inline void
829f74d2 168lbitset_elt_unlink (bitset bset, lbitset_elt *elt)
7086e707
AD
169{
170 lbitset_elt *next = elt->next;
171 lbitset_elt *prev = elt->prev;
172
173 if (prev)
174 prev->next = next;
175
176 if (next)
177 next->prev = prev;
178
179 if (LBITSET_HEAD (bset) == elt)
180 LBITSET_HEAD (bset) = next;
181 if (LBITSET_TAIL (bset) == elt)
182 LBITSET_TAIL (bset) = prev;
183
184 /* Update cache pointer. Since the first thing we try is to insert
185 before current, make current the next entry in preference to the
186 previous. */
187 if (LBITSET_CURRENT (bset) == elt)
188 {
189 if (next)
190 {
ef017502
AD
191 bset->b.cdata = next->words;
192 bset->b.cindex = next->index;
7086e707
AD
193 }
194 else if (prev)
195 {
ef017502
AD
196 bset->b.cdata = prev->words;
197 bset->b.cindex = prev->index;
7086e707
AD
198 }
199 else
200 {
ef017502
AD
201 bset->b.csize = 0;
202 bset->b.cdata = 0;
7086e707
AD
203 }
204 }
205
206 lbitset_elt_free (elt);
207}
208
209
210/* Cut the chain of bitset BSET before element ELT and free the
211 elements. */
212static inline void
829f74d2 213lbitset_prune (bitset bset, lbitset_elt *elt)
7086e707
AD
214{
215 lbitset_elt *next;
216
217 if (!elt)
ef017502 218 return;
7086e707
AD
219
220 if (elt->prev)
ef017502 221 {
7086e707 222 LBITSET_TAIL (bset) = elt->prev;
ef017502
AD
223 bset->b.cdata = elt->prev->words;
224 bset->b.cindex = elt->prev->index;
7086e707 225 elt->prev->next = 0;
ef017502 226 }
7086e707 227 else
ef017502 228 {
7086e707
AD
229 LBITSET_HEAD (bset) = 0;
230 LBITSET_TAIL (bset) = 0;
ef017502
AD
231 bset->b.cdata = 0;
232 bset->b.csize = 0;
233 }
7086e707
AD
234
235 for (; elt; elt = next)
236 {
237 next = elt->next;
238 lbitset_elt_free (elt);
239 }
240}
241
242
d0829076
PE
243/* Are all bits in an element zero? */
244static inline bool
829f74d2 245lbitset_elt_zero_p (lbitset_elt *elt)
7086e707
AD
246{
247 int i;
248
249 for (i = 0; i < LBITSET_ELT_WORDS; i++)
250 if (elt->words[i])
d0829076 251 return false;
7086e707 252
d0829076 253 return true;
7086e707
AD
254}
255
256
257/* Link the bitset element into the current bitset linked list. */
258static inline void
829f74d2 259lbitset_elt_link (bitset bset, lbitset_elt *elt)
7086e707 260{
345cea78 261 bitset_windex windex = elt->index;
7086e707
AD
262 lbitset_elt *ptr;
263 lbitset_elt *current;
264
ef017502
AD
265 if (bset->b.csize)
266 current = LBITSET_CURRENT (bset);
7086e707 267 else
ef017502 268 current = LBITSET_HEAD (bset);
7086e707
AD
269
270 /* If this is the first and only element, add it in. */
271 if (LBITSET_HEAD (bset) == 0)
272 {
273 elt->next = elt->prev = 0;
274 LBITSET_HEAD (bset) = elt;
275 LBITSET_TAIL (bset) = elt;
276 }
277
278 /* If this index is less than that of the current element, it goes
279 somewhere before the current element. */
345cea78 280 else if (windex < bset->b.cindex)
7086e707
AD
281 {
282 for (ptr = current;
345cea78 283 ptr->prev && ptr->prev->index > windex; ptr = ptr->prev)
7086e707
AD
284 continue;
285
286 if (ptr->prev)
287 ptr->prev->next = elt;
288 else
289 LBITSET_HEAD (bset) = elt;
290
291 elt->prev = ptr->prev;
292 elt->next = ptr;
293 ptr->prev = elt;
294 }
295
296 /* Otherwise, it must go somewhere after the current element. */
297 else
298 {
299 for (ptr = current;
345cea78 300 ptr->next && ptr->next->index < windex; ptr = ptr->next)
7086e707
AD
301 continue;
302
303 if (ptr->next)
304 ptr->next->prev = elt;
305 else
306 LBITSET_TAIL (bset) = elt;
307
308 elt->next = ptr->next;
309 elt->prev = ptr;
310 ptr->next = elt;
311 }
312
313 /* Set up so this is the first element searched. */
345cea78 314 bset->b.cindex = windex;
ef017502
AD
315 bset->b.csize = LBITSET_ELT_WORDS;
316 bset->b.cdata = elt->words;
7086e707
AD
317}
318
319
320static lbitset_elt *
829f74d2
PE
321lbitset_elt_find (bitset bset, bitset_windex windex,
322 enum lbitset_find_mode mode)
7086e707
AD
323{
324 lbitset_elt *elt;
325 lbitset_elt *current;
326
ef017502 327 if (bset->b.csize)
7086e707
AD
328 {
329 current = LBITSET_CURRENT (bset);
330 /* Check if element is the cached element. */
345cea78 331 if ((windex - bset->b.cindex) < bset->b.csize)
7086e707
AD
332 return current;
333 }
334 else
335 {
336 current = LBITSET_HEAD (bset);
337 }
338
339 if (current)
340 {
345cea78 341 if (windex < bset->b.cindex)
7086e707
AD
342 {
343 for (elt = current;
345cea78 344 elt->prev && elt->index > windex; elt = elt->prev)
7086e707
AD
345 continue;
346 }
347 else
348 {
349 for (elt = current;
345cea78 350 elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
7086e707
AD
351 elt = elt->next)
352 continue;
353 }
354
6aa452a6 355 /* ELT is the nearest to the one we want. If it's not the one
7086e707 356 we want, the one we want does not exist. */
345cea78 357 if (elt && (windex - elt->index) < LBITSET_ELT_WORDS)
7086e707 358 {
ef017502
AD
359 bset->b.cindex = elt->index;
360 bset->b.csize = LBITSET_ELT_WORDS;
361 bset->b.cdata = elt->words;
7086e707
AD
362 return elt;
363 }
364 }
365
366 switch (mode)
367 {
368 case LBITSET_FIND:
369 return 0;
370
371 case LBITSET_CREATE:
5c319390 372 windex -= windex % LBITSET_ELT_WORDS;
7086e707
AD
373
374 elt = lbitset_elt_calloc ();
345cea78 375 elt->index = windex;
7086e707
AD
376 lbitset_elt_link (bset, elt);
377 return elt;
378
379 case LBITSET_SUBST:
380 return &lbitset_zero_elts[0];
381
382 default:
383 abort ();
384 }
385}
386
387
388/* Weed out the zero elements from the list. */
389static inline void
829f74d2 390lbitset_weed (bitset bset)
7086e707
AD
391{
392 lbitset_elt *elt;
393 lbitset_elt *next;
394
395 for (elt = LBITSET_HEAD (bset); elt; elt = next)
396 {
397 next = elt->next;
398 if (lbitset_elt_zero_p (elt))
399 lbitset_elt_unlink (bset, elt);
400 }
401}
402
403
404/* Set all bits in the bitset to zero. */
6aa452a6 405static void
829f74d2 406lbitset_zero (bitset bset)
7086e707
AD
407{
408 lbitset_elt *head;
409
410 head = LBITSET_HEAD (bset);
411 if (!head)
412 return;
413
414 /* Clear a bitset by freeing the linked list at the head element. */
415 lbitset_prune (bset, head);
416}
417
418
d0829076
PE
419/* Is DST == SRC? */
420static inline bool
829f74d2 421lbitset_equal_p (bitset dst, bitset src)
7086e707
AD
422{
423 lbitset_elt *selt;
424 lbitset_elt *delt;
425 int j;
426
427 if (src == dst)
d0829076 428 return true;
7086e707
AD
429
430 lbitset_weed (src);
431 lbitset_weed (dst);
432 for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
433 selt && delt; selt = selt->next, delt = delt->next)
434 {
435 if (selt->index != delt->index)
d0829076 436 return false;
7086e707
AD
437
438 for (j = 0; j < LBITSET_ELT_WORDS; j++)
439 if (delt->words[j] != selt->words[j])
d0829076 440 return false;
7086e707 441 }
ef017502 442 return !selt && !delt;
7086e707
AD
443}
444
445
446/* Copy bits from bitset SRC to bitset DST. */
447static inline void
829f74d2 448lbitset_copy (bitset dst, bitset src)
7086e707
AD
449{
450 lbitset_elt *elt;
451 lbitset_elt *head;
452 lbitset_elt *prev;
453 lbitset_elt *tmp;
454
455 if (src == dst)
456 return;
457
458 lbitset_zero (dst);
459
460 head = LBITSET_HEAD (src);
461 if (!head)
462 return;
463
464 prev = 0;
465 for (elt = head; elt; elt = elt->next)
466 {
467 tmp = lbitset_elt_alloc ();
468 tmp->index = elt->index;
469 tmp->prev = prev;
470 tmp->next = 0;
471 if (prev)
472 prev->next = tmp;
473 else
474 LBITSET_HEAD (dst) = tmp;
475 prev = tmp;
476
477 memcpy (tmp->words, elt->words, sizeof (elt->words));
478 }
479 LBITSET_TAIL (dst) = tmp;
480
ef017502
AD
481 dst->b.csize = LBITSET_ELT_WORDS;
482 dst->b.cdata = LBITSET_HEAD (dst)->words;
483 dst->b.cindex = LBITSET_HEAD (dst)->index;
7086e707
AD
484}
485
486
d0829076 487/* Copy bits from bitset SRC to bitset DST. Return true if
7086e707 488 bitsets different. */
d0829076 489static inline bool
829f74d2 490lbitset_copy_cmp (bitset dst, bitset src)
7086e707
AD
491{
492 if (src == dst)
d0829076 493 return false;
7086e707 494
ef017502 495 if (!LBITSET_HEAD (dst))
7086e707
AD
496 {
497 lbitset_copy (dst, src);
498 return LBITSET_HEAD (src) != 0;
499 }
500
501 if (lbitset_equal_p (dst, src))
d0829076 502 return false;
7086e707
AD
503
504 lbitset_copy (dst, src);
d0829076 505 return true;
7086e707
AD
506}
507
508
5c319390 509static bitset_bindex
65d5286c 510lbitset_resize (bitset src, bitset_bindex size)
7086e707 511{
65d5286c 512 BITSET_NBITS_ (src) = size;
7086e707 513
65d5286c
PE
514 /* Need to prune any excess bits. FIXME. */
515 return size;
7086e707
AD
516}
517
7086e707
AD
518/* Set bit BITNO in bitset DST. */
519static void
829f74d2 520lbitset_set (bitset dst, bitset_bindex bitno)
7086e707 521{
345cea78 522 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 523
345cea78 524 lbitset_elt_find (dst, windex, LBITSET_CREATE);
7086e707 525
c340180d
PE
526 dst->b.cdata[windex - dst->b.cindex] |=
527 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
7086e707
AD
528}
529
530
531/* Reset bit BITNO in bitset DST. */
532static void
829f74d2 533lbitset_reset (bitset dst, bitset_bindex bitno)
7086e707 534{
345cea78 535 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 536
345cea78 537 if (!lbitset_elt_find (dst, windex, LBITSET_FIND))
ef017502 538 return;
7086e707 539
c340180d
PE
540 dst->b.cdata[windex - dst->b.cindex] &=
541 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
7086e707
AD
542
543 /* If all the data is zero, perhaps we should unlink it now... */
544}
545
546
547/* Test bit BITNO in bitset SRC. */
d0829076 548static bool
829f74d2 549lbitset_test (bitset src, bitset_bindex bitno)
7086e707 550{
345cea78 551 bitset_windex windex = bitno / BITSET_WORD_BITS;
7086e707 552
d0829076
PE
553 return (lbitset_elt_find (src, windex, LBITSET_FIND)
554 && ((src->b.cdata[windex - src->b.cindex]
555 >> (bitno % BITSET_WORD_BITS))
556 & 1));
7086e707
AD
557}
558
559
560static void
829f74d2 561lbitset_free (bitset bset)
7086e707
AD
562{
563 lbitset_zero (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. */
5c319390 570static bitset_bindex
829f74d2
PE
571lbitset_list_reverse (bitset bset, bitset_bindex *list,
572 bitset_bindex num, bitset_bindex *next)
7086e707
AD
573{
574 bitset_bindex rbitno;
575 bitset_bindex bitno;
345cea78
AD
576 unsigned int bcount;
577 bitset_bindex boffset;
578 bitset_windex windex;
7086e707
AD
579 bitset_bindex count;
580 lbitset_elt *elt;
581 bitset_word word;
582 bitset_bindex n_bits;
583
584 elt = LBITSET_TAIL (bset);
585 if (!elt)
586 return 0;
587
588 n_bits = (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS;
589 rbitno = *next;
590
591 if (rbitno >= n_bits)
ef017502 592 return 0;
7086e707
AD
593
594 bitno = n_bits - (rbitno + 1);
595
345cea78 596 windex = bitno / BITSET_WORD_BITS;
7086e707
AD
597
598 /* Skip back to starting element. */
345cea78 599 for (; elt && elt->index > windex; elt = elt->prev)
7086e707
AD
600 continue;
601
602 if (!elt)
603 return 0;
604
6aa452a6
AD
605 if (windex >= elt->index + LBITSET_ELT_WORDS)
606 {
607 /* We are trying to start in no-mans land so start
608 at end of current elt. */
609 bcount = BITSET_WORD_BITS - 1;
610 windex = elt->index + LBITSET_ELT_WORDS - 1;
611 }
612 else
613 {
614 bcount = bitno % BITSET_WORD_BITS;
615 }
7086e707
AD
616
617 count = 0;
345cea78 618 boffset = windex * BITSET_WORD_BITS;
7086e707 619
6aa452a6
AD
620 /* If num is 1, we could speed things up with a binary search
621 of the word of interest. */
622
7086e707
AD
623 while (elt)
624 {
625 bitset_word *srcp = elt->words;
626
345cea78
AD
627 for (; (windex - elt->index) < LBITSET_ELT_WORDS;
628 windex--, boffset -= BITSET_WORD_BITS,
629 bcount = BITSET_WORD_BITS - 1)
7086e707 630 {
ef017502 631 word =
345cea78 632 srcp[windex - elt->index] << (BITSET_WORD_BITS - 1 - bcount);
7086e707 633
345cea78 634 for (; word; bcount--)
7086e707
AD
635 {
636 if (word & BITSET_MSB)
637 {
345cea78 638 list[count++] = boffset + bcount;
7086e707
AD
639 if (count >= num)
640 {
345cea78 641 *next = n_bits - (boffset + bcount);
7086e707
AD
642 return count;
643 }
644 }
645 word <<= 1;
646 }
647 }
648
649 elt = elt->prev;
650 if (elt)
651 {
345cea78
AD
652 windex = elt->index + LBITSET_ELT_WORDS - 1;
653 boffset = windex * BITSET_WORD_BITS;
7086e707
AD
654 }
655 }
656
345cea78 657 *next = n_bits - (boffset + 1);
7086e707
AD
658 return count;
659}
660
661
662/* Find list of up to NUM bits set in BSET starting from and including
ef017502
AD
663 *NEXT and store in array LIST. Return with actual number of bits
664 found and with *NEXT indicating where search stopped. */
5c319390 665static bitset_bindex
829f74d2
PE
666lbitset_list (bitset bset, bitset_bindex *list,
667 bitset_bindex num, bitset_bindex *next)
7086e707
AD
668{
669 bitset_bindex bitno;
345cea78 670 bitset_windex windex;
7086e707
AD
671 bitset_bindex count;
672 lbitset_elt *elt;
673 lbitset_elt *head;
674 bitset_word word;
675
676 head = LBITSET_HEAD (bset);
677 if (!head)
ef017502 678 return 0;
7086e707
AD
679
680 bitno = *next;
681 count = 0;
682
683 if (!bitno)
684 {
685 /* This is the most common case. */
686
687 /* Start with the first element. */
688 elt = head;
345cea78
AD
689 windex = elt->index;
690 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
691 }
692 else
693 {
345cea78 694 windex = bitno / BITSET_WORD_BITS;
7086e707
AD
695
696 /* Skip to starting element. */
697 for (elt = head;
345cea78 698 elt && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
7086e707
AD
699 elt = elt->next)
700 continue;
701
702 if (!elt)
703 return 0;
704
345cea78 705 if (windex < elt->index)
7086e707 706 {
345cea78
AD
707 windex = elt->index;
708 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
709 }
710 else
711 {
712 bitset_word *srcp = elt->words;
713
714 /* We are starting within an element. */
715
345cea78 716 for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
7086e707 717 {
345cea78 718 word = srcp[windex - elt->index] >> (bitno % BITSET_WORD_BITS);
7086e707
AD
719
720 for (; word; bitno++)
721 {
722 if (word & 1)
723 {
724 list[count++] = bitno;
725 if (count >= num)
726 {
727 *next = bitno + 1;
728 return count;
729 }
730 }
731 word >>= 1;
732 }
345cea78 733 bitno = (windex + 1) * BITSET_WORD_BITS;
7086e707
AD
734 }
735
736 elt = elt->next;
737 if (elt)
738 {
345cea78
AD
739 windex = elt->index;
740 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
741 }
742 }
743 }
744
745
746 /* If num is 1, we could speed things up with a binary search
747 of the word of interest. */
748
749 while (elt)
750 {
751 int i;
752 bitset_word *srcp = elt->words;
753
754 if ((count + LBITSET_ELT_BITS) < num)
755 {
756 /* The coast is clear, plant boot! */
757
758#if LBITSET_ELT_WORDS == 2
759 word = srcp[0];
760 if (word)
761 {
ef017502 762 if (!(word & 0xffff))
7086e707
AD
763 {
764 word >>= 16;
765 bitno += 16;
766 }
ef017502 767 if (!(word & 0xff))
7086e707
AD
768 {
769 word >>= 8;
770 bitno += 8;
771 }
772 for (; word; bitno++)
773 {
774 if (word & 1)
775 list[count++] = bitno;
776 word >>= 1;
777 }
778 }
345cea78
AD
779 windex++;
780 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
781
782 word = srcp[1];
783 if (word)
784 {
ef017502 785 if (!(word & 0xffff))
7086e707
AD
786 {
787 word >>= 16;
788 bitno += 16;
789 }
790 for (; word; bitno++)
791 {
792 if (word & 1)
793 list[count++] = bitno;
794 word >>= 1;
795 }
796 }
345cea78
AD
797 windex++;
798 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
799#else
800 for (i = 0; i < LBITSET_ELT_WORDS; i++)
801 {
802 word = srcp[i];
803 if (word)
804 {
ef017502 805 if (!(word & 0xffff))
7086e707
AD
806 {
807 word >>= 16;
808 bitno += 16;
809 }
ef017502 810 if (!(word & 0xff))
7086e707
AD
811 {
812 word >>= 8;
813 bitno += 8;
814 }
815 for (; word; bitno++)
816 {
817 if (word & 1)
818 list[count++] = bitno;
819 word >>= 1;
820 }
821 }
345cea78
AD
822 windex++;
823 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
824 }
825#endif
826 }
827 else
828 {
829 /* Tread more carefully since we need to check
830 if array overflows. */
831
832 for (i = 0; i < LBITSET_ELT_WORDS; i++)
833 {
834 for (word = srcp[i]; word; bitno++)
835 {
836 if (word & 1)
837 {
838 list[count++] = bitno;
839 if (count >= num)
840 {
841 *next = bitno + 1;
842 return count;
843 }
844 }
845 word >>= 1;
846 }
345cea78
AD
847 windex++;
848 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
849 }
850 }
851
852 elt = elt->next;
853 if (elt)
854 {
345cea78
AD
855 windex = elt->index;
856 bitno = windex * BITSET_WORD_BITS;
7086e707
AD
857 }
858 }
859
860 *next = bitno;
861 return count;
862}
863
864
d0829076 865static bool
829f74d2 866lbitset_empty_p (bitset dst)
6aa452a6 867{
65d5286c
PE
868 lbitset_elt *elt;
869 lbitset_elt *next;
870
871 for (elt = LBITSET_HEAD (dst); elt; elt = next)
872 {
873 next = elt->next;
874 if (!lbitset_elt_zero_p (elt))
875 return 0;
876 /* Weed as we go. */
877 lbitset_elt_unlink (dst, elt);
878 }
879
880 return 1;
881}
882
883
884/* Ensure that any unused bits within the last element are clear. */
885static inline void
886lbitset_unused_clear (dst)
887 bitset dst;
888{
889 unsigned int last_bit;
890 bitset_bindex n_bits;
891
892 n_bits = BITSET_SIZE_ (dst);
893 last_bit = n_bits % LBITSET_ELT_BITS;
894
895 if (last_bit)
896 {
897 lbitset_elt *elt;
898 bitset_windex windex;
899 bitset_word *srcp;
900
901 elt = LBITSET_TAIL (dst);
902 srcp = elt->words;
903 windex = n_bits / BITSET_WORD_BITS;
904
905 srcp[windex - elt->index] &= ((bitset_word) 1 << last_bit) - 1;
906 windex++;
907
908 for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
909 srcp[windex - elt->index] = 0;
910 }
6aa452a6
AD
911}
912
913
914static void
829f74d2 915lbitset_ones (bitset dst)
7086e707 916{
5c319390 917 bitset_windex i;
345cea78 918 bitset_windex windex;
7086e707
AD
919 lbitset_elt *elt;
920
6aa452a6
AD
921 /* This is a decidedly unfriendly operation for a linked list
922 bitset! It makes a sparse bitset become dense. An alternative
923 is to have a flag that indicates that the bitset stores the
924 complement of what it indicates. */
829f74d2 925
65d5286c
PE
926 windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
927
6aa452a6 928 for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
7086e707 929 {
6aa452a6
AD
930 /* Create new elements if they cannot be found. */
931 elt = lbitset_elt_find (dst, i, LBITSET_CREATE);
932 memset (elt->words, -1, sizeof (elt->words));
7086e707 933 }
65d5286c
PE
934
935 lbitset_unused_clear (dst);
7086e707
AD
936}
937
938
6aa452a6 939static void
829f74d2 940lbitset_not (bitset dst, bitset src)
7086e707
AD
941{
942 lbitset_elt *elt;
943 lbitset_elt *selt;
944 lbitset_elt *delt;
5c319390 945 bitset_windex i;
7086e707 946 unsigned int j;
345cea78 947 bitset_windex windex;
7086e707 948
6aa452a6
AD
949 /* This is another unfriendly operation for a linked list
950 bitset! */
951 elt = LBITSET_TAIL (dst);
829f74d2 952
65d5286c
PE
953 windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
954
6aa452a6 955 for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
7086e707 956 {
6aa452a6
AD
957 /* Create new elements for dst if they cannot be found
958 or substitute zero elements if src elements not found. */
959 selt = lbitset_elt_find (src, i, LBITSET_SUBST);
960 delt = lbitset_elt_find (dst, i, LBITSET_CREATE);
829f74d2 961
6aa452a6
AD
962 for (j = 0; j < LBITSET_ELT_WORDS; j++)
963 delt->words[j] = ~selt->words[j];
964 }
65d5286c 965 lbitset_unused_clear (dst);
6aa452a6
AD
966 lbitset_weed (dst);
967 return;
968}
7086e707 969
7086e707 970
d0829076
PE
971/* Is DST == DST | SRC? */
972static bool
829f74d2 973lbitset_subset_p (bitset dst, bitset src)
6aa452a6
AD
974{
975 lbitset_elt *selt;
976 lbitset_elt *delt;
977 unsigned int j;
7086e707 978
6aa452a6
AD
979 for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
980 selt || delt; selt = selt->next, delt = delt->next)
981 {
982 if (!selt)
983 selt = &lbitset_zero_elts[0];
984 else if (!delt)
985 delt = &lbitset_zero_elts[0];
986 else if (selt->index != delt->index)
7086e707 987 {
6aa452a6 988 if (selt->index < delt->index)
7086e707 989 {
6aa452a6
AD
990 lbitset_zero_elts[2].next = delt;
991 delt = &lbitset_zero_elts[2];
992 }
993 else
994 {
995 lbitset_zero_elts[1].next = selt;
996 selt = &lbitset_zero_elts[1];
7086e707 997 }
7086e707 998 }
829f74d2 999
6aa452a6
AD
1000 for (j = 0; j < LBITSET_ELT_WORDS; j++)
1001 if (delt->words[j] != (selt->words[j] | delt->words[j]))
d0829076 1002 return false;
6aa452a6 1003 }
d0829076 1004 return true;
6aa452a6
AD
1005}
1006
7086e707 1007
d0829076
PE
1008/* Is DST & SRC == 0? */
1009static bool
829f74d2 1010lbitset_disjoint_p (bitset dst, bitset src)
6aa452a6
AD
1011{
1012 lbitset_elt *selt;
1013 lbitset_elt *delt;
1014 unsigned int j;
1015
1016 for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
1017 selt && delt; selt = selt->next, delt = delt->next)
1018 {
1019 if (selt->index != delt->index)
ef017502 1020 {
6aa452a6 1021 if (selt->index < delt->index)
ef017502 1022 {
6aa452a6
AD
1023 lbitset_zero_elts[2].next = delt;
1024 delt = &lbitset_zero_elts[2];
ef017502 1025 }
6aa452a6
AD
1026 else
1027 {
1028 lbitset_zero_elts[1].next = selt;
1029 selt = &lbitset_zero_elts[1];
1030 }
1031 /* Since the elements are different, there is no
1032 intersection of these elements. */
1033 continue;
ef017502 1034 }
829f74d2 1035
6aa452a6
AD
1036 for (j = 0; j < LBITSET_ELT_WORDS; j++)
1037 if (selt->words[j] & delt->words[j])
d0829076 1038 return false;
7086e707 1039 }
d0829076 1040 return true;
7086e707
AD
1041}
1042
1043
d0829076 1044static bool
829f74d2 1045lbitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
7086e707
AD
1046{
1047 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1048 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1049 lbitset_elt *delt = LBITSET_HEAD (dst);
345cea78
AD
1050 bitset_windex windex1;
1051 bitset_windex windex2;
1052 bitset_windex windex;
7086e707
AD
1053 lbitset_elt *stmp1;
1054 lbitset_elt *stmp2;
1055 lbitset_elt *dtmp;
1056 bitset_word *srcp1;
1057 bitset_word *srcp2;
1058 bitset_word *dstp;
d0829076 1059 bool changed = false;
7086e707
AD
1060 unsigned int i;
1061
7086e707 1062 LBITSET_HEAD (dst) = 0;
ef017502 1063 dst->b.csize = 0;
7086e707 1064
5c319390
PE
1065 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
1066 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
7086e707
AD
1067
1068 while (selt1 || selt2)
1069 {
1070 /* Figure out whether we need to substitute zero elements for
1071 missing links. */
345cea78 1072 if (windex1 == windex2)
7086e707 1073 {
345cea78 1074 windex = windex1;
7086e707
AD
1075 stmp1 = selt1;
1076 stmp2 = selt2;
1077 selt1 = selt1->next;
5c319390 1078 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
7086e707 1079 selt2 = selt2->next;
5c319390 1080 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
7086e707 1081 }
345cea78 1082 else if (windex1 < windex2)
7086e707 1083 {
345cea78 1084 windex = windex1;
7086e707
AD
1085 stmp1 = selt1;
1086 stmp2 = &lbitset_zero_elts[0];
1087 selt1 = selt1->next;
5c319390 1088 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
7086e707
AD
1089 }
1090 else
1091 {
345cea78 1092 windex = windex2;
7086e707
AD
1093 stmp1 = &lbitset_zero_elts[0];
1094 stmp2 = selt2;
1095 selt2 = selt2->next;
5c319390 1096 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
7086e707
AD
1097 }
1098
1099 /* Find the appropriate element from DST. Begin by discarding
1100 elements that we've skipped. */
345cea78 1101 while (delt && delt->index < windex)
7086e707 1102 {
d0829076 1103 changed = true;
7086e707
AD
1104 dtmp = delt;
1105 delt = delt->next;
1106 lbitset_elt_free (dtmp);
1107 }
345cea78 1108 if (delt && delt->index == windex)
7086e707
AD
1109 {
1110 dtmp = delt;
1111 delt = delt->next;
1112 }
1113 else
1114 dtmp = lbitset_elt_calloc ();
1115
1116 /* Do the operation, and if any bits are set, link it into the
1117 linked list. */
1118 srcp1 = stmp1->words;
1119 srcp2 = stmp2->words;
1120 dstp = dtmp->words;
1121 switch (op)
1122 {
ef017502 1123 case BITSET_OP_OR:
7086e707
AD
1124 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1125 {
1126 bitset_word tmp = *srcp1++ | *srcp2++;
1127
1128 if (*dstp != tmp)
1129 {
d0829076 1130 changed = true;
7086e707
AD
1131 *dstp = tmp;
1132 }
1133 }
1134 break;
1135
ef017502 1136 case BITSET_OP_AND:
7086e707
AD
1137 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1138 {
1139 bitset_word tmp = *srcp1++ & *srcp2++;
1140
1141 if (*dstp != tmp)
1142 {
d0829076 1143 changed = true;
7086e707
AD
1144 *dstp = tmp;
1145 }
1146 }
1147 break;
1148
ef017502 1149 case BITSET_OP_XOR:
7086e707
AD
1150 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1151 {
1152 bitset_word tmp = *srcp1++ ^ *srcp2++;
1153
1154 if (*dstp != tmp)
1155 {
d0829076 1156 changed = true;
7086e707
AD
1157 *dstp = tmp;
1158 }
1159 }
1160 break;
1161
ef017502 1162 case BITSET_OP_ANDN:
7086e707
AD
1163 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1164 {
1165 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1166
1167 if (*dstp != tmp)
1168 {
d0829076 1169 changed = true;
7086e707
AD
1170 *dstp = tmp;
1171 }
1172 }
1173 break;
1174
7086e707
AD
1175 default:
1176 abort ();
1177 }
1178
ef017502 1179 if (!lbitset_elt_zero_p (dtmp))
7086e707 1180 {
345cea78 1181 dtmp->index = windex;
7086e707
AD
1182 /* Perhaps this could be optimised... */
1183 lbitset_elt_link (dst, dtmp);
1184 }
1185 else
1186 {
1187 lbitset_elt_free (dtmp);
1188 }
1189 }
1190
1191 /* If we have elements of DST left over, free them all. */
1192 if (delt)
1193 {
d0829076 1194 changed = true;
7086e707
AD
1195 lbitset_prune (dst, delt);
1196 }
1197
1198 return changed;
1199}
1200
1201
d0829076 1202static bool
829f74d2 1203lbitset_and_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1204{
1205 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1206 lbitset_elt *selt2 = LBITSET_HEAD (src2);
d0829076 1207 bool changed;
6aa452a6
AD
1208
1209 if (!selt2)
1210 {
1211 lbitset_weed (dst);
1212 changed = !LBITSET_HEAD (dst);
1213 lbitset_zero (dst);
1214 return changed;
1215 }
1216 else if (!selt1)
1217 {
1218 lbitset_weed (dst);
1219 changed = !LBITSET_HEAD (dst);
1220 lbitset_zero (dst);
1221 return changed;
1222 }
1223 return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_AND);
1224}
1225
1226
ef5da920 1227static void
829f74d2 1228lbitset_and (bitset dst, bitset src1, bitset src2)
ef5da920 1229{
829f74d2 1230 lbitset_and_cmp (dst, src1, src2);
ef5da920
PE
1231}
1232
1233
d0829076 1234static bool
829f74d2 1235lbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1236{
1237 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1238 lbitset_elt *selt2 = LBITSET_HEAD (src2);
d0829076 1239 bool changed;
6aa452a6
AD
1240
1241 if (!selt2)
1242 {
1243 return lbitset_copy_cmp (dst, src1);
1244 }
1245 else if (!selt1)
1246 {
1247 lbitset_weed (dst);
1248 changed = !LBITSET_HEAD (dst);
1249 lbitset_zero (dst);
1250 return changed;
1251 }
1252 return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_ANDN);
1253}
1254
1255
ef5da920 1256static void
829f74d2 1257lbitset_andn (bitset dst, bitset src1, bitset src2)
ef5da920 1258{
829f74d2 1259 lbitset_andn_cmp (dst, src1, src2);
ef5da920
PE
1260}
1261
1262
d0829076 1263static bool
829f74d2 1264lbitset_or_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1265{
1266 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1267 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1268
1269 if (!selt2)
1270 {
1271 return lbitset_copy_cmp (dst, src1);
1272 }
1273 else if (!selt1)
1274 {
1275 return lbitset_copy_cmp (dst, src2);
1276 }
1277 return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_OR);
1278}
1279
1280
ef5da920 1281static void
829f74d2 1282lbitset_or (bitset dst, bitset src1, bitset src2)
ef5da920 1283{
829f74d2 1284 lbitset_or_cmp (dst, src1, src2);
ef5da920
PE
1285}
1286
1287
d0829076 1288static bool
829f74d2 1289lbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
6aa452a6
AD
1290{
1291 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1292 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1293
1294 if (!selt2)
1295 {
1296 return lbitset_copy_cmp (dst, src1);
1297 }
1298 else if (!selt1)
1299 {
1300 return lbitset_copy_cmp (dst, src2);
1301 }
1302 return lbitset_op3_cmp (dst, src1, src2, BITSET_OP_XOR);
1303}
1304
1305
829f74d2
PE
1306static void
1307lbitset_xor (bitset dst, bitset src1, bitset src2)
1308{
1309 lbitset_xor_cmp (dst, src1, src2);
1310}
1311
1312
6aa452a6 1313
7086e707 1314/* Vector of operations for linked-list bitsets. */
6aa452a6 1315struct bitset_vtable lbitset_vtable = {
ef017502
AD
1316 lbitset_set,
1317 lbitset_reset,
6aa452a6 1318 bitset_toggle_,
ef017502 1319 lbitset_test,
65d5286c
PE
1320 lbitset_resize,
1321 bitset_size_,
6aa452a6
AD
1322 bitset_count_,
1323 lbitset_empty_p,
1324 lbitset_ones,
1325 lbitset_zero,
1326 lbitset_copy,
1327 lbitset_disjoint_p,
1328 lbitset_equal_p,
1329 lbitset_not,
1330 lbitset_subset_p,
ef5da920 1331 lbitset_and,
6aa452a6 1332 lbitset_and_cmp,
ef5da920 1333 lbitset_andn,
6aa452a6 1334 lbitset_andn_cmp,
ef5da920 1335 lbitset_or,
6aa452a6 1336 lbitset_or_cmp,
ef5da920 1337 lbitset_xor,
6aa452a6 1338 lbitset_xor_cmp,
ef5da920 1339 bitset_and_or_,
6aa452a6 1340 bitset_and_or_cmp_,
ef5da920 1341 bitset_andn_or_,
6aa452a6 1342 bitset_andn_or_cmp_,
ef5da920 1343 bitset_or_and_,
6aa452a6 1344 bitset_or_and_cmp_,
ef017502 1345 lbitset_list,
6aa452a6 1346 lbitset_list_reverse,
ef017502
AD
1347 lbitset_free,
1348 BITSET_LIST
1349};
7086e707
AD
1350
1351
1352/* Return size of initial structure. */
5c319390 1353size_t
829f74d2 1354lbitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED)
7086e707 1355{
ef5da920 1356 return sizeof (struct lbitset_struct);
7086e707
AD
1357}
1358
1359
1360/* Initialize a bitset. */
7086e707 1361bitset
829f74d2 1362lbitset_init (bitset bset, bitset_bindex n_bits ATTRIBUTE_UNUSED)
7086e707 1363{
65d5286c 1364 BITSET_NBITS_ (bset) = n_bits;
6aa452a6 1365 bset->b.vtable = &lbitset_vtable;
7086e707
AD
1366 return bset;
1367}
1368
1369
1370void
829f74d2 1371lbitset_release_memory (void)
7086e707
AD
1372{
1373 lbitset_free_list = 0;
1374 if (lbitset_obstack_init)
1375 {
d0829076 1376 lbitset_obstack_init = false;
7086e707
AD
1377 obstack_free (&lbitset_obstack, NULL);
1378 }
1379}
6aa452a6
AD
1380
1381
1382/* Function to be called from debugger to debug lbitset. */
1383void
829f74d2 1384debug_lbitset (bitset bset)
6aa452a6
AD
1385{
1386 lbitset_elt *elt;
1387 unsigned int i;
1388
1389 if (!bset)
1390 return;
829f74d2 1391
6aa452a6
AD
1392 for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
1393 {
5c319390 1394 fprintf (stderr, "Elt %lu\n", (unsigned long) elt->index);
6aa452a6
AD
1395 for (i = 0; i < LBITSET_ELT_WORDS; i++)
1396 {
1397 unsigned int j;
1398 bitset_word word;
829f74d2 1399
6aa452a6 1400 word = elt->words[i];
829f74d2 1401
5c319390 1402 fprintf (stderr, " Word %u:", i);
6aa452a6 1403 for (j = 0; j < LBITSET_WORD_BITS; j++)
09147be0 1404 if ((word & ((bitset_word) 1 << j)))
5c319390 1405 fprintf (stderr, " %u", j);
6aa452a6
AD
1406 fprintf (stderr, "\n");
1407 }
1408 }
1409}