[4/*] Redirect strchr to strchrnul
Commit Message
Hi,
this is nontrivial optimization of string inlines.
First it decreases icache pressure as you don't need strchr.
Second is quite basic but you need a quite recent (gcc-4.9+) compiler to
work. Optimized strchr combines checks of c with zero then determine at
end what happened so its basically
strchr (char *s, int c)
{
char *r = strchrnul (s, c);
return *r == c? r : NULL;
}
But user usually needs to check if you returned null for example
char *s = strchr (x, "c");
if (!s)
return 42;
and with this inline you save one branch as compiler optimizes this out
to equivalent of
char *s = strchrnul (x, "c");
if (!*s)
return 42;
OK to commit these?
* string/bits/string2.h (strchrnul): Add inline
(strchr): Optimize.
@@ -108,18 +108,27 @@ __STRING2_COPY_TYPE (8);
#endif
-/* Return pointer to C in S. */
-#ifndef _HAVE_STRING_ARCH_strchr
+#ifndef _HAVE_STRING_ARCH_strchrnul
extern void *__rawmemchr (const void *__s, int __c);
# if __GNUC_PREREQ (3, 2)
-# define strchr(s, c) \
+# define strchrnul(s, c) \
(__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \
&& (c) == '\0' \
? (char *) __rawmemchr (s, c) \
- : __builtin_strchr (s, c)))
+ : __strchrnul (s, c)))
# endif
#endif
+/* Return pointer to C in S. */
+#ifndef _HAVE_STRING_ARCH_strchr
+# if __GNUC_PREREQ (3, 2)
+# define strchr(s, c) \
+ (__extension__ ({ char *__r = strchrnul (s, c); \
+ *__r == c ? __r : NULL; }))
+# endif
+#endif
+
+
/* Copy SRC to DEST, returning pointer to final NUL byte. */
#ifdef __USE_GNU
# if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES