diff options
author | Raoni Fassina Firmino <raoni@linux.ibm.com> | 2021-04-30 18:12:08 -0300 |
---|---|---|
committer | Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | 2021-04-30 18:12:08 -0300 |
commit | 23fdf8178cce3c2ec320dd5eca8b544245bcaef0 (patch) | |
tree | 964850757fe4acf099e9fb3696ac19f79dc24f94 /sysdeps/powerpc/powerpc64/multiarch | |
parent | e941e0ae80626b7661c1db8953a673cafd3b8b19 (diff) | |
download | glibc-23fdf8178cce3c2ec320dd5eca8b544245bcaef0.tar.gz |
powerpc64le: Optimize memset for POWER10
This implementation is based on __memset_power8 and integrates a lot
of suggestions from Anton Blanchard.
The biggest difference is that it makes extensive use of stxvl to
alignment and tail code to avoid branches and small stores. It has
three main execution paths:
a) "Short lengths" for lengths up to 64 bytes, avoiding as many
branches as possible.
b) "General case" for larger lengths, it has an alignment section
using stxvl to avoid branches, a 128 bytes loop and then a tail
code, again using stxvl with few branches.
c) "Zeroing cache blocks" for lengths from 256 bytes upwards and set
value being zero. It is mostly the __memset_power8 code but the
alignment phase was simplified because, at this point, address is
already 16-bytes aligned and also changed to use vector stores.
The tail code was also simplified to reuse the general case tail.
All unaligned stores use stxvl instructions that do not generate
alignment interrupts on POWER10, making it safe to use on
caching-inhibited memory.
On average, this implementation provides something around 30%
improvement when compared to __memset_power8.
Reviewed-by: Matheus Castanho <msc@linux.ibm.com>
Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
Diffstat (limited to 'sysdeps/powerpc/powerpc64/multiarch')
-rw-r--r-- | sysdeps/powerpc/powerpc64/multiarch/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/multiarch/bzero.c | 8 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c | 14 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/multiarch/memset-power10.S | 27 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/multiarch/memset.c | 8 |
5 files changed, 58 insertions, 1 deletions
diff --git a/sysdeps/powerpc/powerpc64/multiarch/Makefile b/sysdeps/powerpc/powerpc64/multiarch/Makefile index 9ef12d3563..ea50b61674 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/Makefile +++ b/sysdeps/powerpc/powerpc64/multiarch/Makefile @@ -32,7 +32,7 @@ sysdep_routines += memcpy-power8-cached memcpy-power7 memcpy-a2 memcpy-power6 \ strncase-power8 ifneq (,$(filter %le,$(config-machine))) -sysdep_routines += memcpy-power10 memmove-power10 \ +sysdep_routines += memcpy-power10 memmove-power10 memset-power10 \ strcmp-power9 strncmp-power9 strcpy-power9 stpcpy-power9 \ rawmemchr-power9 strlen-power9 strncpy-power9 stpncpy-power9 \ strlen-power10 diff --git a/sysdeps/powerpc/powerpc64/multiarch/bzero.c b/sysdeps/powerpc/powerpc64/multiarch/bzero.c index c3f819ff48..50a5320c66 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/bzero.c +++ b/sysdeps/powerpc/powerpc64/multiarch/bzero.c @@ -27,8 +27,16 @@ extern __typeof (bzero) __bzero_power4 attribute_hidden; extern __typeof (bzero) __bzero_power6 attribute_hidden; extern __typeof (bzero) __bzero_power7 attribute_hidden; extern __typeof (bzero) __bzero_power8 attribute_hidden; +# ifdef __LITTLE_ENDIAN__ +extern __typeof (bzero) __bzero_power10 attribute_hidden; +# endif libc_ifunc (__bzero, +# ifdef __LITTLE_ENDIAN__ + (hwcap2 & (PPC_FEATURE2_ARCH_3_1 | PPC_FEATURE2_HAS_ISEL) + && hwcap & PPC_FEATURE_HAS_VSX) + ? __bzero_power10 : +# endif (hwcap2 & PPC_FEATURE2_ARCH_2_07) ? __bzero_power8 : (hwcap & PPC_FEATURE_HAS_VSX) diff --git a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c index 1ab56bb2c9..49d9a33e65 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c +++ b/sysdeps/powerpc/powerpc64/multiarch/ifunc-impl-list.c @@ -86,6 +86,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, /* Support sysdeps/powerpc/powerpc64/multiarch/memset.c. */ IFUNC_IMPL (i, name, memset, +#ifdef __LITTLE_ENDIAN__ + IFUNC_IMPL_ADD (array, i, memset, + hwcap2 & (PPC_FEATURE2_ARCH_3_1 | + PPC_FEATURE2_HAS_ISEL) + && hwcap & PPC_FEATURE_HAS_VSX, + __memset_power10) +#endif IFUNC_IMPL_ADD (array, i, memset, hwcap2 & PPC_FEATURE2_ARCH_2_07, __memset_power8) IFUNC_IMPL_ADD (array, i, memset, hwcap & PPC_FEATURE_HAS_VSX, @@ -187,6 +194,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, /* Support sysdeps/powerpc/powerpc64/multiarch/bzero.c. */ IFUNC_IMPL (i, name, bzero, +#ifdef __LITTLE_ENDIAN__ + IFUNC_IMPL_ADD (array, i, bzero, + hwcap2 & (PPC_FEATURE2_ARCH_3_1 | + PPC_FEATURE2_HAS_ISEL) + && hwcap & PPC_FEATURE_HAS_VSX, + __bzero_power10) +#endif IFUNC_IMPL_ADD (array, i, bzero, hwcap2 & PPC_FEATURE2_ARCH_2_07, __bzero_power8) IFUNC_IMPL_ADD (array, i, bzero, hwcap & PPC_FEATURE_HAS_VSX, diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset-power10.S b/sysdeps/powerpc/powerpc64/multiarch/memset-power10.S new file mode 100644 index 0000000000..548e997897 --- /dev/null +++ b/sysdeps/powerpc/powerpc64/multiarch/memset-power10.S @@ -0,0 +1,27 @@ +/* Optimized memset implementation for POWER10 LE. + Copyright (C) 2021 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 + <https://www.gnu.org/licenses/>. */ + +#define MEMSET __memset_power10 + +#undef libc_hidden_builtin_def +#define libc_hidden_builtin_def(name) + +#undef __bzero +#define __bzero __bzero_power10 + +#include <sysdeps/powerpc/powerpc64/le/power10/memset.S> diff --git a/sysdeps/powerpc/powerpc64/multiarch/memset.c b/sysdeps/powerpc/powerpc64/multiarch/memset.c index d483f66f27..6562646dff 100644 --- a/sysdeps/powerpc/powerpc64/multiarch/memset.c +++ b/sysdeps/powerpc/powerpc64/multiarch/memset.c @@ -33,10 +33,18 @@ extern __typeof (__redirect_memset) __memset_power4 attribute_hidden; extern __typeof (__redirect_memset) __memset_power6 attribute_hidden; extern __typeof (__redirect_memset) __memset_power7 attribute_hidden; extern __typeof (__redirect_memset) __memset_power8 attribute_hidden; +# ifdef __LITTLE_ENDIAN__ +extern __typeof (__redirect_memset) __memset_power10 attribute_hidden; +# endif /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle ifunc symbol properly. */ libc_ifunc (__libc_memset, +# ifdef __LITTLE_ENDIAN__ + (hwcap2 & (PPC_FEATURE2_ARCH_3_1 | PPC_FEATURE2_HAS_ISEL) + && hwcap & PPC_FEATURE_HAS_VSX) + ? __memset_power10 : +# endif (hwcap2 & PPC_FEATURE2_ARCH_2_07) ? __memset_power8 : (hwcap & PPC_FEATURE_HAS_VSX) |