Commit 72fcce70 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Petr Mladek

vsprintf: uninline simple_strntoull(), reorder arguments

* uninline simple_strntoull(),
  gcc overinlines and this function is not performance critical

* reorder arguments, so that appending INT_MAX as 4th argument
  generates very efficient tail call

Space savings:

	add/remove: 1/0 grow/shrink: 0/3 up/down: 27/-179 (-152)
	Function                            old     new   delta
	simple_strntoll                       -      27     +27
	simple_strtoull                      15      10      -5
	simple_strtoll                       41       7     -34
	vsscanf                            1930    1790    -140
Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: default avatarPetr Mladek <pmladek@suse.com>
Signed-off-by: default avatarPetr Mladek <pmladek@suse.com>
Link: https://lore.kernel.org/all/82a2af6e-9b6c-4a09-89d7-ca90cc1cdad1@p183/
parent 3f6074cf
...@@ -60,7 +60,8 @@ ...@@ -60,7 +60,8 @@
bool no_hash_pointers __ro_after_init; bool no_hash_pointers __ro_after_init;
EXPORT_SYMBOL_GPL(no_hash_pointers); EXPORT_SYMBOL_GPL(no_hash_pointers);
static noinline unsigned long long simple_strntoull(const char *startp, size_t max_chars, char **endp, unsigned int base) noinline
static unsigned long long simple_strntoull(const char *startp, char **endp, unsigned int base, size_t max_chars)
{ {
const char *cp; const char *cp;
unsigned long long result = 0ULL; unsigned long long result = 0ULL;
...@@ -95,7 +96,7 @@ static noinline unsigned long long simple_strntoull(const char *startp, size_t m ...@@ -95,7 +96,7 @@ static noinline unsigned long long simple_strntoull(const char *startp, size_t m
noinline noinline
unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base) unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
{ {
return simple_strntoull(cp, INT_MAX, endp, base); return simple_strntoull(cp, endp, base, INT_MAX);
} }
EXPORT_SYMBOL(simple_strtoull); EXPORT_SYMBOL(simple_strtoull);
...@@ -130,8 +131,8 @@ long simple_strtol(const char *cp, char **endp, unsigned int base) ...@@ -130,8 +131,8 @@ long simple_strtol(const char *cp, char **endp, unsigned int base)
} }
EXPORT_SYMBOL(simple_strtol); EXPORT_SYMBOL(simple_strtol);
static long long simple_strntoll(const char *cp, size_t max_chars, char **endp, noinline
unsigned int base) static long long simple_strntoll(const char *cp, char **endp, unsigned int base, size_t max_chars)
{ {
/* /*
* simple_strntoull() safely handles receiving max_chars==0 in the * simple_strntoull() safely handles receiving max_chars==0 in the
...@@ -140,9 +141,9 @@ static long long simple_strntoll(const char *cp, size_t max_chars, char **endp, ...@@ -140,9 +141,9 @@ static long long simple_strntoll(const char *cp, size_t max_chars, char **endp,
* and the content of *cp is irrelevant. * and the content of *cp is irrelevant.
*/ */
if (*cp == '-' && max_chars > 0) if (*cp == '-' && max_chars > 0)
return -simple_strntoull(cp + 1, max_chars - 1, endp, base); return -simple_strntoull(cp + 1, endp, base, max_chars - 1);
return simple_strntoull(cp, max_chars, endp, base); return simple_strntoull(cp, endp, base, max_chars);
} }
/** /**
...@@ -155,7 +156,7 @@ static long long simple_strntoll(const char *cp, size_t max_chars, char **endp, ...@@ -155,7 +156,7 @@ static long long simple_strntoll(const char *cp, size_t max_chars, char **endp,
*/ */
long long simple_strtoll(const char *cp, char **endp, unsigned int base) long long simple_strtoll(const char *cp, char **endp, unsigned int base)
{ {
return simple_strntoll(cp, INT_MAX, endp, base); return simple_strntoll(cp, endp, base, INT_MAX);
} }
EXPORT_SYMBOL(simple_strtoll); EXPORT_SYMBOL(simple_strtoll);
...@@ -3648,13 +3649,11 @@ int vsscanf(const char *buf, const char *fmt, va_list args) ...@@ -3648,13 +3649,11 @@ int vsscanf(const char *buf, const char *fmt, va_list args)
break; break;
if (is_sign) if (is_sign)
val.s = simple_strntoll(str, val.s = simple_strntoll(str, &next, base,
field_width >= 0 ? field_width : INT_MAX, field_width >= 0 ? field_width : INT_MAX);
&next, base);
else else
val.u = simple_strntoull(str, val.u = simple_strntoull(str, &next, base,
field_width >= 0 ? field_width : INT_MAX, field_width >= 0 ? field_width : INT_MAX);
&next, base);
switch (qualifier) { switch (qualifier) {
case 'H': /* that's 'hh' in format */ case 'H': /* that's 'hh' in format */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment