public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/*] Move string inlines to string/string-inlines.c
@ 2015-05-24 22:51 Ondřej Bílka
  2015-05-25  0:18 ` [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations Ondřej Bílka
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-24 22:51 UTC (permalink / raw)
  To: libc-alpha

Hi,

As described in header cleanup thread this is first step.
It just copies inline function declarations to string-inlines.c
An objdump -d produce same assembly. 

OK to commit?


	* string/string-inlines.c: Move inlines from bits/string2.h here.

diff --git a/string/string-inlines.c b/string/string-inlines.c
index 0445be7..3e01dc0 100644
--- a/string/string-inlines.c
+++ b/string/string-inlines.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1999-2015 Free Software Foundation, Inc.
+/* Inline string function optimizations for very old gcc versions.
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -15,20 +16,350 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-/*  <bits/string.h> and <bits/string2.h> declare some extern inline
-    functions.  These functions are declared additionally here if
-    inlining is not possible.  */
-
 #undef __USE_STRING_INLINES
 #define __USE_STRING_INLINES
 #define _FORCE_INLINES
 #define __STRING_INLINE /* empty */
 #define __NO_INLINE__
-
 #include <string.h>
-#undef index
-#undef rindex
 
-#undef __NO_INLINE__
-#include <bits/string.h>
-#include <bits/string2.h>
+void *
+__mempcpy_small (void *__dest1,
+		 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
+		 __uint16_t __src0_2, __uint16_t __src4_2,
+		 __uint32_t __src0_4, __uint32_t __src4_4,
+		 size_t __srclen)
+{
+  union {
+    __uint32_t __ui;
+    __uint16_t __usi;
+    unsigned char __uc;
+    unsigned char __c;
+  } *__u = __dest1;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__c = __src0_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__c = __src2_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__c = __src4_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__c = __src6_1;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      __u = __extension__ ((void *) __u + 4);
+      break;
+    }
+  return (void *) __u;
+}
+
+char *
+__strcpy_small (char *__dest,
+		__uint16_t __src0_2, __uint16_t __src4_2,
+		__uint32_t __src0_4, __uint32_t __src4_4,
+		size_t __srclen)
+{
+  union {
+    __uint32_t __ui;
+    __uint16_t __usi;
+    unsigned char __uc;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__uc = '\0';
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__uc = '\0';
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      break;
+    }
+  return __dest;
+}
+
+char *
+__stpcpy_small (char *__dest,
+		__uint16_t __src0_2, __uint16_t __src4_2,
+		__uint32_t __src0_4, __uint32_t __src4_4,
+		size_t __srclen)
+{
+  union {
+    unsigned int __ui;
+    unsigned short int __usi;
+    unsigned char __uc;
+    char __c;
+  } *__u = (void *) __dest;
+  switch ((unsigned int) __srclen)
+    {
+    case 1:
+      __u->__uc = '\0';
+      break;
+    case 2:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 3:
+      __u->__usi = __src0_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 4:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 3);
+      break;
+    case 5:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__uc = '\0';
+      break;
+    case 6:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 1);
+      break;
+    case 7:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__usi = __src4_2;
+      __u = __extension__ ((void *) __u + 2);
+      __u->__uc = '\0';
+      break;
+    case 8:
+      __u->__ui = __src0_4;
+      __u = __extension__ ((void *) __u + 4);
+      __u->__ui = __src4_4;
+      __u = __extension__ ((void *) __u + 3);
+      break;
+    }
+  return &__u->__c;
+}
+
+size_t
+__strcspn_c1 (const char *__s, int __reject)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject)
+    ++__result;
+  return __result;
+}
+
+size_t
+__strcspn_c2 (const char *__s, int __reject1, int __reject2)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject1
+	 && __s[__result] != __reject2)
+    ++__result;
+  return __result;
+}
+
+size_t
+__strcspn_c3 (const char *__s, int __reject1, int __reject2,
+	      int __reject3)
+{
+  size_t __result = 0;
+  while (__s[__result] != '\0' && __s[__result] != __reject1
+	 && __s[__result] != __reject2 && __s[__result] != __reject3)
+    ++__result;
+  return __result;
+}
+
+
+size_t
+__strspn_c1 (const char *__s, int __accept)
+{
+  size_t __result = 0;
+  /* Please note that __accept never can be '\0'.  */
+  while (__s[__result] == __accept)
+    ++__result;
+  return __result;
+}
+
+size_t
+__strspn_c2 (const char *__s, int __accept1, int __accept2)
+{
+  size_t __result = 0;
+  /* Please note that __accept1 and __accept2 never can be '\0'.  */
+  while (__s[__result] == __accept1 || __s[__result] == __accept2)
+    ++__result;
+  return __result;
+}
+
+size_t
+__strspn_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
+{
+  size_t __result = 0;
+  /* Please note that __accept1 to __accept3 never can be '\0'.  */
+  while (__s[__result] == __accept1 || __s[__result] == __accept2
+	 || __s[__result] == __accept3)
+    ++__result;
+  return __result;
+}
+
+
+
+char *
+__strpbrk_c2 (const char *__s, int __accept1, int __accept2)
+{
+  /* Please note that __accept1 and __accept2 never can be '\0'.  */
+  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2)
+    ++__s;
+  return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+
+char *
+__strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
+{
+  /* Please note that __accept1 to __accept3 never can be '\0'.  */
+  while (*__s != '\0' && *__s != __accept1 && *__s != __accept2
+	 && *__s != __accept3)
+    ++__s;
+  return *__s == '\0' ? NULL : (char *) (size_t) __s;
+}
+
+char *
+__strtok_r_1c (char *__s, char __sep, char **__nextp)
+{
+  char *__result;
+  if (__s == NULL)
+    __s = *__nextp;
+  while (*__s == __sep)
+    ++__s;
+  __result = NULL;
+  if (*__s != '\0')
+    {
+      __result = __s++;
+      while (*__s != '\0')
+	if (*__s++ == __sep)
+	  {
+	    __s[-1] = '\0';
+	    break;
+	  }
+    }
+  *__nextp = __s;
+  return __result;
+}
+
+char *
+__strsep_1c (char **__s, char __reject)
+{
+  char *__retval = *__s;
+  if (__retval != NULL && (*__s = strchr (__retval, __reject)) != NULL)
+    *(*__s)++ = '\0';
+  return __retval;
+}
+
+char *
+__strsep_2c (char **__s, char __reject1, char __reject2)
+{
+  char *__retval = *__s;
+  if (__retval != NULL)
+    {
+      char *__cp = __retval;
+      while (1)
+	{
+	  if (*__cp == '\0')
+	    {
+	      __cp = NULL;
+	  break;
+	    }
+	  if (*__cp == __reject1 || *__cp == __reject2)
+	    {
+	      *__cp++ = '\0';
+	      break;
+	    }
+	  ++__cp;
+	}
+      *__s = __cp;
+    }
+  return __retval;
+}
+
+char *
+__strsep_3c (char **__s, char __reject1, char __reject2, char __reject3)
+{
+  char *__retval = *__s;
+  if (__retval != NULL)
+    {
+      char *__cp = __retval;
+      while (1)
+	{
+	  if (*__cp == '\0')
+	    {
+	      __cp = NULL;
+	  break;
+	    }
+	  if (*__cp == __reject1 || *__cp == __reject2 || *__cp == __reject3)
+	    {
+	      *__cp++ = '\0';
+	      break;
+	    }
+	  ++__cp;
+	}
+      *__s = __cp;
+    }
+  return __retval;
+}

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations.
  2015-05-24 22:51 [PATCH 1/*] Move string inlines to string/string-inlines.c Ondřej Bílka
@ 2015-05-25  0:18 ` Ondřej Bílka
  2015-05-28 16:39   ` Joseph Myers
  2015-05-25  1:02 ` [PATCH 3/*] Use strchrnul for strcspn (x, "c") Ondřej Bílka
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-25  0:18 UTC (permalink / raw)
  To: libc-alpha

As described before this removes optimization for gcc older than 3.4.
Change is mechanical of checking which defines evaluate to false.

Also ok to commit?


	* string/bits/string2.h [!_GNUC_PREREQ (3,4)] Remove.

diff --git a/string/bits/string2.h b/string/bits/string2.h
index 7645176..a595c74 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -92,111 +92,6 @@ __STRING2_COPY_TYPE (8);
 #define __string2_1bptr_p(__x) \
   ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1)
 
-/* Set N bytes of S to C.  */
-#if !defined _HAVE_STRING_ARCH_memset
-# if !__GNUC_PREREQ (3, 0)
-#  if _STRING_ARCH_unaligned
-#   define memset(s, c, n) \
-  (__extension__ (__builtin_constant_p (n) && (n) <= 16			      \
-		  ? ((n) == 1						      \
-		     ? __memset_1 (s, c)				      \
-		     : __memset_gc (s, c, n))				      \
-		  : (__builtin_constant_p (c) && (c) == '\0'		      \
-		     ? ({ void *__s = (s); __bzero (__s, n); __s; })	      \
-		     : memset (s, c, n))))
-
-#   define __memset_1(s, c) ({ void *__s = (s);				      \
-			    *((__uint8_t *) __s) = (__uint8_t) c; __s; })
-
-#   define __memset_gc(s, c, n) \
-  ({ void *__s = (s);							      \
-     union {								      \
-       unsigned int __ui;						      \
-       unsigned short int __usi;					      \
-       unsigned char __uc;						      \
-     } *__u = __s;							      \
-     __uint8_t __c = (__uint8_t) (c);					      \
-									      \
-     /* This `switch' statement will be removed at compile-time.  */	      \
-     switch ((unsigned int) (n))					      \
-       {								      \
-       case 15:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 11:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 7:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 3:								      \
-	 __u->__usi = (unsigned short int) __c * 0x0101;		      \
-	 __u = __extension__ ((void *) __u + 2);			      \
-	 __u->__uc = (unsigned char) __c;				      \
-	 break;								      \
-									      \
-       case 14:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 10:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 6:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 2:								      \
-	 __u->__usi = (unsigned short int) __c * 0x0101;		      \
-	 break;								      \
-									      \
-       case 13:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 9:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 5:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 1:								      \
-	 __u->__uc = (unsigned char) __c;				      \
-	 break;								      \
-									      \
-       case 16:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 12:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 8:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-	 __u = __extension__ ((void *) __u + 4);			      \
-       case 4:								      \
-	 __u->__ui = __c * 0x01010101;					      \
-       case 0:								      \
-	 break;								      \
-       }								      \
-									      \
-     __s; })
-#  else
-#   define memset(s, c, n) \
-  (__extension__ (__builtin_constant_p (c) && (c) == '\0'		      \
-		  ? ({ void *__s = (s); __bzero (__s, n); __s; })	      \
-		  : memset (s, c, n)))
-#  endif
-# endif
-
-/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
-   The optimization is broken before EGCS 1.1.
-   GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
-   if it decides to call the library function, it calls memset
-   and not bzero.  */
-# if __GNUC_PREREQ (2, 91)
-#  define __bzero(s, n) __builtin_memset (s, '\0', n)
-# endif
-
-#endif
-
-
 /* Copy N bytes from SRC to DEST, returning pointer to byte following the
    last copied.  */
 #ifdef __USE_GNU
@@ -204,186 +99,11 @@ __STRING2_COPY_TYPE (8);
 #  ifndef _HAVE_STRING_ARCH_mempcpy
 #   if __GNUC_PREREQ (3, 4)
 #    define __mempcpy(dest, src, n) __builtin_mempcpy (dest, src, n)
-#   elif __GNUC_PREREQ (3, 0)
-#    define __mempcpy(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  && __string2_1bptr_p (src) && n <= 8			      \
-		  ? __builtin_memcpy (dest, src, n) + (n)		      \
-		  : __mempcpy (dest, src, n)))
-#   else
-#    define __mempcpy(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  && __string2_1bptr_p (src) && n <= 8			      \
-		  ? __mempcpy_small (dest, __mempcpy_args (src), n)	      \
-		  : __mempcpy (dest, src, n)))
 #   endif
 /* In glibc we use this function frequently but for namespace reasons
    we have to use the name `__mempcpy'.  */
 #   define mempcpy(dest, src, n) __mempcpy (dest, src, n)
 #  endif
-
-#  if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
-#   if _STRING_ARCH_unaligned
-#    ifndef _FORCE_INLINES
-#     define __mempcpy_args(src) \
-     ((const char *) (src))[0], ((const char *) (src))[2],		      \
-     ((const char *) (src))[4], ((const char *) (src))[6],		      \
-     __extension__ __STRING2_SMALL_GET16 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET16 (src, 4),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 4)
-#    endif
-__STRING_INLINE void *__mempcpy_small (void *, char, char, char, char,
-				       __uint16_t, __uint16_t, __uint32_t,
-				       __uint32_t, size_t);
-__STRING_INLINE void *
-__mempcpy_small (void *__dest1,
-		 char __src0_1, char __src2_1, char __src4_1, char __src6_1,
-		 __uint16_t __src0_2, __uint16_t __src4_2,
-		 __uint32_t __src0_4, __uint32_t __src4_4,
-		 size_t __srclen)
-{
-  union {
-    __uint32_t __ui;
-    __uint16_t __usi;
-    unsigned char __uc;
-    unsigned char __c;
-  } *__u = __dest1;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__c = __src0_1;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 2:
-      __u->__usi = __src0_2;
-      __u = __extension__ ((void *) __u + 2);
-      break;
-    case 3:
-      __u->__usi = __src0_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__c = __src2_1;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 4:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      break;
-    case 5:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__c = __src4_1;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 6:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      __u = __extension__ ((void *) __u + 2);
-      break;
-    case 7:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__c = __src6_1;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 8:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__ui = __src4_4;
-      __u = __extension__ ((void *) __u + 4);
-      break;
-    }
-  return (void *) __u;
-}
-#   else
-#    ifndef _FORCE_INLINES
-#     define __mempcpy_args(src) \
-     ((const char *) (src))[0],						      \
-     __extension__ ((__STRING2_COPY_ARR2)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1] } }),	      \
-     __extension__ ((__STRING2_COPY_ARR3)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2] } }),				      \
-     __extension__ ((__STRING2_COPY_ARR4)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3] } }),	      \
-     __extension__ ((__STRING2_COPY_ARR5)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4] } }),				      \
-     __extension__ ((__STRING2_COPY_ARR6)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5] } }),	      \
-     __extension__ ((__STRING2_COPY_ARR7)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  ((const char *) (src))[6] } }),				      \
-     __extension__ ((__STRING2_COPY_ARR8)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  ((const char *) (src))[6], ((const char *) (src))[7] } })
-#    endif
-__STRING_INLINE void *__mempcpy_small (void *, char, __STRING2_COPY_ARR2,
-				       __STRING2_COPY_ARR3,
-				       __STRING2_COPY_ARR4,
-				       __STRING2_COPY_ARR5,
-				       __STRING2_COPY_ARR6,
-				       __STRING2_COPY_ARR7,
-				       __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE void *
-__mempcpy_small (void *__dest, char __src1,
-		 __STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
-		 __STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
-		 __STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
-		 __STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
-  union {
-    char __c;
-    __STRING2_COPY_ARR2 __sca2;
-    __STRING2_COPY_ARR3 __sca3;
-    __STRING2_COPY_ARR4 __sca4;
-    __STRING2_COPY_ARR5 __sca5;
-    __STRING2_COPY_ARR6 __sca6;
-    __STRING2_COPY_ARR7 __sca7;
-    __STRING2_COPY_ARR8 __sca8;
-  } *__u = __dest;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__c = __src1;
-      break;
-    case 2:
-      __extension__ __u->__sca2 = __src2;
-      break;
-    case 3:
-      __extension__ __u->__sca3 = __src3;
-      break;
-    case 4:
-      __extension__ __u->__sca4 = __src4;
-      break;
-    case 5:
-      __extension__ __u->__sca5 = __src5;
-      break;
-    case 6:
-      __extension__ __u->__sca6 = __src6;
-      break;
-    case 7:
-      __extension__ __u->__sca7 = __src7;
-      break;
-    case 8:
-      __extension__ __u->__sca8 = __src8;
-      break;
-    }
-  return __extension__ ((void *) __u + __srclen);
-}
-#   endif
-#  endif
 # endif
 #endif
 
@@ -397,359 +117,20 @@ extern void *__rawmemchr (const void *__s, int __c);
 		  && (c) == '\0'					      \
 		  ? (char *) __rawmemchr (s, c)				      \
 		  : __builtin_strchr (s, c)))
-# else
-#  define strchr(s, c) \
-  (__extension__ (__builtin_constant_p (c) && (c) == '\0'		      \
-		  ? (char *) __rawmemchr (s, c)				      \
-		  : strchr (s, c)))
-# endif
-#endif
-
-
-/* Copy SRC to DEST.  */
-#if (!defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)) \
-    || defined _FORCE_INLINES
-# if !defined _HAVE_STRING_ARCH_strcpy && !__GNUC_PREREQ (3, 0)
-#  define strcpy(dest, src) \
-  (__extension__ (__builtin_constant_p (src)				      \
-		  ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8	      \
-		     ? __strcpy_small (dest, __strcpy_args (src),	      \
-				       strlen (src) + 1)		      \
-		     : (char *) memcpy (dest, src, strlen (src) + 1))	      \
-		  : strcpy (dest, src)))
-# endif
-
-# if _STRING_ARCH_unaligned
-#  ifndef _FORCE_INLINES
-#   define __strcpy_args(src) \
-     __extension__ __STRING2_SMALL_GET16 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET16 (src, 4),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 4)
-#  endif
-__STRING_INLINE char *__strcpy_small (char *, __uint16_t, __uint16_t,
-				      __uint32_t, __uint32_t, size_t);
-__STRING_INLINE char *
-__strcpy_small (char *__dest,
-		__uint16_t __src0_2, __uint16_t __src4_2,
-		__uint32_t __src0_4, __uint32_t __src4_4,
-		size_t __srclen)
-{
-  union {
-    __uint32_t __ui;
-    __uint16_t __usi;
-    unsigned char __uc;
-  } *__u = (void *) __dest;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__uc = '\0';
-      break;
-    case 2:
-      __u->__usi = __src0_2;
-      break;
-    case 3:
-      __u->__usi = __src0_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__uc = '\0';
-      break;
-    case 4:
-      __u->__ui = __src0_4;
-      break;
-    case 5:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__uc = '\0';
-      break;
-    case 6:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      break;
-    case 7:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__uc = '\0';
-      break;
-    case 8:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__ui = __src4_4;
-      break;
-    }
-  return __dest;
-}
-# else
-#  ifndef _FORCE_INLINES
-#   define __strcpy_args(src) \
-     __extension__ ((__STRING2_COPY_ARR2)				      \
-      { { ((const char *) (src))[0], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR3)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR4)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR5)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR6)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR7)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR8)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  ((const char *) (src))[6], '\0' } })
-#  endif
-__STRING_INLINE char *__strcpy_small (char *, __STRING2_COPY_ARR2,
-				      __STRING2_COPY_ARR3,
-				      __STRING2_COPY_ARR4,
-				      __STRING2_COPY_ARR5,
-				      __STRING2_COPY_ARR6,
-				      __STRING2_COPY_ARR7,
-				      __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE char *
-__strcpy_small (char *__dest,
-		__STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
-		__STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
-		__STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
-		__STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
-  union {
-    char __c;
-    __STRING2_COPY_ARR2 __sca2;
-    __STRING2_COPY_ARR3 __sca3;
-    __STRING2_COPY_ARR4 __sca4;
-    __STRING2_COPY_ARR5 __sca5;
-    __STRING2_COPY_ARR6 __sca6;
-    __STRING2_COPY_ARR7 __sca7;
-    __STRING2_COPY_ARR8 __sca8;
-  } *__u = (void *) __dest;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__c = '\0';
-      break;
-    case 2:
-      __extension__ __u->__sca2 = __src2;
-      break;
-    case 3:
-      __extension__ __u->__sca3 = __src3;
-      break;
-    case 4:
-      __extension__ __u->__sca4 = __src4;
-      break;
-    case 5:
-      __extension__ __u->__sca5 = __src5;
-      break;
-    case 6:
-      __extension__ __u->__sca6 = __src6;
-      break;
-    case 7:
-      __extension__ __u->__sca7 = __src7;
-      break;
-    case 8:
-      __extension__ __u->__sca8 = __src8;
-      break;
-  }
-  return __dest;
-}
 # endif
 #endif
 
-
 /* Copy SRC to DEST, returning pointer to final NUL byte.  */
 #ifdef __USE_GNU
 # if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES
 #  ifndef _HAVE_STRING_ARCH_stpcpy
 #   if __GNUC_PREREQ (3, 4)
 #    define __stpcpy(dest, src) __builtin_stpcpy (dest, src)
-#   elif __GNUC_PREREQ (3, 0)
-#    define __stpcpy(dest, src) \
-  (__extension__ (__builtin_constant_p (src)				      \
-		  ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8	      \
-		     ? __builtin_strcpy (dest, src) + strlen (src)	      \
-		     : ((char *) (__mempcpy) (dest, src, strlen (src) + 1)    \
-			- 1))						      \
-		  : __stpcpy (dest, src)))
-#   else
-#    define __stpcpy(dest, src) \
-  (__extension__ (__builtin_constant_p (src)				      \
-		  ? (__string2_1bptr_p (src) && strlen (src) + 1 <= 8	      \
-		     ? __stpcpy_small (dest, __stpcpy_args (src),	      \
-				       strlen (src) + 1)		      \
-		     : ((char *) (__mempcpy) (dest, src, strlen (src) + 1)    \
-			- 1))						      \
-		  : __stpcpy (dest, src)))
 #   endif
 /* In glibc we use this function frequently but for namespace reasons
    we have to use the name `__stpcpy'.  */
 #   define stpcpy(dest, src) __stpcpy (dest, src)
 #  endif
