bitops: remove "optimizations"

The mapsize optimizations which were moved from x86 to the generic
code in commit 64970b68d2 increased the
binary size on non x86 architectures.

Looking into the real effects of the "optimizations" it turned out
that they are not used in find_next_bit() and find_next_zero_bit().

The ones in find_first_bit() and find_first_zero_bit() are used in a
couple of places but none of them is a real hot path.

Remove the "optimizations" all together and call the library functions
unconditionally.

Boot-tested on x86 and compile tested on every cross compiler I have.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Thomas Gleixner 2008-04-29 12:01:02 +02:00 committed by Linus Torvalds
parent 8972331292
commit fee4b19fb3
2 changed files with 19 additions and 112 deletions

View file

@ -114,8 +114,6 @@ static inline unsigned fls_long(unsigned long l)
#ifdef __KERNEL__ #ifdef __KERNEL__
#ifdef CONFIG_GENERIC_FIND_FIRST_BIT #ifdef CONFIG_GENERIC_FIND_FIRST_BIT
extern unsigned long __find_first_bit(const unsigned long *addr,
unsigned long size);
/** /**
* find_first_bit - find the first set bit in a memory region * find_first_bit - find the first set bit in a memory region
@ -124,28 +122,8 @@ extern unsigned long __find_first_bit(const unsigned long *addr,
* *
* Returns the bit number of the first set bit. * Returns the bit number of the first set bit.
*/ */
static __always_inline unsigned long extern unsigned long find_first_bit(const unsigned long *addr,
find_first_bit(const unsigned long *addr, unsigned long size) unsigned long size);
{
/* Avoid a function call if the bitmap size is a constant */
/* and not bigger than BITS_PER_LONG. */
/* insert a sentinel so that __ffs returns size if there */
/* are no set bits in the bitmap */
if (__builtin_constant_p(size) && (size < BITS_PER_LONG))
return __ffs((*addr) | (1ul << size));
/* the result of __ffs(0) is undefined, so it needs to be */
/* handled separately */
if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
return ((*addr) == 0) ? BITS_PER_LONG : __ffs(*addr);
/* size is not constant or too big */
return __find_first_bit(addr, size);
}
extern unsigned long __find_first_zero_bit(const unsigned long *addr,
unsigned long size);
/** /**
* find_first_zero_bit - find the first cleared bit in a memory region * find_first_zero_bit - find the first cleared bit in a memory region
@ -154,31 +132,12 @@ extern unsigned long __find_first_zero_bit(const unsigned long *addr,
* *
* Returns the bit number of the first cleared bit. * Returns the bit number of the first cleared bit.
*/ */
static __always_inline unsigned long extern unsigned long find_first_zero_bit(const unsigned long *addr,
find_first_zero_bit(const unsigned long *addr, unsigned long size) unsigned long size);
{
/* Avoid a function call if the bitmap size is a constant */
/* and not bigger than BITS_PER_LONG. */
/* insert a sentinel so that __ffs returns size if there */
/* are no set bits in the bitmap */
if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
return __ffs(~(*addr) | (1ul << size));
}
/* the result of __ffs(0) is undefined, so it needs to be */
/* handled separately */
if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
return (~(*addr) == 0) ? BITS_PER_LONG : __ffs(~(*addr));
/* size is not constant or too big */
return __find_first_zero_bit(addr, size);
}
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
#ifdef CONFIG_GENERIC_FIND_NEXT_BIT #ifdef CONFIG_GENERIC_FIND_NEXT_BIT
extern unsigned long __find_next_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/** /**
* find_next_bit - find the next set bit in a memory region * find_next_bit - find the next set bit in a memory region
@ -186,36 +145,8 @@ extern unsigned long __find_next_bit(const unsigned long *addr,
* @offset: The bitnumber to start searching at * @offset: The bitnumber to start searching at
* @size: The bitmap size in bits * @size: The bitmap size in bits
*/ */
static __always_inline unsigned long extern unsigned long find_next_bit(const unsigned long *addr,
find_next_bit(const unsigned long *addr, unsigned long size, unsigned long size, unsigned long offset);
unsigned long offset)
{
unsigned long value;
/* Avoid a function call if the bitmap size is a constant */
/* and not bigger than BITS_PER_LONG. */
/* insert a sentinel so that __ffs returns size if there */
/* are no set bits in the bitmap */
if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
value = (*addr) & ((~0ul) << offset);
value |= (1ul << size);
return __ffs(value);
}
/* the result of __ffs(0) is undefined, so it needs to be */
/* handled separately */
if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
value = (*addr) & ((~0ul) << offset);
return (value == 0) ? BITS_PER_LONG : __ffs(value);
}
/* size is not constant or too big */
return __find_next_bit(addr, size, offset);
}
extern unsigned long __find_next_zero_bit(const unsigned long *addr,
unsigned long size, unsigned long offset);
/** /**
* find_next_zero_bit - find the next cleared bit in a memory region * find_next_zero_bit - find the next cleared bit in a memory region
@ -223,33 +154,11 @@ extern unsigned long __find_next_zero_bit(const unsigned long *addr,
* @offset: The bitnumber to start searching at * @offset: The bitnumber to start searching at
* @size: The bitmap size in bits * @size: The bitmap size in bits
*/ */
static __always_inline unsigned long
find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long offset)
{
unsigned long value;
/* Avoid a function call if the bitmap size is a constant */ extern unsigned long find_next_zero_bit(const unsigned long *addr,
/* and not bigger than BITS_PER_LONG. */ unsigned long size,
unsigned long offset);
/* insert a sentinel so that __ffs returns size if there */
/* are no set bits in the bitmap */
if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
value = (~(*addr)) & ((~0ul) << offset);
value |= (1ul << size);
return __ffs(value);
}
/* the result of __ffs(0) is undefined, so it needs to be */
/* handled separately */
if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
value = (~(*addr)) & ((~0ul) << offset);
return (value == 0) ? BITS_PER_LONG : __ffs(value);
}
/* size is not constant or too big */
return __find_next_zero_bit(addr, size, offset);
}
#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ #endif /* CONFIG_GENERIC_FIND_NEXT_BIT */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif #endif

