Fix loop construction to functions calls

Check wheter the compiler has the option -fno-tree-loop-distribute-patterns
to inhibit loop transformation to library calls and uses it on memset
and memmove default implementation to avoid recursive calls.
This commit is contained in:
Adhemerval Zanella 2013-06-20 19:40:55 -05:00
parent b8c792af85
commit 85c2e6110c
11 changed files with 86 additions and 0 deletions

View File

@ -1,3 +1,19 @@
2013-06-20 Adhemerval Zanella <azanella@linux.vnet.ibm.com>
* config.h.in (HAVE_CC_INHIBIT_LOOP_TO_LIBCALL): New define.
* configure.in (libc_cv_cc_loop_to_function): Check if compiler
accepts -fno-tree-loop-distribute-patterns.
* include/libc-symbols.h (inhibit_loop_to_libcall): New macro.
* string/memmove.c (MEMMOVE): Disable loop transformation to avoid
recursive call.
* string/memset.c (memset): Likewise.
* string/test-memmove.c (simple_memmove): Disable loop transformation
to library calls.
* string/test-memset.c (simple_memset): Likewise.
* benchtests/bench-memmove.c (simple_memmove): Likewise.
* benchtests/bench-memset.c (simple_memset): Likewise.
* configure: Regenerated.
2013-06-20 Joseph Myers <joseph@codesourcery.com> 2013-06-20 Joseph Myers <joseph@codesourcery.com>
* math/test-misc.c (main): Ignore fesetround failure when failures * math/test-misc.c (main): Ignore fesetround failure when failures

View File

@ -46,6 +46,7 @@ IMPL (memmove, 1)
#endif #endif
char * char *
inhibit_loop_to_libcall
simple_memmove (char *dst, const char *src, size_t n) simple_memmove (char *dst, const char *src, size_t n)
{ {
char *ret = dst; char *ret = dst;

View File

@ -63,6 +63,7 @@ builtin_memset (char *s, int c, size_t n)
#endif #endif
char * char *
inhibit_loop_to_libcall
simple_memset (char *s, int c, size_t n) simple_memset (char *s, int c, size_t n)
{ {
char *r = s, *end = s + n; char *r = s, *end = s + n;

View File

@ -69,6 +69,9 @@
/* Define if the compiler supports __builtin_memset. */ /* Define if the compiler supports __builtin_memset. */
#undef HAVE_BUILTIN_MEMSET #undef HAVE_BUILTIN_MEMSET
/* Define if compiler accepts -ftree-loop-distribute-patterns. */
#undef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
/* Define if the regparm attribute shall be used for local functions /* Define if the regparm attribute shall be used for local functions
(gcc on ix86 only). */ (gcc on ix86 only). */
#undef USE_REGPARMS #undef USE_REGPARMS

33
configure vendored
View File

@ -598,6 +598,7 @@ have_selinux
have_libcap have_libcap
have_libaudit have_libaudit
LIBGD LIBGD
libc_cv_cc_loop_to_function
libc_cv_cc_submachine libc_cv_cc_submachine
libc_cv_cc_nofma libc_cv_cc_nofma
exceptions exceptions
@ -6933,6 +6934,38 @@ $as_echo "$libc_cv_cc_submachine" >&6; }
fi fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-tree-loop-distribute-patterns with \
__attribute__ ((__optimize__))" >&5
$as_echo_n "checking if $CC accepts -fno-tree-loop-distribute-patterns with \
__attribute__ ((__optimize__))... " >&6; }
if ${libc_cv_cc_loop_to_function+:} false; then :
$as_echo_n "(cached) " >&6
else
cat > conftest.c <<EOF
void
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c'
{ { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
(eval $ac_try) 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }
then
libc_cv_cc_loop_to_function=yes
fi
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_loop_to_function" >&5
$as_echo "$libc_cv_cc_loop_to_function" >&6; }
if test $libc_cv_cc_loop_to_function = yes; then
$as_echo "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgd" >&5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgd" >&5
$as_echo_n "checking for libgd... " >&6; } $as_echo_n "checking for libgd... " >&6; }
if test "$with_gd" != "no"; then if test "$with_gd" != "no"; then

View File

@ -1964,6 +1964,24 @@ if test -n "$submachine"; then
fi fi
AC_SUBST(libc_cv_cc_submachine) AC_SUBST(libc_cv_cc_submachine)
AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \
__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl
cat > conftest.c <<EOF
void
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
foo (void) {}
EOF
libc_cv_cc_loop_to_function=no
if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c])
then
libc_cv_cc_loop_to_function=yes
fi
rm -f conftest*])
if test $libc_cv_cc_loop_to_function = yes; then
AC_DEFINE(HAVE_CC_INHIBIT_LOOP_TO_LIBCALL)
fi
AC_SUBST(libc_cv_cc_loop_to_function)
dnl Check whether we have the gd library available. dnl Check whether we have the gd library available.
AC_MSG_CHECKING(for libgd) AC_MSG_CHECKING(for libgd)
if test "$with_gd" != "no"; then if test "$with_gd" != "no"; then

View File

@ -782,4 +782,14 @@ for linking")
#define libc_ifunc_hidden_def(name) \ #define libc_ifunc_hidden_def(name) \
libc_ifunc_hidden_def1 (__GI_##name, name) libc_ifunc_hidden_def1 (__GI_##name, name)
/* Add the compiler optimization to inhibit loop transformation to library
calls. This is used to avoid recursive calls in memset and memmove
default implementations. */
#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
# define inhibit_loop_to_libcall \
__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
#else
# define inhibit_loop_to_libcall
#endif
#endif /* libc-symbols.h */ #endif /* libc-symbols.h */

View File

@ -41,6 +41,7 @@
#endif #endif
rettype rettype
inhibit_loop_to_libcall
MEMMOVE (a1, a2, len) MEMMOVE (a1, a2, len)
a1const void *a1; a1const void *a1;
a2const void *a2; a2const void *a2;

View File

@ -21,6 +21,7 @@
#undef memset #undef memset
void * void *
inhibit_loop_to_libcall
memset (dstpp, c, len) memset (dstpp, c, len)
void *dstpp; void *dstpp;
int c; int c;

View File

@ -47,6 +47,7 @@ IMPL (memmove, 1)
#endif #endif
char * char *
inhibit_loop_to_libcall
simple_memmove (char *dst, const char *src, size_t n) simple_memmove (char *dst, const char *src, size_t n)
{ {
char *ret = dst; char *ret = dst;

View File

@ -64,6 +64,7 @@ builtin_memset (char *s, int c, size_t n)
#endif #endif
char * char *
inhibit_loop_to_libcall
simple_memset (char *s, int c, size_t n) simple_memset (char *s, int c, size_t n)
{ {
char *r = s, *end = s + n; char *r = s, *end = s + n;