-
-#  if !__GNUC_PREREQ (3, 0) || defined _FORCE_INLINES
-#   if _STRING_ARCH_unaligned
-#    ifndef _FORCE_INLINES
-#     define __stpcpy_args(src) \
-     __extension__ __STRING2_SMALL_GET16 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET16 (src, 4),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 0),			      \
-     __extension__ __STRING2_SMALL_GET32 (src, 4)
-#    endif
-__STRING_INLINE char *__stpcpy_small (char *, __uint16_t, __uint16_t,
-				      __uint32_t, __uint32_t, size_t);
-__STRING_INLINE char *
-__stpcpy_small (char *__dest,
-		__uint16_t __src0_2, __uint16_t __src4_2,
-		__uint32_t __src0_4, __uint32_t __src4_4,
-		size_t __srclen)
-{
-  union {
-    unsigned int __ui;
-    unsigned short int __usi;
-    unsigned char __uc;
-    char __c;
-  } *__u = (void *) __dest;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__uc = '\0';
-      break;
-    case 2:
-      __u->__usi = __src0_2;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 3:
-      __u->__usi = __src0_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__uc = '\0';
-      break;
-    case 4:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 3);
-      break;
-    case 5:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__uc = '\0';
-      break;
-    case 6:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      __u = __extension__ ((void *) __u + 1);
-      break;
-    case 7:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__usi = __src4_2;
-      __u = __extension__ ((void *) __u + 2);
-      __u->__uc = '\0';
-      break;
-    case 8:
-      __u->__ui = __src0_4;
-      __u = __extension__ ((void *) __u + 4);
-      __u->__ui = __src4_4;
-      __u = __extension__ ((void *) __u + 3);
-      break;
-    }
-  return &__u->__c;
-}
-#   else
-#    ifndef _FORCE_INLINES
-#     define __stpcpy_args(src) \
-     __extension__ ((__STRING2_COPY_ARR2)				      \
-      { { ((const char *) (src))[0], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR3)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR4)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR5)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR6)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], '\0' } }),				      \
-     __extension__ ((__STRING2_COPY_ARR7)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  '\0' } }),							      \
-     __extension__ ((__STRING2_COPY_ARR8)				      \
-      { { ((const char *) (src))[0], ((const char *) (src))[1],		      \
-	  ((const char *) (src))[2], ((const char *) (src))[3],		      \
-	  ((const char *) (src))[4], ((const char *) (src))[5],		      \
-	  ((const char *) (src))[6], '\0' } })
-#    endif
-__STRING_INLINE char *__stpcpy_small (char *, __STRING2_COPY_ARR2,
-				      __STRING2_COPY_ARR3,
-				      __STRING2_COPY_ARR4,
-				      __STRING2_COPY_ARR5,
-				      __STRING2_COPY_ARR6,
-				      __STRING2_COPY_ARR7,
-				      __STRING2_COPY_ARR8, size_t);
-__STRING_INLINE char *
-__stpcpy_small (char *__dest,
-		__STRING2_COPY_ARR2 __src2, __STRING2_COPY_ARR3 __src3,
-		__STRING2_COPY_ARR4 __src4, __STRING2_COPY_ARR5 __src5,
-		__STRING2_COPY_ARR6 __src6, __STRING2_COPY_ARR7 __src7,
-		__STRING2_COPY_ARR8 __src8, size_t __srclen)
-{
-  union {
-    char __c;
-    __STRING2_COPY_ARR2 __sca2;
-    __STRING2_COPY_ARR3 __sca3;
-    __STRING2_COPY_ARR4 __sca4;
-    __STRING2_COPY_ARR5 __sca5;
-    __STRING2_COPY_ARR6 __sca6;
-    __STRING2_COPY_ARR7 __sca7;
-    __STRING2_COPY_ARR8 __sca8;
-  } *__u = (void *) __dest;
-  switch ((unsigned int) __srclen)
-    {
-    case 1:
-      __u->__c = '\0';
-      break;
-    case 2:
-      __extension__ __u->__sca2 = __src2;
-      break;
-    case 3:
-      __extension__ __u->__sca3 = __src3;
-      break;
-    case 4:
-      __extension__ __u->__sca4 = __src4;
-      break;
-    case 5:
-      __extension__ __u->__sca5 = __src5;
-      break;
-    case 6:
-      __extension__ __u->__sca6 = __src6;
-      break;
-    case 7:
-      __extension__ __u->__sca7 = __src7;
-      break;
-    case 8:
-      __extension__ __u->__sca8 = __src8;
-      break;
-  }
-  return __dest + __srclen - 1;
-}
-#   endif
-#  endif
 # endif
 #endif
 
@@ -758,13 +139,6 @@ __stpcpy_small (char *__dest,
 #ifndef _HAVE_STRING_ARCH_strncpy
 # if __GNUC_PREREQ (3, 2)
 #  define strncpy(dest, src, n) __builtin_strncpy (dest, src, n)
-# else
-#  define strncpy(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  ? (strlen (src) + 1 >= ((size_t) (n))			      \
-		     ? (char *) memcpy (dest, src, n)			      \
-		     : strncpy (dest, src, n))				      \
-		  : strncpy (dest, src, n)))
 # endif
 #endif
 
@@ -782,13 +156,6 @@ __stpcpy_small (char *__dest,
 		    : strncat (dest, src, n); }))
 # elif __GNUC_PREREQ (3, 2)
 #  define strncat(dest, src, n) __builtin_strncat (dest, src, n)
-# else
-#  define strncat(dest, src, n) \
-  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
-		  ? (strlen (src) < ((size_t) (n))			      \
-		     ? strcat (dest, src)				      \
-		     : strncat (dest, src, n))				      \
-		  : strncat (dest, src, n)))
 # endif
 #endif
 
@@ -815,27 +182,6 @@ __stpcpy_small (char *__dest,
 	       ? __builtin_strcmp (s1, s2)				      \
 	       : __strcmp_gc (s1, s2, __s2_len))			      \
 	    : __builtin_strcmp (s1, s2)))); })
-# else
-#  define strcmp(s1, s2) \
-  __extension__								      \
-  ({ size_t __s1_len, __s2_len;						      \
-     (__builtin_constant_p (s1) && __builtin_constant_p (s2)		      \
-      && (__s1_len = strlen (s1), __s2_len = strlen (s2),		      \
-	  (!__string2_1bptr_p (s1) || __s1_len >= 4)			      \
-	  && (!__string2_1bptr_p (s2) || __s2_len >= 4))		      \
-      ? memcmp ((const char *) (s1), (const char *) (s2),		      \
-		(__s1_len < __s2_len ? __s1_len : __s2_len) + 1)	      \
-      : (__builtin_constant_p (s1) && __string2_1bptr_p (s1)		      \
-	 && (__s1_len = strlen (s1), __s1_len < 4)			      \
-	 ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2)		      \
-	    ? __strcmp_cc (s1, s2, __s1_len)				      \
-	    : __strcmp_cg (s1, s2, __s1_len))				      \
-	 : (__builtin_constant_p (s2) && __string2_1bptr_p (s2)		      \
-	    && (__s2_len = strlen (s2), __s2_len < 4)			      \
-	    ? (__builtin_constant_p (s1) && __string2_1bptr_p (s1)	      \
-	       ? __strcmp_cc (s1, s2, __s2_len)				      \
-	       : __strcmp_gc (s1, s2, __s2_len))			      \
-	    : strcmp (s1, s2)))); })
 # endif
 
 # define __strcmp_cc(s1, s2, l) \
@@ -924,21 +270,6 @@ __stpcpy_small (char *__dest,
 		     ? __strcspn_c3 (s, __r0, __r1, __r2)		      \
 		     : __builtin_strcspn (s, reject))))))		      \
       : __builtin_strcspn (s, reject)); })