View file

@ -20,8 +20,8 @@
/* /*
* Find the next set bit in a memory region. * Find the next set bit in a memory region.
*/ */
unsigned long __find_next_bit(const unsigned long *addr, unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
unsigned long size, unsigned long offset) unsigned long offset)
{ {
const unsigned long *p = addr + BITOP_WORD(offset); const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1); unsigned long result = offset & ~(BITS_PER_LONG-1);
@ -58,14 +58,14 @@ found_first:
found_middle: found_middle:
return result + __ffs(tmp); return result + __ffs(tmp);
} }
EXPORT_SYMBOL(__find_next_bit); EXPORT_SYMBOL(find_next_bit);
/* /*
* This implementation of find_{first,next}_zero_bit was stolen from * This implementation of find_{first,next}_zero_bit was stolen from
* Linus' asm-alpha/bitops.h. * Linus' asm-alpha/bitops.h.
*/ */
unsigned long __find_next_zero_bit(const unsigned long *addr, unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
unsigned long size, unsigned long offset) unsigned long offset)
{ {
const unsigned long *p = addr + BITOP_WORD(offset); const unsigned long *p = addr + BITOP_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1); unsigned long result = offset & ~(BITS_PER_LONG-1);
@ -102,15 +102,14 @@ found_first:
found_middle: found_middle:
return result + ffz(tmp); return result + ffz(tmp);
} }
EXPORT_SYMBOL(__find_next_zero_bit); EXPORT_SYMBOL(find_next_zero_bit);
#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ #endif /* CONFIG_GENERIC_FIND_NEXT_BIT */
#ifdef CONFIG_GENERIC_FIND_FIRST_BIT #ifdef CONFIG_GENERIC_FIND_FIRST_BIT
/* /*
* Find the first set bit in a memory region. * Find the first set bit in a memory region.
*/ */
unsigned long __find_first_bit(const unsigned long *addr, unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
unsigned long size)
{ {
const unsigned long *p = addr; const unsigned long *p = addr;
unsigned long result = 0; unsigned long result = 0;
@ -131,13 +130,12 @@ unsigned long __find_first_bit(const unsigned long *addr,
found: found:
return result + __ffs(tmp); return result + __ffs(tmp);
} }
EXPORT_SYMBOL(__find_first_bit); EXPORT_SYMBOL(find_first_bit);
/* /*
* Find the first cleared bit in a memory region. * Find the first cleared bit in a memory region.
*/ */
unsigned long __find_first_zero_bit(const unsigned long *addr, unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
unsigned long size)
{ {
const unsigned long *p = addr; const unsigned long *p = addr;
unsigned long result = 0; unsigned long result = 0;
@ -158,7 +156,7 @@ unsigned long __find_first_zero_bit(const unsigned long *addr,
found: found:
return result + ffz(tmp); return result + ffz(tmp);
} }
EXPORT_SYMBOL(__find_first_zero_bit); EXPORT_SYMBOL(find_first_zero_bit);
#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ #endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN