mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-07 06:43:00 +03:00
wcsmbs: optimize wcscat
This patch rewrites wcscat using wcslen and wcscpy. This is similar to
the optimization done on strcat by 6e46de42fe
.
The strcpy changes are mainly to add the internal alias to avoid PLT
calls.
Checked on x86_64-linux-gnu and a build against the affected
architectures.
* include/wchar.h (__wcscpy): New prototype.
* sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
(__wcscpy): Route internal symbol to generic implementation.
* sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy.c (wcscpy):
Add internal __wcscpy alias.
* sysdeps/powerpc/powerpc64/multiarch/wcscpy.c (wcscpy): Likewise.
* sysdeps/s390/wcscpy.c (wcscpy): Likewise.
* sysdeps/x86_64/multiarch/wcscpy.c (wcscpy): Likewise.
* wcsmbs/wcscpy.c (wcscpy): Add
* sysdeps/x86_64/multiarch/wcscpy-c.c (WCSCPY): Adjust macro to
use generic implementation.
* wcsmbs/wcscat.c (wcscat): Rewrite using wcslen and wcscpy.
This commit is contained in:
13
ChangeLog
13
ChangeLog
@@ -1,5 +1,18 @@
|
|||||||
2019-02-27 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
2019-02-27 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||||
|
|
||||||
|
* include/wchar.h (__wcscpy): New prototype.
|
||||||
|
* sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy-ppc32.c
|
||||||
|
(__wcscpy): Route internal symbol to generic implementation.
|
||||||
|
* sysdeps/powerpc/powerpc32/power4/multiarch/wcscpy.c (wcscpy):
|
||||||
|
Add internal __wcscpy alias.
|
||||||
|
* sysdeps/powerpc/powerpc64/multiarch/wcscpy.c (wcscpy): Likewise.
|
||||||
|
* sysdeps/s390/wcscpy.c (wcscpy): Likewise.
|
||||||
|
* sysdeps/x86_64/multiarch/wcscpy.c (wcscpy): Likewise.
|
||||||
|
* wcsmbs/wcscpy.c (wcscpy): Add
|
||||||
|
* sysdeps/x86_64/multiarch/wcscpy-c.c (WCSCPY): Adjust macro to
|
||||||
|
use generic implementation.
|
||||||
|
* wcsmbs/wcscat.c (wcscat): Rewrite using wcslen and wcscpy.
|
||||||
|
|
||||||
* wcsmbs/wcpncpy.c (__wcpcpy): Rewrite using wcslen, wmemcpy, and
|
* wcsmbs/wcpncpy.c (__wcpcpy): Rewrite using wcslen, wmemcpy, and
|
||||||
wmemset.
|
wmemset.
|
||||||
|
|
||||||
|
@@ -182,6 +182,10 @@ extern size_t __wcsnrtombs (char *__restrict __dst,
|
|||||||
size_t __nwc, size_t __len,
|
size_t __nwc, size_t __len,
|
||||||
__mbstate_t *__restrict __ps)
|
__mbstate_t *__restrict __ps)
|
||||||
attribute_hidden;
|
attribute_hidden;
|
||||||
|
extern wchar_t *__wcscpy (wchar_t *__restrict __dest,
|
||||||
|
const wchar_t *__restrict __src)
|
||||||
|
attribute_hidden __nonnull ((1, 2));
|
||||||
|
libc_hidden_proto (__wcscpy)
|
||||||
extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
|
extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
|
||||||
const wchar_t *__restrict __src, size_t __n);
|
const wchar_t *__restrict __src, size_t __n);
|
||||||
extern wchar_t *__wcpcpy (wchar_t *__dest, const wchar_t *__src);
|
extern wchar_t *__wcpcpy (wchar_t *__dest, const wchar_t *__src);
|
||||||
|
@@ -17,10 +17,11 @@
|
|||||||
|
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#if IS_IN (libc)
|
|
||||||
# define WCSCPY __wcscpy_ppc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern __typeof (wcscpy) __wcscpy_ppc;
|
extern __typeof (wcscpy) __wcscpy_ppc;
|
||||||
|
|
||||||
|
#define WCSCPY __wcscpy_ppc
|
||||||
#include <wcsmbs/wcscpy.c>
|
#include <wcsmbs/wcscpy.c>
|
||||||
|
|
||||||
|
#ifdef SHARED
|
||||||
|
__hidden_ver1 (__wcscpy_ppc, __GI___wcscpy, __wcscpy_ppc);
|
||||||
|
#endif
|
||||||
|
@@ -17,20 +17,20 @@
|
|||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#if IS_IN (libc)
|
#if IS_IN (libc)
|
||||||
|
# define wcscpy __redirect_wcscpy
|
||||||
# include <wchar.h>
|
# include <wchar.h>
|
||||||
# include <shlib-compat.h>
|
# undef wcscpy
|
||||||
# include "init-arch.h"
|
# include "init-arch.h"
|
||||||
|
|
||||||
extern __typeof (wcscpy) __wcscpy_ppc attribute_hidden;
|
extern __typeof (__redirect_wcscpy) __wcscpy_ppc attribute_hidden;
|
||||||
extern __typeof (wcscpy) __wcscpy_power6 attribute_hidden;
|
extern __typeof (__redirect_wcscpy) __wcscpy_power6 attribute_hidden;
|
||||||
extern __typeof (wcscpy) __wcscpy_power7 attribute_hidden;
|
extern __typeof (__redirect_wcscpy) __wcscpy_power7 attribute_hidden;
|
||||||
|
|
||||||
libc_ifunc (wcscpy,
|
libc_ifunc_redirected (__redirect_wcscpy, wcscpy,
|
||||||
(hwcap & PPC_FEATURE_HAS_VSX)
|
(hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
? __wcscpy_power7 :
|
? __wcscpy_power7 :
|
||||||
(hwcap & PPC_FEATURE_ARCH_2_05)
|
(hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
? __wcscpy_power6
|
? __wcscpy_power6
|
||||||
: __wcscpy_ppc);
|
: __wcscpy_ppc);
|
||||||
#else
|
weak_alias (wcscpy, __wcscpy)
|
||||||
#include <wcsmbs/wcscpy.c>
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,8 +16,9 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#if IS_IN (libc)
|
#define __wcscpy __redirect___wcscpy
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
#undef __wcscpy
|
||||||
#include <shlib-compat.h>
|
#include <shlib-compat.h>
|
||||||
#include "init-arch.h"
|
#include "init-arch.h"
|
||||||
|
|
||||||
@@ -25,12 +26,10 @@ extern __typeof (wcscpy) __wcscpy_ppc attribute_hidden;
|
|||||||
extern __typeof (wcscpy) __wcscpy_power6 attribute_hidden;
|
extern __typeof (wcscpy) __wcscpy_power6 attribute_hidden;
|
||||||
extern __typeof (wcscpy) __wcscpy_power7 attribute_hidden;
|
extern __typeof (wcscpy) __wcscpy_power7 attribute_hidden;
|
||||||
|
|
||||||
libc_ifunc (wcscpy,
|
libc_ifunc_redirected (__redirect___wcscpy, __wcscpy,
|
||||||
(hwcap & PPC_FEATURE_HAS_VSX)
|
(hwcap & PPC_FEATURE_HAS_VSX)
|
||||||
? __wcscpy_power7 :
|
? __wcscpy_power7 :
|
||||||
(hwcap & PPC_FEATURE_ARCH_2_05)
|
(hwcap & PPC_FEATURE_ARCH_2_05)
|
||||||
? __wcscpy_power6
|
? __wcscpy_power6
|
||||||
: __wcscpy_ppc);
|
: __wcscpy_ppc);
|
||||||
#else
|
weak_alias (__wcscpy, wcscpy)
|
||||||
#include <wcsmbs/wcscpy.c>
|
|
||||||
#endif
|
|
||||||
|
@@ -30,9 +30,11 @@ extern __typeof (wcscpy) WCSCPY_C attribute_hidden;
|
|||||||
extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden;
|
extern __typeof (wcscpy) WCSCPY_Z13 attribute_hidden;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
s390_libc_ifunc_expr (wcscpy, wcscpy,
|
s390_libc_ifunc_expr (wcscpy, __wcscpy,
|
||||||
(HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX))
|
(HAVE_WCSCPY_Z13 && (hwcap & HWCAP_S390_VX))
|
||||||
? WCSCPY_Z13
|
? WCSCPY_Z13
|
||||||
: WCSCPY_DEFAULT
|
: WCSCPY_DEFAULT
|
||||||
)
|
)
|
||||||
|
weak_alias (__wcscpy, wcscpy)
|
||||||
|
libc_hidden_def (__wcscpy)
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
#if IS_IN (libc)
|
#if IS_IN (libc)
|
||||||
# define wcscpy __wcscpy_sse2
|
# define WCSCPY __wcscpy_sse2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wcsmbs/wcscpy.c"
|
#include <wcsmbs/wcscpy.c>
|
||||||
|
@@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
/* Define multiple versions only for the definition in libc. */
|
/* Define multiple versions only for the definition in libc. */
|
||||||
#if IS_IN (libc)
|
#if IS_IN (libc)
|
||||||
# define wcscpy __redirect_wcscpy
|
# define __wcscpy __redirect_wcscpy
|
||||||
# include <wchar.h>
|
# include <wchar.h>
|
||||||
# undef wcscpy
|
# undef __wcscpy
|
||||||
|
|
||||||
# define SYMBOL_NAME wcscpy
|
# define SYMBOL_NAME wcscpy
|
||||||
# include <init-arch.h>
|
# include <init-arch.h>
|
||||||
@@ -40,5 +40,10 @@ IFUNC_SELECTOR (void)
|
|||||||
return OPTIMIZE (sse2);
|
return OPTIMIZE (sse2);
|
||||||
}
|
}
|
||||||
|
|
||||||
libc_ifunc_redirected (__redirect_wcscpy, wcscpy, IFUNC_SELECTOR ());
|
libc_ifunc_redirected (__redirect_wcscpy, __wcscpy, IFUNC_SELECTOR ());
|
||||||
|
weak_alias (__wcscpy, wcscpy)
|
||||||
|
# ifdef SHARED
|
||||||
|
__hidden_ver1 (__wcscpy, __GI___wcscpy, __redirect_wcscpy)
|
||||||
|
__attribute__((visibility ("hidden"))) __attribute_copy__ (wcscpy);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
@@ -26,26 +26,7 @@
|
|||||||
wchar_t *
|
wchar_t *
|
||||||
__wcscat (wchar_t *dest, const wchar_t *src)
|
__wcscat (wchar_t *dest, const wchar_t *src)
|
||||||
{
|
{
|
||||||
wchar_t *s1 = dest;
|
__wcscpy (dest + __wcslen (dest), src);
|
||||||
const wchar_t *s2 = src;
|
|
||||||
wchar_t c;
|
|
||||||
|
|
||||||
/* Find the end of the string. */
|
|
||||||
do
|
|
||||||
c = *s1++;
|
|
||||||
while (c != L'\0');
|
|
||||||
|
|
||||||
/* Make S1 point before the next character, so we can increment
|
|
||||||
it while memory is read (wins on pipelined cpus). */
|
|
||||||
s1 -= 2;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = *s2++;
|
|
||||||
*++s1 = c;
|
|
||||||
}
|
|
||||||
while (c != L'\0');
|
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
#ifndef WCSCAT
|
#ifndef WCSCAT
|
||||||
|
@@ -20,13 +20,13 @@
|
|||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef WCSCPY
|
#ifdef WCSCPY
|
||||||
# define WCSCPY wcscpy
|
# define __wcscpy WCSCPY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Copy SRC to DEST. */
|
/* Copy SRC to DEST. */
|
||||||
wchar_t *
|
wchar_t *
|
||||||
WCSCPY (wchar_t *dest, const wchar_t *src)
|
__wcscpy (wchar_t *dest, const wchar_t *src)
|
||||||
{
|
{
|
||||||
wint_t c;
|
wint_t c;
|
||||||
wchar_t *wcp;
|
wchar_t *wcp;
|
||||||
@@ -58,3 +58,7 @@ WCSCPY (wchar_t *dest, const wchar_t *src)
|
|||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
#ifndef WCSCPY
|
||||||
|
weak_alias (__wcscpy, wcscpy)
|
||||||
|
libc_hidden_def (__wcscpy)
|
||||||
|
#endif
|
||||||
|
Reference in New Issue
Block a user