]> git.saurik.com Git - bison.git/blobdiff - lib/lbitset.c
Don't let maintainer-*-check targets force a version update.
[bison.git] / lib / lbitset.c
index 6499201d779c98b2b33f90ae543084f1112cdc09..9a6fc0aeebdf1dd0f7a4adfb4afa06fd942fdb21 100644 (file)
@@ -1,10 +1,10 @@
 /* Functions to support link list bitsets.
 /* Functions to support link list bitsets.
-   Copyright (C) 2002 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
 
    Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include <config.h>
 
 #include "lbitset.h"
 
 #include "lbitset.h"
+
 #include "obstack.h"
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include "obstack.h"
 #include <stddef.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 /* This file implements linked-list bitsets.  These bitsets can be of
    arbitrary length and are more efficient than arrays of bits for
 
 /* This file implements linked-list bitsets.  These bitsets can be of
    arbitrary length and are more efficient than arrays of bits for
 /* Number of words to use for each element.  The larger the value the
    greater the size of the cache and the shorter the time to find a given bit
    but the more memory wasted for sparse bitsets and the longer the time
 /* Number of words to use for each element.  The larger the value the
    greater the size of the cache and the shorter the time to find a given bit
    but the more memory wasted for sparse bitsets and the longer the time
-   to search for set bits.  */
+   to search for set bits.
+
+   The routines that dominate timing profiles are lbitset_elt_find
+   and lbitset_elt_link, especially when accessing the bits randomly.  */
 
 #define LBITSET_ELT_WORDS 2
 
 
 #define LBITSET_ELT_WORDS 2
 
@@ -50,7 +51,7 @@ typedef bitset_word lbitset_word;
 
 /* Number of bits stored in each element.  */
 #define LBITSET_ELT_BITS \
 
 /* Number of bits stored in each element.  */
 #define LBITSET_ELT_BITS \
