ce426f
From 5c616c0a75792d2836412d6c4ed5c71e8e754992 Mon Sep 17 00:00:00 2001
ce426f
From: Adhemerval Zanella <azanella@linux.vnet.ibm.com>
ce426f
Date: Thu, 20 Jun 2013 19:40:55 -0500
ce426f
Subject: [PATCH 41/42] Fix loop construction to functions calls
ce426f
ce426f
Check wheter the compiler has the option -fno-tree-loop-distribute-patterns
ce426f
to inhibit loop transformation to library calls and uses it on memset
ce426f
and memmove default implementation to avoid recursive calls.
ce426f
(backported from commit 85c2e6110c9a01ec817c30f1b7e20549d7229987)
ce426f
ce426f
This backport excluded the benchmark tests from the original commit.
ce426f
---
ce426f
 config.h.in            |  3 +++
ce426f
 configure              | 33 +++++++++++++++++++++++++++++++++
ce426f
 configure.in           | 18 ++++++++++++++++++
ce426f
 include/libc-symbols.h | 10 ++++++++++
ce426f
 string/memmove.c       |  1 +
ce426f
 string/memset.c        |  1 +
ce426f
 string/test-memmove.c  |  1 +
ce426f
 string/test-memset.c   |  1 +
ce426f
 9 files changed, 82 insertions(+)
ce426f
ce426f
diff --git glibc-2.17-c758a686/config.h.in glibc-2.17-c758a686/config.h.in
ce426f
index f3fe6b8..b34aac2 100644
ce426f
--- glibc-2.17-c758a686/config.h.in
ce426f
+++ glibc-2.17-c758a686/config.h.in
ce426f
@@ -69,6 +69,9 @@
ce426f
 /* Define if the compiler supports __builtin_memset.  */
ce426f
 #undef	HAVE_BUILTIN_MEMSET
ce426f
 
ce426f
+/* Define if compiler accepts -ftree-loop-distribute-patterns.  */
ce426f
+#undef  HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
ce426f
+
ce426f
 /* Define if the regparm attribute shall be used for local functions
ce426f
    (gcc on ix86 only).  */
ce426f
 #undef	USE_REGPARMS
ce426f
diff --git glibc-2.17-c758a686/configure glibc-2.17-c758a686/configure
ce426f
index 8799b7d..99e85be 100755
ce426f
--- glibc-2.17-c758a686/configure
ce426f
+++ glibc-2.17-c758a686/configure
ce426f
@@ -605,6 +605,7 @@ have_selinux
ce426f
 have_libcap
ce426f
 have_libaudit
ce426f
 LIBGD
ce426f
+libc_cv_cc_loop_to_function
ce426f
 libc_cv_cc_submachine
ce426f
 exceptions
ce426f
 gnu89_inline
ce426f
@@ -7164,6 +7165,38 @@ $as_echo "$libc_cv_cc_submachine" >&6; }
ce426f
 fi
ce426f
 
ce426f
 
ce426f
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC accepts -fno-tree-loop-distribute-patterns with \
ce426f
+__attribute__ ((__optimize__))" >&5
ce426f
+$as_echo_n "checking if $CC accepts -fno-tree-loop-distribute-patterns with \
ce426f
+__attribute__ ((__optimize__))... " >&6; }
ce426f
+if ${libc_cv_cc_loop_to_function+:} false; then :
ce426f
+  $as_echo_n "(cached) " >&6
ce426f
+else
ce426f
+  cat > conftest.c <
ce426f
+void
ce426f
+__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
ce426f
+foo (void) {}
ce426f
+EOF
ce426f
+libc_cv_cc_loop_to_function=no
ce426f
+if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c'
ce426f
+  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
ce426f
+  (eval $ac_try) 2>&5
ce426f
+  ac_status=$?
ce426f
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
ce426f
+  test $ac_status = 0; }; }
ce426f
+then
ce426f
+  libc_cv_cc_loop_to_function=yes
ce426f
+fi
ce426f
+rm -f conftest*
ce426f
+fi
ce426f
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_cc_loop_to_function" >&5
ce426f
+$as_echo "$libc_cv_cc_loop_to_function" >&6; }
ce426f
+if test $libc_cv_cc_loop_to_function = yes; then
ce426f
+  $as_echo "#define HAVE_CC_INHIBIT_LOOP_TO_LIBCALL 1" >>confdefs.h
ce426f
+
ce426f
+fi
ce426f
+
ce426f
+
ce426f
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libgd" >&5
ce426f
 $as_echo_n "checking for libgd... " >&6; }
ce426f
 if test "$with_gd" != "no"; then
ce426f
diff --git glibc-2.17-c758a686/configure.in glibc-2.17-c758a686/configure.in
ce426f
index d369382..379e77a 100644
ce426f
--- glibc-2.17-c758a686/configure.in
ce426f
+++ glibc-2.17-c758a686/configure.in
ce426f
@@ -1928,6 +1928,24 @@ if test -n "$submachine"; then
ce426f
 fi