-#  else
-#   define strcspn(s, reject) \
-  __extension__								      \
-  ({ char __r0, __r1, __r2;						      \
-     (__builtin_constant_p (reject) && __string2_1bptr_p (reject)	      \
-      ? ((__r0 = ((const char *) (reject))[0], __r0 == '\0')		      \
-	 ? strlen (s)							      \
-	 : ((__r1 = ((const char *) (reject))[1], __r1 == '\0')		      \
-	    ? __strcspn_c1 (s, __r0)					      \
-	    : ((__r2 = ((const char *) (reject))[2], __r2 == '\0')	      \
-	       ? __strcspn_c2 (s, __r0, __r1)				      \
-	       : (((const char *) (reject))[3] == '\0'			      \
-		  ? __strcspn_c3 (s, __r0, __r1, __r2)			      \
-		  : strcspn (s, reject)))))				      \
-      : strcspn (s, reject)); })
 #  endif
 # endif
 
@@ -1000,21 +331,6 @@ __strcspn_c3 (const char *__s, int __reject1, int __reject2,
 		     ? __strspn_c3 (s, __a0, __a1, __a2)		      \
 		     : __builtin_strspn (s, accept))))))		      \
       : __builtin_strspn (s, accept)); })
-#  else
-#   define strspn(s, accept) \
-  __extension__								      \
-  ({ char __a0, __a1, __a2;						      \
-     (__builtin_constant_p (accept) && __string2_1bptr_p (accept)	      \
-      ? ((__a0 = ((const char *) (accept))[0], __a0 == '\0')		      \
-	 ? ((void) (s), (size_t) 0)					      \
-	 : ((__a1 = ((const char *) (accept))[1], __a1 == '\0')		      \
-	    ? __strspn_c1 (s, __a0)					      \
-	    : ((__a2 = ((const char *) (accept))[2], __a2 == '\0')	      \
-	       ? __strspn_c2 (s, __a0, __a1)				      \
-	       : (((const char *) (accept))[3] == '\0'			      \
-		  ? __strspn_c3 (s, __a0, __a1, __a2)			      \
-		  : strspn (s, accept)))))				      \
-      : strspn (s, accept)); })
 #  endif
 # endif
 
@@ -1076,21 +392,6 @@ __strspn_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
 		     ? __strpbrk_c3 (s, __a0, __a1, __a2)		      \
 		     : __builtin_strpbrk (s, accept))))))		      \
       : __builtin_strpbrk (s, accept)); })
-#  else
-#   define strpbrk(s, accept) \
-  __extension__								      \
-  ({ char __a0, __a1, __a2;						      \
-     (__builtin_constant_p (accept) && __string2_1bptr_p (accept)	      \
-      ? ((__a0 = ((const char  *) (accept))[0], __a0 == '\0')		      \
-	 ? ((void) (s), (char *) NULL)					      \
-	 : ((__a1 = ((const char *) (accept))[1], __a1 == '\0')		      \
-	    ? strchr (s, __a0)						      \
-	    : ((__a2 = ((const char *) (accept))[2], __a2 == '\0')	      \
-	       ? __strpbrk_c2 (s, __a0, __a1)				      \
-	       : (((const char *) (accept))[3] == '\0'			      \
-		  ? __strpbrk_c3 (s, __a0, __a1, __a2)			      \
-		  : strpbrk (s, accept)))))				      \
-      : strpbrk (s, accept)); })
 #  endif
 # endif
 
@@ -1118,22 +419,6 @@ __strpbrk_c3 (const char *__s, int __accept1, int __accept2, int __accept3)
 }
 #endif
 
-
-/* Find the first occurrence of NEEDLE in HAYSTACK.  Newer gcc versions
-   do this itself.  */
-#if !defined _HAVE_STRING_ARCH_strstr && !__GNUC_PREREQ (2, 97)
-# define strstr(haystack, needle) \
-  (__extension__ (__builtin_constant_p (needle) && __string2_1bptr_p (needle) \
-		  ? (((const char *) (needle))[0] == '\0'		      \
-		     ? (char *) (size_t) (haystack)			      \
-		     : (((const char *) (needle))[1] == '\0'		      \
-			? strchr (haystack,				      \
-				  ((const char *) (needle))[0]) 	      \
-			: strstr (haystack, needle)))			      \
-		  : strstr (haystack, needle)))
-#endif
-
-
 #if !defined _HAVE_STRING_ARCH_strtok_r || defined _FORCE_INLINES
 # ifndef _HAVE_STRING_ARCH_strtok_r
 #  define __strtok_r(s, sep, nextp) \

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 3/*] Use strchrnul for strcspn (x, "c")
  2015-05-24 22:51 [PATCH 1/*] Move string inlines to string/string-inlines.c Ondřej Bílka
  2015-05-25  0:18 ` [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations Ondřej Bílka
@ 2015-05-25  1:02 ` Ondřej Bílka
  2015-05-25  1:58 ` [PATCH 4/*] Redirect strchr to strchrnul Ondřej Bílka
  2015-05-28 16:27 ` [PATCH 1/*] Move string inlines to string/string-inlines.c Joseph Myers
  3 siblings, 0 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-25  1:02 UTC (permalink / raw)
  To: libc-alpha

A loop there is clearly suboptimal. We improve performance by using
strchrnul equivalent. 

OK to commit?

	* string/bits/string2.h (__strcspn_c1): Optimize with __strchrnul.

diff --git a/string/bits/string2.h b/string/bits/string2.h
index a595c74..2fe67b3 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -277,10 +277,7 @@ __STRING_INLINE size_t __strcspn_c1 (const char *__s, int __reject);
 __STRING_INLINE size_t
 __strcspn_c1 (const char *__s, int __reject)
 {
-  size_t __result = 0;
-  while (__s[__result] != '\0' && __s[__result] != __reject)
-    ++__result;
-  return __result;
+  return __strchrnul (__s, __reject) - __s;
 }
 
 __STRING_INLINE size_t __strcspn_c2 (const char *__s, int __reject1,

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/*] Redirect strchr to strchrnul
  2015-05-24 22:51 [PATCH 1/*] Move string inlines to string/string-inlines.c Ondřej Bílka
  2015-05-25  0:18 ` [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations Ondřej Bílka
  2015-05-25  1:02 ` [PATCH 3/*] Use strchrnul for strcspn (x, "c") Ondřej Bílka
@ 2015-05-25  1:58 ` Ondřej Bílka
  2015-05-25  2:06   ` [PATCH 4/* v2] Optimize strchrnul more Ondřej Bílka
  2015-05-28 16:27 ` [PATCH 1/*] Move string inlines to string/string-inlines.c Joseph Myers
  3 siblings, 1 reply; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-25  1:58 UTC (permalink / raw)
  To: libc-alpha; +Cc: Wilco Dijkstra

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 --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

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/* v2] Optimize strchrnul more
  2015-05-25  1:58 ` [PATCH 4/*] Redirect strchr to strchrnul Ondřej Bílka
@ 2015-05-25  2:06   ` Ondřej Bílka
  2015-05-26 13:24     ` Wilco Dijkstra
  2015-05-28 16:42     ` [PATCH 4/* v2] Optimize strchrnul more Joseph Myers
  0 siblings, 2 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-25  2:06 UTC (permalink / raw)
  To: libc-alpha; +Cc: Wilco Dijkstra

On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> Hi,
> this is nontrivial optimization of string inlines.
> First it decreases icache pressure as you don't need strchr.
> 

Just realized that optimization there is silly way to find terminating
zero. On x64 rawmemchr is around 50% slower than strlen so add rawmemchr
special case that does just that.
 
 	* string/bits/string2.h (strchrnul, rawmemchr): Add inline
 	  (strchr): Optimize.


diff --git a/string/bits/string2.h b/string/bits/string2.h
index 2fe67b3..8f1eb04 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -108,18 +108,39 @@ __STRING2_COPY_TYPE (8);
 #endif
 
 
-/* Return pointer to C in S.  */
-#ifndef _HAVE_STRING_ARCH_strchr
+#ifndef _HAVE_STRING_ARCH_rawmemchr
 extern void *__rawmemchr (const void *__s, int __c);
 # if __GNUC_PREREQ (3, 2)
