X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/ef5da9206129cdf46b899e5bc55e1854f8c3a9cd..b165c324a3149114250c796852dd2b33d79db67d:/lib/lbitset.c diff --git a/lib/lbitset.c b/lib/lbitset.c index 6499201d..82fc10ce 100644 --- a/lib/lbitset.c +++ b/lib/lbitset.c @@ -1,5 +1,5 @@ /* Functions to support link list bitsets. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003 Free Software Foundation, Inc. Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz). This program is free software; you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include #include #include +#include /* This file implements linked-list bitsets. These bitsets can be of arbitrary length and are more efficient than arrays of bits for @@ -40,7 +41,10 @@ /* 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 @@ -66,53 +70,14 @@ lbitset_elt; 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 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_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)); #define LBITSET_CURRENT1(X) \ @@ -125,7 +90,7 @@ extern void debug_lbitset PARAMS ((bitset)); /* Allocate a lbitset element. The bits are not cleared. */ static inline lbitset_elt * -lbitset_elt_alloc () +lbitset_elt_alloc (void) { lbitset_elt *elt; @@ -138,7 +103,7 @@ lbitset_elt_alloc () { if (!lbitset_obstack_init) { - lbitset_obstack_init = 1; + lbitset_obstack_init = true; /* Let particular systems override the size of a chunk. */ @@ -180,7 +145,7 @@ lbitset_elt_alloc () /* Allocate a lbitset element. The bits are cleared. */ static inline lbitset_elt * -lbitset_elt_calloc () +lbitset_elt_calloc (void) { lbitset_elt *elt; @@ -191,8 +156,7 @@ lbitset_elt_calloc () 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; @@ -201,9 +165,7 @@ lbitset_elt_free (elt) /* 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; @@ -248,9 +210,7 @@ lbitset_elt_unlink (bset, elt) /* 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; @@ -280,26 +240,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]) - return 0; + return false; - return 1; + return true; } /* 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; @@ -361,10 +318,8 @@ lbitset_elt_link (bset, 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; @@ -432,8 +387,7 @@ lbitset_elt_find (bset, windex, mode) /* 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; @@ -449,8 +403,7 @@ lbitset_weed (bset) /* Set all bits in the bitset to zero. */ static void -lbitset_zero (bset) - bitset bset; +lbitset_zero (bitset bset) { lbitset_elt *head; @@ -463,18 +416,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) - return 1; + return true; lbitset_weed (src); lbitset_weed (dst); @@ -482,11 +433,11 @@ lbitset_equal_p (dst, src) 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]) - return 0; + return false; } return !selt && !delt; } @@ -494,9 +445,7 @@ lbitset_equal_p (dst, src) /* 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; @@ -535,15 +484,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. */ -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) - return 0; + return false; if (!LBITSET_HEAD (dst)) { @@ -552,34 +499,25 @@ lbitset_copy_cmp (dst, src) } if (lbitset_equal_p (dst, src)) - return 0; + return false; lbitset_copy (dst, src); - return 1; + return true; } -/* Return size in bits of bitset SRC. */ static bitset_bindex -lbitset_size (src) - bitset src; +lbitset_resize (bitset src, bitset_bindex size) { - lbitset_elt *elt; - - elt = LBITSET_TAIL (src); - if (!elt) - return 0; + BITSET_NBITS_ (src) = size; - /* 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 -lbitset_set (dst, bitno) - bitset dst; - bitset_bindex bitno; +lbitset_set (bitset dst, bitset_bindex bitno) { bitset_windex windex = bitno / BITSET_WORD_BITS; @@ -592,9 +530,7 @@ lbitset_set (dst, bitno) /* 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; @@ -609,24 +545,20 @@ lbitset_reset (dst, bitno) /* 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; - 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 -lbitset_free (bset) - bitset bset; +lbitset_free (bitset bset) { lbitset_zero (bset); } @@ -636,11 +568,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 -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; @@ -734,11 +663,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 -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; @@ -936,20 +862,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; } +/* 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 -lbitset_ones (dst) - bitset dst; +lbitset_ones (bitset dst) { bitset_windex i; bitset_windex windex; @@ -959,25 +921,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. */ - 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)); } + + lbitset_unused_clear (dst); } static void -lbitset_not (dst, src) - bitset dst; - bitset src; +lbitset_not (bitset dst, bitset src) { lbitset_elt *elt; lbitset_elt *selt; @@ -989,31 +948,28 @@ lbitset_not (dst, src) /* 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 (j = 0; j < LBITSET_ELT_WORDS; j++) delt->words[j] = ~selt->words[j]; } + lbitset_unused_clear (dst); 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; @@ -1039,20 +995,18 @@ lbitset_subset_p (dst, src) selt = &lbitset_zero_elts[1]; } } - + 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; @@ -1077,21 +1031,17 @@ lbitset_disjoint_p (dst, src) intersection of these elements. */ continue; } - + 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); @@ -1105,7 +1055,7 @@ lbitset_op3_cmp (dst, src1, src2, op) bitset_word *srcp1; bitset_word *srcp2; bitset_word *dstp; - int changed = 0; + bool changed = false; unsigned int i; LBITSET_HEAD (dst) = 0; @@ -1149,7 +1099,7 @@ lbitset_op3_cmp (dst, src1, src2, op) elements that we've skipped. */ while (delt && delt->index < windex) { - changed = 1; + changed = true; dtmp = delt; delt = delt->next; lbitset_elt_free (dtmp); @@ -1176,7 +1126,7 @@ lbitset_op3_cmp (dst, src1, src2, op) if (*dstp != tmp) { - changed = 1; + changed = true; *dstp = tmp; } } @@ -1189,7 +1139,7 @@ lbitset_op3_cmp (dst, src1, src2, op) if (*dstp != tmp) { - changed = 1; + changed = true; *dstp = tmp; } } @@ -1202,7 +1152,7 @@ lbitset_op3_cmp (dst, src1, src2, op) if (*dstp != tmp) { - changed = 1; + changed = true; *dstp = tmp; } } @@ -1215,7 +1165,7 @@ lbitset_op3_cmp (dst, src1, src2, op) if (*dstp != tmp) { - changed = 1; + changed = true; *dstp = tmp; } } @@ -1240,7 +1190,7 @@ lbitset_op3_cmp (dst, src1, src2, op) /* If we have elements of DST left over, free them all. */ if (delt) { - changed = 1; + changed = true; lbitset_prune (dst, delt); } @@ -1248,25 +1198,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); - int changed; + bool changed; if (!selt2) { @@ -1287,24 +1224,18 @@ lbitset_and_cmp (dst, src1, src2) 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); - int changed; + bool changed; if (!selt2) { @@ -1322,20 +1253,14 @@ lbitset_andn_cmp (dst, src1, src2) 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); @@ -1353,20 +1278,14 @@ lbitset_or_cmp (dst, src1, src2) 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); @@ -1383,6 +1302,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 = { @@ -1390,7 +1316,8 @@ struct bitset_vtable lbitset_vtable = { lbitset_reset, bitset_toggle_, lbitset_test, - lbitset_size, + lbitset_resize, + bitset_size_, bitset_count_, lbitset_empty_p, lbitset_ones, @@ -1423,8 +1350,7 @@ struct bitset_vtable lbitset_vtable = { /* 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); } @@ -1432,22 +1358,21 @@ lbitset_bytes (n_bits) /* 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 -lbitset_release_memory () +lbitset_release_memory (void) { lbitset_free_list = 0; if (lbitset_obstack_init) { - lbitset_obstack_init = 0; + lbitset_obstack_init = false; obstack_free (&lbitset_obstack, NULL); } } @@ -1455,15 +1380,14 @@ lbitset_release_memory () /* 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; - + for (elt = LBITSET_HEAD (bset); elt; elt = elt->next) { fprintf (stderr, "Elt %lu\n", (unsigned long) elt->index); @@ -1471,9 +1395,9 @@ debug_lbitset (bset) { unsigned int j; bitset_word word; - + word = elt->words[i]; - + fprintf (stderr, " Word %u:", i); for (j = 0; j < LBITSET_WORD_BITS; j++) if ((word & ((bitset_word) 1 << j)))