beinsn: Avoid copying bitsets by using a raw bitset for the admissible registers.
[libfirm] / ir / adt / raw_bitset.h
index 0dbf6b2..8af6662 100644 (file)
@@ -22,7 +22,6 @@
  * @brief   raw bitsets (low-level bitset operations)
  * @date    15.10.2004
  * @author  Matthias Braun
- * @version $Id$
  *
  *     Raw bitsets are constructed from unsigned int arrays. Additional
  *     information like the size of the bitset or the used memory are not
  *
  * @return the new bitset
  */
-static inline unsigned *rbitset_malloc(unsigned size)
+static inline unsigned *rbitset_malloc(size_t size)
 {
-       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res        = xmalloc(size_bytes);
-       memset(res, 0, size_bytes);
-
-       return res;
+       return XMALLOCNZ(unsigned, BITSET_SIZE_ELEMS(size));
 }
 
 /**
  * Allocate an empty raw bitset on the stack.
  *
- * @param res   will contain the newly allocated bitset
  * @param size  number of bits in the bitset
  */
-#define rbitset_alloca(res, size) \
-do { \
-       unsigned size_bytes = BITSET_SIZE_BYTES(size); \
-       res = alloca(size_bytes); \
-       memset(res, 0, size_bytes); \
-} while(0)
+#define rbitset_alloca(size) \
+       ((unsigned*)memset(alloca(BITSET_SIZE_BYTES(size)), 0, BITSET_SIZE_BYTES(size)))
 
 /**
  * Allocate an empty raw bitset on an obstack.
@@ -87,13 +77,9 @@ do { \
  * @return the new bitset
  */
 static inline unsigned *rbitset_obstack_alloc(struct obstack *obst,
-                                              unsigned size)
+                                              size_t size)
 {
-       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res        = obstack_alloc(obst, size_bytes);
-       memset(res, 0, size_bytes);
-
-       return res;
+       return OALLOCNZ(obst, unsigned, BITSET_SIZE_ELEMS(size));
 }
 
 /**
@@ -106,10 +92,10 @@ static inline unsigned *rbitset_obstack_alloc(struct obstack *obst,
  * @return the new bitset
  */
 static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