-#  define strchr(s, c) \
+#  define __rawmemchr(s, c) \
+  (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s)	      \
+		  && (c) == '\0'					      \
+		  ? s + strlen (s) 					      \
+		  : __rawmemchr (s, c)))
+# endif
+#endif
+
+
+
+#ifndef _HAVE_STRING_ARCH_strchrnul
+# if __GNUC_PREREQ (3, 2)
+#  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
 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: [PATCH 4/* v2] Optimize strchrnul more
  2015-05-25  2:06   ` [PATCH 4/* v2] Optimize strchrnul more Ondřej Bílka
@ 2015-05-26 13:24     ` Wilco Dijkstra
  2015-05-26 15:13       ` Ondřej Bílka
  2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
  2015-05-28 16:42     ` [PATCH 4/* v2] Optimize strchrnul more Joseph Myers
  1 sibling, 2 replies; 17+ messages in thread
From: Wilco Dijkstra @ 2015-05-26 13:24 UTC (permalink / raw)
  To: 'Ondřej Bílka', libc-alpha

> Ondřej Bílka wrote:
> On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> > Hi,
> > this is nontrivial optimization of string inlines.
> > First it decreases icache pressure as you don't need strchr.

It's not obvious to me that is the right thing to do. Generally it is best
to use the standard C90/C99 functions rather than infrequently used
non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.

Using strchrnul also means extra work compared to calling strchr at the
callsite (the *__r == c) as well as in strchrnul if the character is not
found (returning NULL is easier than computing the pointer to the 
terminating nul character).

(note for string/strchr.c it seems reasonable to defer to strchrnul)

> Just realized that optimization there is silly way to find terminating
> zero. On x64 rawmemchr is around 50% slower than strlen so add rawmemchr
> special case that does just that.

Yes, given GCC doesn't optimize strchr (s, 0) into s + strlen (s), I agree
we should add this to the GLIBC headers.

>  	* string/bits/string2.h (strchrnul, rawmemchr): Add inline
>  	  (strchr): Optimize.
> 
> 
> diff --git a/string/bits/string2.h b/string/bits/string2.h
> index 2fe67b3..8f1eb04 100644
> --- a/string/bits/string2.h
> +++ b/string/bits/string2.h
> @@ -108,18 +108,39 @@ __STRING2_COPY_TYPE (8);
>  #endif
> 
> 
> -/* Return pointer to C in S.  */
> -#ifndef _HAVE_STRING_ARCH_strchr
> +#ifndef _HAVE_STRING_ARCH_rawmemchr
>  extern void *__rawmemchr (const void *__s, int __c);
>  # if __GNUC_PREREQ (3, 2)
> -#  define strchr(s, c) \
> +#  define __rawmemchr(s, c) \
> +  (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s)	      \
> +		  && (c) == '\0'					      \
> +		  ? s + strlen (s) 					      \
> +		  : __rawmemchr (s, c)))
> +# endif
> +#endif
> +
> +
> +
> +#ifndef _HAVE_STRING_ARCH_strchrnul
> +# if __GNUC_PREREQ (3, 2)
> +#  define strchrnul(s, c) \
>    (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s)	      \
>  		  && (c) == '\0'					      \
>  		  ? (char *) __rawmemchr (s, c)				      \

Should use s + strlen (s) here too rather than rely on above define.

> -		  : __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

I think this should do the strlen optimization and only change into strchrnul
on targets that do have an optimized strchrnul implementation but not strchr.

