]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fix loop construction to functions calls
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Fri, 21 Jun 2013 00:40:55 +0000 (19:40 -0500)
committerRyan S. Arnold <rsa@linux.vnet.ibm.com>
Fri, 26 Jul 2013 17:56:47 +0000 (12:56 -0500)
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.
(backported from commit 85c2e6110c9a01ec817c30f1b7e20549d7229987)

This backport excluded the benchmark tests from the original commit.

ChangeLog
config.h.in
configure
configure.in
include/libc-symbols.h
string/memmove.c
string/memset.c
string/test-memmove.c
string/test-memset.c

index 685083b118a7e08af6b98cb1c3ed1ea88becd41a..bf91984fd36bafb7ed318edd3bdc185ec247a00b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+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.
+       * configure: Regenerated.
+
 2013-06-28  Ryan S. Arnold  <rsa@linux.vnet.ibm.com>
 
        * sysdeps/powerpc/Makefile: Add comment about generating an offset to
index f3fe6b88bef9aae06576c5cff17d7bb61e9531d7..b34aac2f45f1addc5285cbfd794b8556c34da0f5 100644 (file)
@@ -69,6 +69,9 @@
 /* Define if the compiler supports __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
    (gcc on ix86 only).  */
 #undef USE_REGPARMS
index 8799b7de785e813e5a6d458153213876a5a9a741..99e85bea679e8f8bf3b255923ed095cecfb72d6a 100755 (executable)
--- a/configure
+++ b/configure
@@ -605,6 +605,7 @@ have_selinux
 have_libcap
 have_libaudit
 LIBGD
+libc_cv_cc_loop_to_function
 libc_cv_cc_submachine
 exceptions
 gnu89_inline
@@ -7164,6 +7165,38 @@ $as_echo "$libc_cv_cc_submachine" >&6; }
 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_n "checking for libgd... " >&6; }
 if test "$with_gd" != "no"; then
index d369382264e5dd3d59ceb424462ab3da077c6b04..379e77a2500a89b9742ed014539551b66f0d5bd9 100644 (file)
@@ -1928,6 +1928,24 @@ if test -n "$submachine"; then
 fi
 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.
 AC_MSG_CHECKING(for libgd)
 if test "$with_gd" != "no"; then
index a626d593db0cec521b871670736f10a5b16bef66..8f2c0467f0969db13846633fd95044f571c998a4 100644 (file)
@@ -783,4 +783,14 @@ for linking")
 #define libc_ifunc_hidden_def(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 */
index bf7dcc162770503ed62a262f627bfa526fc5a0d7..c59e7a9c2a640f7df6cc099bf88eac40eabb8913 100644 (file)
@@ -41,6 +41,7 @@
 #endif
 
 rettype
+inhibit_loop_to_libcall
 MEMMOVE (a1, a2, len)
      a1const void *a1;
      a2const void *a2;
index 036cb5f624f5df441d15fea4020a9be670271ac3..eb83c1b5a81badde7be4b739a2ad26332432f355 100644 (file)
@@ -21,6 +21,7 @@
 #undef memset
 
 void *
+inhibit_loop_to_libcall
 memset (dstpp, c, len)
      void *dstpp;
      int c;
index 13c5aff8a29029130642d4b6cff4130b63d748fb..0a969c34efb07d8d22d24bcca1ce2f8d385d1644 100644 (file)
@@ -47,6 +47,7 @@ IMPL (memmove, 1)
 #endif
 
 char *
+inhibit_loop_to_libcall
 simple_memmove (char *dst, const char *src, size_t n)
 {
   char *ret = dst;
index af85a28762a236cfbcf2872fdeee47ab55f6b64a..04320305fbefda99595ae2093084ba67f48be7b0 100644 (file)
@@ -64,6 +64,7 @@ builtin_memset (char *s, int c, size_t n)
 #endif
 
 char *
+inhibit_loop_to_libcall
 simple_memset (char *s, int c, size_t n)
 {
   char *r = s, *end = s + n;