This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [RFC] Faster strspn/strcspn implementation.
- From: OndÅej BÃlka <neleai at seznam dot cz>
- To: libc-alpha at sourceware dot org
- Cc: hubicka at ucw dot cz
- Date: Fri, 28 Dec 2012 10:30:56 +0100
- Subject: Re: [RFC] Faster strspn/strcspn implementation.
- References: <20121227212146.GA26540@domone>
On Thu, Dec 27, 2012 at 10:21:46PM +0100, OndÅej BÃlka wrote:
> __strspn4( s,a0,a1,a2,a3) - when needle consist at most 4 characters.
> __strspn_rng(s,from,to) - when needle is consecutive interval.
> __strspn16(s,a) - when needle consist at most 16 characters.
> __strspn_arf(s,a) - anything else.
>
> In header string/bits/string2.h I changed implementation to call
> __strspn4 for small needles. Currently I can not persudate gcc to
> recognize intervals at compile time.
>
For backward compatibility I defined compatibility function and made it
weak alias to new function. Could be gcc taugth to unify identical
static functions?
This does not compile for rtld yet as I would need update makefile.
diff --git a/string/bits/string2.h b/string/bits/string2.h
index 2e560de..de82b77 100644
--- a/string/bits/string2.h
+++ b/string/bits/string2.h
@@ -925,8 +925,26 @@ __stpcpy_small (char *__dest,
? strcmp (s1, s2) : strncmp (s1, s2, n)))
#endif
+#ifdef NO_STRSPN4_WEAK_ALIAS
+/* Redefition without weak alias causes error, so we need to disable
this.*/
extern size_t __strspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3);
extern size_t __strcspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3);
+#else
+extern size_t __strspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3) __attribute__ ((weak, alias ("__strspn4_compat")));
+extern size_t __strcspn4 (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3) __attribute__ ((weak, alias ("__strcspn4_compat")));
+
+static size_t __strspn4_compat (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3)
+{
+ char n[5];
+ n[0] = a0; n[1] = a1; n[2] = a2; n[3] = a3; n[4] = 0;
+ return strspn(a,n);
+}
+static size_t __strcspn4_compat (const char *a,unsigned char a0,unsigned char a1,unsigned char a2,unsigned char a3)
+{
+ char n[5];
+ n[0] = a0; n[1] = a1; n[2] = a2; n[3] = a3; n[4] = 0;
+ return strcspn(a,n);
+}
+#endif
/* Return the length of the initial segment of S which
diff --git a/string/strspn_internal.c b/string/strspn_internal.c
index 3962925..1cb4190 100644
--- a/string/strspn_internal.c
+++ b/string/strspn_internal.c
@@ -27,6 +27,7 @@
#define SPN_ARY SPN_CSPN(__strspn_ary ,__strcspn_ary)
#define SPN_RNG SPN_CSPN(__strspn_rng ,__strcspn_rng)
+#define NO_STRSPN4_WEAK_ALIAS
#include <string.h>
size_t SPN_ARY (unsigned char* s,unsigned char* n)
--
1.7.4.4