Wilco


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/* v2] Optimize strchrnul more
  2015-05-26 13:24     ` Wilco Dijkstra
@ 2015-05-26 15:13       ` Ondřej Bílka
  2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
  1 sibling, 0 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-26 15:13 UTC (permalink / raw)
  To: Wilco Dijkstra; +Cc: libc-alpha

On Tue, May 26, 2015 at 01:23:36PM +0100, Wilco Dijkstra wrote:
> > Ondřej Bílka wrote:
> > On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> > > Hi,
> > > this is nontrivial optimization of string inlines.
> > > First it decreases icache pressure as you don't need strchr.
>

I addressed these in original mail but I will reply again anyway.
 
> It's not obvious to me that is the right thing to do. Generally it is best
> to use the standard C90/C99 functions rather than infrequently used
> non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
> than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.
> 
For optimizations its often handy to introduce new specialized functions that 
are faster. Strchrnul fits that role.

Yes there will be transition period where apps will use both strchr and
strchrnul but eventually only strchrnul would be used.

As architectures thats problem that maintainers should address. I could
add _HAVE_FAST_STRCHRNUL and maintainers would enable that when they add
implementation.

Also you need to do this way as for strchr you would need do strlen if
it returns null.

> Using strchrnul also means extra work compared to calling strchr at the
> callsite (the *__r == c) as well as in strchrnul if the character is not
> found (returning NULL is easier than computing the pointer to the 
> terminating nul character).
> 
This is false. using strchrnul is one reason for this optimization.
With recent gcc since 4.9 there would be extra branch only when user
didn't check if function returns null.

gcc does simplify pattern ((*s == '\0' ? s : NULL) == NULL) 
into *s == '\0'

Then to answer that returning NULL is easier you didn't optize your
implementation enough. You should combine char mask with null mask and
have only one check instead of two separate ones for null and character.

Also you forgotten to add cost of branch misprediction. It isn't that
terrible here, character is found only 16.35% times but still
significant.

And you need to calculate index of zero byte anyway. A character could
be also found and you need to determine if character or zero comes
first.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Optimized? strchr implementations.
  2015-05-26 13:24     ` Wilco Dijkstra
  2015-05-26 15:13       ` Ondřej Bílka
@ 2015-05-26 16:32       ` Ondřej Bílka
  2015-05-26 18:00         ` Matt Turner
                           ` (2 more replies)
  1 sibling, 3 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-26 16:32 UTC (permalink / raw)
  To: Wilco Dijkstra; +Cc: libc-alpha, Richard henderson

On Tue, May 26, 2015 at 01:23:36PM +0100, Wilco Dijkstra wrote:
> > Ondřej Bílka wrote:
> > On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> > > Hi,
> > > this is nontrivial optimization of string inlines.
> > > First it decreases icache pressure as you don't need strchr.
> 
> It's not obvious to me that is the right thing to do. Generally it is best
> to use the standard C90/C99 functions rather than infrequently used
> non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
> than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.
>
I looked at how architectures optimize strchr and that number is less.

Some of these are not optimized implementations. If you do gcc
string/strchr.c -S then you get assembly implementation. Several
architectures don't exploit any hardware capabilities, just use same
algorithm as generic so these could be deleted.

I know that generic implementation could be improved and will post a
patches.

Only two that are real optimizations and don't have strchnul are armv6
and alpha
So could you adapt armv6 one? 

Richard as you added alpha could you adapt it to strchnul? And why you
do a binary search there? Accoring to wiki alpha supports ctlz
instruction that does exactly that.


So here follows list of strchr(nul)? 

./sysdeps/powerpc/powerpc64/power7/strchr.S
./sysdeps/powerpc/powerpc64/power7/strchrnul.S
./sysdeps/powerpc/powerpc64/strchr.S
./sysdeps/powerpc/powerpc32/power7/strchr.S
./sysdeps/powerpc/powerpc32/power7/strchrnul.S
./sysdeps/powerpc/powerpc32/strchr.S

Power7 hardware support.

A generic could be replaced by one from string.h

./sysdeps/m68k/strchr.S
./sysdeps/m68k/strchrnul.S

replace by generic

./sysdeps/i386/strchr.S
./sysdeps/i386/strchrnul.S

replace by generic

./sysdeps/ia64/strchr.S

hardware dont have strchrnul

./sysdeps/sparc/sparc64/strchr.S
./sysdeps/sparc/sparc32/strchr.S

replace with generic

./sysdeps/alpha/strchr.S

harware

./sysdeps/arm/armv6/strchr.S

hardware

./sysdeps/aarch64/strchr.S
./sysdeps/aarch64/strchrnul.S

hardware



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Optimized? strchr implementations.
  2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
@ 2015-05-26 18:00         ` Matt Turner
  2015-05-26 18:19           ` Ondřej Bílka
  2015-05-26 18:48         ` Richard Henderson
  2015-05-27 13:23         ` Wilco Dijkstra
  2 siblings, 1 reply; 17+ messages in thread
From: Matt Turner @ 2015-05-26 18:00 UTC (permalink / raw)
  To: Ondřej Bílka; +Cc: Wilco Dijkstra, GNU C Library, Richard henderson

On Tue, May 26, 2015 at 7:38 AM, Ondřej Bílka <neleai@seznam.cz> wrote:
> On Tue, May 26, 2015 at 01:23:36PM +0100, Wilco Dijkstra wrote:
>> > Ondřej Bílka wrote:
>> > On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
>> > > Hi,
>> > > this is nontrivial optimization of string inlines.
>> > > First it decreases icache pressure as you don't need strchr.
>>
>> It's not obvious to me that is the right thing to do. Generally it is best
>> to use the standard C90/C99 functions rather than infrequently used
>> non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
>> than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.
>>
> I looked at how architectures optimize strchr and that number is less.
>
> Some of these are not optimized implementations. If you do gcc
> string/strchr.c -S then you get assembly implementation. Several
> architectures don't exploit any hardware capabilities, just use same
> algorithm as generic so these could be deleted.
>
> I know that generic implementation could be improved and will post a
> patches.
>
> Only two that are real optimizations and don't have strchnul are armv6
> and alpha
> So could you adapt armv6 one?
>
> Richard as you added alpha could you adapt it to strchnul? And why you
> do a binary search there? Accoring to wiki alpha supports ctlz
> instruction that does exactly that.

It's because Alphas < EV67 don't have ctlz.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Optimized? strchr implementations.
  2015-05-26 18:00         ` Matt Turner
@ 2015-05-26 18:19           ` Ondřej Bílka
  0 siblings, 0 replies; 17+ messages in thread
From: Ondřej Bílka @ 2015-05-26 18:19 UTC (permalink / raw)
  To: Matt Turner; +Cc: Wilco Dijkstra, GNU C Library, Richard henderson

On Tue, May 26, 2015 at 09:58:01AM -0700, Matt Turner wrote:
> On Tue, May 26, 2015 at 7:38 AM, Ondřej Bílka <neleai@seznam.cz> wrote:
> > On Tue, May 26, 2015 at 01:23:36PM +0100, Wilco Dijkstra wrote:
> >> > Ondřej Bílka wrote:
> >> > On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> >> > > Hi,
> >> > > this is nontrivial optimization of string inlines.
> >> > > First it decreases icache pressure as you don't need strchr.
> >>
> >> It's not obvious to me that is the right thing to do. Generally it is best
> >> to use the standard C90/C99 functions rather than infrequently used
> >> non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
> >> than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.
> >>
> > I looked at how architectures optimize strchr and that number is less.
> >
> > Some of these are not optimized implementations. If you do gcc
> > string/strchr.c -S then you get assembly implementation. Several
> > architectures don't exploit any hardware capabilities, just use same
> > algorithm as generic so these could be deleted.
> >
> > I know that generic implementation could be improved and will post a
> > patches.
> >
> > Only two that are real optimizations and don't have strchnul are armv6
> > and alpha
> > So could you adapt armv6 one?
> >
> > Richard as you added alpha could you adapt it to strchnul? And why you
> > do a binary search there? Accoring to wiki alpha supports ctlz
> > instruction that does exactly that.
> 
> It's because Alphas < EV67 don't have ctlz.

OK. You could try optimize it bit by implementing ctl with
multiplication but that likely doesn't matter.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Optimized? strchr implementations.
  2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
  2015-05-26 18:00         ` Matt Turner
@ 2015-05-26 18:48         ` Richard Henderson
  2015-05-27 13:23         ` Wilco Dijkstra
  2 siblings, 0 replies; 17+ messages in thread
From: Richard Henderson @ 2015-05-26 18:48 UTC (permalink / raw)
  To: Ondřej Bílka, Wilco Dijkstra; +Cc: libc-alpha

On 05/26/2015 07:38 AM, Ondřej Bílka wrote:
> Richard as you added alpha could you adapt it to strchnul? And why you
> do a binary search there? Accoring to wiki alpha supports ctlz
> instruction that does exactly that.

I suppose I could.  Does it get used often, or indeed ever?

Matt already mentioned the ev67 thing, and you can see that we do indeed have
another copy that uses it: sysdeps/alpha/alphaev67/strchr.S.


r~

^ permalink raw reply	[flat|nested] 17+ messages in thread

* RE: Optimized? strchr implementations.
  2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
  2015-05-26 18:00         ` Matt Turner
  2015-05-26 18:48         ` Richard Henderson
@ 2015-05-27 13:23         ` Wilco Dijkstra
  2 siblings, 0 replies; 17+ messages in thread
From: Wilco Dijkstra @ 2015-05-27 13:23 UTC (permalink / raw)
  To: 'Ondřej Bílka'; +Cc: libc-alpha

> Ondřej Bílka wrote:
> On Tue, May 26, 2015 at 01:23:36PM +0100, Wilco Dijkstra wrote:
> > > Ondřej Bílka wrote:
> > > On Sun, May 24, 2015 at 06:32:14PM +0200, Ondřej Bílka wrote:
> > > > Hi,
> > > > this is nontrivial optimization of string inlines.
> > > > First it decreases icache pressure as you don't need strchr.
> >
> > It's not obvious to me that is the right thing to do. Generally it is best
> > to use the standard C90/C99 functions rather than infrequently used
> > non-standard ones. A quick grep of GLIBC shows strchr is used a lot more
> > than strchrnul, and 9 targets have an optimized strchr vs 5 for strchrnul.
> >
> I looked at how architectures optimize strchr and that number is less.
> 
> Some of these are not optimized implementations. If you do gcc
> string/strchr.c -S then you get assembly implementation. Several
> architectures don't exploit any hardware capabilities, just use same
> algorithm as generic so these could be deleted.
> 
> I know that generic implementation could be improved and will post a
> patches.

Sounds good.

> Only two that are real optimizations and don't have strchnul are armv6
> and alpha
> So could you adapt armv6 one?

Yes that shouldn't be too hard - and looking at it, it seems feasible to
tweak some extra performance out of it as well.

Wilco


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 1/*] Move string inlines to string/string-inlines.c
  2015-05-24 22:51 [PATCH 1/*] Move string inlines to string/string-inlines.c Ondřej Bílka
                   ` (2 preceding siblings ...)
  2015-05-25  1:58 ` [PATCH 4/*] Redirect strchr to strchrnul Ondřej Bílka
@ 2015-05-28 16:27 ` Joseph Myers
  3 siblings, 0 replies; 17+ messages in thread
From: Joseph Myers @ 2015-05-28 16:27 UTC (permalink / raw)
  To: Ondřej Bílka; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1084 bytes --]

On Sun, 24 May 2015, Ondøej Bílka wrote:

> Hi,
> 
> As described in header cleanup thread this is first step.
> It just copies inline function declarations to string-inlines.c
> An objdump -d produce same assembly. 

As I noted in 
<https://sourceware.org/ml/libc-alpha/2015-05/msg00248.html>, there is a 
separate x86 version of string-inlines.c.  Thus, any patches moving 
inlines to string-inlines.c need to handle both the generic version and 
the x86 one, in a way that avoids duplicating function definitions in any 
cases where x86 uses the generic definitions from bits/string2.h in 
string-inlines.c at present (in many cases it may not, if 
sysdeps/x86/bits/string.h overrides them, so I don't know if there's 
actually much duplication to avoid).  And such patches need testing both 
on 32-bit x86 and on another architecture such as x86_64.

(sysdeps/i386/string-inlines.c can be ignored or removed since plain i386 
is no longer supported; only string/string-inlines.c and 
sysdeps/i386/i486/string-inlines.c are relevant.)

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations.
  2015-05-25  0:18 ` [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations Ondřej Bílka
@ 2015-05-28 16:39   ` Joseph Myers
  2015-06-08 10:30     ` Ondřej Bílka
  0 siblings, 1 reply; 17+ messages in thread
From: Joseph Myers @ 2015-05-28 16:39 UTC (permalink / raw)
  To: Ondřej Bílka; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 547 bytes --]

On Sun, 24 May 2015, Ondøej Bílka wrote:

> -/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
> -   The optimization is broken before EGCS 1.1.
> -   GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
> -   if it decides to call the library function, it calls memset
> -   and not bzero.  */
> -# if __GNUC_PREREQ (2, 91)
> -#  define __bzero(s, n) __builtin_memset (s, '\0', n)
> -# endif

It looks like you're removing a definition that would be used with current 
GCC here.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 4/* v2] Optimize strchrnul more
  2015-05-25  2:06   ` [PATCH 4/* v2] Optimize strchrnul more Ondřej Bílka
  2015-05-26 13:24     ` Wilco Dijkstra
@ 2015-05-28 16:42     ` Joseph Myers
  1 sibling, 0 replies; 17+ messages in thread
From: Joseph Myers @ 2015-05-28 16:42 UTC (permalink / raw)
  To: Ondřej Bílka; +Cc: libc-alpha, Wilco Dijkstra

[-- Attachment #1: Type: text/plain, Size: 611 bytes --]

On Sun, 24 May 2015, Ondřej Bílka wrote:

> +/* 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

strchrnul is not an ISO C function.  If you want to define strchr in terms 
of it, you need to add an export of __strchrnul from libc.so (updating all 
the ABI test baselines), with an associated declaration in string.h, and 
then use it instead of strchrnul here.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations.
  2015-05-28 16:39   ` Joseph Myers
@ 2015-06-08 10:30     ` Ondřej Bílka
  2015-06-08 11:24       ` Joseph Myers
  0 siblings, 1 reply; 17+ messages in thread
From: Ondřej Bílka @ 2015-06-08 10:30 UTC (permalink / raw)
  To: Joseph Myers; +Cc: libc-alpha

On Thu, May 28, 2015 at 04:05:56PM +0000, Joseph Myers wrote:
> On Sun, 24 May 2015, Ondřej Bílka wrote:
> 
> > -/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
> > -   The optimization is broken before EGCS 1.1.
> > -   GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
> > -   if it decides to call the library function, it calls memset
> > -   and not bzero.  */
> > -# if __GNUC_PREREQ (2, 91)
> > -#  define __bzero(s, n) __builtin_memset (s, '\0', n)
> > -# endif
> 
> It looks like you're removing a definition that would be used with current 
> GCC here.
> 
As comment says its unnecessary as gcc 4 converts bzero to memset as
this header tries.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations.
  2015-06-08 10:30     ` Ondřej Bílka
@ 2015-06-08 11:24       ` Joseph Myers
  0 siblings, 0 replies; 17+ messages in thread
From: Joseph Myers @ 2015-06-08 11:24 UTC (permalink / raw)
  To: Ondřej Bílka; +Cc: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 909 bytes --]

On Mon, 8 Jun 2015, Ondřej Bílka wrote:

> On Thu, May 28, 2015 at 04:05:56PM +0000, Joseph Myers wrote:
> > On Sun, 24 May 2015, Ondřej Bílka wrote:
> > 
> > > -/* GCC < 3.0 optimizes memset(s, 0, n) but not bzero(s, n).
> > > -   The optimization is broken before EGCS 1.1.
> > > -   GCC 3.0+ has __builtin_bzero as well, but at least till GCC 3.4
> > > -   if it decides to call the library function, it calls memset
> > > -   and not bzero.  */
> > > -# if __GNUC_PREREQ (2, 91)
> > > -#  define __bzero(s, n) __builtin_memset (s, '\0', n)
> > > -# endif
> > 
> > It looks like you're removing a definition that would be used with current 
> > GCC here.
> > 
> As comment says its unnecessary as gcc 4 converts bzero to memset as
> this header tries.

This macro definition is of __bzero, not bzero.  GCC does not do anything 
special with __bzero.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-06-08 10:37 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-24 22:51 [PATCH 1/*] Move string inlines to string/string-inlines.c Ondřej Bílka
2015-05-25  0:18 ` [PATCH 2/*] Remove pre-gcc 3.4 string inline optimizations Ondřej Bílka
2015-05-28 16:39   ` Joseph Myers
2015-06-08 10:30     ` Ondřej Bílka
2015-06-08 11:24       ` Joseph Myers
2015-05-25  1:02 ` [PATCH 3/*] Use strchrnul for strcspn (x, "c") Ondřej Bílka
2015-05-25  1:58 ` [PATCH 4/*] Redirect strchr to strchrnul Ondřej Bílka
2015-05-25  2:06   ` [PATCH 4/* v2] Optimize strchrnul more Ondřej Bílka
2015-05-26 13:24     ` Wilco Dijkstra
2015-05-26 15:13       ` Ondřej Bílka
2015-05-26 16:32       ` Optimized? strchr implementations Ondřej Bílka
2015-05-26 18:00         ` Matt Turner
2015-05-26 18:19           ` Ondřej Bílka
2015-05-26 18:48         ` Richard Henderson
2015-05-27 13:23         ` Wilco Dijkstra
2015-05-28 16:42     ` [PATCH 4/* v2] Optimize strchrnul more Joseph Myers
2015-05-28 16:27 ` [PATCH 1/*] Move string inlines to string/string-inlines.c Joseph Myers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).