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