diff mbox

[4/*] Redirect strchr to strchrnul

Message ID 20150524163214.GA28053@domone
State New
Headers show

Commit Message

Ondrej Bilka May 24, 2015, 4:32 p.m. UTC
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.
diff mbox

Patch

diff --git a/string/bits/string2.h b/string/bits/string2.h
index 2fe67b3..565fd00 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -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