This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] | |
This patch optimizes strcasestr function for power >= 7 systems. This patch uses optimized strlen and strnlen for calculating string length and the average improvement of this optimization is ~40%. This patch is tested on powerpc64 and powerpc64le. Attached the benchresults with this new patch. 2015-05-29 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com> * sysdeps/powerpc/powerpc64/multiarch/Makefile: Add strcasestr(). * sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c: Likewise. * sysdeps/powerpc/powerpc64/power7/strcasestr.S: New File. * sysdeps/powerpc/powerpc64/multiarch/strcasestr-power7.S: New File. * sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c: New File. * sysdeps/powerpc/powerpc64/multiarch/strcasestr.c: New File. --- sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 +- .../powerpc/powerpc64/multiarch/ifunc-impl-list.c | 7 + .../powerpc64/multiarch/strcasestr-power7.S | 43 +++++ .../powerpc/powerpc64/multiarch/strcasestr-ppc64.c | 34 ++++ sysdeps/powerpc/powerpc64/multiarch/strcasestr.c | 37 +++++ sysdeps/powerpc/powerpc64/power7/strcasestr.S | 177 +++++++++++++++++++++ 6 files changed, 299 insertions(+), 1 deletion(-)create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr-power7.S
create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c
create mode 100644 sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
create mode 100644 sysdeps/powerpc/powerpc64/power7/strcasestr.S
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile
b/sysdeps/powerpc/powerpc64/multiarch/Makefile
index 17265bd..06b2c67 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/Makefile
+++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile
@@ -19,7 +19,7 @@ sysdep_routines += memcpy-power7 memcpy-a2
memcpy-power6 memcpy-cell \
strcmp-power8 strcmp-power7 strcmp-ppc64 \
strcat-power8 strcat-power7 strcat-ppc64 \
memmove-power7 memmove-ppc64 wordcopy-ppc64 bcopy-ppc64 \
- strncpy-power8
+ strncpy-power8 strcasestr-power7 strcasestr-ppc64 \
CFLAGS-strncase-power7.c += -mcpu=power7 -funroll-loops
CFLAGS-strncase_l-power7.c += -mcpu=power7 -funroll-loops
diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
index f5fdea5..0fd2bd2 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c
@@ -322,5 +322,12 @@ __libc_ifunc_impl_list (const char *name, struct
libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, strcat, 1,
__strcat_ppc))
+ /* Support sysdeps/powerpc/powerpc64/multiarch/strcasestr.c. */
+ IFUNC_IMPL (i, name, strcasestr,
+ IFUNC_IMPL_ADD (array, i, strcasestr,
+ hwcap & PPC_FEATURE_HAS_VSX,
+ __strcasestr_power7)
+ IFUNC_IMPL_ADD (array, i, strcasestr, 1,
+ __strcasestr_ppc))
return i;
}
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power7.S
b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power7.S
new file mode 100644
index 0000000..e13f575
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-power7.S
@@ -0,0 +1,43 @@
+/* Optimized strcasestr implementation for POWER7.
+ Copyright (C) 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#undef EALIGN
+#define EALIGN(name, alignt, words) \
+ .section ".text"; \
+ ENTRY_2(__strcasestr_power7) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ BODY_LABEL(__strcasestr_power7): \
+ cfi_startproc; \
+ LOCALENTRY(__strcasestr_power7)
+
+#undef END
+#define END(name) \
+ cfi_endproc; \
+ TRACEBACK(__strcasestr_power7) \
+ END_2(__strcasestr_power7)
+
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+
+#define STRLEN __strlen_power7
+#define STRNLEN __strnlen_power7
+
+#include <sysdeps/powerpc/powerpc64/power7/strcasestr.S>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c
b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c
new file mode 100644
index 0000000..614c7bf
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr-ppc64.c
@@ -0,0 +1,34 @@
+/* PowerPC64 default implementation of strcasestr.
+ Copyright (C) 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+
+#define STRCASESTR __strcasestr_ppc
+#if IS_IN (libc) && defined(SHARED)
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name) \
+ __hidden_ver1(__strstr_ppc, __GI_strstr, __strstr_ppc);
+#endif
+
+
+#undef weak_alias
+#define weak_alias(a,b )
+
+extern __typeof (strcasestr) __strcasestr_ppc attribute_hidden;
+
+#include <string/strcasestr.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
new file mode 100644
index 0000000..6564314
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcasestr.c
@@ -0,0 +1,37 @@
+/* Multiple versions of strcasestr.
+ Copyright (C) 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#if IS_IN (libc)
+# include <string.h>
+# include <shlib-compat.h>
+# include "init-arch.h"
+
+extern __typeof (__strcasestr) __strcasestr_ppc attribute_hidden;
+extern __typeof (__strcasestr) __strcasestr_power7 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+libc_ifunc (__strcasestr,
+ (hwcap & PPC_FEATURE_HAS_VSX)
+ ? __strcasestr_power7
+ : __strcasestr_ppc);
+
+weak_alias (__strcasestr, strcasestr)
+#else
+#include <string/strcasestr.c>
+#endif
diff --git a/sysdeps/powerpc/powerpc64/power7/strcasestr.S
b/sysdeps/powerpc/powerpc64/power7/strcasestr.S
new file mode 100644
index 0000000..521eadb
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power7/strcasestr.S
@@ -0,0 +1,177 @@
+/* Optimized strcasestr implementation for PowerPC64.
+ Copyright (C) 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
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <locale-defines.h>
+
+#ifndef STRLEN
+/* For builds with no IFUNC support, local calls should be made to internal
+ GLIBC symbol (created by libc_hidden_builtin_def). */
+# ifdef SHARED
+# define STRLEN __GI_strlen
+# else
+# define STRLEN strlen
+# endif
+#endif
+
+#ifndef STRNLEN
+/* For builds with no IFUNC support, local calls should be made to internal
+ GLIBC symbol (created by libc_hidden_builtin_def). */
+# ifdef SHARED
+# define STRNLEN __GI_strnlen
+# else
+# define STRNLEN strnlen
+# endif
+#endif
+
+#undef strcasestr
+#undef __strcasestr
+
+#ifndef STRCASESTR
+#define STRCASESTR __strcasestr
+#endif
+
+/* char * [r3] strcasestr (char *s [r3], char * pat[r4]) */
+
+/*
+* Load byte from input string and search substring and convert
+* each character to lower case character and then compare both.
+* If they are same, load byte from both r3 and r4 and proceed,
+* Else, load next byte from r3 and compare with current r4.
+*/
+
+#define FRAMESIZE (FRAME_MIN_SIZE+32)
+ .machine power7
+EALIGN (STRCASESTR, 4, 0)
+ CALL_MCOUNT 2
+ mflr r0 /* Load link register LR to r0. */
+ std r31, -8(r1) /* Save callers register r31. */
+ cfi_offset(r31, -8)
+ std r30, -16(r1) /* Save callers register r30. */
+ cfi_offset(r30, -16)
+ std r29, -24(r1) /* Save callers register r29. */
+ cfi_offset(r29, -24)
+ std r0, 16(r1) /* Store the link register. */
+ cfi_offset(lr, 16)
+ stdu r1, -FRAMESIZE(r1) /* Create the stack frame. */
+ cfi_adjust_cfa_offset(FRAMESIZE)
+
+ dcbt 0, r3
+ dcbt 0, r4
+
+ and r0, r3, r4
+ cmpdi cr7, r0, 0
+ beq cr7, L(retnull)
+
+ mr r29, r3
+ mr r30, r4
+ mr r3, r4
+ bl STRLEN
+ nop
+
+ /* Call __strcasestr_ppc if needle len > 2048. */
+ cmpdi cr7, r3, 2048
+ bgt cr7, L(default)
+
+ cmpdi cr7, r3, 0 /* If search str is null. */
+ beq cr7, L(ret_r3)
+ mr r31, r3
+ mr r4, r3
+ mr r3, r29
+ bl STRNLEN
+ nop
+
+ cmpd cr7, r3, r31 /* If len(r3) < len(r4). */
+ blt cr7, L(retnull)
+
+ mr r3, r29
+ mr r8, r3 /* Save r3. */
+ addi r8, r8, -1
+ ld r10, __libc_tsd_LOCALE@got@tprel(r2)
+ add r11, r10, __libc_tsd_LOCALE@tls
+ ld r11, 0(r11)
+ ld r11, LOCALE_CTYPE_TOLOWER(r11)
+
+ mr r4, r30
+ lbz r6, 0(r4) /* Load next byte from r4. */
+ cmpdi cr7, r6, 0 /* Is it null? */
+ beq cr7, L(updater3)
+ sldi r7, r6, 2 /* Convert to lower case. */
+ lwzx r7, r11, r7
+ mr r12, r7 /* Save it for next loop. */
+L(loop1):
+ addi r8, r8, 1
+ mr r3, r8 /* Restore r3. */
+ mr r4, r30 /* Restore r4. */
+ mr r7, r12
+L(loop):
+ lbz r5, 0(r3) /* Load byte from r3. */
+ cmpdi cr7, r5, 0 /* Is it null? */
+ beq cr7, L(retnull) /* If yes, return. */
+ sldi r10, r5, 2 /* Convert to lower case. */
+ lwzx r10, r11, r10
+ cmpw cr7, r7, r10 /* Compare with byte from r4. */
+ bne cr7, L(loop1)
+ addi r3, r3, 1 /* Increment r3. */
+ addi r4, r4, 1 /* Increment r4. */
+ lbz r6, 0(r4) /* Load next byte from r4. */
+ cmpdi cr7, r6, 0 /* Is it null? */
+ beq cr7, L(updater3)
+ sldi r7, r6, 2 /* Convert to lower case. */
+ lwzx r7, r11, r7
+ b L(loop)
+
+ /* Handling return values. */
+ .align 4
+L(updater3):
+ subf r3, r31, r3 /* Reduce len of r4 from r3. */
+ b L(end)
+
+ .align 4
+L(ret_r3):
+ mr r3, r29 /* Return r3. */
+ b L(end)
+
+ .align 4
+L(retnull):
+ li r3, 0 /* Return NULL. */
+ b L(end)
+
+ .align 4
+L(default):
+ mr r3, r29
+ mr r4, r30
+ bl __strcasestr_ppc
+ nop
+
+ .align 4
+L(end):
+ addi r1, r1, FRAMESIZE /* Restore stack pointer. */
+ cfi_adjust_cfa_offset(-FRAMESIZE)
+ ld r0, 16(r1) /* Restore the saved link register. */
+ ld r29, -24(r1) /* Restore callers save register r29. */
+ ld r30, -16(r1) /* Restore callers save register r30. */
+ ld r31, -8(r1) /* Restore callers save register r31. */
+ mtlr r0 /* Branch to link register. */
+ blr
+END (STRCASESTR)
+#ifndef NO_ALIAS
+weak_alias (__strcasestr, strcasestr)
+#endif
+
+libc_hidden_builtin_def (strcasestr)
--
2.1.0
Attachment:
strcasestr-benchresults
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |