rework bitset to use raw_bitset
authorMatthias Braun <matze@braunis.de>
Fri, 12 Mar 2010 19:04:19 +0000 (19:04 +0000)
committerMatthias Braun <matze@braunis.de>
Fri, 12 Mar 2010 19:04:19 +0000 (19:04 +0000)
[r27293]

20 files changed:
ir/adt/bitset.h
ir/adt/bitset_ia32.h [deleted file]
ir/adt/bitset_std.h [deleted file]
ir/adt/raw_bitset.h
ir/ana/irlivechk.c
ir/be/bearch.h
ir/be/bechordal.c
ir/be/bechordal_common.c
ir/be/becopyheur.c
ir/be/becopyheur2.c
ir/be/becopyheur4.c
ir/be/becopyilp2.c
ir/be/becopyopt.c
ir/be/beifg_pointer.c
ir/be/beilpsched.c
ir/be/beschedrss.c
ir/be/bespill.c
ir/ir/irargs.c
ir/ir/irbitset.h
ir/opt/opt_ldst.c

index 674012e..9f01046 100644 (file)
@@ -19,9 +19,9 @@
 
 /**
  * @file
- * @brief   A bitset implementation.
- * @author  Sebastian Hack
- * @date    15.10.2004
+ * @brief   convenience layer over raw_bitsets (stores number of bits
+ *          with the bitfield)
+ * @author  Matthias Braun
  * @version $Id$
  */
 #ifndef FIRM_ADT_BITSET_H
 
 #include "xmalloc.h"
 #include "bitfiddle.h"
+#include "raw_bitset.h"
 
-typedef unsigned int bitset_pos_t;
-
-#include "bitset_std.h"
-
-#if defined(__GNUC__) && defined(__i386__)
-#include "bitset_ia32.h"
-#endif
-
-typedef struct _bitset_t {
-       bitset_pos_t units;
-       bitset_pos_t size;
+typedef struct bitset_t {
+       unsigned size;     /**< size of the bitset in bits */
+       unsigned data[1];  /**< data (should be declared data[] but this is only
+                               allowed in C99) */
 } bitset_t;
 
-#define BS_UNIT_SIZE         sizeof(bitset_unit_t)
-#define BS_UNIT_SIZE_BITS    (BS_UNIT_SIZE * 8)
-#define BS_UNIT_MASK         (BS_UNIT_SIZE_BITS - 1)
-
-#define BS_DATA(bs)          ((bitset_unit_t *) ((char *) (bs) + sizeof(bitset_t)))
-#define BS_UNITS(bits)       (round_up2(bits, BS_UNIT_SIZE_BITS) / BS_UNIT_SIZE_BITS)
-#define BS_TOTAL_SIZE(bits)  (sizeof(bitset_t) + BS_UNITS(bits) * BS_UNIT_SIZE)
-
 /**
- * Initialize a bitset.
- * This functions should not be called.
- *
- * Note that this function needs three macros which must be provided by the
- * bitfield implementor:
- * - _bitset_overall_size(size) The overall size that must be
- *   allocated for the bitfield in bytes.
- * - _bitset_units(size) The number of units that will be
- *   present in the bitfield for a given highest bit.
- * - _bitset_data_ptr(data, size) This produces as pointer to the
- *   first unit in the allocated memory area. The main reason for this
- *   macro is, that some bitset implementors want control over memory
- *   alignment.
- *
- * @param area A pointer to memory reserved for the bitset.
- * @param size The size of the bitset in bits.
- * @return A pointer to the initialized bitset.
+ * return the number of bytes a bitset would need
  */
-static inline bitset_t *_bitset_prepare(void *area, bitset_pos_t size)
+static inline size_t bitset_total_size(unsigned n_bits)
 {
-       bitset_t *ptr = area;
-       memset(ptr, 0, BS_TOTAL_SIZE(size));
-       ptr->units = BS_UNITS(size);
-       ptr->size  = size;
-       return ptr;
+       return sizeof(bitset_t) - sizeof(((bitset_t*)0)->data)
+               + BITSET_SIZE_BYTES(n_bits);
 }
 
 /**
- * Mask out all bits, which are only there, because the number
- * of bits in the set didn't match a unit size boundary.
- * @param bs The bitset.
- * @return The masked bitset.
+ * initialize a bitset for bitsize size (bitset should point to memory
+ * with a size calculated by bitset_total_size)
  */
-static inline bitset_t *_bitset_mask_highest(bitset_t *bs)
+static inline bitset_t *bitset_init(void *memory, unsigned size)
 {
-       bitset_pos_t rest = bs->size & BS_UNIT_MASK;
-       if (rest)
-               BS_DATA(bs)[bs->units - 1] &= (1 << rest) - 1;
-       return bs;
+       bitset_t *result = (bitset_t*) memory;
+       result->size = size;
+       rbitset_clear_all(result->data, size);
+       return result;
 }
 
-/**
- * Get the capacity of the bitset in bits.
- * @param bs The bitset.
- * @return The capacity in bits of the bitset.
- */
-#define bitset_capacity(bs) ((bs)->units * BS_UNIT_SIZE_BITS)
-
-/**
- * Get the size of the bitset in bits.
- * @note Note the difference between capacity and size.
- * @param bs The bitset.
- * @return The highest bit which can be set or cleared plus 1.
- */
-#define bitset_size(bs)  ((bs)->size)
-
 /**
  * Allocate a bitset on an obstack.
  * @param obst The obstack.
  * @param size The greatest bit that shall be stored in the set.
  * @return A pointer to an empty initialized bitset.
  */
-#define bitset_obstack_alloc(obst,size) \
-       _bitset_prepare(obstack_alloc(obst, BS_TOTAL_SIZE(size)), size)
+static inline bitset_t *bitset_obstack_alloc(struct obstack *obst,
+                                             unsigned n_bits)
+{
+       size_t size   = bitset_total_size(n_bits);
+       void  *memory = obstack_alloc(obst, size);
+       return bitset_init(memory, n_bits);
+}
 
 /**
  * Allocate a bitset via malloc.
  * @param size The greatest bit that shall be stored in the set.
  * @return A pointer to an empty initialized bitset.
  */
-#define bitset_malloc(size) \
-       _bitset_prepare(xmalloc(BS_TOTAL_SIZE(size)), size)
+static inline bitset_t *bitset_malloc(unsigned n_bits)
+{
+       size_t  size   = bitset_total_size(n_bits);
+       void   *memory = xmalloc(size);
+       return bitset_init(memory, n_bits);
+}
 
 /**
  * Free a bitset allocated with bitset_malloc().
  * @param bs The bitset.
  */
-#define bitset_free(bs) free(bs)
+static inline void bitset_free(bitset_t *bitset)
+{
+       xfree(bitset);
+}
 
 /**
  * Allocate a bitset on the stack via alloca.
@@ -142,20 +104,17 @@ static inline bitset_t *_bitset_mask_highest(bitset_t *bs)
  * @return A pointer to an empty initialized bitset.
  */
 #define bitset_alloca(size) \
-       _bitset_prepare(alloca(BS_TOTAL_SIZE(size)), size)
-
+       bitset_init(alloca(bitset_total_size(size)), (size))
 
 /**
- * Get the unit which contains a specific bit.
- * This function is internal.
+ * Get the size of the bitset in bits.
+ * @note Note the difference between capacity and size.
  * @param bs The bitset.
- * @param bit The bit.
- * @return A pointer to the unit containing the bit.
+ * @return The highest bit which can be set or cleared plus 1.
  */
-static inline bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t bit)
+static inline unsigned bitset_size(const bitset_t *bitset)
 {
-       assert(bit <= bs->size && "Bit to large");
-       return BS_DATA(bs) + bit / BS_UNIT_SIZE_BITS;
+       return bitset->size;
 }
 
 /**
@@ -163,10 +122,10 @@ static inline bitset_unit_t *_bitset_get_unit(const bitset_t *bs, bitset_pos_t b
  * @param bs The bitset.
  * @param bit The bit to set.
  */
