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