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