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