bitmap: test for constant as well as small size for inline versions
authorRusty Russell <rusty@rustcorp.com.au>
Mon, 29 Dec 2008 22:35:13 +0000 (09:05 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Mon, 29 Dec 2008 22:35:13 +0000 (09:05 +1030)
Impact: reduce text size

bitmap_zero et al have a fastpath for nbits <= BITS_PER_LONG, but this
should really only apply where the nbits is known at compile time.

This only saves about 1200 bytes on an allyesconfig kernel, but with
cpumasks going variable that number will increase.

   text data bss dec hex filename
35327852        5035607 6782976 47146435        2cf65c3 vmlinux-before
35326640        5035607 6782976 47145223        2cf6107 vmlinux-after

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
include/linux/bitmap.h

index a08c33a..2878811 100644 (file)
@@ -137,9 +137,12 @@ extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits);
                (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL               \
 )
 
                (1UL<<((nbits) % BITS_PER_LONG))-1 : ~0UL               \
 )
 
+#define small_const_nbits(nbits) \
+       (__builtin_constant_p(nbits) && (nbits) <= BITS_PER_LONG)
+
 static inline void bitmap_zero(unsigned long *dst, int nbits)
 {
 static inline void bitmap_zero(unsigned long *dst, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = 0UL;
        else {
                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
                *dst = 0UL;
        else {
                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
@@ -150,7 +153,7 @@ static inline void bitmap_zero(unsigned long *dst, int nbits)
 static inline void bitmap_fill(unsigned long *dst, int nbits)
 {
        size_t nlongs = BITS_TO_LONGS(nbits);
 static inline void bitmap_fill(unsigned long *dst, int nbits)
 {
        size_t nlongs = BITS_TO_LONGS(nbits);
-       if (nlongs > 1) {
+       if (!small_const_nbits(nbits)) {
                int len = (nlongs - 1) * sizeof(unsigned long);
                memset(dst, 0xff,  len);
        }
                int len = (nlongs - 1) * sizeof(unsigned long);
                memset(dst, 0xff,  len);
        }
@@ -160,7 +163,7 @@ static inline void bitmap_fill(unsigned long *dst, int nbits)
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
                        int nbits)
 {
 static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
                        int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src;
        else {
                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
                *dst = *src;
        else {
                int len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
@@ -171,7 +174,7 @@ static inline void bitmap_copy(unsigned long *dst, const unsigned long *src,
 static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src1 & *src2;
        else
                __bitmap_and(dst, src1, src2, nbits);
                *dst = *src1 & *src2;
        else
                __bitmap_and(dst, src1, src2, nbits);
@@ -180,7 +183,7 @@ static inline void bitmap_and(unsigned long *dst, const unsigned long *src1,
 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src1 | *src2;
        else
                __bitmap_or(dst, src1, src2, nbits);
                *dst = *src1 | *src2;
        else
                __bitmap_or(dst, src1, src2, nbits);
@@ -189,7 +192,7 @@ static inline void bitmap_or(unsigned long *dst, const unsigned long *src1,
 static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src1 ^ *src2;
        else
                __bitmap_xor(dst, src1, src2, nbits);
                *dst = *src1 ^ *src2;
        else
                __bitmap_xor(dst, src1, src2, nbits);
@@ -198,7 +201,7 @@ static inline void bitmap_xor(unsigned long *dst, const unsigned long *src1,
 static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src1 & ~(*src2);
        else
                __bitmap_andnot(dst, src1, src2, nbits);
                *dst = *src1 & ~(*src2);
        else
                __bitmap_andnot(dst, src1, src2, nbits);
@@ -207,7 +210,7 @@ static inline void bitmap_andnot(unsigned long *dst, const unsigned long *src1,
 static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
                        int nbits)
 {
 static inline void bitmap_complement(unsigned long *dst, const unsigned long *src,
                        int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
        else
                __bitmap_complement(dst, src, nbits);
                *dst = ~(*src) & BITMAP_LAST_WORD_MASK(nbits);
        else
                __bitmap_complement(dst, src, nbits);
@@ -216,7 +219,7 @@ static inline void bitmap_complement(unsigned long *dst, const unsigned long *sr
 static inline int bitmap_equal(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline int bitmap_equal(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_equal(src1, src2, nbits);
                return ! ((*src1 ^ *src2) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_equal(src1, src2, nbits);
@@ -225,7 +228,7 @@ static inline int bitmap_equal(const unsigned long *src1,
 static inline int bitmap_intersects(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline int bitmap_intersects(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
        else
                return __bitmap_intersects(src1, src2, nbits);
                return ((*src1 & *src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0;
        else
                return __bitmap_intersects(src1, src2, nbits);
@@ -234,7 +237,7 @@ static inline int bitmap_intersects(const unsigned long *src1,
 static inline int bitmap_subset(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
 static inline int bitmap_subset(const unsigned long *src1,
                        const unsigned long *src2, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_subset(src1, src2, nbits);
                return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_subset(src1, src2, nbits);
@@ -242,7 +245,7 @@ static inline int bitmap_subset(const unsigned long *src1,
 
 static inline int bitmap_empty(const unsigned long *src, int nbits)
 {
 
 static inline int bitmap_empty(const unsigned long *src, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_empty(src, nbits);
                return ! (*src & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_empty(src, nbits);
@@ -250,7 +253,7 @@ static inline int bitmap_empty(const unsigned long *src, int nbits)
 
 static inline int bitmap_full(const unsigned long *src, int nbits)
 {
 
 static inline int bitmap_full(const unsigned long *src, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_full(src, nbits);
                return ! (~(*src) & BITMAP_LAST_WORD_MASK(nbits));
        else
                return __bitmap_full(src, nbits);
@@ -258,7 +261,7 @@ static inline int bitmap_full(const unsigned long *src, int nbits)
 
 static inline int bitmap_weight(const unsigned long *src, int nbits)
 {
 
 static inline int bitmap_weight(const unsigned long *src, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
        return __bitmap_weight(src, nbits);
 }
                return hweight_long(*src & BITMAP_LAST_WORD_MASK(nbits));
        return __bitmap_weight(src, nbits);
 }
@@ -266,7 +269,7 @@ static inline int bitmap_weight(const unsigned long *src, int nbits)
 static inline void bitmap_shift_right(unsigned long *dst,
                        const unsigned long *src, int n, int nbits)
 {
 static inline void bitmap_shift_right(unsigned long *dst,
                        const unsigned long *src, int n, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = *src >> n;
        else
                __bitmap_shift_right(dst, src, n, nbits);
                *dst = *src >> n;
        else
                __bitmap_shift_right(dst, src, n, nbits);
@@ -275,7 +278,7 @@ static inline void bitmap_shift_right(unsigned long *dst,
 static inline void bitmap_shift_left(unsigned long *dst,
                        const unsigned long *src, int n, int nbits)
 {
 static inline void bitmap_shift_left(unsigned long *dst,
                        const unsigned long *src, int n, int nbits)
 {
-       if (nbits <= BITS_PER_LONG)
+       if (small_const_nbits(nbits))
                *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits);
        else
                __bitmap_shift_left(dst, src, n, nbits);
                *dst = (*src << n) & BITMAP_LAST_WORD_MASK(nbits);
        else
                __bitmap_shift_left(dst, src, n, nbits);