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