-static inline void bitset_set(bitset_t *bs, bitset_pos_t bit)
+static inline void bitset_set(bitset_t *bs, unsigned bit)
 {
-       bitset_unit_t *unit = _bitset_get_unit(bs, bit);
-       _bitset_inside_set(unit, bit & BS_UNIT_MASK);
+       assert(bit < bs->size);
+       rbitset_set(bs->data, bit);
 }
 
 /**
@@ -174,10 +133,10 @@ static inline void bitset_set(bitset_t *bs, bitset_pos_t bit)
  * @param bs The bitset.
  * @param bit The bit to clear.
  */
-static inline void bitset_clear(bitset_t *bs, bitset_pos_t bit)
+static inline void bitset_clear(bitset_t *bs, unsigned bit)
 {
-       bitset_unit_t *unit = _bitset_get_unit(bs, bit);
-       _bitset_inside_clear(unit, bit & BS_UNIT_MASK);
+       assert(bit < bs->size);
+       rbitset_clear(bs->data, bit);
 }
 
 /**
@@ -186,10 +145,10 @@ static inline void bitset_clear(bitset_t *bs, bitset_pos_t bit)
  * @param bit The bit to check for.
  * @return 1, if the bit was set, 0 if not.
  */
-static inline int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
+static inline bool bitset_is_set(const bitset_t *bs, unsigned bit)
 {
-       bitset_unit_t *unit = _bitset_get_unit(bs, bit);
-       return _bitset_inside_is_set(unit, bit & BS_UNIT_MASK);
+       assert(bit < bs->size);
+       return rbitset_is_set(bs->data, bit);
 }
 
 /**
@@ -197,10 +156,10 @@ static inline int bitset_is_set(const bitset_t *bs, bitset_pos_t bit)
  * @param bs The bitset.
  * @param bit The bit to flip.
  */
-static inline void bitset_flip(bitset_t *bs, bitset_pos_t bit)
+static inline void bitset_flip(bitset_t *bs, unsigned bit)
 {
-       bitset_unit_t *unit = _bitset_get_unit(bs, bit);
-       _bitset_inside_flip(unit, bit & BS_UNIT_MASK);
+       assert(bit < bs->size);
+       rbitset_flip(bs->data, bit);
 }
 
 /**
@@ -209,27 +168,35 @@ static inline void bitset_flip(bitset_t *bs, bitset_pos_t bit)
  */
 static inline void bitset_flip_all(bitset_t *bs)
 {
-       bitset_pos_t i;
-       for(i = 0; i < bs->units; i++)
-               _bitset_inside_flip_unit(&BS_DATA(bs)[i]);
-       _bitset_mask_highest(bs);
+       rbitset_flip_all(bs->data, bs->size);
 }
 
 /**
- * Copy a bitset to another.
+ * Copy a bitset to another. Both bitset must be initialized and have the same
+ * number of bits.
  * @param tgt The target bitset.
  * @param src The source bitset.
  * @return The target bitset.
  */
-static inline bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
+static inline void bitset_copy(bitset_t *tgt, const bitset_t *src)
 {
-       bitset_pos_t tu = tgt->units;
-       bitset_pos_t su = src->units;
-       bitset_pos_t min_units = tu < su ? tu : su;
-       memcpy(BS_DATA(tgt), BS_DATA(src), min_units * BS_UNIT_SIZE);
-       if(tu > min_units)
-               memset(BS_DATA(tgt) + min_units, 0, BS_UNIT_SIZE * (tu - min_units));
-       return _bitset_mask_highest(tgt);
+       assert(tgt->size == src->size);
+       rbitset_copy(tgt->data, src->data, src->size);
+}
+
+/**
+ * Find the next unset bit from a given bit.
+ * @note Note that if pos is unset, pos is returned.
+ * @param bs The bitset.
+ * @param pos The bit from which to search for the next set bit.
+ * @return The next set bit from pos on, or (unsigned)-1, if no unset bit was
+ * found after pos.
+ */
+static inline unsigned bitset_next_clear(const bitset_t *bs, unsigned pos)
+{
+       if (pos >= bs->size)
+               return (unsigned)-1;
+       return rbitset_next_max(bs->data, pos, bs->size, false);
 }
 
 /**
@@ -237,75 +204,27 @@ static inline bitset_t *bitset_copy(bitset_t *tgt, const bitset_t *src)
  * @note Note that if pos is set, pos is returned.
  * @param bs The bitset.
  * @param pos The bit from which to search for the next set bit.
- * @return The next set bit from pos on, or -1, if no set bit was found
- * after pos.
+ * @return The next set bit from pos on, or (unsigned)-1, if no set bit was
+ * found after pos.
  */
-static inline bitset_pos_t _bitset_next(const bitset_t *bs,
-               bitset_pos_t pos, int set)
+static inline unsigned bitset_next_set(const bitset_t *bs, unsigned pos)
 {
-       bitset_pos_t unit_number = pos / BS_UNIT_SIZE_BITS;
-       bitset_pos_t res;
-
-       if(pos >= bs->size)
-               return -1;
-
-       {
-               bitset_pos_t bit_in_unit = pos & BS_UNIT_MASK;
-               bitset_pos_t in_unit_mask = (1 << bit_in_unit) - 1;
-
-               /*
-                * Mask out the bits smaller than pos in the current unit.
-                * We are only interested in bits set higher than pos.
-                */
-               bitset_unit_t curr_unit = BS_DATA(bs)[unit_number];
-
-               /*
-                * Find the next bit set in the unit.
-                * Mind that this function returns 0, if the unit is -1 and
-                * counts the bits from 1 on.
-                */
-               bitset_pos_t next_in_this_unit =
-                       _bitset_inside_ntz_value((set ? curr_unit : ~curr_unit) & ~in_unit_mask);
-
-               /* If there is a bit set in the current unit, exit. */
-               if (next_in_this_unit < BS_UNIT_SIZE_BITS) {
-                       res = next_in_this_unit + unit_number * BS_UNIT_SIZE_BITS;
-                       return res < bs->size ? res : (bitset_pos_t) -1;
-               }
-
-               /* Else search for set bits in the next units. */
-               else {
-                       bitset_pos_t i;
-                       for(i = unit_number + 1; i < bs->units; ++i) {
-                               bitset_unit_t data = BS_DATA(bs)[i];
-                               bitset_pos_t first_set =
-                                       _bitset_inside_ntz_value(set ? data : ~data);
-
-                               if (first_set < BS_UNIT_SIZE_BITS) {
-                                       res = first_set + i * BS_UNIT_SIZE_BITS;
-                                       return res < bs->size ? res : (bitset_pos_t) -1;
-                               }
-                       }
-               }
-       }
-
-       return -1;
+       if (pos >= bs->size)
+               return (unsigned)-1;
+       return rbitset_next_max(bs->data, pos, bs->size, true);
 }
 
-#define bitset_next_clear(bs,pos) _bitset_next((bs), (pos), 0)
-#define bitset_next_set(bs,pos) _bitset_next((bs), (pos), 1)
-
 /**
  * Convenience macro for bitset iteration.
  * @param bitset The bitset.
  * @param elm A unsigned long variable.
  */
 #define bitset_foreach(bitset,elm) \
-       for(elm = bitset_next_set(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_set(bitset,elm+1))
+       for(elm = bitset_next_set(bitset,0); elm != (unsigned) -1; elm = bitset_next_set(bitset,elm+1))
 
 
 #define bitset_foreach_clear(bitset,elm) \
-       for(elm = bitset_next_clear(bitset,0); elm != (bitset_pos_t) -1; elm = bitset_next_clear(bitset,elm+1))
+       for(elm = bitset_next_clear(bitset,0); elm != (unsigned) -1; elm = bitset_next_clear(bitset,elm+1))
 
 /**
  * Count the bits set.
@@ -315,14 +234,7 @@ static inline bitset_pos_t _bitset_next(const bitset_t *bs,
  */
 static inline unsigned bitset_popcount(const bitset_t *bs)
 {
-       bitset_pos_t  i;
-       bitset_unit_t *unit;
-       unsigned      pop = 0;
-
-       for (i = 0, unit = BS_DATA(bs); i < bs->units; ++i, ++unit)
-               pop += _bitset_inside_pop(unit);
-
-       return pop;
+       return rbitset_popcount(bs->data, bs->size);
 }
 
 /**
@@ -330,10 +242,9 @@ static inline unsigned bitset_popcount(const bitset_t *bs)
  * This sets all bits to zero.
  * @param bs The bitset.
  */
-static inline bitset_t *bitset_clear_all(bitset_t *bs)
+static inline void bitset_clear_all(bitset_t *bs)
 {
-       memset(BS_DATA(bs), 0, BS_UNIT_SIZE * bs->units);
-       return bs;
+       rbitset_clear_all(bs->data, bs->size);
 }
 
 /**
@@ -341,10 +252,9 @@ static inline bitset_t *bitset_clear_all(bitset_t *bs)
  * This sets all bits to one.
  * @param bs The bitset.
  */
-static inline bitset_t *bitset_set_all(bitset_t *bs)
+static inline void bitset_set_all(bitset_t *bs)
 {
-       memset(BS_DATA(bs), -1, bs->units * BS_UNIT_SIZE);
-       return _bitset_mask_highest(bs);
+       rbitset_set_all(bs->data, bs->size);
 }
 
 /**
@@ -354,31 +264,10 @@ static inline bitset_t *bitset_set_all(bitset_t *bs)
  * @param rhs Another bitset.
  * @return 1, if all bits in lhs are also set in rhs, 0 otherwise.
  */
-static inline int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
+static inline bool bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
 {
-       bitset_pos_t n = lhs->units < rhs->units ? lhs->units : rhs->units;
-       bitset_pos_t i;
-
-       for(i = 0; i < n; ++i) {
-               bitset_unit_t lu = BS_DATA(lhs)[i];
-               bitset_unit_t ru = BS_DATA(rhs)[i];
-
-               if((lu | ru) & ~ru)
-                       return 0;
-       }
-
-       /*
-        * If the left hand sinde is a larger bitset than rhs,
-        * we have to check, that all extra bits in lhs are 0
-        */
-       if(lhs->units > n) {
-               for(i = n; i < lhs->units; ++i) {
-                       if(BS_DATA(lhs)[i] != 0)
-                               return 0;
-               }
-       }
-
-       return 1;
+       assert(lhs->size == rhs->size);
+       return rbitset_contains(lhs->data, rhs->data, lhs->size);
 }
 
 /**
@@ -388,20 +277,7 @@ static inline int bitset_contains(const bitset_t *lhs, const bitset_t *rhs)
  */
 static inline void bitset_minus1(bitset_t *bs)
 {
-#define _SH (sizeof(bitset_unit_t) * 8 - 1)
-
-       bitset_pos_t i;
-
-       for(i = 0; i < bs->units; ++i) {
-               bitset_unit_t unit = BS_DATA(bs)[i];
-               bitset_unit_t um1  = unit - 1;
-
-               BS_DATA(bs)[i] = um1;
-
-               if(((unit >> _SH) ^ (um1 >> _SH)) == 0)
-                       break;
-       }
-#undef _SH
+       rbitset_minus1(bs->data, bs->size);
 }
 
 /**
@@ -410,16 +286,10 @@ static inline void bitset_minus1(bitset_t *bs)
  * @param b The second bitset.
  * @return 1 if they have a bit in common, 0 if not.
  */
-static inline int bitset_intersect(const bitset_t *a, const bitset_t *b)
+static inline bool bitset_intersect(const bitset_t *a, const bitset_t *b)
 {
-       bitset_pos_t n = a->units < b->units ? a->units : b->units;
-       bitset_pos_t i;
-
-       for (i = 0; i < n; ++i)
-               if (BS_DATA(a)[i] & BS_DATA(b)[i])
-                       return 1;
-
-       return 0;
+       assert(a->size == b->size);
+       return rbitsets_have_common(a->data, b->data, a->size);
 }
 
 /**
@@ -429,16 +299,14 @@ static inline int bitset_intersect(const bitset_t *a, const bitset_t *b)
  * @param to     The last index plus one to set to one.
  * @param do_set If 1 the bits are set, if 0, they are cleared.
  */
-static inline void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t to, int do_set)
+static inline void bitset_mod_range(bitset_t *a, unsigned from, unsigned to,
+                                    bool do_set)
 {
-       bitset_pos_t from_unit, to_unit, i;
-       bitset_unit_t from_unit_mask, to_unit_mask;
-
        if (from == to)
            return;
 
        if (to < from) {
-               bitset_pos_t tmp = from;
+               unsigned tmp = from;
                from = to;
                to = tmp;
        }
@@ -446,53 +314,7 @@ static inline void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t
        if (to > a->size)
                to = a->size;
 
-       /*
-        * A small example (for cleaning bits in the same unit).
-        * from   = 7
-        * to     = 19
-        * do_set = 0
-        * result:         xxxxxxx000000000000xxxxxxxxxxxxx
-        * from_unit_mask: 00000001111111111111111111111111
-        * to_unit_mask:   11111111111111111110000000000000
-        * scale:          01234567890123456789012345678901
-        *                           1         2         3
-        */
-
-       from_unit      = from / BS_UNIT_SIZE_BITS;
-       from_unit_mask = ~((1 << from) - 1);
-       from           = from & BS_UNIT_MASK;
-
-       to_unit        = to / BS_UNIT_SIZE_BITS;
-       to_unit_mask   = (1 << to) - 1;
-       to             = to & BS_UNIT_MASK;
-
-       /* do we want to set the bits in the range? */
-       if (do_set) {
-               /* If from and to are in the same unit: */
-               if (from_unit == to_unit)
-                       BS_DATA(a)[from_unit] |= from_unit_mask & to_unit_mask;
-
-               /* Else, we have to treat the from and to units seperately */
-               else {
-                       BS_DATA(a)[from_unit] |= from_unit_mask;
-                       BS_DATA(a)[to_unit]   |= to_unit_mask;
-                       for (i = from_unit + 1; i < to_unit; i++)
-                               BS_DATA(a)[i] = BITSET_UNIT_ALL_ONE;
-               }
-       }
-
-       /* ... or clear them? */
-       else {
-               if (from_unit == to_unit)
-                       BS_DATA(a)[from_unit] &= ~(from_unit_mask & to_unit_mask);
-
-               else {
-                       BS_DATA(a)[from_unit] &= ~from_unit_mask;
-                       BS_DATA(a)[to_unit]   &= ~to_unit_mask;
-                       for (i = from_unit + 1; i < to_unit; i++)
-                               BS_DATA(a)[i] = 0;
-               }
-       }
+       rbitset_set_range(a->data, from, to, do_set);
 }
 
 #define bitset_set_range(bs, from, to)   bitset_mod_range((bs), (from), (to), 1)
@@ -503,13 +325,9 @@ static inline void bitset_mod_range(bitset_t *a, bitset_pos_t from, bitset_pos_t
  * @param a The bitset.
  * @return 1, if the bitset is empty, 0 if not.
  */
-static inline int bitset_is_empty(const bitset_t *a)
+static inline bool bitset_is_empty(const bitset_t *bs)
 {
-       bitset_pos_t i;
-       for (i = 0; i < a->units; ++i)
-               if (BS_DATA(a)[i] != 0)
-                       return 0;
-       return 1;
+       return rbitset_is_empty(bs->data, bs->size);
 }
 
 /**
@@ -525,28 +343,35 @@ static inline void bitset_fprint(FILE *file, const bitset_t *bs)
 
        putc('{', file);
        for(i = bitset_next_set(bs, 0); i != -1; i = bitset_next_set(bs, i + 1)) {
-               fprintf(file, "%s%u", prefix, i);
+               fprintf(file, "%s%d", prefix, i);
                prefix = ",";
        }
        putc('}', file);
 }
 
-static inline void bitset_debug_fprint(FILE *file, const bitset_t *bs)
+/**
+ * Perform tgt = tgt & src operation.
+ * @param tgt  The target bitset.
+ * @param src  The source bitset.
+ * @return the tgt set.
+ */
+static inline void bitset_and(bitset_t *tgt, const bitset_t *src)
 {
-       bitset_pos_t i;
-
-       fprintf(file, "%u:", bs->units);
-       for(i = 0; i < bs->units; ++i)
-               fprintf(file, " " BITSET_UNIT_FMT, BS_DATA(bs)[i]);
+       assert(tgt->size == src->size);
+       rbitset_and(tgt->data, src->data, src->size);
 }
 
 /**
- * Perform tgt = tgt src operation.
+ * Perform tgt = tgt & ~src operation.
  * @param tgt  The target bitset.
  * @param src  The source bitset.
  * @return the tgt set.
  */
-static inline bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
+static inline void bitset_andnot(bitset_t *tgt, const bitset_t *src)
+{
+       assert(tgt->size == src->size);
+       rbitset_andnot(tgt->data, src->data, src->size);
+}
 
 /**
  * Perform Union, tgt = tgt u src operation.
@@ -554,48 +379,31 @@ static inline bitset_t *bitset_andnot(bitset_t *tgt, const bitset_t *src);
  * @param src  The source bitset.
  * @return the tgt set.
  */
-static inline bitset_t *bitset_or(bitset_t *tgt, const bitset_t *src);
+static inline void bitset_or(bitset_t *tgt, const bitset_t *src)
+{
+       assert(tgt->size == src->size);
+       rbitset_or(tgt->data, src->data, src->size);
+}
 
 /**
- * Perform tgt = tgt ^ ~src operation.
+ * Perform tgt = tgt ^ src operation.
  * @param tgt  The target bitset.
  * @param src  The source bitset.
  * @return the tgt set.
  */
-static inline bitset_t *bitset_xor(bitset_t *tgt, const bitset_t *src);
-
-/*
- * Here, the binary operations follow.
- * And, Or, And Not, Xor are available.
- */
-#define BINARY_OP(op) \
-static inline bitset_t *bitset_ ## op(bitset_t *tgt, const bitset_t *src) \
-{ \
-       bitset_pos_t i; \
-       bitset_pos_t n = tgt->units > src->units ? src->units : tgt->units; \
-       for(i = 0; i < n; i += _BITSET_BINOP_UNITS_INC) \
-               _bitset_inside_binop_ ## op(&BS_DATA(tgt)[i], &BS_DATA(src)[i]); \
-       if(n < tgt->units) \
-               _bitset_clear_rest(&BS_DATA(tgt)[i], tgt->units - i); \
-       return _bitset_mask_highest(tgt); \
+static inline void bitset_xor(bitset_t *tgt, const bitset_t *src)
+{
+       assert(tgt->size == src->size);
+       rbitset_xor(tgt->data, src->data, src->size);
 }
 
-/*
- * Define the clear rest macro for the and, since it is the only case,
- * were non existed (treated as 0) units in the src must be handled.
- * For all other operations holds: x Op 0 = x for Op in { Andnot, Or, Xor }
- *
- * For and, each bitset implementer has to provide the macro
- * _bitset_clear_units(data, n), which clears n units from the pointer
- * data on.
- */
-#define _bitset_clear_rest(data,n) _bitset_inside_clear_units(data, n)
-BINARY_OP(and)
-#undef _bitset_clear_rest
-#define _bitset_clear_rest(data,n) do { } while(0)
-
-BINARY_OP(andnot)
-BINARY_OP(or)
-BINARY_OP(xor)
+/**
+ * Copy a raw bitset into an bitset.
+ */
+static inline void rbitset_copy_to_bitset(const unsigned *rbitset,
+                                          bitset_t *bitset)
+{
+       rbitset_copy(bitset->data, rbitset, bitset->size);
+}
 
 #endif
diff --git a/ir/adt/bitset_ia32.h b/ir/adt/bitset_ia32.h
deleted file mode 100644 (file)
index 20ad631..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief    intel 80x86 implementation of bitsets
- * @version  $Id$
- */
-#ifndef _BITSET_IA32_H
-#define _BITSET_IA32_H
-
-#undef _bitset_inside_clear
-#undef _bitset_inside_set
-#undef _bitset_inside_flip
-
-#define _bitset_inside_set(unit, bit) \
-       __asm__ __volatile__( "btsl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#define _bitset_inside_clear(unit, bit) \
-       __asm__ __volatile__( "btrl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#define _bitset_inside_flip(unit, bit) \
-       __asm__ __volatile__( "btcl %1,%0" :"=m" (*unit) : "Ir" (bit) : "cc")
-
-#undef _bitset_inside_is_set
-#undef _bitset_inside_nlz
-#undef _bitset_inside_ntz
-#undef _bitset_inside_ntz_value
-
-#define _bitset_inside_is_set(unit, bit) _bitset_ia32_inside_is_set(unit, bit)
-#define _bitset_inside_nlz(unit)         _bitset_ia32_inside_nlz(unit)
-#define _bitset_inside_ntz(unit)         _bitset_ia32_inside_ntz(unit)
-#define _bitset_inside_ntz_value(unit)   _bitset_ia32_inside_ntz_value(unit)
-
-static inline int _bitset_ia32_inside_is_set(bitset_unit_t *unit, unsigned bit)
-{
-       int res;
-       __asm__("bt    %2, %1\n\t"
-                       "rcl   $1, %0\n\t"
-                       "and   $1, %0"
-                       : "=r" (res)
-                       : "m" (*unit), "Ir" (bit)
-                       : "cc");
-       return res;
-}
-
-static inline unsigned _bitset_ia32_inside_nlz(bitset_unit_t *unit)
-{
-       unsigned res;
-       __asm__("bsr    %1, %0\n\t"
-                       "cmovz  %2, %0\n\t"
-                       "neg    %0\n\t"
-                       "add   $31, %0"
-                       : "=&r" (res)
-                       : "m" (*unit), "r" (-1)
-                       : "cc");
-       return res;
-}
-
-static inline unsigned _bitset_ia32_inside_ntz(bitset_unit_t *unit) {
-       unsigned res;
-       __asm__("bsfl   %1, %0\n\t"
-                       "cmovz  %2, %0\n\t"
-                       : "=&r" (res)
-                       : "m" (*unit), "r" (32)
-                       : "cc");
-       return res;
-}
-
-static inline unsigned _bitset_ia32_inside_ntz_value(bitset_unit_t unit) {
-       unsigned res;
-       __asm__("bsfl   %1, %0\n\t"
-                       "cmovz  %2, %0\n\t"
-                       : "=&r" (res)
-                       : "r" (unit), "r" (32)
-                       : "cc");
-       return res;
-}
-
-#endif
diff --git a/ir/adt/bitset_std.h b/ir/adt/bitset_std.h
deleted file mode 100644 (file)
index 784dccc..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
- * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
- */
-
-/**
- * @file
- * @brief    ANSI-C compliant implementation of bitsets
- * @version  $Id$
- */
-#ifndef FIRM_ADT_BITSET_STD_H
-#define FIRM_ADT_BITSET_STD_H
-
-#include "bitfiddle.h"
-
-/** Use ordinary ints as unit types. */
-typedef unsigned int bitset_unit_t;
-
-#define BITSET_UNIT_FMT "%0x"
-#define BITSET_UNIT_ALL_ONE ((unsigned int) -1)
-
-/**
- * Clear some units from a certain address on.
- * @param addr The address from where to clear.
- * @param n The number of units to set to 0.
- */
-#define _bitset_inside_clear_units(addr,n) \
-       memset(addr, 0, n * BS_UNIT_SIZE)
-
-/**
- * Set a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_set(unit_ptr,bit) (*unit_ptr) |= (1 << (bit))
-
-/**
- * Clear a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_clear(unit_ptr,bit) (*unit_ptr) &= ~(1 << (bit))
-
-/**
- * Flip a bit in a unit.
- * @param unit A pointer to the unit.
- * @param bit which bit to set.
- */
-#define _bitset_inside_flip(unit_ptr,bit) (*unit_ptr) ^= (1 << (bit))
-
-/**
- * Flip a whole unit.
- * @param unit_ptr The pointer to the unit.
- */
-#define _bitset_inside_flip_unit(unit_ptr) (*unit_ptr) = ~(*unit_ptr)
-
-/**
- * Count the number of leading zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_nlz(unit_ptr) (nlz(*unit_ptr))
-
-
-/**
- * Count the number of trailing zeroes in a unit.
- * @param unit A pointer to the unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz(unit_ptr) _bitset_std_inside_ntz(unit_ptr)
-static inline unsigned _bitset_std_inside_ntz(bitset_unit_t *unit_ptr)
-{
-       unsigned long data = *unit_ptr;
-       return 32 - (unsigned) nlz(~data & (data - 1));
-}
-
-/**
- * Count the number of trailing zeroes in a unit (whereas the unit is no
- * pointer but a value).
- * @param unit A unit.
- * @return The Number of leading zeroes.
- */
-#define _bitset_inside_ntz_value(unit) (32 - nlz(~(unit) & ((unit) - 1)))
-
-/**
- * test if a bit is set in a unit.
- * @param unit_ptr The pointer to the unit.
- * @param bit The bit to check.
- * @return 1, if the bit is set, 0 otherise.
- */
-#define _bitset_inside_is_set(unit_ptr,bit) \
-       (((*unit_ptr) & (1 << (bit))) != 0)
-
-/**
- * count the number of bits set in a unit.
- * @param unit_ptr The pointer to a unit.
- * @return The number of bits set in the unit.
- */
-#define _bitset_inside_pop(unit_ptr) (popcount(*unit_ptr))
-
-#define _BITSET_BINOP_UNITS_INC 1
-
-#define _bitset_inside_binop_and(tgt,src) ((*tgt) &= (*src))
-#define _bitset_inside_binop_andnot(tgt,src) ((*tgt) &= ~(*src))
-#define _bitset_inside_binop_or(tgt,src) ((*tgt) |= (*src))
-#define _bitset_inside_binop_xor(tgt,src) ((*tgt) ^= (*src))
-
-#endif
index 0318224..6149b99 100644 (file)
 
 /**
  * @file
- * @brief   helper functions for working with raw bitsets
+ * @brief   raw bitsets (low-level bitset operations)
  * @date    15.10.2004
  * @author  Matthias Braun
  * @version $Id$
- * @brief
- *     Raw bitsets are constructed from unsigned int arrays. Additional information
- *     like the size of the bitset or the used memory are not stored for
- *     efficiency reasons.
+ *
+ *     Raw bitsets are constructed from unsigned int arrays. Additional
+ *     information like the size of the bitset or the used memory are not
+ *     stored for (memory) efficiency reasons.
  *
  *     These bitsets need less space than bitset_t and their representation
  *     as int arrays allows having constant bitsets in the ro data segment.
  *     They should for smaller bitset, whose length is known through other means
  *     (a typical usage case is a set of cpu registers)
  *
- *     The bitset is built as an array of unsigned integers. It is assumed that
- *     exactly 32 bits may be put into each element of the array. If there are
- *     remaining bits, then they should be 0
+ *     The bitset is built as an array of unsigned integers. The unused bits
+ *     must be zero.
  */
 #ifndef FIRM_ADT_RAW_BITSET_H
 #define FIRM_ADT_RAW_BITSET_H
 
 #include <assert.h>
-#include "bitset.h"
+#include <stdbool.h>
 #include "bitfiddle.h"
 #include "obst.h"
 
-/** The base type for raw bitsets. */
-typedef unsigned int  rawbs_base_t;
-
-#define BITS_PER_ELEM                   (sizeof(rawbs_base_t) * 8)
-#define BITSET_SIZE_ELEMS(size_bits)    ((size_bits)/BITS_PER_ELEM + 1)
-#define BITSET_SIZE_BYTES(size_bits)    (BITSET_SIZE_ELEMS(size_bits) * sizeof(rawbs_base_t))
-#define BITSET_ELEM(bitset,pos)         bitset[pos / BITS_PER_ELEM]
+#define BITS_PER_ELEM                (sizeof(unsigned) * 8)
+#define BITSET_SIZE_ELEMS(size_bits) ((size_bits)/BITS_PER_ELEM + 1)
+#define BITSET_SIZE_BYTES(size_bits) (BITSET_SIZE_ELEMS(size_bits) * sizeof(unsigned))
+#define BITSET_ELEM(bitset,pos)      bitset[pos / BITS_PER_ELEM]
 
 /**
  * Allocate an empty raw bitset on the heap.
@@ -60,9 +56,10 @@ typedef unsigned int  rawbs_base_t;
  *
  * @return the new bitset
  */
-static inline unsigned *rbitset_malloc(unsigned size) {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res = xmalloc(size_bytes);
+static inline unsigned *rbitset_malloc(unsigned size)
+{
+       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
+       unsigned *res        = xmalloc(size_bytes);
        memset(res, 0, size_bytes);
 
        return res;
@@ -89,10 +86,11 @@ do { \
  *
  * @return the new bitset
  */
-static inline unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned size)
+static inline unsigned *rbitset_obstack_alloc(struct obstack *obst,
+                                              unsigned size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res = obstack_alloc(obst, size_bytes);
+       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
+       unsigned *res        = obstack_alloc(obst, size_bytes);
        memset(res, 0, size_bytes);
 
        return res;
@@ -107,10 +105,11 @@ static inline unsigned *rbitset_obstack_alloc(struct obstack *obst, unsigned siz
  *
  * @return the new bitset
  */
-static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsigned size)
+static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst,
+                                                     unsigned size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res = obstack_alloc(obst, size_bytes + sizeof(unsigned));
+       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
+       unsigned *res        = obstack_alloc(obst, size_bytes + sizeof(unsigned));
        *res = size;
        ++res;
        memset(res, 0, size_bytes);
@@ -133,8 +132,8 @@ static inline unsigned *rbitset_w_size_obstack_alloc(struct obstack *obst, unsig
 static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
        const unsigned *old_bitset, unsigned size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res = obstack_alloc(obst, size_bytes);
+       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
+       unsigned *res        = obstack_alloc(obst, size_bytes);
        memcpy(res, old_bitset, size_bytes);
 
        return res;
@@ -143,16 +142,17 @@ static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
 /**
  * Check if a bitset is empty, ie all bits cleared.
  */
-static inline int rbitset_is_empty(unsigned *bitset, unsigned size)
+static inline bool rbitset_is_empty(const unsigned *bitset, unsigned size)
 {
-       unsigned n = BITSET_SIZE_ELEMS(size);
        unsigned i;
+       unsigned n = BITSET_SIZE_ELEMS(size);
+
        for (i = 0; i < n; ++i) {
-               if (bitset[i] != 0)
-                       return 0;
+               if (bitset[i] != 0) {
+                       return false;
+               }
        }
-
-       return 1;
+       return true;
 }
 
 /**
@@ -166,6 +166,26 @@ static inline void rbitset_set(unsigned *bitset, unsigned pos)
        BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
 }
 
+/**
+ * Flip a bit at position pos. A zero bit becomes one, a one bit becomes zero.
+ *
+ * @param bitset  the bitset
+ * @param pos     position of the bit to be flipped
+ */
+static inline void rbitset_flip(unsigned *bitset, unsigned pos)
+{
+       BITSET_ELEM(bitset, pos) ^= 1 << (pos % BITS_PER_ELEM);
+}
+
+static inline unsigned rbitset_last_mask_(unsigned size)
+{
+       unsigned p;
+       if (size == 0)
+               return 0;
+       p = size % BITS_PER_ELEM;
+       return p == 0 ? ~0u : (1u << p)-1u;
+}
+
 /**
  * Set all bits in a given bitset.
  *
@@ -174,10 +194,14 @@ static inline void rbitset_set(unsigned *bitset, unsigned pos)
  */
 static inline void rbitset_set_all(unsigned *bitset, unsigned size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
-       memset(bitset, ~0, size_bytes);
-}
+       unsigned i;
+       unsigned n = BITSET_SIZE_ELEMS(size);
 
+       for (i = 0; i < n-1; ++i) {
+               bitset[i] = ~0u;
+       }
+       bitset[i] = rbitset_last_mask_(size);
+}
 
 /**
  * Clear a bit at position pos.
@@ -202,13 +226,29 @@ static inline void rbitset_clear_all(unsigned *bitset, unsigned size)
        memset(bitset, 0, size_bytes);
 }
 
+/**
+ * Flip all bits in a given bitset.
+ *
+ * @param bitset  the bitset
+ * @param size    number of bits in the bitset
+ */
+static inline void rbitset_flip_all(unsigned *bitset, unsigned size)
+{
+       unsigned pos;
+       unsigned n    = BITSET_SIZE_ELEMS(size);
+       for (pos = 0; pos < n-1; ++pos) {
+               bitset[pos] ^= ~0u;
+       }
+       bitset[pos] ^= rbitset_last_mask_(size);
+}
+
 /**
  * Check if a bit is set at position pos.
  *
  * @param bitset  the bitset
  * @param pos     the position of the bit to check
  */
-static inline int rbitset_is_set(const unsigned *bitset, unsigned pos)
+static inline bool rbitset_is_set(const unsigned *bitset, unsigned pos)
 {
        return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
 }
@@ -217,16 +257,16 @@ static inline int rbitset_is_set(const unsigned *bitset, unsigned pos)
  * Calculate the number of set bits (number of elements).
  *
  * @param bitset  the bitset
- * @param size    size of the bitset
+ * @param size    size of the bitset in bits
  */
 static inline unsigned rbitset_popcount(const unsigned *bitset, unsigned size)
 {
-       unsigned pos;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       unsigned i;
+       unsigned n   = BITSET_SIZE_ELEMS(size);
        unsigned res = 0;
 
-       for (pos = 0; pos < n; ++pos) {
-               res += popcount(bitset[pos]);
+       for (i = 0; i < n; ++i) {
+               res += popcount(bitset[i]);
        }
 
        return res;
@@ -245,14 +285,15 @@ static inline unsigned rbitset_popcount(const unsigned *bitset, unsigned size)
  * @note Does NOT check the size of the bitset, so ensure that a bit
  *       will be found or use a sentinel bit!
  */
-static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos, int set)
+static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos,
+                                    bool set)
 {
        unsigned p;
        unsigned elem_pos = pos / BITS_PER_ELEM;
        unsigned bit_pos = pos % BITS_PER_ELEM;
 
        unsigned elem = bitset[elem_pos];
-       unsigned mask = 0;
+       unsigned mask = set ? 0 : ~0u;
 
        /*
         * Mask out the bits smaller than pos in the current unit.
@@ -260,8 +301,6 @@ static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos, int se
         */
        unsigned in_elem_mask = (1 << bit_pos) - 1;
 
-       if (!set)
-               mask = ~mask;
        elem ^= mask;
        p = ntz(elem & ~in_elem_mask);
 
@@ -282,12 +321,68 @@ static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos, int se
        }
 }
 
+/**
+ * Returns the position of the next bit starting from (and including)
+ * a given position.
+ *
+ * @param bitset  a bitset
+ * @param pos     the first position to check
+ * @param last    first position that is not checked anymore
+ * @param set     if 0 search for unset bit, else for set bit
+ *
+ * @return the first position where a matched bit was found.
+ *         (unsigned)-1 if no bit was found.
+ */
+static inline unsigned rbitset_next_max(const unsigned *bitset, unsigned pos,
+                                        unsigned last, bool set)
+{
+       unsigned p;
+       unsigned elem_pos = pos / BITS_PER_ELEM;
+       unsigned bit_pos  = pos % BITS_PER_ELEM;
+
+       unsigned elem = bitset[elem_pos];
+       unsigned mask = set ? 0 : ~0u;
+       unsigned res  = (unsigned)-1;
+
+       /*
+        * Mask out the bits smaller than pos in the current unit.
+        * We are only interested in bits set higher than pos.
+        */
+       unsigned in_elem_mask = (1 << bit_pos) - 1;
+
+       assert(pos < last);
+
+       elem ^= mask;
+       p = ntz(elem & ~in_elem_mask);
+
+       /* If there is a bit set in the current elem, exit. */
+       if (p < BITS_PER_ELEM) {
+               res = elem_pos * BITS_PER_ELEM + p;
+       } else {
+               unsigned n = BITSET_SIZE_ELEMS(last);
+               /* Else search for set bits in the next units. */
+               for (elem_pos++; elem_pos < n; elem_pos++) {
+                       elem = bitset[elem_pos] ^ mask;
+
+                       p = ntz(elem);
+                       if (p < BITS_PER_ELEM) {
+                               res = elem_pos * BITS_PER_ELEM + p;
+                               break;
+                       }
+               }
+       }
+       if (res >= last)
+               res = (unsigned)-1;
+
+       return res;
+}
+
 /**
  * Inplace Intersection of two sets.
  *
  * @param dst   the destination bitset and first operand
  * @param src   the second bitset
- * @param size  size of both bitsets
+ * @param size  size of both bitsets in bits
  */
 static inline void rbitset_and(unsigned *dst, const unsigned *src, unsigned size)
 {
@@ -303,7 +398,7 @@ static inline void rbitset_and(unsigned *dst, const unsigned *src, unsigned size
  *
  * @param dst   the destination bitset and first operand
  * @param src   the second bitset
- * @param size  size of both bitsets
+ * @param size  size of both bitsets in bits
  */
 static inline void rbitset_or(unsigned *dst, const unsigned *src, unsigned size)
 {
@@ -319,7 +414,7 @@ static inline void rbitset_or(unsigned *dst, const unsigned *src, unsigned size)
  *
  * @param dst   the destination bitset and first operand
  * @param src   the second bitset
- * @param size  size of both bitsets
+ * @param size  size of both bitsets in bits
  */
 static inline void rbitset_andnot(unsigned *dst, const unsigned *src, unsigned size)
 {
@@ -335,7 +430,7 @@ static inline void rbitset_andnot(unsigned *dst, const unsigned *src, unsigned s
  *
  * @param dst   the destination bitset and first operand
  * @param src   the second bitset
- * @param size  size of both bitsets
+ * @param size  size of both bitsets in bits
  */
 static inline void rbitset_xor(unsigned *dst, const unsigned *src, unsigned size)
 {
@@ -346,17 +441,75 @@ static inline void rbitset_xor(unsigned *dst, const unsigned *src, unsigned size
        }
 }
 
+/**
+ * Set bits in a range to zero or one
+ * @param bitset   the bitset
+ * @param from     first bit to set
+ * @param to       last bit (the first bit which is not set anymore)
+ * @param val      wether to set to 1 or 0
+ */
+static inline void rbitset_set_range(unsigned *bitset, unsigned from,
+                                     unsigned to, bool val)
+{
+       assert(from < to);
+
+    /*
+     * A small example (for cleaning bits in the same unit).
+     * from   = 7
+     * to     = 19
+     * do_set = 0
+     * result:         xxxxxxx000000000000xxxxxxxxxxxxx
+     * from_unit_mask: 00000001111111111111111111111111
+     * to_unit_mask:   11111111111111111110000000000000
+     * scale:          01234567890123456789012345678901
+     *                           1         2         3
+     */
+
+       unsigned from_bit       = from % BITS_PER_ELEM;
+       unsigned from_pos       = from / BITS_PER_ELEM;
+       unsigned from_unit_mask = ~((1 << from_bit) - 1);
+
+       unsigned to_bit         = to % BITS_PER_ELEM;
+       unsigned to_pos         = to / BITS_PER_ELEM;
+       unsigned to_unit_mask   = (1 << to_bit) - 1;
+
+       /* do we want to set the bits in the range? */
+       if (val) {
+               if (from_pos == to_pos) {
+                       BITSET_ELEM(bitset, from_pos) |= from_unit_mask & to_unit_mask;
+               } else {
+                       unsigned i;
+                       BITSET_ELEM(bitset, from_pos) |= from_unit_mask;
+                       BITSET_ELEM(bitset, to_pos)   |= to_unit_mask;
+                       for (i = from_pos + 1; i < to_pos; ++i)
+                               BITSET_ELEM(bitset, i) = ~0u;
+               }
+       } else {
+               /* ... or clear them? */
+               if (from_pos == to_pos) {
+                       BITSET_ELEM(bitset, from_pos) &= ~(from_unit_mask & to_unit_mask);
+               } else {
+                       unsigned i;
+                       BITSET_ELEM(bitset, from_pos) &= ~from_unit_mask;
+                       BITSET_ELEM(bitset, to_pos)   &= ~to_unit_mask;
+                       for (i = from_pos + 1; i < to_pos; ++i)
+                               BITSET_ELEM(bitset, i) = 0;
+               }
+       }
+}
+
 /**
  * Returns 1 of two bitsets are equal.
  *
  * @param bitset1  the first bitset
  * @param bitset2  the second bitset
- * @param size     size of both bitsets
+ * @param size     size of both bitsets in bits
  */
-static inline int rbitset_equal(const unsigned *bitset1,
-                                const unsigned *bitset2, size_t size)
+static inline bool rbitsets_equal(const unsigned *bitset1,
+                                  const unsigned *bitset2, unsigned size)
 {
-       return memcmp(bitset1, bitset2, BITSET_SIZE_BYTES(size)) == 0;
+       unsigned size_bytes = BITSET_SIZE_BYTES(size);
+       return memcmp(bitset1, bitset2, size_bytes) == 0;
 }
 
 /**
@@ -364,46 +517,74 @@ static inline int rbitset_equal(const unsigned *bitset1,
  *
  * @param bitset1  the first bitset
  * @param bitset2  the second bitset
- * @param size     size of both bitsets
+ * @param size     size of both bitsets in bits
  */
-static inline int rbitsets_have_common(const unsigned *bitset1,
-                                       const unsigned *bitset2, size_t size)
+static inline bool rbitsets_have_common(const unsigned *bitset1,
+                                        const unsigned *bitset2, unsigned size)
 {
        unsigned i;
        unsigned n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                if ((bitset1[i] & bitset2[i]) != 0)
-                       return 1;
+                       return true;
        }
-       return 0;
+       return false;
 }
 
 /**
- * Copy a raw bitset into another.
+ * Tests wether all bits set in bitset1 are also set in bitset2.
  *
- * @param dst   the destination set
- * @param src   the source set
- * @param size  size of both bitsets
+ * @param bitset1  the first bitset
+ * @param bitset2  the second bitset
+ * @param size     size of both bitsets in bits
  */
-static inline void rbitset_copy(unsigned *dst, const unsigned *src, size_t size)
+static inline bool rbitset_contains(const unsigned *bitset1,
+                                    const unsigned *bitset2, unsigned size)
 {
-       memcpy(dst, src, BITSET_SIZE_BYTES(size));
+       unsigned i;
+       unsigned n = BITSET_SIZE_ELEMS(size);
+
+       for (i = 0; i < n; ++i) {
+               if ((bitset1[i] & bitset2[i]) != bitset1[i])
+                       return false;
+       }
+       return true;
 }
 
 /**
- * Copy a raw bitset into an bitset.
- *
- * @deprecated
+ * Treat the bitset as a number and subtract 1.
+ * @param  bitset  the bitset.
+ * @return size    size of the bitset in bits
  */
-static inline void rbitset_copy_to_bitset(const unsigned *rbitset, bitset_t *bitset)
+static inline void rbitset_minus1(unsigned *bitset, unsigned size)
 {
-       // TODO optimize me (or remove me)
-       unsigned i, n = bitset_size(bitset);
+       unsigned i;
+       unsigned n         = BITSET_SIZE_ELEMS(size);
+       unsigned last_mask = rbitset_last_mask_(size);
+
        for (i = 0; i < n; ++i) {
-               if (rbitset_is_set(rbitset, i))
-                       bitset_set(bitset, i);
+               unsigned mask       = i == n-1 ? last_mask : ~0u;
+               unsigned val        = bitset[i] & mask;
+               unsigned val_minus1 = val - 1;
+               bitset[i] = val_minus1 & mask;
+
+               if (((val >> (BITS_PER_ELEM-1)) ^ (val_minus1 >> (BITS_PER_ELEM-1))) == 0)
+                       break;
        }
 }
 
-#endif /* FIRM_ADT_RAW_BITSET_H */
+/**
+ * Copy a raw bitset into another.
+ *
+ * @param dst   the destination set
+ * @param src   the source set
+ * @param size  size of both bitsets in bits
+ */
+static inline void rbitset_copy(unsigned *dst, const unsigned *src,
+                                unsigned size)
+{
+       memcpy(dst, src, BITSET_SIZE_BYTES(size));
+}
+
+#endif
index 0fa2a27..38798ac 100644 (file)
@@ -168,7 +168,7 @@ static void compute_back_edge_chain(lv_chk_t *lv, const ir_node *bl)
        bitset_t *tmp = bitset_alloca(lv->n_blocks);
        bl_info_t *bi = get_block_info(lv, bl);
 
-       bitset_pos_t elm;
+       unsigned elm;
 
        DBG((lv->dbg, LEVEL_2, "computing T_%d\n", bi->id));
 
@@ -205,7 +205,7 @@ static void compute_back_edge_chain(lv_chk_t *lv, const ir_node *bl)
 
 static inline void compute_back_edge_chains(lv_chk_t *lv)
 {
-       bitset_pos_t elm;
+       unsigned elm;
        int i, n;
 
        DBG((lv->dbg, LEVEL_2, "back edge sources: %B\n", lv->back_edge_src));
index 72ec89f..cdf1610 100644 (file)
@@ -333,7 +333,7 @@ static inline int reg_reqs_equal(const arch_register_req_t *req1,
                        return 0;
 
                n_regs = arch_register_class_n_regs(req1->cls);
-               if (!rbitset_equal(req1->limited, req2->limited, n_regs))
+               if (!rbitsets_equal(req1->limited, req2->limited, n_regs))
                        return 0;
        }
 
index 3a21088..25e7227 100644 (file)
@@ -84,25 +84,6 @@ typedef struct _be_chordal_alloc_env_t {
        int colors_n;          /**< The number of colors. */
 } be_chordal_alloc_env_t;
 
-#if 0
-static void check_border_list(struct list_head *head)
-{
-       border_t *x;
-       list_for_each_entry(border_t, x, head, list) {
-               assert(x->magic == BORDER_FOURCC);
-       }
-}
-
-static void check_heads(be_chordal_env_t *env)
-{
-       pmap_entry *ent;
-       for (ent = pmap_first(env->border_heads); ent; ent = pmap_next(env->border_heads)) {
-               /* ir_printf("checking border list of block %+F\n", ent->key); */
-               check_border_list(ent->value);
-       }
-}
-#endif
-
 static int get_next_free_reg(const be_chordal_alloc_env_t *alloc_env, bitset_t *colors)
 {
        bitset_t *tmp = alloc_env->tmp_colors;
@@ -198,7 +179,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env,
        int *assignment;
        pmap *partners;
        int i, n_alloc;
-       bitset_pos_t col;
+       unsigned col;
        const ir_edge_t *edge;
        ir_node *perm = NULL;
        //int match_res, cost;
index a58d3da..130a1e8 100644 (file)
@@ -120,7 +120,7 @@ void create_borders(ir_node *block, void *env_ptr)
        be_lv_t *lv                       = env->birg->lv;
 
        int i, n;
-       bitset_pos_t elm;
+       unsigned elm;
        unsigned step = 0;
        unsigned pressure = 0;
        struct list_head *head;
index 6303f9d..3b1c1d3 100644 (file)
@@ -397,7 +397,7 @@ static inline void qnode_max_ind_set(qnode_t *qn, const unit_t *ou)
        ir_node **safe, **unsafe;
        int i, o, safe_count, safe_costs, unsafe_count, *unsafe_costs;
        bitset_t *curr, *best;
-       bitset_pos_t pos;
+       unsigned pos;
        int next, curr_weight, best_weight = 0;
 
        /* assign the nodes into two groups.
@@ -552,8 +552,8 @@ static void ou_optimize(unit_t *ou)
        qnode_t                     *tmp;
        const arch_register_req_t   *req;
        bitset_t const*              ignore;
-       bitset_pos_t                 n_regs;
-       bitset_pos_t                 idx;
+       unsigned                     n_regs;
+       unsigned                     idx;
        int                          i;
 
        DBG((dbg, LEVEL_1, "\tOptimizing unit:\n"));
@@ -567,7 +567,7 @@ static void ou_optimize(unit_t *ou)
        ignore  = ou->co->cenv->ignore_colors;
        n_regs  = req->cls->n_regs;
        if (arch_register_req_is(req, limited)) {
-               rawbs_base_t const* limited = req->limited;
+               unsigned const* limited = req->limited;
 
                for (idx = 0; idx != n_regs; ++idx) {
                        if (bitset_is_set(ignore, idx))
index 20bd1cb..60f1e79 100644 (file)
@@ -327,7 +327,7 @@ static void determine_color_costs(co2_t *env, co2_irn_t *ci, col_cost_pair_t *co
        bitset_t *forb     = bitset_alloca(n_regs);
        affinity_node_t *a = ci->aff;
 
-       bitset_pos_t elm;
+       unsigned elm;
        const ir_node *pos;
        void *it;
        int i;
@@ -614,7 +614,7 @@ static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
        be_ifg_t *ifg  = env->co->cenv->ifg;
        bitset_t *bs   = bitset_alloca(n_regs);
 
-       bitset_pos_t elm;
+       unsigned elm;
        const ir_node *irn;
        void *it;
 
@@ -630,7 +630,7 @@ static void node_color_badness(co2_cloud_irn_t *ci, int *badness)
 
                admissible_colors(env, ni, bs);
                if (bitset_popcount(bs) == 1) {
-                       bitset_pos_t c = bitset_next_set(bs, 0);
+                       unsigned c = bitset_next_set(bs, 0);
                        badness[c] += ci->costs;
                }
 
index e0833e0..7654c69 100644 (file)
@@ -171,7 +171,7 @@ static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c)
  */
 static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *node)
 {
-       bitset_pos_t idx;
+       unsigned idx;
        (void) env;
 
        if (bitset_popcount(node->adm_colors) < 1)
@@ -566,7 +566,7 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
 
                        node->chunk = c;
                        if (node->constr_factor > REAL(0.0)) {
-                               bitset_pos_t col;
+                               unsigned col;
                                bitset_foreach (node->adm_colors, col)
                                        c->color_affinity[col].cost += node->constr_factor;
                        }
index 2270339..b5a0a30 100644 (file)
@@ -82,7 +82,7 @@ static void build_coloring_cstr(ilp_env_t *ienv)
 
        be_ifg_foreach_node(ifg, iter, irn)
                if (!sr_is_removed(ienv->sr, irn)) {
-                       bitset_pos_t col;
+                       unsigned col;
                        int cst_idx;
                        const arch_register_req_t *req;
                        int curr_node_color = get_irn_col(irn);
index b479661..08ca33a 100644 (file)
@@ -310,7 +310,7 @@ static int ou_max_ind_set_costs(unit_t *ou)
        ir_node **safe, **unsafe;
        int i, o, safe_count, safe_costs, unsafe_count, *unsafe_costs;
        bitset_t *curr;
-       bitset_pos_t pos;
+       unsigned  pos;
        int max, curr_weight, best_weight = 0;
 
        /* assign the nodes into two groups.
index e7a985f..a830a70 100644 (file)
@@ -108,8 +108,8 @@ static ptr_head_t *ptr_get_new_head(ifg_pointer_t *ifg)
 
 static void write_pointers(bitset_t *live, ifg_pointer_t *ifg)
 {
-       ir_node      *live_irn;
-       bitset_pos_t  elm;
+       ir_node  *live_irn;
+       unsigned  elm;
 
        bitset_foreach_irn(ifg->env->irg, live, elm, live_irn) {
                ptr_head_t *head    = phase_get_or_set_irn_data(&ifg->ph, live_irn);
@@ -182,7 +182,7 @@ static void find_neighbour_walker(ir_node *bl, void *data)
        ir_node          *first    = NULL;
        bitset_t         *live     = bitset_malloc(get_irg_last_idx(ifg->env->irg));
        bitset_t         *my_live;
-       bitset_pos_t     my_elm;
+       unsigned         my_elm;
        border_t         *b;
        ir_node          *my_irn;
        element_content  last_irn;
index d083788..dd8fc9a 100644 (file)
@@ -1207,7 +1207,7 @@ static void create_assignment_and_precedence_constraints(be_ilpsched_env_t *env,
 
                /* the precedence constraints */
                stat_ev_tim_push();
-               bs_block_irns = bitset_clear_all(bs_block_irns);
+               bitset_clear_all(bs_block_irns);
 
                sta_collect_in_deps(irn, &deps);
                foreach_ir_nodeset(&deps, pred, iter) {
index 95c7bc3..7009126 100644 (file)
@@ -1894,14 +1894,16 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, ir_nod
                                                be simultaneously alive with u
                                        */
                                        bitset_copy(bs_tmp, bs_vdesc);
-                                       mu1 = bitset_popcount(bitset_and(bs_tmp, bs_sv));
+                                       bitset_and(bs_tmp, bs_sv);
+                                       mu1 = bitset_popcount(bs_tmp);
 
                                        /*
                                                mu2 = | accum_desc_all_pkiller(u) without descendants(v) |
                                        */
                                        if (is_pkiller) {
                                                bitset_copy(bs_tmp, bs_ukilldesc);
-                                               mu2 = bitset_popcount(bitset_andnot(bs_tmp, bs_vdesc));
+                                               bitset_andnot(bs_tmp, bs_vdesc);
+                                               mu2 = bitset_popcount(bs_tmp);
                                        }
                                        else {
                                                mu2 = 0;
index 4b9a940..1e18a65 100644 (file)
@@ -136,7 +136,7 @@ static void prepare_constr_insn(be_pre_spill_env_t *env, ir_node *node)
 
                        /* if the constraint is the same, no copy is necessary
                         * TODO generalise unequal but overlapping constraints */
-                       if (rbitset_equal(req->limited, req2->limited, cls->n_regs))
+                       if (rbitsets_equal(req->limited, req2->limited, cls->n_regs))
                                continue;
 
                        copy = be_new_Copy(cls, block, in);
index d0dcf13..e8c533e 100644 (file)
@@ -66,7 +66,7 @@ static int bitset_emit(lc_appendable_t *app,
 {
        int res = 2;
        bitset_t *b = arg->v_ptr;
-       bitset_pos_t p;
+       unsigned  p;
        char buf[32];
        const char *prefix = "";
 
index 28884ac..de2fb14 100644 (file)
 
 
 /* Internal use. */
-#define _bsfe_get_irn(irg, elm) (elm == (bitset_pos_t) -1 ? NULL : get_idx_irn((irg), (unsigned) elm))
+#define _bsfe_get_irn(irg, elm) (elm == (unsigned) -1 ? NULL : get_idx_irn((irg), (unsigned) elm))
 
 /**
  * Iterate over a bitset containing node indexes.
  * @param irg The graph the nodes are in.
  * @param bs  The bitset containing the indexes.
- * @param elm A loop variable for the bitset (must be of type bitset_pos_t).
+ * @param elm A loop variable for the bitset
  * @param irn An ir_node * which is set to the current node.
  */
 #define bitset_foreach_irn(irg, bs, elm, irn) \
-       for(elm = bitset_next_set(bs, 0), irn = _bsfe_get_irn(irg, elm); elm != (bitset_pos_t) -1; elm = bitset_next_set(bs, elm + 1), irn = _bsfe_get_irn(irg, elm))
+       for(elm = bitset_next_set(bs, 0), irn = _bsfe_get_irn(irg, elm); elm != (unsigned) -1; elm = bitset_next_set(bs, elm + 1), irn = _bsfe_get_irn(irg, elm))
 
 
 #endif
index 9b0c2ef..5b3fc86 100644 (file)
@@ -1690,7 +1690,7 @@ static int backward_antic(block_t *bl)
        }
 
        memcpy(bl->id_2_memop_antic, env.curr_id_2_memop, env.rbs_size * sizeof(env.curr_id_2_memop[0]));
-       if (! rbitset_equal(bl->anticL_in, env.curr_set, env.rbs_size)) {
+       if (! rbitsets_equal(bl->anticL_in, env.curr_set, env.rbs_size)) {
                /* changed */
                rbitset_copy(bl->anticL_in, env.curr_set, env.rbs_size);
                dump_curr(bl, "AnticL_in*");
@@ -2166,7 +2166,7 @@ static int insert_Load(block_t *bl)
        /* always update the map after gen/kill, as values might have been changed due to RAR/WAR/WAW */
        memcpy(bl->id_2_memop_avail, env.curr_id_2_memop, env.rbs_size * sizeof(env.curr_id_2_memop[0]));
 
-       if (!rbitset_equal(bl->avail_out, env.curr_set, env.rbs_size)) {
+       if (!rbitsets_equal(bl->avail_out, env.curr_set, env.rbs_size)) {
                /* the avail set has changed */
                rbitset_copy(bl->avail_out, env.curr_set, env.rbs_size);
                dump_curr(bl, "Avail_out*");