]> git.saurik.com Git - bison.git/blob - lib/lbitset.c
6b0a50b85299e13c785a09924ee997c08d266c2b
[bison.git] / lib / lbitset.c
1 /* Functions to support link list bitsets.
2 Copyright (C) 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
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.
9
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.
14
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
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "lbitset.h"
25 #include "obstack.h"
26 #include <stddef.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
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
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
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. */
48
49 #define LBITSET_ELT_WORDS 2
50
51 typedef 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. */
61 typedef 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 }
68 lbitset_elt;
69
70
71 enum lbitset_find_mode
72 { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
73
74 static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits. */
75
76 /* Obstack to allocate bitset elements from. */
77 static struct obstack lbitset_obstack;
78 static bool lbitset_obstack_init = false;
79 static lbitset_elt *lbitset_free_list; /* Free list of bitset elements. */
80
81 extern void debug_lbitset PARAMS ((bitset));
82
83 #define LBITSET_CURRENT1(X) \
84 ((lbitset_elt *) (void *) ((char *) (X) - offsetof (lbitset_elt, words)))
85
86 #define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->b.cdata)
87
88 #define LBITSET_HEAD(X) ((X)->l.head)
89 #define LBITSET_TAIL(X) ((X)->l.tail)
90
91 /* Allocate a lbitset element. The bits are not cleared. */
92 static inline lbitset_elt *
93 lbitset_elt_alloc (void)
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 {
104 if (!lbitset_obstack_init)
105 {
106 lbitset_obstack_init = true;
107
108 /* Let particular systems override the size of a chunk. */
109
110 #ifndef OBSTACK_CHUNK_SIZE
111 #define OBSTACK_CHUNK_SIZE 0
112 #endif
113
114 /* Let them override the alloc and free routines too. */
115
116 #ifndef OBSTACK_CHUNK_ALLOC
117 #define OBSTACK_CHUNK_ALLOC xmalloc
118 #endif
119
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),
130 (void *(*)PARAMS ((long)))
131 OBSTACK_CHUNK_ALLOC,
132 (void (*)PARAMS ((void *)))
133 OBSTACK_CHUNK_FREE);
134 }
135
136 /* Perhaps we should add a number of new elements to the free
137 list. */
138 elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack,
139 sizeof (lbitset_elt));
140 }
141
142 return elt;
143 }
144
145
146 /* Allocate a lbitset element. The bits are cleared. */
147 static inline lbitset_elt *
148 lbitset_elt_calloc (void)
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
158 static inline void
159 lbitset_elt_free (lbitset_elt *elt)
160 {
161 elt->next = lbitset_free_list;
162 lbitset_free_list = elt;
163 }
164
165
166 /* Unlink element ELT from bitset BSET. */
167 static inline void
168 lbitset_elt_unlink (bitset bset, lbitset_elt *elt)
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 {
191 bset->b.cdata = next->words;
192 bset->b.cindex = next->index;
193 }
194 else if (prev)
195 {
196 bset->b.cdata = prev->words;
197 bset->b.cindex = prev->index;
198 }
199 else
200 {
201 bset->b.csize = 0;
202 bset->b.cdata = 0;
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. */
212 static inline void
213 lbitset_prune (bitset bset, lbitset_elt *elt)
214 {
215 lbitset_elt *next;
216
217 if (!elt)
218 return;
219
220 if (elt->prev)
221 {
222 LBITSET_TAIL (bset) = elt->prev;
223 bset->b.cdata = elt->prev->words;
224 bset->b.cindex = elt->prev->index;
225 elt->prev->next = 0;
226 }
227 else
228 {
229 LBITSET_HEAD (bset) = 0;
230 LBITSET_TAIL (bset) = 0;
231 bset->b.cdata = 0;
232 bset->b.csize = 0;
233 }
234
235 for (; elt; elt = next)
236 {
237 next = elt->next;
238 lbitset_elt_free (elt);
239 }
240 }
241
242
243 /* Are all bits in an element zero? */
244 static inline bool
245 lbitset_elt_zero_p (lbitset_elt *elt)
246 {
247 int i;
248
249 for (i = 0; i < LBITSET_ELT_WORDS; i++)
250 if (elt->words[i])
251 return false;
252
253 return true;
254 }
255
256
257 /* Link the bitset element into the current bitset linked list. */
258 static inline void
259 lbitset_elt_link (bitset bset, lbitset_elt *elt)
260 {
261 bitset_windex windex = elt->index;
262 lbitset_elt *ptr;
263 lbitset_elt *current;
264
265 if (bset->b.csize)
266 current = LBITSET_CURRENT (bset);
267 else
268 current = LBITSET_HEAD (bset);
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. */
280 else if (windex < bset->b.cindex)
281 {
282 for (ptr = current;
283 ptr->prev && ptr->prev->index > windex; ptr = ptr->prev)
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;
300 ptr->next && ptr->next->index < windex; ptr = ptr->next)
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. */
314 bset->b.cindex = windex;
315 bset->b.csize = LBITSET_ELT_WORDS;
316 bset->b.cdata = elt->words;
317 }
318
319
320 static lbitset_elt *
321 lbitset_elt_find (bitset bset, bitset_windex windex,
322 enum lbitset_find_mode mode)
323 {
324 lbitset_elt *elt;
325 lbitset_elt *current;
326
327 if (bset->b.csize)
328 {
329 current = LBITSET_CURRENT (bset);
330 /* Check if element is the cached element. */
331 if ((windex - bset->b.cindex) < bset->b.csize)
332 return current;
333 }
334 else
335 {
336 current = LBITSET_HEAD (bset);
337 }
338
339 if (current)
340 {
341 if (windex < bset->b.cindex)
342 {
343 for (elt = current;
344 elt->prev && elt->index > windex; elt = elt->prev)
345 continue;
346 }
347 else
348 {
349 for (elt = current;
350 elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
351 elt = elt->next)
352 continue;
353 }
354
355 /* ELT is the nearest to the one we want. If it's not the one
356 we want, the one we want does not exist. */
357 if (elt && (windex - elt->index) < LBITSET_ELT_WORDS)
358 {
359 bset->b.cindex = elt->index;
360 bset->b.csize = LBITSET_ELT_WORDS;
361 bset->b.cdata = elt->words;
362 return elt;
363 }
364 }
365
366 switch (mode)
367 {
368 case LBITSET_FIND:
369 return 0;
370
371 case LBITSET_CREATE:
372 windex -= windex % LBITSET_ELT_WORDS;
373
374 elt = lbitset_elt_calloc ();
375 elt->index = windex;
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. */
389 static inline void
390 lbitset_weed (bitset bset)
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. */
405 static void
406 lbitset_zero (bitset bset)
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
419 /* Is DST == SRC? */
420 static inline bool
421 lbitset_equal_p (bitset dst, bitset src)
422 {
423 lbitset_elt *selt;
424 lbitset_elt *delt;
425 int j;
426
427 if (src == dst)
428 return true;
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)
436 return false;
437
438 for (j = 0; j < LBITSET_ELT_WORDS; j++)
439 if (delt->words[j] != selt->words[j])
440 return false;
441 }
442 return !selt && !delt;
443 }
444
445
446 /* Copy bits from bitset SRC to bitset DST. */
447 static inline void
448 lbitset_copy (bitset dst, bitset src)
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
481 dst->b.csize = LBITSET_ELT_WORDS;
482 dst->b.cdata = LBITSET_HEAD (dst)->words;
483 dst->b.cindex = LBITSET_HEAD (dst)->index;
484 }
485
486
487 /* Copy bits from bitset SRC to bitset DST. Return true if
488 bitsets different. */
489 static inline bool
490 lbitset_copy_cmp (bitset dst, bitset src)
491 {
492 if (src == dst)
493 return false;
494
495 if (!LBITSET_HEAD (dst))
496 {
497 lbitset_copy (dst, src);
498 return LBITSET_HEAD (src) != 0;
499 }
500
501 if (lbitset_equal_p (dst, src))
502 return false;
503
504 lbitset_copy (dst, src);
505 return true;
506 }
507
508
509 static bitset_bindex
510 lbitset_resize (bitset src, bitset_bindex size)
511 {
512 BITSET_NBITS_ (src) = size;
513
514 /* Need to prune any excess bits. FIXME. */
515 return size;
516 }
517
518 /* Set bit BITNO in bitset DST. */
519 static void
520 lbitset_set (bitset dst, bitset_bindex bitno)
521 {
522 bitset_windex windex = bitno / BITSET_WORD_BITS;
523
524 lbitset_elt_find (dst, windex, LBITSET_CREATE);
525
526 dst->b.cdata[windex - dst->b.cindex] |=
527 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
528 }
529
530
531 /* Reset bit BITNO in bitset DST. */
532 static void
533 lbitset_reset (bitset dst, bitset_bindex bitno)
534 {
535 bitset_windex windex = bitno / BITSET_WORD_BITS;
536
537 if (!lbitset_elt_find (dst, windex, LBITSET_FIND))
538 return;
539
540 dst->b.cdata[windex - dst->b.cindex] &=
541 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
542
543 /* If all the data is zero, perhaps we should unlink it now... */
544 }
545
546
547 /* Test bit BITNO in bitset SRC. */
548 static bool
549 lbitset_test (bitset src, bitset_bindex bitno)
550 {
551 bitset_windex windex = bitno / BITSET_WORD_BITS;
552
553 return (lbitset_elt_find (src, windex, LBITSET_FIND)
554 && ((src->b.cdata[windex - src->b.cindex]
555 >> (bitno % BITSET_WORD_BITS))
556 & 1));
557 }
558
559
560 static void
561 lbitset_free (bitset bset)
562 {
563 lbitset_zero (bset);
564 }
565
566
567 /* Find list of up to NUM bits set in BSET starting from and including
568 *NEXT and store in array LIST. Return with actual number of bits
569 found and with *NEXT indicating where search stopped. */
570 static bitset_bindex
571 lbitset_list_reverse (bitset bset, bitset_bindex *list,
572 bitset_bindex num, bitset_bindex *next)
573 {
574 bitset_bindex rbitno;
575 bitset_bindex bitno;
576 unsigned int bcount;
577 bitset_bindex boffset;
578 bitset_windex windex;
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)
592 return 0;
593
594 bitno = n_bits - (rbitno + 1);
595
596 windex = bitno / BITSET_WORD_BITS;
597
598 /* Skip back to starting element. */
599 for (; elt && elt->index > windex; elt = elt->prev)
600 continue;
601
602 if (!elt)
603 return 0;
604
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 }
616
617 count = 0;
618 boffset = windex * BITSET_WORD_BITS;
619
620 /* If num is 1, we could speed things up with a binary search
621 of the word of interest. */
622
623 while (elt)
624 {
625 bitset_word *srcp = elt->words;
626
627 for (; (windex - elt->index) < LBITSET_ELT_WORDS;
628 windex--, boffset -= BITSET_WORD_BITS,
629 bcount = BITSET_WORD_BITS - 1)
630 {
631 word =
632 srcp[windex - elt->index] << (BITSET_WORD_BITS - 1 - bcount);
633
634 for (; word; bcount--)
635 {
636 if (word & BITSET_MSB)
637 {
638 list[count++] = boffset + bcount;
639 if (count >= num)
640 {
641 *next = n_bits - (boffset + bcount);
642 return count;
643 }
644 }
645 word <<= 1;
646 }
647 }
648
649 elt = elt->prev;
650 if (elt)
651 {
652 windex = elt->index + LBITSET_ELT_WORDS - 1;
653 boffset = windex * BITSET_WORD_BITS;
654 }
655 }
656
657 *next = n_bits - (boffset + 1);
658 return count;
659 }
660
661
662 /* Find list of up to NUM bits set in BSET starting from and including
663 *NEXT and store in array LIST. Return with actual number of bits
664 found and with *NEXT indicating where search stopped. */
665 static bitset_bindex
666 lbitset_list (bitset bset, bitset_bindex *list,
667 bitset_bindex num, bitset_bindex *next)
668 {
669 bitset_bindex bitno;
670 bitset_windex windex;
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)
678 return 0;
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;
689 windex = elt->index;
690 bitno = windex * BITSET_WORD_BITS;
691 }
692 else
693 {
694 windex = bitno / BITSET_WORD_BITS;
695
696 /* Skip to starting element. */
697 for (elt = head;
698 elt && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
699 elt = elt->next)
700 continue;
701
702 if (!elt)
703 return 0;
704
705 if (windex < elt->index)
706 {
707 windex = elt->index;
708 bitno = windex * BITSET_WORD_BITS;
709 }
710 else
711 {
712 bitset_word *srcp = elt->words;
713
714 /* We are starting within an element. */
715
716 for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
717 {
718 word = srcp[windex - elt->index] >> (bitno % BITSET_WORD_BITS);
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 }
733 bitno = (windex + 1) * BITSET_WORD_BITS;
734 }
735
736 elt = elt->next;
737 if (elt)
738 {
739 windex = elt->index;
740 bitno = windex * BITSET_WORD_BITS;
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 {
762 if (!(word & 0xffff))
763 {
764 word >>= 16;
765 bitno += 16;
766 }
767 if (!(word & 0xff))
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 }
779 windex++;
780 bitno = windex * BITSET_WORD_BITS;
781
782 word = srcp[1];
783 if (word)
784 {
785 if (!(word & 0xffff))
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 }
797 windex++;
798 bitno = windex * BITSET_WORD_BITS;
799 #else
800 for (i = 0; i < LBITSET_ELT_WORDS; i++)
801 {
802 word = srcp[i];
803 if (word)
804 {
805 if (!(word & 0xffff))
806 {
807 word >>= 16;
808 bitno += 16;
809 }
810 if (!(word & 0xff))
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 }
822 windex++;
823 bitno = windex * BITSET_WORD_BITS;
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 }
847 windex++;
848 bitno = windex * BITSET_WORD_BITS;
849 }
850 }
851
852 elt = elt->next;
853 if (elt)
854 {
855 windex = elt->index;
856 bitno = windex * BITSET_WORD_BITS;
857 }
858 }
859
860 *next = bitno;
861 return count;
862 }
863
864
865 static bool
866 lbitset_empty_p (bitset dst)
867 {
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. */
885 static inline void
886 lbitset_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 }
911 }
912
913
914 static void
915 lbitset_ones (bitset dst)
916 {
917 bitset_windex i;
918 bitset_windex windex;
919 lbitset_elt *elt;
920
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. */
925
926 windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
927
928 for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
929 {
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));
933 }
934
935 lbitset_unused_clear (dst);
936 }
937
938
939 static void
940 lbitset_not (bitset dst, bitset src)
941 {
942 lbitset_elt *elt;
943 lbitset_elt *selt;
944 lbitset_elt *delt;
945 bitset_windex i;
946 unsigned int j;
947 bitset_windex windex;
948
949 /* This is another unfriendly operation for a linked list
950 bitset! */
951 elt = LBITSET_TAIL (dst);
952
953 windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
954
955 for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
956 {
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);
961
962 for (j = 0; j < LBITSET_ELT_WORDS; j++)
963 delt->words[j] = ~selt->words[j];
964 }
965 lbitset_unused_clear (dst);
966 lbitset_weed (dst);
967 return;
968 }
969
970
971 /* Is DST == DST | SRC? */
972 static bool
973 lbitset_subset_p (bitset dst, bitset src)
974 {
975 lbitset_elt *selt;
976 lbitset_elt *delt;
977 unsigned int j;
978
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)
987 {
988 if (selt->index < delt->index)
989 {
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];
997 }
998 }
999
1000 for (j = 0; j < LBITSET_ELT_WORDS; j++)
1001 if (delt->words[j] != (selt->words[j] | delt->words[j]))
1002 return false;
1003 }
1004 return true;
1005 }
1006
1007
1008 /* Is DST & SRC == 0? */
1009 static bool
1010 lbitset_disjoint_p (bitset dst, bitset src)
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)
1020 {
1021 if (selt->index < delt->index)
1022 {
1023 lbitset_zero_elts[2].next = delt;
1024 delt = &lbitset_zero_elts[2];
1025 }
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;
1034 }
1035
1036 for (j = 0; j < LBITSET_ELT_WORDS; j++)
1037 if (selt->words[j] & delt->words[j])
1038 return false;
1039 }
1040 return true;
1041 }
1042
1043
1044 static bool
1045 lbitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
1046 {
1047 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1048 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1049 lbitset_elt *delt = LBITSET_HEAD (dst);
1050 bitset_windex windex1;
1051 bitset_windex windex2;
1052 bitset_windex windex;
1053 lbitset_elt *stmp1;
1054 lbitset_elt *stmp2;
1055 lbitset_elt *dtmp;
1056 bitset_word *srcp1;
1057 bitset_word *srcp2;
1058 bitset_word *dstp;
1059 bool changed = false;
1060 unsigned int i;
1061
1062 LBITSET_HEAD (dst) = 0;
1063 dst->b.csize = 0;
1064
1065 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
1066 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
1067
1068 while (selt1 || selt2)
1069 {
1070 /* Figure out whether we need to substitute zero elements for
1071 missing links. */
1072 if (windex1 == windex2)
1073 {
1074 windex = windex1;
1075 stmp1 = selt1;
1076 stmp2 = selt2;
1077 selt1 = selt1->next;
1078 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
1079 selt2 = selt2->next;
1080 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
1081 }
1082 else if (windex1 < windex2)
1083 {
1084 windex = windex1;
1085 stmp1 = selt1;
1086 stmp2 = &lbitset_zero_elts[0];
1087 selt1 = selt1->next;
1088 windex1 = (selt1) ? selt1->index : BITSET_WINDEX_MAX;
1089 }
1090 else
1091 {
1092 windex = windex2;
1093 stmp1 = &lbitset_zero_elts[0];
1094 stmp2 = selt2;
1095 selt2 = selt2->next;
1096 windex2 = (selt2) ? selt2->index : BITSET_WINDEX_MAX;
1097 }
1098
1099 /* Find the appropriate element from DST. Begin by discarding
1100 elements that we've skipped. */
1101 while (delt && delt->index < windex)
1102 {
1103 changed = true;
1104 dtmp = delt;
1105 delt = delt->next;
1106 lbitset_elt_free (dtmp);
1107 }
1108 if (delt && delt->index == windex)
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 {
1123 case BITSET_OP_OR:
1124 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1125 {
1126 bitset_word tmp = *srcp1++ | *srcp2++;
1127
1128 if (*dstp != tmp)
1129 {
1130 changed = true;
1131 *dstp = tmp;
1132 }
1133 }
1134 break;
1135
1136 case BITSET_OP_AND:
1137 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1138 {
1139 bitset_word tmp = *srcp1++ & *srcp2++;
1140
1141 if (*dstp != tmp)
1142 {
1143 changed = true;
1144 *dstp = tmp;
1145 }
1146 }
1147 break;
1148
1149 case BITSET_OP_XOR:
1150 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1151 {
1152 bitset_word tmp = *srcp1++ ^ *srcp2++;
1153
1154 if (*dstp != tmp)
1155 {
1156 changed = true;
1157 *dstp = tmp;
1158 }
1159 }
1160 break;
1161
1162 case BITSET_OP_ANDN:
1163 for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
1164 {
1165 bitset_word tmp = *srcp1++ & ~(*srcp2++);
1166
1167 if (*dstp != tmp)
1168 {
1169 changed = true;
1170 *dstp = tmp;
1171 }
1172 }
1173 break;
1174
1175 default:
1176 abort ();
1177 }
1178
1179 if (!lbitset_elt_zero_p (dtmp))
1180 {
1181 dtmp->index = windex;
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 {
1194 changed = true;
1195 lbitset_prune (dst, delt);
1196 }
1197
1198 return changed;
1199 }
1200
1201
1202 static bool
1203 lbitset_and_cmp (bitset dst, bitset src1, bitset src2)
1204 {
1205 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1206 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1207 bool changed;
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
1227 static void
1228 lbitset_and (bitset dst, bitset src1, bitset src2)
1229 {
1230 lbitset_and_cmp (dst, src1, src2);
1231 }
1232
1233
1234 static bool
1235 lbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
1236 {
1237 lbitset_elt *selt1 = LBITSET_HEAD (src1);
1238 lbitset_elt *selt2 = LBITSET_HEAD (src2);
1239 bool changed;
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
1256 static void
1257 lbitset_andn (bitset dst, bitset src1, bitset src2)
1258 {
1259 lbitset_andn_cmp (dst, src1, src2);
1260 }
1261
1262
1263 static bool
1264 lbitset_or_cmp (bitset dst, bitset src1, bitset src2)
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
1281 static void
1282 lbitset_or (bitset dst, bitset src1, bitset src2)
1283 {
1284 lbitset_or_cmp (dst, src1, src2);
1285 }
1286
1287
1288 static bool
1289 lbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
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
1306 static void
1307 lbitset_xor (bitset dst, bitset src1, bitset src2)
1308 {
1309 lbitset_xor_cmp (dst, src1, src2);
1310 }
1311
1312
1313
1314 /* Vector of operations for linked-list bitsets. */
1315 struct bitset_vtable lbitset_vtable = {
1316 lbitset_set,
1317 lbitset_reset,
1318 bitset_toggle_,
1319 lbitset_test,
1320 lbitset_resize,
1321 bitset_size_,
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,
1331 lbitset_and,
1332 lbitset_and_cmp,
1333 lbitset_andn,
1334 lbitset_andn_cmp,
1335 lbitset_or,
1336 lbitset_or_cmp,
1337 lbitset_xor,
1338 lbitset_xor_cmp,
1339 bitset_and_or_,
1340 bitset_and_or_cmp_,
1341 bitset_andn_or_,
1342 bitset_andn_or_cmp_,
1343 bitset_or_and_,
1344 bitset_or_and_cmp_,
1345 lbitset_list,
1346 lbitset_list_reverse,
1347 lbitset_free,
1348 BITSET_LIST
1349 };
1350
1351
1352 /* Return size of initial structure. */
1353 size_t
1354 lbitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED)
1355 {
1356 return sizeof (struct lbitset_struct);
1357 }
1358
1359
1360 /* Initialize a bitset. */
1361 bitset
1362 lbitset_init (bitset bset, bitset_bindex n_bits ATTRIBUTE_UNUSED)
1363 {
1364 BITSET_NBITS_ (bset) = n_bits;
1365 bset->b.vtable = &lbitset_vtable;
1366 return bset;
1367 }
1368
1369
1370 void
1371 lbitset_release_memory (void)
1372 {
1373 lbitset_free_list = 0;
1374 if (lbitset_obstack_init)
1375 {
1376 lbitset_obstack_init = false;
1377 obstack_free (&lbitset_obstack, NULL);
1378 }
1379 }
1380
1381
1382 /* Function to be called from debugger to debug lbitset. */
1383 void
1384 debug_lbitset (bitset bset)
1385 {
1386 lbitset_elt *elt;
1387 unsigned int i;
1388
1389 if (!bset)
1390 return;
1391
1392 for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
1393 {
1394 fprintf (stderr, "Elt %lu\n", (unsigned long) elt->index);
1395 for (i = 0; i < LBITSET_ELT_WORDS; i++)
1396 {
1397 unsigned int j;
1398 bitset_word word;
1399
1400 word = elt->words[i];
1401
1402 fprintf (stderr, " Word %u:", i);
1403 for (j = 0; j < LBITSET_WORD_BITS; j++)
1404 if ((word & ((bitset_word) 1 << j)))
1405 fprintf (stderr, " %u", j);
1406 fprintf (stderr, "\n");
1407 }
1408 }
1409 }