From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8022 invoked by alias); 26 May 2004 15:00:48 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 7732 invoked from network); 26 May 2004 15:00:36 -0000 Received: from unknown (HELO sunsite.ms.mff.cuni.cz) (195.113.15.26) by sourceware.org with SMTP; 26 May 2004 15:00:36 -0000 Received: from sunsite.ms.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8) with ESMTP id i4QCl13j032435; Wed, 26 May 2004 14:47:01 +0200 Received: (from jakub@localhost) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8/Submit) id i4QCl00X032398; Wed, 26 May 2004 14:47:00 +0200 Date: Wed, 26 May 2004 17:27:00 -0000 From: Jakub Jelinek To: Ulrich Drepper Cc: Glibc hackers , gcc@gcc.gnu.org Subject: [PATCH] changes for GCC 3.2+ and 3.4+ Message-ID: <20040526124659.GT5191@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2004-05/txt/msg00044.txt.bz2 Hi! I went through and GCC 3.2.3, 3.3.3, 3.4.0 and trunk. This patch is removing memset macro for GCC 3.0+, since GCC really does in most cases as good or better job as glibc and certainly has far more information that glibc. mempcpy in 3.4+ has all the optimizations glibc provided, similarly stpcpy. The strchr macro is kept, as the optimization of strchr (p, '\0') to __rawmemchr (p, '\0') is worthy, but was changed to optimize cases like strchr ("foobar", '\0') with GCC 3.2+. _USE_STRING_ARCH_mempcpy is not defined in any of the bits/string.h headers, so I have removed that case from strncpy inline. For strncpy and strncat GCC 3.2+ has the same optimizations as glibc did. For strcmp, with GCC 3.2+ we can now optimize comparision of two constant strings, yet the macro is kept for strcmp (p, "ab") cases (where one string is literal with up to 4 characters). For strcspn, strspn and strpbrk with GCC 3.2+ the macros have been changed to handle both arguments string literals. 2004-05-26 Jakub Jelinek * include/string.h (mempcpy, stpcpy): Add libc_hidden_builtin_proto. * string/bits/string2.h (memset): Disable macro for GCC 3.0+. (__mempcpy): Use __builtin_mempcpy for GCC 3.4+. (strchr): For GCC 3.2+, only use __rawmemchr if second argument is constant '\0' and first argument is not constant. (__stpcpy): Use __builtin_stpcpy for GCC 3.4+. (strncpy): Remove #ifdef _USE_STRING_ARCH_mempcpy variant. For GCC 3.2+ use __builtin_strncpy. (strncat): For GCC 3.2+ use __builtin_strncat. (strcmp): For GCC 3.2+ use __builtin_strcmp if both arguments are constant. (strcspn, strspn, strpbrk): For GCC 3.2+, use builtin function if both arguments are constant. --- libc/include/string.h.jj 2004-04-13 10:42:51.000000000 +0200 +++ libc/include/string.h 2004-05-26 16:08:50.082921658 +0200 @@ -83,6 +83,7 @@ libc_hidden_proto (__strxfrm_l) libc_hidden_builtin_proto (memchr) libc_hidden_builtin_proto (memcpy) +libc_hidden_builtin_proto (mempcpy) libc_hidden_builtin_proto (memcmp) libc_hidden_builtin_proto (memmove) libc_hidden_builtin_proto (memset) @@ -95,6 +96,7 @@ libc_hidden_builtin_proto (strlen) libc_hidden_builtin_proto (strncmp) libc_hidden_builtin_proto (strncpy) libc_hidden_builtin_proto (strpbrk) +libc_hidden_builtin_proto (stpcpy) libc_hidden_builtin_proto (strrchr) libc_hidden_builtin_proto (strspn) libc_hidden_builtin_proto (strstr) --- libc/string/bits/string2.h.jj 2004-05-07 14:32:32.000000000 +0200 +++ libc/string/bits/string2.h 2004-05-26 15:57:38.423291808 +0200 @@ -30,7 +30,7 @@ means the code size increases a lot. Instead the definitions here optimize some functions in a way which do not dramatically increase the code size and which do not use assembler. The main - trick is to use GNU CC's `__builtin_constant_p' function. + trick is to use GCC's `__builtin_constant_p' function. Every function XXX which has a defined version in must be accompanied by a symbol _HAVE_STRING_ARCH_XXX @@ -94,7 +94,7 @@ __STRING2_COPY_TYPE (8); ((size_t)(const void *)((__x) + 1) - (size_t)(const void *)(__x) == 1) /* Set N bytes of S to C. */ -#ifndef _HAVE_STRING_ARCH_memset +#if !defined _HAVE_STRING_ARCH_memset && ! __GNUC_PREREQ (3, 0) # if _STRING_ARCH_unaligned # define memset(s, c, n) \ (__extension__ (__builtin_constant_p (n) && (n) <= 16 \ @@ -178,12 +178,10 @@ __STRING2_COPY_TYPE (8); \ __s; }) # else -# if ! __GNUC_PREREQ (3, 0) -# define memset(s, c, n) \ +# 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 optimizes memset(s, 0, n) but not bzero(s, n). @@ -200,7 +198,9 @@ __STRING2_COPY_TYPE (8); #ifdef __USE_GNU # if !defined _HAVE_STRING_ARCH_mempcpy || defined _FORCE_INLINES # ifndef _HAVE_STRING_ARCH_mempcpy -# if __GNUC_PREREQ (3, 0) +# 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 \ @@ -387,10 +387,18 @@ __mempcpy_small (void *__dest, char __sr /* Return pointer to C in S. */ #ifndef _HAVE_STRING_ARCH_strchr extern void *__rawmemchr (const void *__s, int __c); -# define strchr(s, c) \ +# if __GNUC_PREREQ (3, 2) +# define strchr(s, c) \ + (__extension__ (__builtin_constant_p (c) && !__builtin_constant_p (s) \ + && (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 @@ -560,7 +568,9 @@ __strcpy_small (char *__dest, #ifdef __USE_GNU # if !defined _HAVE_STRING_ARCH_stpcpy || defined _FORCE_INLINES # ifndef _HAVE_STRING_ARCH_stpcpy -# if __GNUC_PREREQ (3, 0) +# 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 \ @@ -742,16 +752,8 @@ __stpcpy_small (char *__dest, /* Copy no more than N characters of SRC to DEST. */ #ifndef _HAVE_STRING_ARCH_strncpy -# if defined _USE_STRING_ARCH_memset && defined _USE_STRING_ARCH_mempcpy -# define strncpy(dest, src, n) \ - (__extension__ ({ char *__dest = (dest); \ - __builtin_constant_p (src) && __builtin_constant_p (n) \ - ? (strlen (src) + 1 >= ((size_t) (n)) \ - ? (char *) memcpy (__dest, src, n) \ - : (memset (__mempcpy (__dest, src, strlen (src)), \ - '\0', n - strlen (src)), \ - __dest)) \ - : strncpy (__dest, src, n); })) +# 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) \ @@ -774,6 +776,8 @@ __stpcpy_small (char *__dest, : (*((char *) __mempcpy (strchr (__dest, '\0'), \ src, n)) = '\0', __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) \ @@ -787,7 +791,28 @@ __stpcpy_small (char *__dest, /* Compare characters of S1 and S2. */ #ifndef _HAVE_STRING_ARCH_strcmp -# define strcmp(s1, s2) \ +# if __GNUC_PREREQ (3, 2) +# 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)) \ + ? __builtin_strcmp (s1, s2) \ + : (__builtin_constant_p (s1) && __string2_1bptr_p (s1) \ + && (__s1_len = strlen (s1), __s1_len < 4) \ + ? (__builtin_constant_p (s2) && __string2_1bptr_p (s2) \ + ? __builtin_strcmp (s1, s2) \ + : __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) \ + ? __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) \ @@ -807,6 +832,7 @@ __stpcpy_small (char *__dest, ? __strcmp_cc (s1, s2, __s2_len) \ : __strcmp_gc (s1, s2, __s2_len)) \ : strcmp (s1, s2)))); }) +#endif # define __strcmp_cc(s1, s2, l) \ (__extension__ ({ register int __result = \ @@ -900,7 +926,25 @@ __stpcpy_small (char *__dest, consists entirely of characters not in REJECT. */ #if !defined _HAVE_STRING_ARCH_strcspn || defined _FORCE_INLINES # ifndef _HAVE_STRING_ARCH_strcspn -# define strcspn(s, reject) \ +# if __GNUC_PREREQ (3, 2) +# define strcspn(s, reject) \ + __extension__ \ + ({ char __r0, __r1, __r2; \ + (__builtin_constant_p (reject) && __string2_1bptr_p (reject) \ + ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \ + ? __builtin_strcspn (s, 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) \ + : __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) \ @@ -913,7 +957,8 @@ __stpcpy_small (char *__dest, : (((__const char *) (reject))[3] == '\0' \ ? __strcspn_c3 (s, __r0, __r1, __r2) \ : strcspn (s, reject))))) \ - : strcspn (s, reject)); }) + : strcspn (s, reject)); }) +# endif # endif __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject); @@ -957,7 +1002,25 @@ __strcspn_c3 (__const char *__s, int __r consists entirely of characters in ACCEPT. */ #if !defined _HAVE_STRING_ARCH_strspn || defined _FORCE_INLINES # ifndef _HAVE_STRING_ARCH_strspn -# define strspn(s, accept) \ +# if __GNUC_PREREQ (3, 2) +# define strspn(s, accept) \ + __extension__ \ + ({ char __a0, __a1, __a2; \ + (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \ + ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \ + ? __builtin_strspn (s, accept) \ + : ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \ + ? ((void) (s), 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) \ + : __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) \ @@ -971,6 +1034,7 @@ __strcspn_c3 (__const char *__s, int __r ? __strspn_c3 (s, __a0, __a1, __a2) \ : strspn (s, accept))))) \ : strspn (s, accept)); }) +# endif # endif __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept); @@ -1014,6 +1078,24 @@ __strspn_c3 (__const char *__s, int __ac /* Find the first occurrence in S of any character in ACCEPT. */ #if !defined _HAVE_STRING_ARCH_strpbrk || defined _FORCE_INLINES # ifndef _HAVE_STRING_ARCH_strpbrk +# if __GNUC_PREREQ (3, 2) +# define strpbrk(s, accept) \ + __extension__ \ + ({ char __a0, __a1, __a2; \ + (__builtin_constant_p (accept) && __string2_1bptr_p (accept) \ + ? ((__builtin_constant_p (s) && __string2_1bptr_p (s)) \ + ? __builtin_strpbrk (s, accept) \ + : ((__a0 = ((__const char *) (accept))[0], __a0 == '\0') \ + ? ((void) (s), (char *) NULL) \ + : ((__a1 = ((__const char *) (accept))[1], __a1 == '\0') \ + ? __builtin_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) \ + : __builtin_strpbrk (s, accept)))))) \ + : __builtin_strpbrk (s, accept)); }) +# else # define strpbrk(s, accept) \ __extension__ \ ({ char __a0, __a1, __a2; \ @@ -1028,6 +1110,7 @@ __strspn_c3 (__const char *__s, int __ac ? __strpbrk_c3 (s, __a0, __a1, __a2) \ : strpbrk (s, accept))))) \ : strpbrk (s, accept)); }) +# endif # endif __STRING_INLINE char *__strpbrk_c2 (__const char *__s, int __accept1, Jakub