ce426f
 AC_SUBST(libc_cv_cc_submachine)
ce426f
 
ce426f
+AC_CACHE_CHECK(if $CC accepts -fno-tree-loop-distribute-patterns with \
ce426f
+__attribute__ ((__optimize__)), libc_cv_cc_loop_to_function, [dnl
ce426f
+cat > conftest.c <
ce426f
+void
ce426f
+__attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
ce426f
+foo (void) {}
ce426f
+EOF
ce426f
+libc_cv_cc_loop_to_function=no
ce426f
+if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS -c conftest.c])
ce426f
+then
ce426f
+  libc_cv_cc_loop_to_function=yes
ce426f
+fi
ce426f
+rm -f conftest*])
ce426f
+if test $libc_cv_cc_loop_to_function = yes; then
ce426f
+  AC_DEFINE(HAVE_CC_INHIBIT_LOOP_TO_LIBCALL)
ce426f
+fi
ce426f
+AC_SUBST(libc_cv_cc_loop_to_function)
ce426f
+
ce426f
 dnl Check whether we have the gd library available.
ce426f
 AC_MSG_CHECKING(for libgd)
ce426f
 if test "$with_gd" != "no"; then
ce426f
diff --git glibc-2.17-c758a686/include/libc-symbols.h glibc-2.17-c758a686/include/libc-symbols.h
ce426f
index a626d59..8f2c046 100644
ce426f
--- glibc-2.17-c758a686/include/libc-symbols.h
ce426f
+++ glibc-2.17-c758a686/include/libc-symbols.h
ce426f
@@ -783,4 +783,14 @@ for linking")
ce426f
 #define libc_ifunc_hidden_def(name) \
ce426f
   libc_ifunc_hidden_def1 (__GI_##name, name)
ce426f
 
ce426f
+/* Add the compiler optimization to inhibit loop transformation to library
ce426f
+   calls.  This is used to avoid recursive calls in memset and memmove
ce426f
+   default implementations.  */
ce426f
+#ifdef HAVE_CC_INHIBIT_LOOP_TO_LIBCALL
ce426f
+# define inhibit_loop_to_libcall \
ce426f
+    __attribute__ ((__optimize__ ("-fno-tree-loop-distribute-patterns")))
ce426f
+#else
ce426f
+# define inhibit_loop_to_libcall
ce426f
+#endif
ce426f
+
ce426f
 #endif /* libc-symbols.h */
ce426f
diff --git glibc-2.17-c758a686/string/memmove.c glibc-2.17-c758a686/string/memmove.c
ce426f
index bf7dcc1..c59e7a9 100644
ce426f
--- glibc-2.17-c758a686/string/memmove.c
ce426f
+++ glibc-2.17-c758a686/string/memmove.c
ce426f
@@ -41,6 +41,7 @@
ce426f
 #endif
ce426f
 
ce426f
 rettype
ce426f
+inhibit_loop_to_libcall
ce426f
 MEMMOVE (a1, a2, len)
ce426f
      a1const void *a1;
ce426f
      a2const void *a2;
ce426f
diff --git glibc-2.17-c758a686/string/memset.c glibc-2.17-c758a686/string/memset.c
ce426f
index 036cb5f..eb83c1b 100644
ce426f
--- glibc-2.17-c758a686/string/memset.c
ce426f
+++ glibc-2.17-c758a686/string/memset.c
ce426f
@@ -21,6 +21,7 @@
ce426f
 #undef memset
ce426f
 
ce426f
 void *
ce426f
+inhibit_loop_to_libcall
ce426f
 memset (dstpp, c, len)
ce426f
      void *dstpp;
ce426f
      int c;
ce426f
diff --git glibc-2.17-c758a686/string/test-memmove.c glibc-2.17-c758a686/string/test-memmove.c
ce426f
index 13c5aff..0a969c3 100644
ce426f
--- glibc-2.17-c758a686/string/test-memmove.c
ce426f
+++ glibc-2.17-c758a686/string/test-memmove.c
ce426f
@@ -47,6 +47,7 @@ IMPL (memmove, 1)
ce426f
 #endif
ce426f
 
ce426f
 char *
ce426f
+inhibit_loop_to_libcall
ce426f
 simple_memmove (char *dst, const char *src, size_t n)
ce426f
 {
ce426f
   char *ret = dst;
ce426f
diff --git glibc-2.17-c758a686/string/test-memset.c glibc-2.17-c758a686/string/test-memset.c
ce426f
index af85a28..0432030 100644
ce426f
--- glibc-2.17-c758a686/string/test-memset.c
ce426f
+++ glibc-2.17-c758a686/string/test-memset.c
ce426f
@@ -64,6 +64,7 @@ builtin_memset (char *s, int c, size_t n)
ce426f
 #endif
ce426f
 
ce426f
 char *
ce426f
+inhibit_loop_to_libcall
ce426f
 simple_memset (char *s, int c, size_t n)
ce426f
 {
ce426f
   char *r = s, *end = s + n;
ce426f
-- 
ce426f
1.7.11.7
ce426f