From patchwork Thu Mar 31 14:01:02 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 64793 Delivered-To: patch@linaro.org Received: by 10.112.199.169 with SMTP id jl9csp175517lbc; Thu, 31 Mar 2016 07:01:59 -0700 (PDT) X-Received: by 10.66.124.226 with SMTP id ml2mr22017058pab.90.1459432918900; Thu, 31 Mar 2016 07:01:58 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id am4si14328855pad.172.2016.03.31.07.01.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 31 Mar 2016 07:01:58 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-68490-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of libc-alpha-return-68490-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-68490-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=aSnC3uV1wT1BrhPfGhNnFmx7OBN6oE8 ADGtL2oRdpk2ULU58fevVcCFbsOLL4HzcZzzkpIJcgHBTIx2F6Y9z6SyjTQQ5fZV W2omv5uvT/xJKGSiQwXobeImnWKpHv4WYaP5Lx3sv/GFXVF4jQ/BbgXSNrC5ODUq JINQ5REufjK8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=Dg6sjFiq+oDaEikjhKsfZAQyhq4=; b=EX3ql tdnCod3HB+sYPk+/ZXHwlIdg4xC6ie/nZdsTiiptu80cmUoLg+Uh8ysHxb7alki1 MfiWrPpFJ82Oza4g3AyPn0QjoQntgVivZNk34YyXmmazM1vfGWdp+48txiBzz2/0 FDxKvTdmRRNS+LFPS0357hxV0tTGeJWd25T66A= Received: (qmail 116908 invoked by alias); 31 Mar 2016 14:01:26 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 116834 invoked by uid 89); 31 Mar 2016 14:01:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=strpbrk, 1074 X-HELO: mail-yw0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=N9+tK9FvRiXgFJQJGkdBSVXKlbEwj7Wjl2cimAJdv+o=; b=IF9QGKvf5WQoiW/0alwwXgNtI8uXr/DdCNpYJdupQo4r9WiFGYfuEv6ncDlt8Eit69 bdPM5j/lhL1sFPcD7qzOejSJueBxSk/tG7RMfySctDZp3spJonmQEwh6DnQt3SUzRs3p O8T6zX0sTl6vfpa3ny+2BDoJtd5oTMo/jl2PsVm0e7LQb+28dvndGyypN9E1/1RJEfVi MJBQfJbQt/nBZyqvBW23lUk7mHBjJUBFIBT5f/qhdh4JhJ32OEkJQfHgf17gZ/C0PzJy +WmnJxLbvV0lFO0GosmnedeNbnvcQZNWFKO89TCJDUpfV4ymRJgxsKWVOD6CuC4EY5+z eZLA== X-Gm-Message-State: AD7BkJKZg4S34BogBfpRyK+gGHNf85a8tlE41BHIr0H6VKeXSPqbzxnmQtf3Za2OwiajkBpw X-Received: by 10.37.81.137 with SMTP id f131mr7641101ybb.54.1459432873579; Thu, 31 Mar 2016 07:01:13 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 3/4] Improve generic strpbrk performance Date: Thu, 31 Mar 2016 11:01:02 -0300 Message-Id: <1459432863-20749-4-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1459432863-20749-1-git-send-email-adhemerval.zanella@linaro.org> References: <1459432863-20749-1-git-send-email-adhemerval.zanella@linaro.org> With now a faster strcspn implementation, it is also faster to just use it with some return tests than reimplementing strpbrk itself. As for strcspn optimization, it is generally at least 10 times faster than the existing implementation on bench-strspn on a few AArch64 implementations. Also the string/bits/string2.h inlines make no longer sense, as current implementation will already implement most of the optimizations. Tested on x86_64, i386, and aarch64. * string/strpbrk.c (strpbrk): Rewrite function. * string/bits/string2.h (strpbrk): Use __builtin_strpbrk. (__strpbrk_c2): Likewise. (__strpbrk_c3): Likewise. * string/string-inlines.c [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strpbrk_c2): Likewise. [SHLIB_COMPAT(libc, GLIBC_2_1_1, GLIBC_2_24)] (__strpbrk_c3): Likewise. --- ChangeLog | 10 ++++++++ string/bits/string2.h | 61 +++---------------------------------------------- string/string-inlines.c | 21 +++++++++++++++++ string/strpbrk.c | 12 ++-------- 4 files changed, 36 insertions(+), 68 deletions(-) -- 1.9.1 diff --git a/string/bits/string2.h b/string/bits/string2.h index 75a66a1..5a138dc 100644 --- a/string/bits/string2.h +++ b/string/bits/string2.h @@ -922,65 +922,10 @@ __stpcpy_small (char *__dest, /* 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; \ - (__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 +#ifndef _HAVE_STRING_ARCH_strpbrk +# if __GNUC_PREREQ (3, 2) +# define strpbrk(s, accept) __builtin_strpbrk (s, accept) # endif - -__STRING_INLINE char *__strpbrk_c2 (const char *__s, int __accept1, - int __accept2); -__STRING_INLINE 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; -} - -__STRING_INLINE char *__strpbrk_c3 (const char *__s, int __accept1, - int __accept2, int __accept3); -__STRING_INLINE 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; -} #endif diff --git a/string/string-inlines.c b/string/string-inlines.c index 754b315..0648376 100644 --- a/string/string-inlines.c +++ b/string/string-inlines.c @@ -107,4 +107,25 @@ __old_strspn_c3 (const char *__s, int __accept1, int __accept2, } compat_symbol (libc, __old_strspn_c3, __strspn_c3, GLIBC_2_1_1); +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; +} +compat_symbol (libc, __old_strpbrk_c2, __strpbrk_c2, GLIBC_2_1_1); + +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; +} +compat_symbol (libc, __old_strpbrk_c3, __strpbrk_c3, GLIBC_2_1_1); + #endif diff --git a/string/strpbrk.c b/string/strpbrk.c index fddd473..1ede719 100644 --- a/string/strpbrk.c +++ b/string/strpbrk.c @@ -27,15 +27,7 @@ char * STRPBRK (const char *s, const char *accept) { - while (*s != '\0') - { - const char *a = accept; - while (*a != '\0') - if (*a++ == *s) - return (char *) s; - ++s; - } - - return NULL; + s += strcspn (s, accept); + return *s ? (char *)s : NULL; } libc_hidden_builtin_def (strpbrk)