-       const unsigned *old_bitset, unsigned size)
+       const unsigned *old_bitset, size_t size)
 {
-       unsigned  size_bytes = BITSET_SIZE_BYTES(size);
-       unsigned *res        = obstack_alloc(obst, size_bytes);
+       size_t    size_bytes = BITSET_SIZE_BYTES(size);
+       unsigned *res        = OALLOCN(obst, unsigned, BITSET_SIZE_ELEMS(size));
        memcpy(res, old_bitset, size_bytes);
 
        return res;
@@ -118,10 +104,10 @@ static inline unsigned *rbitset_duplicate_obstack_alloc(struct obstack *obst,
 /**
  * Check if a bitset is empty, ie all bits cleared.
  */
-static inline bool rbitset_is_empty(const unsigned *bitset, unsigned size)
+static inline bool rbitset_is_empty(const unsigned *bitset, size_t size)
 {
-       unsigned i;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       size_t i;
+       size_t n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                if (bitset[i] != 0) {
@@ -137,7 +123,7 @@ static inline bool rbitset_is_empty(const unsigned *bitset, unsigned size)
  * @param bitset  the bitset
  * @param pos     the position of the bit to be set
  */
-static inline void rbitset_set(unsigned *bitset, unsigned pos)
+static inline void rbitset_set(unsigned *bitset, size_t pos)
 {
        BITSET_ELEM(bitset,pos) |= 1 << (pos % BITS_PER_ELEM);
 }
@@ -148,14 +134,14 @@ static inline void rbitset_set(unsigned *bitset, unsigned pos)
  * @param bitset  the bitset
  * @param pos     position of the bit to be flipped
  */
-static inline void rbitset_flip(unsigned *bitset, unsigned pos)
+static inline void rbitset_flip(unsigned *bitset, size_t pos)
 {
        BITSET_ELEM(bitset, pos) ^= 1 << (pos % BITS_PER_ELEM);
 }
 
-static inline unsigned rbitset_last_mask_(unsigned size)
+static inline unsigned rbitset_last_mask_(size_t size)
 {
-       unsigned p;
+       size_t p;
        if (size == 0)
                return 0;
        p = size % BITS_PER_ELEM;
@@ -168,10 +154,10 @@ static inline unsigned rbitset_last_mask_(unsigned size)
  * @param bitset  the bitset
  * @param size    number of bits in the bitset
  */
-static inline void rbitset_set_all(unsigned *bitset, unsigned size)
+static inline void rbitset_set_all(unsigned *bitset, size_t size)
 {
-       unsigned i;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       size_t i;
+       size_t n = BITSET_SIZE_ELEMS(size);
 
        if (n == 0)
                return;
@@ -188,7 +174,7 @@ static inline void rbitset_set_all(unsigned *bitset, unsigned size)
  * @param bitset  the bitset
  * @param pos     the position of the bit to be clear
  */
-static inline void rbitset_clear(unsigned *bitset, unsigned pos)
+static inline void rbitset_clear(unsigned *bitset, size_t pos)
 {
        BITSET_ELEM(bitset, pos) &= ~(1 << (pos % BITS_PER_ELEM));
 }
@@ -199,9 +185,9 @@ static inline void rbitset_clear(unsigned *bitset, unsigned pos)
  * @param bitset  the bitset
  * @param size    number of bits in the bitset
  */
-static inline void rbitset_clear_all(unsigned *bitset, unsigned size)
+static inline void rbitset_clear_all(unsigned *bitset, size_t size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
+       size_t size_bytes = BITSET_SIZE_BYTES(size);
        memset(bitset, 0, size_bytes);
 }
 
@@ -211,10 +197,10 @@ static inline void rbitset_clear_all(unsigned *bitset, unsigned size)
  * @param bitset  the bitset
  * @param size    number of bits in the bitset
  */
-static inline void rbitset_flip_all(unsigned *bitset, unsigned size)
+static inline void rbitset_flip_all(unsigned *bitset, size_t size)
 {
-       unsigned pos;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       size_t pos;
+       size_t n = BITSET_SIZE_ELEMS(size);
 
        if (n == 0)
                return;
@@ -231,9 +217,9 @@ static inline void rbitset_flip_all(unsigned *bitset, unsigned size)
  * @param bitset  the bitset
  * @param pos     the position of the bit to check
  */
-static inline bool rbitset_is_set(const unsigned *bitset, unsigned pos)
+static inline bool rbitset_is_set(const unsigned *bitset, size_t pos)
 {
-       return BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM));
+       return (BITSET_ELEM(bitset, pos) & (1 << (pos % BITS_PER_ELEM))) != 0;
 }
 
 /**
@@ -242,11 +228,10 @@ static inline bool rbitset_is_set(const unsigned *bitset, unsigned pos)
  * @param bitset  the bitset
  * @param size    size of the bitset in bits
  */
-static inline unsigned rbitset_popcount(const unsigned *bitset, unsigned size)
+static inline size_t rbitset_popcount(const unsigned *bitset, size_t size)
 {
-       unsigned i;
-       unsigned n   = BITSET_SIZE_ELEMS(size);
-       unsigned res = 0;
+       size_t i, n  = BITSET_SIZE_ELEMS(size);
+       size_t res = 0;
 
        for (i = 0; i < n; ++i) {
                res += popcount(bitset[i]);
@@ -268,12 +253,12 @@ 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,
-                                    bool set)
+static inline size_t rbitset_next(const unsigned *bitset, size_t pos,
+                                  bool set)
 {
        unsigned p;
-       unsigned elem_pos = pos / BITS_PER_ELEM;
-       unsigned bit_pos = pos % BITS_PER_ELEM;
+       size_t elem_pos = pos / BITS_PER_ELEM;
+       size_t bit_pos = pos % BITS_PER_ELEM;
 
        unsigned elem = bitset[elem_pos];
        unsigned mask = set ? 0 : ~0u;
@@ -314,24 +299,24 @@ static inline unsigned rbitset_next(const unsigned *bitset, unsigned pos,
  * @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.
+ *         (size_t)-1 if no bit was found.
  */
-static inline unsigned rbitset_next_max(const unsigned *bitset, unsigned pos,
-                                        unsigned last, bool set)
+static inline size_t rbitset_next_max(const unsigned *bitset, size_t pos,
+                                      size_t last, bool set)
 {
-       unsigned p;
-       unsigned elem_pos = pos / BITS_PER_ELEM;
-       unsigned bit_pos  = pos % BITS_PER_ELEM;
+       size_t p;
+       size_t elem_pos = pos / BITS_PER_ELEM;
+       size_t bit_pos  = pos % BITS_PER_ELEM;
 
        unsigned elem = bitset[elem_pos];
-       unsigned mask = set ? 0 : ~0u;
-       unsigned res  = (unsigned)-1;
+       unsigned mask = set ? 0u : ~0u;
+       size_t res  = (size_t)-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;
+       unsigned in_elem_mask = (1u << bit_pos) - 1;
 
        assert(pos < last);
 
@@ -342,7 +327,7 @@ static inline unsigned rbitset_next_max(const unsigned *bitset, unsigned pos,
        if (p < BITS_PER_ELEM) {
                res = elem_pos * BITS_PER_ELEM + p;
        } else {
-               unsigned n = BITSET_SIZE_ELEMS(last);
+               size_t 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;
@@ -355,7 +340,7 @@ static inline unsigned rbitset_next_max(const unsigned *bitset, unsigned pos,
                }
        }
        if (res >= last)
-               res = (unsigned)-1;
+               res = (size_t)-1;
 
        return res;
 }
@@ -367,9 +352,9 @@ static inline unsigned rbitset_next_max(const unsigned *bitset, unsigned pos,
  * @param src   the second bitset
  * @param size  size of both bitsets in bits
  */
-static inline void rbitset_and(unsigned *dst, const unsigned *src, unsigned size)
+static inline void rbitset_and(unsigned *dst, const unsigned *src, size_t size)
 {
-       unsigned i, n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                dst[i] &= src[i];
@@ -383,9 +368,9 @@ static inline void rbitset_and(unsigned *dst, const unsigned *src, unsigned size
  * @param src   the second bitset
  * @param size  size of both bitsets in bits
  */
-static inline void rbitset_or(unsigned *dst, const unsigned *src, unsigned size)
+static inline void rbitset_or(unsigned *dst, const unsigned *src, size_t size)
 {
-       unsigned i, n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                dst[i] |= src[i];
@@ -399,9 +384,9 @@ static inline void rbitset_or(unsigned *dst, const unsigned *src, unsigned size)
  * @param src   the second bitset
  * @param size  size of both bitsets in bits
  */
-static inline void rbitset_andnot(unsigned *dst, const unsigned *src, unsigned size)
+static inline void rbitset_andnot(unsigned *dst, const unsigned *src, size_t size)
 {
-       unsigned i, n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                dst[i] &= ~src[i];
@@ -415,9 +400,9 @@ static inline void rbitset_andnot(unsigned *dst, const unsigned *src, unsigned s
  * @param src   the second bitset
  * @param size  size of both bitsets in bits
  */
-static inline void rbitset_xor(unsigned *dst, const unsigned *src, unsigned size)
+static inline void rbitset_xor(unsigned *dst, const unsigned *src, size_t size)
 {
-       unsigned i, n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                dst[i] ^= src[i];
@@ -429,10 +414,10 @@ static inline void rbitset_xor(unsigned *dst, const unsigned *src, unsigned size
  * @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
+ * @param val      whether to set to 1 or 0
  */
-static inline void rbitset_set_range(unsigned *bitset, unsigned from,
-                                     unsigned to, bool val)
+static inline void rbitset_set_range(unsigned *bitset, size_t from,
+                                     size_t to, bool val)
 {
        /*
         * A small example (for cleaning bits in the same unit).
@@ -446,13 +431,13 @@ static inline void rbitset_set_range(unsigned *bitset, unsigned from,
         *                           1         2         3
         */
 
-       unsigned from_bit       = from % BITS_PER_ELEM;
-       unsigned from_pos       = from / BITS_PER_ELEM;
+       size_t from_bit         = from % BITS_PER_ELEM;
+       size_t 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;
+       size_t to_bit         = to % BITS_PER_ELEM;
+       size_t to_pos         = to / BITS_PER_ELEM;
+       unsigned to_unit_mask = (1 << to_bit) - 1;
 
        assert(from < to);
 
@@ -461,7 +446,7 @@ static inline void rbitset_set_range(unsigned *bitset, unsigned from,
                if (from_pos == to_pos) {
                        BITSET_ELEM(bitset, from_pos) |= from_unit_mask & to_unit_mask;
                } else {
-                       unsigned i;
+                       size_t 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)
@@ -472,7 +457,7 @@ static inline void rbitset_set_range(unsigned *bitset, unsigned from,
                if (from_pos == to_pos) {
                        BITSET_ELEM(bitset, from_pos) &= ~(from_unit_mask & to_unit_mask);
                } else {
-                       unsigned i;
+                       size_t 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)
@@ -489,24 +474,23 @@ static inline void rbitset_set_range(unsigned *bitset, unsigned from,
  * @param size     size of both bitsets in bits
  */
 static inline bool rbitsets_equal(const unsigned *bitset1,
-                                  const unsigned *bitset2, unsigned size)
+                                  const unsigned *bitset2, size_t size)
 {
-       unsigned size_bytes = BITSET_SIZE_BYTES(size);
+       size_t size_bytes = BITSET_SIZE_BYTES(size);
        return memcmp(bitset1, bitset2, size_bytes) == 0;
 }
 
 /**
- * Tests wether 2 bitsets wether at least 1 bit is set in both.
+ * Tests whether 2 bitsets have at least one common set bit.
  *
  * @param bitset1  the first bitset
  * @param bitset2  the second bitset
  * @param size     size of both bitsets in bits
  */
 static inline bool rbitsets_have_common(const unsigned *bitset1,
-                                        const unsigned *bitset2, unsigned size)
+                                        const unsigned *bitset2, size_t size)
 {
-       unsigned i;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                if ((bitset1[i] & bitset2[i]) != 0)
@@ -516,17 +500,16 @@ static inline bool rbitsets_have_common(const unsigned *bitset1,
 }
 
 /**
- * Tests wether all bits set in bitset1 are also set in bitset2.
+ * Tests whether all bits set in bitset1 are also set in bitset2.
  *
  * @param bitset1  the first bitset
  * @param bitset2  the second bitset
  * @param size     size of both bitsets in bits
  */
 static inline bool rbitset_contains(const unsigned *bitset1,
-                                    const unsigned *bitset2, unsigned size)
+                                    const unsigned *bitset2, size_t size)
 {
-       unsigned i;
-       unsigned n = BITSET_SIZE_ELEMS(size);
+       size_t i, n = BITSET_SIZE_ELEMS(size);
 
        for (i = 0; i < n; ++i) {
                if ((bitset1[i] & bitset2[i]) != bitset1[i])
@@ -540,10 +523,9 @@ static inline bool rbitset_contains(const unsigned *bitset1,
  * @param  bitset  the bitset.
  * @return size    size of the bitset in bits
  */
-static inline void rbitset_minus1(unsigned *bitset, unsigned size)
+static inline void rbitset_minus1(unsigned *bitset, size_t size)
 {
-       unsigned i;
-       unsigned n         = BITSET_SIZE_ELEMS(size);
+       size_t i, n        = BITSET_SIZE_ELEMS(size);
        unsigned last_mask = rbitset_last_mask_(size);
 
        for (i = 0; i < n; ++i) {
@@ -565,19 +547,28 @@ static inline void rbitset_minus1(unsigned *bitset, unsigned size)
  * @param size  size of both bitsets in bits
  */
 static inline void rbitset_copy(unsigned *dst, const unsigned *src,
-                                unsigned size)
+                                size_t size)
 {
        memcpy(dst, src, BITSET_SIZE_BYTES(size));
 }
 
 static inline void rbitset_copy_into(unsigned *dst, const unsigned *src,
-                                     unsigned size)
+                                     size_t size)
 {
-       unsigned n         = BITSET_SIZE_ELEMS(size);
+       size_t n           = BITSET_SIZE_ELEMS(size);
        unsigned last_mask = rbitset_last_mask_(size);
 
        memcpy(dst, src, (n-1) * (BITS_PER_ELEM/8));
        dst[n-1] = (src[n-1] & last_mask) | (dst[n-1] & ~last_mask);
 }
 
+/**
+ * Convenience macro for raw bitset iteration.
+ * @param bitset The bitset.
+ * @param size   Size of the bitset.
+ * @param elm    A size_t variable.
+ */
+#define rbitset_foreach(bitset, size, elm) \
+       for (size_t elm = 0; (elm = rbitset_next_max((bitset), elm, size, 1)) != (size_t)-1; ++elm)
+
 #endif