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