-  ((unsigned) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
+  ((unsigned int) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
 
 /* Lbitset element.   We use an array of bits for each element.
    These are linked together in a doubly-linked list.  */
 
 /* Lbitset element.   We use an array of bits for each element.
    These are linked together in a doubly-linked list.  */
@@ -66,54 +67,15 @@ lbitset_elt;
 
 enum lbitset_find_mode
   { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
 
 enum lbitset_find_mode
   { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
-typedef int enum_lbitset_find_mode;
 
 static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits.  */
 
 /* Obstack to allocate bitset elements from.  */
 static struct obstack lbitset_obstack;
 
 static lbitset_elt lbitset_zero_elts[3]; /* Elements of all zero bits.  */
 
 /* Obstack to allocate bitset elements from.  */
 static struct obstack lbitset_obstack;
-static int lbitset_obstack_init = 0;
+static bool lbitset_obstack_init = false;
 static lbitset_elt *lbitset_free_list; /* Free list of bitset elements.  */
 
 static lbitset_elt *lbitset_free_list; /* Free list of bitset elements.  */
 
-static lbitset_elt *lbitset_elt_alloc PARAMS ((void));
-static lbitset_elt *lbitset_elt_calloc PARAMS ((void));
-static void lbitset_elt_link PARAMS ((bitset, lbitset_elt *));
-static void lbitset_elt_unlink PARAMS ((bitset, lbitset_elt *));
-static void lbitset_elt_free PARAMS ((lbitset_elt *));
-static lbitset_elt *lbitset_elt_find PARAMS ((bitset, bitset_windex,
-                                             enum_lbitset_find_mode));
-static int lbitset_elt_zero_p PARAMS ((lbitset_elt *));
-
-static void lbitset_prune PARAMS ((bitset, lbitset_elt *));
-static void lbitset_weed PARAMS ((bitset));
-static void lbitset_zero PARAMS ((bitset));
-static int lbitset_equal_p PARAMS ((bitset, bitset));
-static void lbitset_copy PARAMS ((bitset, bitset));
-static int lbitset_copy_cmp PARAMS ((bitset, bitset));
-static void lbitset_set PARAMS ((bitset, bitset_bindex));
-static void lbitset_reset PARAMS ((bitset, bitset_bindex));
-static int lbitset_test PARAMS ((bitset, bitset_bindex));
-static bitset_bindex lbitset_size PARAMS ((bitset));
-static int lbitset_op3_cmp PARAMS ((bitset, bitset, bitset, enum_bitset_ops));
-static void lbitset_and PARAMS ((bitset, bitset, bitset));
-static int lbitset_and_cmp PARAMS ((bitset, bitset, bitset));
-static void lbitset_andn PARAMS ((bitset, bitset, bitset));
-static int lbitset_andn_cmp PARAMS ((bitset, bitset, bitset));
-static void lbitset_or PARAMS ((bitset, bitset, bitset));
-static int lbitset_or_cmp PARAMS ((bitset, bitset, bitset));
-static void lbitset_xor PARAMS ((bitset, bitset, bitset));
-static int lbitset_xor_cmp PARAMS ((bitset, bitset, bitset));
-static bitset_bindex lbitset_list PARAMS ((bitset, bitset_bindex *,
-                                          bitset_bindex, bitset_bindex *));
-static bitset_bindex lbitset_list_reverse
-PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
-static int lbitset_empty_p PARAMS ((bitset));
-static void lbitset_ones PARAMS ((bitset));
-static void lbitset_not PARAMS ((bitset, bitset));
-static int lbitset_subset_p PARAMS ((bitset, bitset));
-static int lbitset_disjoint_p PARAMS ((bitset, bitset));
-static void lbitset_free PARAMS ((bitset));
-extern void debug_lbitset PARAMS ((bitset));
+extern void debug_lbitset (bitset);
 
 #define LBITSET_CURRENT1(X) \
   ((lbitset_elt *) (void *) ((char *) (X) - offsetof (lbitset_elt, words)))
 
 #define LBITSET_CURRENT1(X) \
   ((lbitset_elt *) (void *) ((char *) (X) - offsetof (lbitset_elt, words)))
@@ -125,7 +87,7 @@ extern void debug_lbitset PARAMS ((bitset));
 
 /* Allocate a lbitset element.  The bits are not cleared.  */
 static inline lbitset_elt *
 
 /* Allocate a lbitset element.  The bits are not cleared.  */
 static inline lbitset_elt *
-lbitset_elt_alloc ()
+lbitset_elt_alloc (void)
 {
   lbitset_elt *elt;
 
 {
   lbitset_elt *elt;
 
@@ -138,7 +100,7 @@ lbitset_elt_alloc ()
     {
       if (!lbitset_obstack_init)
        {
     {
       if (!lbitset_obstack_init)
        {
-         lbitset_obstack_init = 1;
+         lbitset_obstack_init = true;
 
          /* Let particular systems override the size of a chunk.  */
 
 
          /* Let particular systems override the size of a chunk.  */
 
@@ -156,15 +118,13 @@ lbitset_elt_alloc ()
 #define OBSTACK_CHUNK_FREE free
 #endif
 
 #define OBSTACK_CHUNK_FREE free
 #endif
 
-#if !defined(__GNUC__) || (__GNUC__ < 2)
+#if ! defined __GNUC__ || __GNUC__ < 2
 #define __alignof__(type) 0
 #endif
 
          obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
                                      __alignof__ (lbitset_elt),
 #define __alignof__(type) 0
 #endif
 
          obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
                                      __alignof__ (lbitset_elt),
-                                     (void *(*)PARAMS ((long)))
                                      OBSTACK_CHUNK_ALLOC,
                                      OBSTACK_CHUNK_ALLOC,
-                                     (void (*)PARAMS ((void *)))
                                      OBSTACK_CHUNK_FREE);
        }
 
                                      OBSTACK_CHUNK_FREE);
        }
 
@@ -180,7 +140,7 @@ lbitset_elt_alloc ()
 
 /* Allocate a lbitset element.  The bits are cleared.  */
 static inline lbitset_elt *
 
 /* Allocate a lbitset element.  The bits are cleared.  */
 static inline lbitset_elt *
-lbitset_elt_calloc ()
+lbitset_elt_calloc (void)
 {
   lbitset_elt *elt;
 
 {
   lbitset_elt *elt;
 
@@ -191,8 +151,7 @@ lbitset_elt_calloc ()
 
 
 static inline void
 
 
 static inline void
-lbitset_elt_free (elt)
-     lbitset_elt *elt;
+lbitset_elt_free (lbitset_elt *elt)
 {
   elt->next = lbitset_free_list;
   lbitset_free_list = elt;
 {
   elt->next = lbitset_free_list;
   lbitset_free_list = elt;
@@ -201,9 +160,7 @@ lbitset_elt_free (elt)
 
 /* Unlink element ELT from bitset BSET.  */
 static inline void
 
 /* Unlink element ELT from bitset BSET.  */
 static inline void
-lbitset_elt_unlink (bset, elt)
-     bitset bset;
-     lbitset_elt *elt;
+lbitset_elt_unlink (bitset bset, lbitset_elt *elt)
 {
   lbitset_elt *next = elt->next;
   lbitset_elt *prev = elt->prev;
 {
   lbitset_elt *next = elt->next;
   lbitset_elt *prev = elt->prev;
@@ -248,9 +205,7 @@ lbitset_elt_unlink (bset, elt)
 /* Cut the chain of bitset BSET before element ELT and free the
    elements.  */
 static inline void
 /* Cut the chain of bitset BSET before element ELT and free the
    elements.  */
 static inline void
-lbitset_prune (bset, elt)
-     bitset bset;
-     lbitset_elt *elt;
+lbitset_prune (bitset bset, lbitset_elt *elt)
 {
   lbitset_elt *next;
 
 {
   lbitset_elt *next;
 
@@ -280,26 +235,23 @@ lbitset_prune (bset, elt)
 }
 
 
 }
 
 
-/* Return nonzero if all bits in an element are zero.  */
-static inline int
-lbitset_elt_zero_p (elt)
-     lbitset_elt *elt;
+/* Are all bits in an element zero?  */
+static inline bool
+lbitset_elt_zero_p (lbitset_elt *elt)
 {
   int i;
 
   for (i = 0; i < LBITSET_ELT_WORDS; i++)
     if (elt->words[i])
 {
   int i;
 
   for (i = 0; i < LBITSET_ELT_WORDS; i++)
     if (elt->words[i])
-      return 0;
+      return false;
 
 
-  return 1;
+  return true;
 }
 
 
 /* Link the bitset element into the current bitset linked list.  */
 static inline void
 }
 
 
 /* Link the bitset element into the current bitset linked list.  */
 static inline void
-lbitset_elt_link (bset, elt)
-     bitset bset;
-     lbitset_elt *elt;
+lbitset_elt_link (bitset bset, lbitset_elt *elt)
 {
   bitset_windex windex = elt->index;
   lbitset_elt *ptr;
 {
   bitset_windex windex = elt->index;
   lbitset_elt *ptr;
@@ -361,10 +313,8 @@ lbitset_elt_link (bset, elt)
 
 
 static lbitset_elt *
 
 
 static lbitset_elt *
-lbitset_elt_find (bset, windex, mode)
-     bitset bset;
-     bitset_windex windex;
-     enum_lbitset_find_mode mode;
+lbitset_elt_find (bitset bset, bitset_windex windex,
+                 enum lbitset_find_mode mode)
 {
   lbitset_elt *elt;
   lbitset_elt *current;
 {
   lbitset_elt *elt;
   lbitset_elt *current;
@@ -410,6 +360,9 @@ lbitset_elt_find (bset, windex, mode)
 
   switch (mode)
     {
 
   switch (mode)
     {
+    default:
+      abort ();
+
     case LBITSET_FIND:
       return 0;
 
     case LBITSET_FIND:
       return 0;
 
@@ -423,17 +376,13 @@ lbitset_elt_find (bset, windex, mode)
 
     case LBITSET_SUBST:
       return &lbitset_zero_elts[0];
 
     case LBITSET_SUBST:
       return &lbitset_zero_elts[0];
-
-    default:
-      abort ();
     }
 }
 
 
 /* Weed out the zero elements from the list.  */
 static inline void
     }
 }
 
 
 /* Weed out the zero elements from the list.  */
 static inline void
-lbitset_weed (bset)
-     bitset bset;
+lbitset_weed (bitset bset)
 {
   lbitset_elt *elt;
   lbitset_elt *next;
 {
   lbitset_elt *elt;
   lbitset_elt *next;
@@ -449,8 +398,7 @@ lbitset_weed (bset)
 
 /* Set all bits in the bitset to zero.  */
 static void
 
 /* Set all bits in the bitset to zero.  */
 static void
-lbitset_zero (bset)
-     bitset bset;
+lbitset_zero (bitset bset)
 {
   lbitset_elt *head;
 
 {
   lbitset_elt *head;
 
@@ -463,18 +411,16 @@ lbitset_zero (bset)
 }
 
 
 }
 
 
-/* Return 1 if DST == SRC.  */
-static inline int
-lbitset_equal_p (dst, src)
-     bitset dst;
-     bitset src;
+/* Is DST == SRC?  */
+static inline bool
+lbitset_equal_p (bitset dst, bitset src)
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
   int j;
 
   if (src == dst)
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
   int j;
 
   if (src == dst)
-    return 1;
+    return true;
 
   lbitset_weed (src);
   lbitset_weed (dst);
 
   lbitset_weed (src);
   lbitset_weed (dst);
@@ -482,11 +428,11 @@ lbitset_equal_p (dst, src)
        selt && delt; selt = selt->next, delt = delt->next)
     {
       if (selt->index != delt->index)
        selt && delt; selt = selt->next, delt = delt->next)
     {
       if (selt->index != delt->index)
-       return 0;
+       return false;
 
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (delt->words[j] != selt->words[j])
 
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (delt->words[j] != selt->words[j])
-         return 0;
+         return false;
     }
   return !selt && !delt;
 }
     }
   return !selt && !delt;
 }
@@ -494,9 +440,7 @@ lbitset_equal_p (dst, src)
 
 /* Copy bits from bitset SRC to bitset DST.  */
 static inline void
 
 /* Copy bits from bitset SRC to bitset DST.  */
 static inline void
-lbitset_copy (dst, src)
-     bitset dst;
-     bitset src;
+lbitset_copy (bitset dst, bitset src)
 {
   lbitset_elt *elt;
   lbitset_elt *head;
 {
   lbitset_elt *elt;
   lbitset_elt *head;
@@ -535,15 +479,13 @@ lbitset_copy (dst, src)
 }
 
 
 }
 
 
-/* Copy bits from bitset SRC to bitset DST.  Return non-zero if
+/* Copy bits from bitset SRC to bitset DST.  Return true if
    bitsets different.  */
    bitsets different.  */
-static inline int
-lbitset_copy_cmp (dst, src)
-     bitset dst;
-     bitset src;
+static inline bool
+lbitset_copy_cmp (bitset dst, bitset src)
 {
   if (src == dst)
 {
   if (src == dst)
-    return 0;
+    return false;
 
   if (!LBITSET_HEAD (dst))
     {
 
   if (!LBITSET_HEAD (dst))
     {
@@ -552,34 +494,25 @@ lbitset_copy_cmp (dst, src)
     }
 
   if (lbitset_equal_p (dst, src))
     }
 
   if (lbitset_equal_p (dst, src))
-    return 0;
+    return false;
 
   lbitset_copy (dst, src);
 
   lbitset_copy (dst, src);
-  return 1;
+  return true;
 }
 
 
 }
 
 
-/* Return size in bits of bitset SRC.  */
 static bitset_bindex
 static bitset_bindex
-lbitset_size (src)
-     bitset src;
+lbitset_resize (bitset src, bitset_bindex size)
 {
 {
-  lbitset_elt *elt;
+    BITSET_NBITS_ (src) = size;
 
 
-  elt = LBITSET_TAIL (src);
-  if (!elt)
-    return 0;
-
-  /* Return current size of bitset in bits.  */
-  return (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS;
+    /* Need to prune any excess bits.  FIXME.  */
+    return size;
 }
 
 }
 
-
 /* Set bit BITNO in bitset DST.  */
 static void
 /* Set bit BITNO in bitset DST.  */
 static void
-lbitset_set (dst, bitno)
-     bitset dst;
-     bitset_bindex bitno;
+lbitset_set (bitset dst, bitset_bindex bitno)
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
@@ -592,9 +525,7 @@ lbitset_set (dst, bitno)
 
 /* Reset bit BITNO in bitset DST.  */
 static void
 
 /* Reset bit BITNO in bitset DST.  */
 static void
-lbitset_reset (dst, bitno)
-     bitset dst;
-     bitset_bindex bitno;
+lbitset_reset (bitset dst, bitset_bindex bitno)
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
@@ -609,24 +540,20 @@ lbitset_reset (dst, bitno)
 
 
 /* Test bit BITNO in bitset SRC.  */
 
 
 /* Test bit BITNO in bitset SRC.  */
-static int
-lbitset_test (src, bitno)
-     bitset src;
-     bitset_bindex bitno;
+static bool
+lbitset_test (bitset src, bitset_bindex bitno)
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
 {
   bitset_windex windex = bitno / BITSET_WORD_BITS;
 
-  if (!lbitset_elt_find (src, windex, LBITSET_FIND))
-    return 0;
-
-  return (src->b.cdata[windex - src->b.cindex] 
-         >> (bitno % BITSET_WORD_BITS)) & 1;
+  return (lbitset_elt_find (src, windex, LBITSET_FIND)
+         && ((src->b.cdata[windex - src->b.cindex]
+              >> (bitno % BITSET_WORD_BITS))
+             & 1));
 }
 
 
 static void
 }
 
 
 static void
-lbitset_free (bset)
-     bitset bset;
+lbitset_free (bitset bset)
 {
   lbitset_zero (bset);
 }
 {
   lbitset_zero (bset);
 }
@@ -636,11 +563,8 @@ lbitset_free (bset)
  *NEXT and store in array LIST.  Return with actual number of bits
  found and with *NEXT indicating where search stopped.  */
 static bitset_bindex
  *NEXT and store in array LIST.  Return with actual number of bits
  found and with *NEXT indicating where search stopped.  */
 static bitset_bindex
-lbitset_list_reverse (bset, list, num, next)
-     bitset bset;
-     bitset_bindex *list;
-     bitset_bindex num;
-     bitset_bindex *next;
+lbitset_list_reverse (bitset bset, bitset_bindex *list,
+                     bitset_bindex num, bitset_bindex *next)
 {
   bitset_bindex rbitno;
   bitset_bindex bitno;
 {
   bitset_bindex rbitno;
   bitset_bindex bitno;
@@ -734,11 +658,8 @@ lbitset_list_reverse (bset, list, num, next)
  *NEXT and store in array LIST.  Return with actual number of bits
  found and with *NEXT indicating where search stopped.  */
 static bitset_bindex
  *NEXT and store in array LIST.  Return with actual number of bits
  found and with *NEXT indicating where search stopped.  */
 static bitset_bindex
-lbitset_list (bset, list, num, next)
-     bitset bset;
-     bitset_bindex *list;
-     bitset_bindex num;
-     bitset_bindex *next;
+lbitset_list (bitset bset, bitset_bindex *list,
+             bitset_bindex num, bitset_bindex *next)
 {
   bitset_bindex bitno;
   bitset_windex windex;
 {
   bitset_bindex bitno;
   bitset_windex windex;
@@ -936,20 +857,56 @@ lbitset_list (bset, list, num, next)
 }
 
 
 }
 
 
-static int
-lbitset_empty_p (dst)
-     bitset dst;
+static bool
+lbitset_empty_p (bitset dst)
 {
 {
-  lbitset_weed (dst);
-  if (LBITSET_HEAD (dst))
-      return 0;
+  lbitset_elt *elt;
+  lbitset_elt *next;
+
+  for (elt = LBITSET_HEAD (dst); elt; elt = next)
+    {
+      next = elt->next;
+      if (!lbitset_elt_zero_p (elt))
+       return 0;
+      /* Weed as we go.  */
+      lbitset_elt_unlink (dst, elt);
+    }
+
   return 1;
 }
 
 
   return 1;
 }
 
 
+/* Ensure that any unused bits within the last element are clear.  */
+static inline void
+lbitset_unused_clear (bitset dst)
+{
+  unsigned int last_bit;
+  bitset_bindex n_bits;
+
+  n_bits = BITSET_SIZE_ (dst);
+  last_bit = n_bits % LBITSET_ELT_BITS;
+
+  if (last_bit)
+    {
+      lbitset_elt *elt;
+      bitset_windex windex;
+      bitset_word *srcp;
+
+      elt = LBITSET_TAIL (dst);
+      srcp = elt->words;
+      windex = n_bits / BITSET_WORD_BITS;
+
+      srcp[windex - elt->index] &= ((bitset_word) 1 << last_bit) - 1;
+      windex++;
+
+      for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
+       srcp[windex - elt->index] = 0;
+    }
+}
+
+
 static void
 static void
-lbitset_ones (dst)
-     bitset dst;
+lbitset_ones (bitset dst)
 {
   bitset_windex i;
   bitset_windex windex;
 {
   bitset_windex i;
   bitset_windex windex;
@@ -959,25 +916,22 @@ lbitset_ones (dst)
       bitset!  It makes a sparse bitset become dense.  An alternative
       is to have a flag that indicates that the bitset stores the
       complement of what it indicates.  */
       bitset!  It makes a sparse bitset become dense.  An alternative
       is to have a flag that indicates that the bitset stores the
       complement of what it indicates.  */
-  elt = LBITSET_TAIL (dst);
-  /* Ignore empty set.  */
-  if (!elt)
-    return;
-  
-  windex = elt->index;
+
+  windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
+
   for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
     {
       /* Create new elements if they cannot be found.  */
       elt = lbitset_elt_find (dst, i, LBITSET_CREATE);
       memset (elt->words, -1, sizeof (elt->words));
     }
   for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
     {
       /* Create new elements if they cannot be found.  */
       elt = lbitset_elt_find (dst, i, LBITSET_CREATE);
       memset (elt->words, -1, sizeof (elt->words));
     }
+
+  lbitset_unused_clear (dst);
 }
 
 
 static void
 }
 
 
 static void
-lbitset_not (dst, src)
-     bitset dst;
-     bitset src;
+lbitset_not (bitset dst, bitset src)
 {
   lbitset_elt *elt;
   lbitset_elt *selt;
 {
   lbitset_elt *elt;
   lbitset_elt *selt;
@@ -989,31 +943,28 @@ lbitset_not (dst, src)
   /* This is another unfriendly operation for a linked list
      bitset!  */
   elt = LBITSET_TAIL (dst);
   /* This is another unfriendly operation for a linked list
      bitset!  */
   elt = LBITSET_TAIL (dst);
-  /* Ignore empty set.  */
-  if (!elt)
-    return;
-  
-  windex = elt->index;
+
+  windex = (BITSET_SIZE_ (dst) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS;
+
   for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
     {
       /* Create new elements for dst if they cannot be found
         or substitute zero elements if src elements not found.  */
       selt = lbitset_elt_find (src, i, LBITSET_SUBST);
       delt = lbitset_elt_find (dst, i, LBITSET_CREATE);
   for (i = 0; i < windex; i += LBITSET_ELT_WORDS)
     {
       /* Create new elements for dst if they cannot be found
         or substitute zero elements if src elements not found.  */
       selt = lbitset_elt_find (src, i, LBITSET_SUBST);
       delt = lbitset_elt_find (dst, i, LBITSET_CREATE);
-      
+
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        delt->words[j] = ~selt->words[j];
     }
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        delt->words[j] = ~selt->words[j];
     }
+  lbitset_unused_clear (dst);
   lbitset_weed (dst);
   return;
 }
 
 
   lbitset_weed (dst);
   return;
 }
 
 
-/* Return 1 if DST == DST | SRC.  */
-static int
-lbitset_subset_p (dst, src)
-     bitset dst;
-     bitset src;
+/* Is DST == DST | SRC?  */
+static bool
+lbitset_subset_p (bitset dst, bitset src)
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
@@ -1039,20 +990,18 @@ lbitset_subset_p (dst, src)
              selt = &lbitset_zero_elts[1];
            }
        }
              selt = &lbitset_zero_elts[1];
            }
        }
-      
+
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (delt->words[j] != (selt->words[j] | delt->words[j]))
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (delt->words[j] != (selt->words[j] | delt->words[j]))
-         return 0;
+         return false;
     }
     }
-  return 1;
+  return true;
 }
 
 
 }
 
 
-/* Return 1 if DST & SRC == 0.  */
-static int
-lbitset_disjoint_p (dst, src)
-     bitset dst;
-     bitset src;
+/* Is DST & SRC == 0?  */
+static bool
+lbitset_disjoint_p (bitset dst, bitset src)
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
 {
   lbitset_elt *selt;
   lbitset_elt *delt;
@@ -1077,21 +1026,17 @@ lbitset_disjoint_p (dst, src)
             intersection of these elements.  */
          continue;
        }
             intersection of these elements.  */
          continue;
        }
-      
+
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (selt->words[j] & delt->words[j])
       for (j = 0; j < LBITSET_ELT_WORDS; j++)
        if (selt->words[j] & delt->words[j])
-         return 0;
+         return false;
     }
     }
-  return 1;
+  return true;
 }
 
 
 }
 
 
-static int
-lbitset_op3_cmp (dst, src1, src2, op)
-     bitset dst;
-     bitset src1;
-     bitset src2;
-     enum_bitset_ops op;
+static bool
+lbitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op)
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
@@ -1105,7 +1050,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
   bitset_word *srcp1;
   bitset_word *srcp2;
   bitset_word *dstp;
   bitset_word *srcp1;
   bitset_word *srcp2;
   bitset_word *dstp;
-  int changed = 0;
+  bool changed = false;
   unsigned int i;
 
   LBITSET_HEAD (dst) = 0;
   unsigned int i;
 
   LBITSET_HEAD (dst) = 0;
@@ -1149,7 +1094,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
         elements that we've skipped.  */
       while (delt && delt->index < windex)
        {
         elements that we've skipped.  */
       while (delt && delt->index < windex)
        {
-         changed = 1;
+         changed = true;
          dtmp = delt;
          delt = delt->next;
          lbitset_elt_free (dtmp);
          dtmp = delt;
          delt = delt->next;
          lbitset_elt_free (dtmp);
@@ -1169,6 +1114,9 @@ lbitset_op3_cmp (dst, src1, src2, op)
       dstp = dtmp->words;
       switch (op)
        {
       dstp = dtmp->words;
       switch (op)
        {
+       default:
+         abort ();
+
        case BITSET_OP_OR:
          for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
            {
        case BITSET_OP_OR:
          for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
            {
@@ -1176,7 +1124,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
 
              if (*dstp != tmp)
                {
 
              if (*dstp != tmp)
                {
-                 changed = 1;
+                 changed = true;
                  *dstp = tmp;
                }
            }
                  *dstp = tmp;
                }
            }
@@ -1189,7 +1137,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
 
              if (*dstp != tmp)
                {
 
              if (*dstp != tmp)
                {
-                 changed = 1;
+                 changed = true;
                  *dstp = tmp;
                }
            }
                  *dstp = tmp;
                }
            }
@@ -1202,7 +1150,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
 
              if (*dstp != tmp)
                {
 
              if (*dstp != tmp)
                {
-                 changed = 1;
+                 changed = true;
                  *dstp = tmp;
                }
            }
                  *dstp = tmp;
                }
            }
@@ -1215,14 +1163,11 @@ lbitset_op3_cmp (dst, src1, src2, op)
 
              if (*dstp != tmp)
                {
 
              if (*dstp != tmp)
                {
-                 changed = 1;
+                 changed = true;
                  *dstp = tmp;
                }
            }
          break;
                  *dstp = tmp;
                }
            }
          break;
