lib/kstrtox.c: smaller _parse_integer()
Set "overflow" bit upon encountering it instead of postponing to the end of the conversion. Somehow gcc unwedges itself and generates better code: $ ./scripts/bloat-o-meter ../vmlinux-000 ../obj/vmlinux _parse_integer 177 139 -38 Inspired by patch from Zhaoxiu Zeng. Link: http://lkml.kernel.org/r/20160826221920.GA1909@p183.telecom.by Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1204c77f9b
commit
8cfd56d479
@ -48,11 +48,9 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
|
|||||||
{
|
{
|
||||||
unsigned long long res;
|
unsigned long long res;
|
||||||
unsigned int rv;
|
unsigned int rv;
|
||||||
int overflow;
|
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
rv = 0;
|
rv = 0;
|
||||||
overflow = 0;
|
|
||||||
while (*s) {
|
while (*s) {
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
@ -71,15 +69,13 @@ unsigned int _parse_integer(const char *s, unsigned int base, unsigned long long
|
|||||||
*/
|
*/
|
||||||
if (unlikely(res & (~0ull << 60))) {
|
if (unlikely(res & (~0ull << 60))) {
|
||||||
if (res > div_u64(ULLONG_MAX - val, base))
|
if (res > div_u64(ULLONG_MAX - val, base))
|
||||||
overflow = 1;
|
rv |= KSTRTOX_OVERFLOW;
|
||||||
}
|
}
|
||||||
res = res * base + val;
|
res = res * base + val;
|
||||||
rv++;
|
rv++;
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
*p = res;
|
*p = res;
|
||||||
if (overflow)
|
|
||||||
rv |= KSTRTOX_OVERFLOW;
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user