Copyright (C) 2002 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
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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. */
+ 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.
+*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include "bitset.h"
+#include "lbitset.h"
#include "obstack.h"
#include <stdlib.h>
-# if WITH_DMALLOC
-# define DMALLOC_FUNC_CHECK
-# include <dmalloc.h>
-# endif /* WITH_DMALLOC */
-
/* This file implements linked-list bitsets. These bitsets can be of
arbitrary length and are more efficient than arrays of bits for
large sparse sets.
- Usually if all the bits in an element are zero we remove the element
- from the list. However, a side effect of the bit caching is that we
- do not always notice when an element becomes zero. Hence the
- lbitset_weed function which removes zero elements. */
+ Usually if all the bits in an element are zero we remove the element
+ from the list. However, a side effect of the bit caching is that we
+ do not always notice when an element becomes zero. Hence the
+ lbitset_weed function which removes zero elements. */
+
+
+/* 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. */
+
+#define LBITSET_ELT_WORDS 2
+
+typedef bitset_word lbitset_word;
+
+#define LBITSET_WORD_BITS BITSET_WORD_BITS
+
+/* Number of bits stored in each element. */
+#define LBITSET_ELT_BITS \
+ ((unsigned) (LBITSET_ELT_WORDS * LBITSET_WORD_BITS))
-enum lbitset_find_mode {LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST};
+/* Lbitset element. We use an array of bits for each element.
+ These are linked together in a doubly-linked list. */
+typedef struct lbitset_elt_struct
+{
+ struct lbitset_elt_struct *next; /* Next element. */
+ struct lbitset_elt_struct *prev; /* Previous element. */
+ bitset_windex index; /* bitno / BITSET_WORD_BITS. */
+ bitset_word words[LBITSET_ELT_WORDS]; /* Bits that are set. */
+}
+lbitset_elt;
+
+
+/* Head of lbitset linked list. */
+typedef struct lbitset_struct
+{
+ lbitset_elt *head; /* First element in linked list. */
+ lbitset_elt *tail; /* Last element in linked list. */
+}
+*lbitset;
+
+
+struct bitset_struct
+{
+ struct bbitset_struct b;
+ struct lbitset_struct l;
+};
+
+
+enum lbitset_find_mode
+ { LBITSET_FIND, LBITSET_CREATE, LBITSET_SUBST };
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 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_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_compare 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 int lbitset_size PARAMS((bitset));
-static int lbitset_op1 PARAMS((bitset, enum bitset_ops));
-static int lbitset_op2 PARAMS((bitset, bitset, enum bitset_ops));
-static int lbitset_op3 PARAMS((bitset, bitset, bitset, enum bitset_ops));
-static int lbitset_op4 PARAMS((bitset, bitset, bitset, bitset,
- enum bitset_ops));
-static int lbitset_list PARAMS((bitset, bitset_bindex *, bitset_bindex,
- bitset_bindex *));
-static int lbitset_reverse_list PARAMS((bitset, bitset_bindex *, bitset_bindex,
- bitset_bindex *));
-static void lbitset_free 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_compare 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 int lbitset_size PARAMS ((bitset));
+static int lbitset_op1 PARAMS ((bitset, enum bitset_ops));
+static int lbitset_op2 PARAMS ((bitset, bitset, enum bitset_ops));
+static int lbitset_op3 PARAMS ((bitset, bitset, bitset, enum bitset_ops));
+static int lbitset_list PARAMS ((bitset, bitset_bindex *, bitset_bindex,
+ bitset_bindex *));
+static int lbitset_reverse_list
+PARAMS ((bitset, bitset_bindex *, bitset_bindex, bitset_bindex *));
+static void lbitset_free PARAMS ((bitset));
#define LBITSET_CURRENT1(X) (lbitset_elt *)((char *)(X) + ((char *)&(((lbitset_elt *)(X))->next) - (char *)&(((lbitset_elt *)(X))->words)))
-#define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->cdata)
+#define LBITSET_CURRENT(X) LBITSET_CURRENT1((X)->b.cdata)
-#define LBITSET_HEAD(X) ((X)->u.l.head)
-#define LBITSET_TAIL(X) ((X)->u.l.tail)
+#define LBITSET_HEAD(X) ((X)->l.head)
+#define LBITSET_TAIL(X) ((X)->l.tail)
/* Allocate a lbitset element. The bits are not cleared. */
static inline lbitset_elt *
}
else
{
- /* We can't use gcc_obstack_init to initialize the obstack since
- print-rtl.c now calls bitset functions, and bitset is linked
- into the gen* functions. */
if (!lbitset_obstack_init)
{
lbitset_obstack_init = 1;
/* Let particular systems override the size of a chunk. */
+
#ifndef OBSTACK_CHUNK_SIZE
#define OBSTACK_CHUNK_SIZE 0
#endif
+
/* Let them override the alloc and free routines too. */
+
#ifndef OBSTACK_CHUNK_ALLOC
#define OBSTACK_CHUNK_ALLOC xmalloc
#endif
+
#ifndef OBSTACK_CHUNK_FREE
#define OBSTACK_CHUNK_FREE free
#endif
obstack_specify_allocation (&lbitset_obstack, OBSTACK_CHUNK_SIZE,
__alignof__ (lbitset_elt),
- (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
- (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
+ (void *(*)PARAMS ((long)))
+ OBSTACK_CHUNK_ALLOC,
+ (void (*)PARAMS ((void *)))
+ OBSTACK_CHUNK_FREE);
}
/* Perhaps we should add a number of new elements to the free
- list. */
+ list. */
elt = (lbitset_elt *) obstack_alloc (&lbitset_obstack,
sizeof (lbitset_elt));
}
}
-/* Allocate a lbitset element. The bits are not cleared. */
+/* Allocate a lbitset element. The bits are cleared. */
static inline lbitset_elt *
lbitset_elt_calloc ()
{
{
if (next)
{
- bset->cdata = next->words;
- bset->cindex = next->index;
+ bset->b.cdata = next->words;
+ bset->b.cindex = next->index;
}
else if (prev)
{
- bset->cdata = prev->words;
- bset->cindex = prev->index;
+ bset->b.cdata = prev->words;
+ bset->b.cindex = prev->index;
}
else
{
- bset->csize = 0;
- bset->cdata = 0;
+ bset->b.csize = 0;
+ bset->b.cdata = 0;
}
}
lbitset_elt *next;
if (!elt)
- return;
+ return;
if (elt->prev)
- {
+ {
LBITSET_TAIL (bset) = elt->prev;
- bset->cdata = elt->prev->words;
- bset->cindex = elt->prev->index;
+ bset->b.cdata = elt->prev->words;
+ bset->b.cindex = elt->prev->index;
elt->prev->next = 0;
- }
+ }
else
- {
+ {
LBITSET_HEAD (bset) = 0;
LBITSET_TAIL (bset) = 0;
- bset->cdata = 0;
- bset->csize = 0;
- }
+ bset->b.cdata = 0;
+ bset->b.csize = 0;
+ }
for (; elt; elt = next)
{
bitset bset;
lbitset_elt *elt;
{
- bitset_windex index = elt->index;
+ bitset_windex windex = elt->index;
lbitset_elt *ptr;
lbitset_elt *current;
- if (bset->csize)
- current = LBITSET_CURRENT (bset);
+ if (bset->b.csize)
+ current = LBITSET_CURRENT (bset);
else
- current = LBITSET_HEAD (bset);
+ current = LBITSET_HEAD (bset);
/* If this is the first and only element, add it in. */
if (LBITSET_HEAD (bset) == 0)
/* If this index is less than that of the current element, it goes
somewhere before the current element. */
- else if (index < bset->cindex)
+ else if (windex < bset->b.cindex)
{
for (ptr = current;
- ptr->prev && ptr->prev->index > index;
- ptr = ptr->prev)
+ ptr->prev && ptr->prev->index > windex; ptr = ptr->prev)
continue;
if (ptr->prev)
else
{
for (ptr = current;
- ptr->next && ptr->next->index < index;
- ptr = ptr->next)
+ ptr->next && ptr->next->index < windex; ptr = ptr->next)
continue;
if (ptr->next)
}
/* Set up so this is the first element searched. */
- bset->cindex = index;
- bset->csize = LBITSET_ELT_WORDS;
- bset->cdata = elt->words;
+ bset->b.cindex = windex;
+ bset->b.csize = LBITSET_ELT_WORDS;
+ bset->b.cdata = elt->words;
}
static lbitset_elt *
-lbitset_elt_find (bset, index, mode)
+lbitset_elt_find (bset, windex, mode)
bitset bset;
- bitset_windex index;
+ bitset_windex windex;
enum lbitset_find_mode mode;
{
lbitset_elt *elt;
lbitset_elt *current;
- if (bset->csize)
+ if (bset->b.csize)
{
current = LBITSET_CURRENT (bset);
/* Check if element is the cached element. */
- if ((index - bset->cindex) < bset->csize)
+ if ((windex - bset->b.cindex) < bset->b.csize)
return current;
}
else
if (current)
{
- if (index < bset->cindex)
+ if (windex < bset->b.cindex)
{
for (elt = current;
- elt->prev && elt->index > index;
- elt = elt->prev)
+ elt->prev && elt->index > windex; elt = elt->prev)
continue;
}
else
{
for (elt = current;
- elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < index;
+ elt->next && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
}
/* `element' is the nearest to the one we want. If it's not the one
we want, the one we want does not exist. */
- if (elt && (index - elt->index) < LBITSET_ELT_WORDS)
+ if (elt && (windex - elt->index) < LBITSET_ELT_WORDS)
{
- bset->cindex = elt->index;
- bset->csize = LBITSET_ELT_WORDS;
- bset->cdata = elt->words;
+ bset->b.cindex = elt->index;
+ bset->b.csize = LBITSET_ELT_WORDS;
+ bset->b.cdata = elt->words;
return elt;
}
}
return 0;
case LBITSET_CREATE:
- index = (index / (unsigned) LBITSET_ELT_WORDS) * LBITSET_ELT_WORDS;
+ windex = (windex / (unsigned) LBITSET_ELT_WORDS) * LBITSET_ELT_WORDS;
elt = lbitset_elt_calloc ();
- elt->index = index;
+ elt->index = windex;
lbitset_elt_link (bset, elt);
return elt;
if (delt->words[j] != selt->words[j])
return 0;
}
- return ! selt && ! delt;
+ return !selt && !delt;
}
}
LBITSET_TAIL (dst) = tmp;
- dst->csize = LBITSET_ELT_WORDS;
- dst->cdata = LBITSET_HEAD (dst)->words;
- dst->cindex = LBITSET_HEAD (dst)->index;
+ dst->b.csize = LBITSET_ELT_WORDS;
+ dst->b.cdata = LBITSET_HEAD (dst)->words;
+ dst->b.cindex = LBITSET_HEAD (dst)->index;
}
if (src == dst)
return 0;
- if (! LBITSET_HEAD (dst))
+ if (!LBITSET_HEAD (dst))
{
lbitset_copy (dst, src);
return LBITSET_HEAD (src) != 0;
elt = LBITSET_TAIL (src);
if (!elt)
- return 0;
+ return 0;
/* Return current size of bitset in bits. */
return (elt->index + LBITSET_ELT_WORDS) * BITSET_WORD_BITS;
bitset dst;
bitset_bindex bitno;
{
- bitset_windex index = bitno / BITSET_WORD_BITS;
+ bitset_windex windex = bitno / BITSET_WORD_BITS;
- lbitset_elt_find (dst, index, LBITSET_CREATE);
+ lbitset_elt_find (dst, windex, LBITSET_CREATE);
- dst->cdata[index - dst->cindex] |= (1 << (bitno % BITSET_WORD_BITS));
+ dst->b.cdata[windex - dst->b.cindex] |=
+ (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
}
bitset dst;
bitset_bindex bitno;
{
- bitset_windex index = bitno / BITSET_WORD_BITS;
+ bitset_windex windex = bitno / BITSET_WORD_BITS;
- if (!lbitset_elt_find (dst, index, LBITSET_FIND))
- return;
+ if (!lbitset_elt_find (dst, windex, LBITSET_FIND))
+ return;
- dst->cdata[index - dst->cindex] &= ~(1 << (bitno % BITSET_WORD_BITS));
+ dst->b.cdata[windex - dst->b.cindex] &=
+ ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
/* If all the data is zero, perhaps we should unlink it now... */
}
bitset src;
bitset_bindex bitno;
{
- bitset_windex index = bitno / BITSET_WORD_BITS;
+ bitset_windex windex = bitno / BITSET_WORD_BITS;
- if (!lbitset_elt_find (src, index, LBITSET_FIND))
+ if (!lbitset_elt_find (src, windex, LBITSET_FIND))
return 0;
- return (src->cdata[index - src->cindex] >> (bitno % BITSET_WORD_BITS)) & 1;
+ return (src->b.cdata[windex - src->b.cindex]
+ >> (bitno % BITSET_WORD_BITS)) & 1;
}
/* Find list of up to NUM bits set in BSET starting from and including
- *NEXT and store in array LIST. Return with actual number of bits
- found and with *NEXT indicating where search stopped. */
+ *NEXT and store in array LIST. Return with actual number of bits
+ found and with *NEXT indicating where search stopped. */
static int
lbitset_reverse_list (bset, list, num, next)
bitset bset;
{
bitset_bindex rbitno;
bitset_bindex bitno;
- unsigned int bitcnt;
- bitset_bindex bitoff;
- bitset_windex index;
+ unsigned int bcount;
+ bitset_bindex boffset;
+ bitset_windex windex;
bitset_bindex count;
lbitset_elt *elt;
bitset_word word;
rbitno = *next;
if (rbitno >= n_bits)
- return 0;
+ return 0;
bitno = n_bits - (rbitno + 1);
- index = bitno / BITSET_WORD_BITS;
+ windex = bitno / BITSET_WORD_BITS;
/* Skip back to starting element. */
- for (; elt && elt->index > index; elt = elt->prev)
+ for (; elt && elt->index > windex; elt = elt->prev)
continue;
if (!elt)
of the word of interest. */
count = 0;
- bitcnt = bitno % BITSET_WORD_BITS;
- bitoff = index * BITSET_WORD_BITS;
+ bcount = bitno % BITSET_WORD_BITS;
+ boffset = windex * BITSET_WORD_BITS;
while (elt)
{
bitset_word *srcp = elt->words;
- for (; (index - elt->index) < LBITSET_ELT_WORDS;
- index--, bitoff -= BITSET_WORD_BITS,
- bitcnt = BITSET_WORD_BITS - 1)
+ for (; (windex - elt->index) < LBITSET_ELT_WORDS;
+ windex--, boffset -= BITSET_WORD_BITS,
+ bcount = BITSET_WORD_BITS - 1)
{
- word = srcp[index - elt->index] << (BITSET_WORD_BITS - 1 - bitcnt);
+ word =
+ srcp[windex - elt->index] << (BITSET_WORD_BITS - 1 - bcount);
- for (; word; bitcnt--)
+ for (; word; bcount--)
{
if (word & BITSET_MSB)
{
- list[count++] = bitoff + bitcnt;
+ list[count++] = boffset + bcount;
if (count >= num)
{
- *next = n_bits - (bitoff + bitcnt);
+ *next = n_bits - (boffset + bcount);
return count;
}
}
elt = elt->prev;
if (elt)
{
- index = elt->index + LBITSET_ELT_WORDS - 1;
- bitoff = index * BITSET_WORD_BITS;
+ windex = elt->index + LBITSET_ELT_WORDS - 1;
+ boffset = windex * BITSET_WORD_BITS;
}
}
- *next = n_bits - (bitoff + 1);
+ *next = n_bits - (boffset + 1);
return count;
}
/* Find list of up to NUM bits set in BSET starting from and including
- *NEXT and store in array LIST. Return with actual number of bits
- found and with *NEXT indicating where search stopped. */
+ *NEXT and store in array LIST. Return with actual number of bits
+ found and with *NEXT indicating where search stopped. */
static int
lbitset_list (bset, list, num, next)
bitset bset;
bitset_bindex *next;
{
bitset_bindex bitno;
- bitset_windex index;
+ bitset_windex windex;
bitset_bindex count;
lbitset_elt *elt;
lbitset_elt *head;
head = LBITSET_HEAD (bset);
if (!head)
- return 0;
+ return 0;
bitno = *next;
count = 0;
/* Start with the first element. */
elt = head;
- index = elt->index;
- bitno = index * BITSET_WORD_BITS;
+ windex = elt->index;
+ bitno = windex * BITSET_WORD_BITS;
}
else
{
- index = bitno / BITSET_WORD_BITS;
+ windex = bitno / BITSET_WORD_BITS;
/* Skip to starting element. */
for (elt = head;
- elt && (elt->index + LBITSET_ELT_WORDS - 1) < index;
+ elt && (elt->index + LBITSET_ELT_WORDS - 1) < windex;
elt = elt->next)
continue;
if (!elt)
return 0;
- if (index < elt->index)
+ if (windex < elt->index)
{
- index = elt->index;
- bitno = index * BITSET_WORD_BITS;
+ windex = elt->index;
+ bitno = windex * BITSET_WORD_BITS;
}
else
{
/* We are starting within an element. */
- for (; (index - elt->index) < LBITSET_ELT_WORDS; index++)
+ for (; (windex - elt->index) < LBITSET_ELT_WORDS; windex++)
{
- word = srcp[index - elt->index] >> (bitno % BITSET_WORD_BITS);
+ word = srcp[windex - elt->index] >> (bitno % BITSET_WORD_BITS);
for (; word; bitno++)
{
}
word >>= 1;
}
- bitno = (index + 1) * BITSET_WORD_BITS;
+ bitno = (windex + 1) * BITSET_WORD_BITS;
}
elt = elt->next;
if (elt)
{
- index = elt->index;
- bitno = index * BITSET_WORD_BITS;
+ windex = elt->index;
+ bitno = windex * BITSET_WORD_BITS;
}
}
}
word = srcp[0];
if (word)
{
- if (! (word & 0xffff))
+ if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
- if (! (word & 0xff))
+ if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
word >>= 1;
}
}
- index++;
- bitno = index * BITSET_WORD_BITS;
+ windex++;
+ bitno = windex * BITSET_WORD_BITS;
word = srcp[1];
if (word)
{
- if (! (word & 0xffff))
+ if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
word >>= 1;
}
}
- index++;
- bitno = index * BITSET_WORD_BITS;
+ windex++;
+ bitno = windex * BITSET_WORD_BITS;
#else
for (i = 0; i < LBITSET_ELT_WORDS; i++)
{
word = srcp[i];
if (word)
{
- if (! (word & 0xffff))
+ if (!(word & 0xffff))
{
word >>= 16;
bitno += 16;
}
- if (! (word & 0xff))
+ if (!(word & 0xff))
{
word >>= 8;
bitno += 8;
word >>= 1;
}
}
- index++;
- bitno = index * BITSET_WORD_BITS;
+ windex++;
+ bitno = windex * BITSET_WORD_BITS;
}
#endif
}
}
word >>= 1;
}
- index++;
- bitno = index * BITSET_WORD_BITS;
+ windex++;
+ bitno = windex * BITSET_WORD_BITS;
}
}
elt = elt->next;
if (elt)
{
- index = elt->index;
- bitno = index * BITSET_WORD_BITS;
+ windex = elt->index;
+ bitno = windex * BITSET_WORD_BITS;
}
}
enum bitset_ops op;
{
unsigned int i;
- bitset_windex index;
+ bitset_windex windex;
lbitset_elt *elt;
switch (op)
{
- case BITSET_ZERO:
+ case BITSET_OP_ZERO:
lbitset_zero (dst);
break;
- case BITSET_ONES:
+ case BITSET_OP_ONES:
/* This is a decidedly unfriendly operation for a linked list
bitset! */
elt = LBITSET_TAIL (dst);
if (!elt)
return 0;
- index = elt->index;
- for (i = 0; i < index; i += LBITSET_ELT_WORDS)
+ windex = elt->index;
+ 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, ~0, sizeof (elt->words));
+ memset (elt->words, -1, sizeof (elt->words));
}
break;
- case BITSET_EMPTY_P:
+ case BITSET_OP_EMPTY_P:
lbitset_weed (dst);
if (LBITSET_HEAD (dst))
return 0;
lbitset_elt *delt;
unsigned int i;
unsigned int j;
- bitset_windex index;
+ bitset_windex windex;
switch (op)
{
- case BITSET_COPY:
+ case BITSET_OP_COPY:
lbitset_copy (dst, src);
break;
- case BITSET_NOT:
+ case BITSET_OP_NOT:
/* This is another unfriendly operation for a linked list
bitset! */
elt = LBITSET_TAIL (dst);
if (!elt)
return 0;
- index = elt->index;
- for (i = 0; i < index; i += LBITSET_ELT_WORDS)
+ windex = elt->index;
+ 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. */
lbitset_weed (dst);
break;
- case BITSET_EQUAL_P:
+ /* Return 1 if DST == SRC. */
+ case BITSET_OP_EQUAL_P:
return lbitset_equal_p (dst, src);
break;
- case BITSET_SUBSET_P:
+ /* Return 1 if DST == DST | SRC. */
+ case BITSET_OP_SUBSET_P:
for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
selt || delt; selt = selt->next, delt = delt->next)
{
}
break;
+ /* Return 1 if DST & SRC == 0. */
+ case BITSET_OP_DISJOINT_P:
+ for (selt = LBITSET_HEAD (src), delt = LBITSET_HEAD (dst);
+ selt && delt; selt = selt->next, delt = delt->next)
+ {
+ if (selt->index != delt->index)
+ {
+ if (selt->index < delt->index)
+ {
+ lbitset_zero_elts[2].next = delt;
+ delt = &lbitset_zero_elts[2];
+ }
+ else
+ {
+ lbitset_zero_elts[1].next = selt;
+ selt = &lbitset_zero_elts[1];
+ }
+ /* Since the elements are different, there is no
+ intersection of these elements. */
+ continue;
+ }
+
+ for (j = 0; j < LBITSET_ELT_WORDS; j++)
+ if (selt->words[j] & delt->words[j])
+ return 0;
+ }
+ break;
+
default:
abort ();
}
lbitset_elt *selt1 = LBITSET_HEAD (src1);
lbitset_elt *selt2 = LBITSET_HEAD (src2);
lbitset_elt *delt = LBITSET_HEAD (dst);
- bitset_windex index1;
- bitset_windex index2;
- bitset_windex index;
+ bitset_windex windex1;
+ bitset_windex windex2;
+ bitset_windex windex;
lbitset_elt *stmp1;
lbitset_elt *stmp2;
lbitset_elt *dtmp;
/* Fast track common, simple cases. */
if (!selt2)
{
- if (op == BITSET_AND)
+ if (op == BITSET_OP_AND)
{
lbitset_weed (dst);
- changed = ! LBITSET_HEAD (dst);
+ changed = !LBITSET_HEAD (dst);
lbitset_zero (dst);
return changed;
}
- else if (op == BITSET_ANDN || op == BITSET_OR || op == BITSET_XOR)
+ else if (op == BITSET_OP_ANDN || op == BITSET_OP_OR
+ || op == BITSET_OP_XOR)
{
return lbitset_copy_compare (dst, src1);
}
}
else if (!selt1)
{
- if (op == BITSET_AND || op == BITSET_ANDN)
+ if (op == BITSET_OP_AND || op == BITSET_OP_ANDN)
{
lbitset_weed (dst);
- changed = ! LBITSET_HEAD (dst);
+ changed = !LBITSET_HEAD (dst);
lbitset_zero (dst);
return changed;
}
- else if (op == BITSET_OR || op == BITSET_XOR)
+ else if (op == BITSET_OP_OR || op == BITSET_OP_XOR)
{
return lbitset_copy_compare (dst, src2);
}
}
-
LBITSET_HEAD (dst) = 0;
- dst->csize = 0;
+ dst->b.csize = 0;
- index1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
- index2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
+ windex1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
+ windex2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
while (selt1 || selt2)
{
/* Figure out whether we need to substitute zero elements for
missing links. */
- if (index1 == index2)
+ if (windex1 == windex2)
{
- index = index1;
+ windex = windex1;
stmp1 = selt1;
stmp2 = selt2;
selt1 = selt1->next;
- index1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
+ windex1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
selt2 = selt2->next;
- index2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
+ windex2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
}
- else if (index1 < index2)
+ else if (windex1 < windex2)
{
- index = index1;
+ windex = windex1;
stmp1 = selt1;
stmp2 = &lbitset_zero_elts[0];
selt1 = selt1->next;
- index1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
+ windex1 = (selt1) ? selt1->index : BITSET_INDEX_MAX;
}
else
{
- index = index2;
+ windex = windex2;
stmp1 = &lbitset_zero_elts[0];
stmp2 = selt2;
selt2 = selt2->next;
- index2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
+ windex2 = (selt2) ? selt2->index : BITSET_INDEX_MAX;
}
/* Find the appropriate element from DST. Begin by discarding
elements that we've skipped. */
- while (delt && delt->index < index)
+ while (delt && delt->index < windex)
{
changed = 1;
dtmp = delt;
delt = delt->next;
lbitset_elt_free (dtmp);
}
- if (delt && delt->index == index)
+ if (delt && delt->index == windex)
{
dtmp = delt;
delt = delt->next;
dstp = dtmp->words;
switch (op)
{
- case BITSET_OR:
+ case BITSET_OP_OR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ | *srcp2++;
}
break;
- case BITSET_AND:
+ case BITSET_OP_AND:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & *srcp2++;
}
break;
- case BITSET_XOR:
+ case BITSET_OP_XOR:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ ^ *srcp2++;
}
break;
- case BITSET_ANDN:
+ case BITSET_OP_ANDN:
for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
{
bitset_word tmp = *srcp1++ & ~(*srcp2++);
}
break;
- case BITSET_ORN:
- for (i = 0; i < LBITSET_ELT_WORDS; i++, dstp++)
- {
- bitset_word tmp = *srcp1++ | ~(*srcp2++);
-
- if (*dstp != tmp)
- {
- changed = 1;
- *dstp = tmp;
- }
- }
- break;
-
default:
abort ();
}
- if (! lbitset_elt_zero_p (dtmp))
+ if (!lbitset_elt_zero_p (dtmp))
{
- dtmp->index = index;
+ dtmp->index = windex;
/* Perhaps this could be optimised... */
lbitset_elt_link (dst, dtmp);
}
}
-static int
-lbitset_op4 (dst, src1, src2, src3, op)
- bitset dst;
- bitset src1;
- bitset src2;
- bitset src3;
- enum bitset_ops op;
-{
- int changed = 0;
- bitset tmp;
-
-#ifdef ENABLE_CHECKING
- /* Check for compatiblity. */
- if (src1->ops != dst->ops || src2->ops != dst->ops || src3->ops != dst->ops)
- abort ();
-#endif
-
- tmp = bitset_create (BITSET_LIST, 0);
-
- switch (op)
- {
- case BITSET_OR_AND:
- bitset_or (tmp, src1, src2);
- changed = bitset_and (dst, src3, tmp);
- break;
-
- case BITSET_AND_OR:
- bitset_and (tmp, src1, src2);
- changed = bitset_or (dst, src3, tmp);
- break;
-
- case BITSET_ANDN_OR:
- bitset_andn (tmp, src1, src2);
- changed = bitset_or (dst, src3, tmp);
- break;
-
- default:
- abort ();
- }
-
- bitset_free (tmp);
- return changed;
-}
-
-
/* Vector of operations for linked-list bitsets. */
-struct bitset_ops_struct lbitset_ops =
- {
- lbitset_set,
- lbitset_reset,
- lbitset_test,
- lbitset_size,
- lbitset_op1,
- lbitset_op2,
- lbitset_op3,
- lbitset_op4,
- lbitset_list,
- lbitset_reverse_list,
- lbitset_free,
- BITSET_LIST
- };
+struct bitset_ops_struct lbitset_ops = {
+ lbitset_set,
+ lbitset_reset,
+ lbitset_test,
+ lbitset_size,
+ lbitset_op1,
+ lbitset_op2,
+ lbitset_op3,
+ bitset_op4,
+ lbitset_list,
+ lbitset_reverse_list,
+ lbitset_free,
+ BITSET_LIST
+};
/* Return size of initial structure. */
bitset bset;
bitset_bindex n_bits ATTRIBUTE_UNUSED;
{
- LBITSET_HEAD (bset) = 0;
- LBITSET_TAIL (bset) = 0;
-
- bset->ops = &lbitset_ops;
-
- bset->cindex = 0;
- /* Disable cache until have some elements allocated.
- If we have variable length arrays, then we may
- need to allocate dummy element. */
- bset->csize = 0;
- bset->cdata = 0;
+ bset->b.ops = &lbitset_ops;
return bset;
}