-
-       default:
-         abort ();
        }
 
       if (!lbitset_elt_zero_p (dtmp))
        }
 
       if (!lbitset_elt_zero_p (dtmp))
@@ -1240,7 +1185,7 @@ lbitset_op3_cmp (dst, src1, src2, op)
   /* If we have elements of DST left over, free them all.  */
   if (delt)
     {
   /* If we have elements of DST left over, free them all.  */
   if (delt)
     {
-      changed = 1;
+      changed = true;
       lbitset_prune (dst, delt);
     }
 
       lbitset_prune (dst, delt);
     }
 
@@ -1248,25 +1193,12 @@ lbitset_op3_cmp (dst, src1, src2, op)
 }
 
 
 }
 
 
-static void
-lbitset_and (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
-{
-  lbitset_and_cmp (dst, src1, src2);
-}
-
-
-static int
-lbitset_and_cmp (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+static bool
+lbitset_and_cmp (bitset dst, bitset src1, bitset src2)
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
-  int changed;
+  bool changed;
 
   if (!selt2)
     {
 
   if (!selt2)
     {
@@ -1287,24 +1219,18 @@ lbitset_and_cmp (dst, src1, src2)
 
 
 static void
 
 
 static void
-lbitset_andn (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+lbitset_and (bitset dst, bitset src1, bitset src2)
 {
 {
-  lbitset_andn_cmp (dst, src1, src2);
+  lbitset_and_cmp (dst, src1, src2);
 }
 
 
 }
 
 
-static int
-lbitset_andn_cmp (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+static bool
+lbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
-  int changed;
+  bool changed;
 
   if (!selt2)
     {
 
   if (!selt2)
     {
@@ -1322,20 +1248,14 @@ lbitset_andn_cmp (dst, src1, src2)
 
 
 static void
 
 
 static void
-lbitset_or (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+lbitset_andn (bitset dst, bitset src1, bitset src2)
 {
 {
-  lbitset_or_cmp (dst, src1, src2);
+  lbitset_andn_cmp (dst, src1, src2);
 }
 
 
 }
 
 
-static int
-lbitset_or_cmp (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+static bool
+lbitset_or_cmp (bitset dst, bitset src1, bitset src2)
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
@@ -1353,20 +1273,14 @@ lbitset_or_cmp (dst, src1, src2)
 
 
 static void
 
 
 static void
-lbitset_xor (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+lbitset_or (bitset dst, bitset src1, bitset src2)
 {
 {
-  lbitset_xor_cmp (dst, src1, src2);
+  lbitset_or_cmp (dst, src1, src2);
 }
 
 
 }
 
 
-static int
-lbitset_xor_cmp (dst, src1, src2)
-     bitset dst;
-     bitset src1;
-     bitset src2;
+static bool
+lbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
 {
   lbitset_elt *selt1 = LBITSET_HEAD (src1);
   lbitset_elt *selt2 = LBITSET_HEAD (src2);
@@ -1383,6 +1297,13 @@ lbitset_xor_cmp (dst, src1, src2)
 }
 
 
 }
 
 
+static void
+lbitset_xor (bitset dst, bitset src1, bitset src2)
+{
+  lbitset_xor_cmp (dst, src1, src2);
+}
+
+
 
 /* Vector of operations for linked-list bitsets.  */
 struct bitset_vtable lbitset_vtable = {
 
 /* Vector of operations for linked-list bitsets.  */
 struct bitset_vtable lbitset_vtable = {
@@ -1390,7 +1311,8 @@ struct bitset_vtable lbitset_vtable = {
   lbitset_reset,
   bitset_toggle_,
   lbitset_test,
   lbitset_reset,
   bitset_toggle_,
   lbitset_test,
-  lbitset_size,
+  lbitset_resize,
+  bitset_size_,
   bitset_count_,
   lbitset_empty_p,
   lbitset_ones,
   bitset_count_,
   lbitset_empty_p,
   lbitset_ones,
@@ -1423,8 +1345,7 @@ struct bitset_vtable lbitset_vtable = {
 
 /* Return size of initial structure.  */
 size_t
 
 /* Return size of initial structure.  */
 size_t
-lbitset_bytes (n_bits)
-     bitset_bindex n_bits ATTRIBUTE_UNUSED;
+lbitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED)
 {
   return sizeof (struct lbitset_struct);
 }
 {
   return sizeof (struct lbitset_struct);
 }
@@ -1432,22 +1353,21 @@ lbitset_bytes (n_bits)
 
 /* Initialize a bitset.  */
 bitset
 
 /* Initialize a bitset.  */
 bitset
-lbitset_init (bset, n_bits)
-     bitset bset;
-     bitset_bindex n_bits ATTRIBUTE_UNUSED;
+lbitset_init (bitset bset, bitset_bindex n_bits ATTRIBUTE_UNUSED)
 {
 {
+  BITSET_NBITS_ (bset) = n_bits;
   bset->b.vtable = &lbitset_vtable;
   return bset;
 }
 
 
 void
   bset->b.vtable = &lbitset_vtable;
   return bset;
 }
 
 
 void
-lbitset_release_memory ()
+lbitset_release_memory (void)
 {
   lbitset_free_list = 0;
   if (lbitset_obstack_init)
     {
 {
   lbitset_free_list = 0;
   if (lbitset_obstack_init)
     {
-      lbitset_obstack_init = 0;
+      lbitset_obstack_init = false;
       obstack_free (&lbitset_obstack, NULL);
     }
 }
       obstack_free (&lbitset_obstack, NULL);
     }
 }
@@ -1455,25 +1375,24 @@ lbitset_release_memory ()
 
 /* Function to be called from debugger to debug lbitset.  */
 void
 
 /* Function to be called from debugger to debug lbitset.  */
 void
-debug_lbitset (bset)
-     bitset bset;
+debug_lbitset (bitset bset)
 {
   lbitset_elt *elt;
   unsigned int i;
 
   if (!bset)
     return;
 {
   lbitset_elt *elt;
   unsigned int i;
 
   if (!bset)
     return;
-  
+
   for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
     {
   for (elt = LBITSET_HEAD (bset); elt; elt = elt->next)
     {
-      fprintf (stderr, "Elt %lu\n", (unsigned long) elt->index);
+      fprintf (stderr, "Elt %lu\n", (unsigned long int) elt->index);
       for (i = 0; i < LBITSET_ELT_WORDS; i++)
        {
          unsigned int j;
          bitset_word word;
       for (i = 0; i < LBITSET_ELT_WORDS; i++)
        {
          unsigned int j;
          bitset_word word;
-         
+
          word = elt->words[i];
          word = elt->words[i];
-         
+
          fprintf (stderr, "  Word %u:", i);
          for (j = 0; j < LBITSET_WORD_BITS; j++)
            if ((word & ((bitset_word) 1 << j)))
          fprintf (stderr, "  Word %u:", i);
          for (j = 0; j < LBITSET_WORD_BITS; j++)
            if ((word & ((bitset_word) 1 << j)))