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