aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2008-04-29 06:01:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:11:16 -0400
commitfee4b19fb3f28d17c0b9f9ea0668db5275697178 (patch)
tree0d7c34ef39cdac5a0c7f89376e85cc3ef621a7da /include
parent8972331292753c89dbdd10b175e999ce78dc3be7 (diff)
bitops: remove "optimizations"
The mapsize optimizations which were moved from x86 to the generic code in commit 64970b68d2b3ed32b964b0b30b1b98518fde388e 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>
Diffstat (limited to 'include')
-rw-r--r--include/linux/bitops.h115
1 files changed, 12 insertions, 103 deletions
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 8340a3aba49a..024f2b027244 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -114,8 +114,6 @@ static inline unsigned fls_long(unsigned long l)
114 114
115#ifdef __KERNEL__ 115#ifdef __KERNEL__
116#ifdef CONFIG_GENERIC_FIND_FIRST_BIT 116#ifdef CONFIG_GENERIC_FIND_FIRST_BIT
117extern unsigned long __find_first_bit(const unsigned long *addr,
118 unsigned long size);
119 117
120/** 118/**
121 * find_first_bit - find the first set bit in a memory region 119 * 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,
124 * 122 *
125 * Returns the bit number of the first set bit. 123 * Returns the bit number of the first set bit.
126 */ 124 */
127static __always_inline unsigned long 125extern unsigned long find_first_bit(const unsigned long *addr,
128find_first_bit(const unsigned long *addr, unsigned long size) 126 unsigned long size);
129{
130 /* Avoid a function call if the bitmap size is a constant */
131 /* and not bigger than BITS_PER_LONG. */
132
133 /* insert a sentinel so that __ffs returns size if there */
134 /* are no set bits in the bitmap */
135 if (__builtin_constant_p(size) && (size < BITS_PER_LONG))
136 return __ffs((*addr) | (1ul << size));
137
138 /* the result of __ffs(0) is undefined, so it needs to be */
139 /* handled separately */
140 if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
141 return ((*addr) == 0) ? BITS_PER_LONG : __ffs(*addr);
142
143 /* size is not constant or too big */
144 return __find_first_bit(addr, size);
145}
146
147extern unsigned long __find_first_zero_bit(const unsigned long *addr,
148 unsigned long size);
149 127
150/** 128/**
151 * find_first_zero_bit - find the first cleared bit in a memory region 129 * 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,
154 * 132 *
155 * Returns the bit number of the first cleared bit. 133 * Returns the bit number of the first cleared bit.
156 */ 134 */
157static __always_inline unsigned long 135extern unsigned long find_first_zero_bit(const unsigned long *addr,
158find_first_zero_bit(const unsigned long *addr, unsigned long size) 136 unsigned long size);
159{ 137
160 /* Avoid a function call if the bitmap size is a constant */
161 /* and not bigger than BITS_PER_LONG. */
162
163 /* insert a sentinel so that __ffs returns size if there */
164 /* are no set bits in the bitmap */
165 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
166 return __ffs(~(*addr) | (1ul << size));
167 }
168
169 /* the result of __ffs(0) is undefined, so it needs to be */
170 /* handled separately */
171 if (__builtin_constant_p(size) && (size == BITS_PER_LONG))
172 return (~(*addr) == 0) ? BITS_PER_LONG : __ffs(~(*addr));
173
174 /* size is not constant or too big */
175 return __find_first_zero_bit(addr, size);
176}
177#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */ 138#endif /* CONFIG_GENERIC_FIND_FIRST_BIT */
178 139
179#ifdef CONFIG_GENERIC_FIND_NEXT_BIT 140#ifdef CONFIG_GENERIC_FIND_NEXT_BIT
180extern unsigned long __find_next_bit(const unsigned long *addr,
181 unsigned long size, unsigned long offset);
182 141
183/** 142/**
184 * find_next_bit - find the next set bit in a memory region 143 * 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,
186 * @offset: The bitnumber to start searching at 145 * @offset: The bitnumber to start searching at
187 * @size: The bitmap size in bits 146 * @size: The bitmap size in bits
188 */ 147 */
189static __always_inline unsigned long 148extern unsigned long find_next_bit(const unsigned long *addr,
190find_next_bit(const unsigned long *addr, unsigned long size, 149 unsigned long size, unsigned long offset);
191 unsigned long offset)
192{
193 unsigned long value;
194
195 /* Avoid a function call if the bitmap size is a constant */
196 /* and not bigger than BITS_PER_LONG. */
197
198 /* insert a sentinel so that __ffs returns size if there */
199 /* are no set bits in the bitmap */
200 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
201 value = (*addr) & ((~0ul) << offset);
202 value |= (1ul << size);
203 return __ffs(value);
204 }
205
206 /* the result of __ffs(0) is undefined, so it needs to be */
207 /* handled separately */
208 if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
209 value = (*addr) & ((~0ul) << offset);
210 return (value == 0) ? BITS_PER_LONG : __ffs(value);
211 }
212
213 /* size is not constant or too big */
214 return __find_next_bit(addr, size, offset);
215}
216
217extern unsigned long __find_next_zero_bit(const unsigned long *addr,
218 unsigned long size, unsigned long offset);
219 150
220/** 151/**
221 * find_next_zero_bit - find the next cleared bit in a memory region 152 * 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,
223 * @offset: The bitnumber to start searching at 154 * @offset: The bitnumber to start searching at
224 * @size: The bitmap size in bits 155 * @size: The bitmap size in bits
225 */ 156 */
226static __always_inline unsigned long 157
227find_next_zero_bit(const unsigned long *addr, unsigned long size, 158extern unsigned long find_next_zero_bit(const unsigned long *addr,
228 unsigned long offset) 159 unsigned long size,
229{ 160 unsigned long offset);
230 unsigned long value; 161
231
232 /* Avoid a function call if the bitmap size is a constant */
233 /* and not bigger than BITS_PER_LONG. */
234
235 /* insert a sentinel so that __ffs returns size if there */
236 /* are no set bits in the bitmap */
237 if (__builtin_constant_p(size) && (size < BITS_PER_LONG)) {
238 value = (~(*addr)) & ((~0ul) << offset);
239 value |= (1ul << size);
240 return __ffs(value);
241 }
242
243 /* the result of __ffs(0) is undefined, so it needs to be */
244 /* handled separately */
245 if (__builtin_constant_p(size) && (size == BITS_PER_LONG)) {
246 value = (~(*addr)) & ((~0ul) << offset);
247 return (value == 0) ? BITS_PER_LONG : __ffs(value);
248 }
249
250 /* size is not constant or too big */
251 return __find_next_zero_bit(addr, size, offset);
252}
253#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */ 162#endif /* CONFIG_GENERIC_FIND_NEXT_BIT */
254#endif /* __KERNEL__ */ 163#endif /* __KERNEL__ */
255#endif 164#endif