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