alloca: port to compilers that can optimize like GCC 4.6.0
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 20 Jun 2011 22:03:03 +0000 (15:03 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 20 Jun 2011 22:14:59 +0000 (15:14 -0700)
* lib/alloca.c (find_stack_direction): New signature, taken from
Autoconf git.  This works with GCC 4.6.0.  This code should never
be used with GCC 4.6.0 itself, as GCC has alloca, but it might
be used with other compilers that optimize as well as GCC 4.6.0 does.
(alloca): Adjust to new signature.
* m4/alloca.m4 (__AC_LIBOBJ_ALLOCA) [Autoconf version < 2.69]:
New macro, which patches Autoconf in a similar way.

ChangeLog
lib/alloca.c
m4/alloca.m4

index d595489..967c8b7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2011-06-20  Paul Eggert  <eggert@cs.ucla.edu>
 
+       alloca: port to compilers that can optimize like GCC 4.6.0
+       * lib/alloca.c (find_stack_direction): New signature, taken from
+       Autoconf git.  This works with GCC 4.6.0.  This code should never
+       be used with GCC 4.6.0 itself, as GCC has alloca, but it might
+       be used with other compilers that optimize as well as GCC 4.6.0 does.
+       (alloca): Adjust to new signature.
+       * m4/alloca.m4 (__AC_LIBOBJ_ALLOCA) [Autoconf version < 2.69]:
+       New macro, which patches Autoconf in a similar way.
+
        c-stack: stop worrying about stack direction
        * lib/c-stack.c (find_stack_direction): Remove.
        (segv_handler): Don't worry about stack direction growth, as it's
index 2f5e27e..c7e91ab 100644 (file)
@@ -93,25 +93,15 @@ long i00afunc ();
 static int stack_dir;           /* 1 or -1 once known.  */
 #   define STACK_DIR    stack_dir
 
-static void
-find_stack_direction (char **ptr)
+static int
+find_stack_direction (int *addr, int depth)
 {
-  auto char dummy;              /* To get stack address.  */
-
-  if (*ptr == NULL)
-    {                           /* Initial entry.  */
-      *ptr = ADDRESS_FUNCTION (dummy);
-
-      find_stack_direction (ptr);  /* Recurse once.  */
-    }
-  else
-    {
-      /* Second entry.  */
-      if (ADDRESS_FUNCTION (dummy) > *ptr)
-        stack_dir = 1;          /* Stack grew upward.  */
-      else
-        stack_dir = -1;         /* Stack grew downward.  */
-    }
+  int dir, dummy = 0;
+  if (! addr)
+    addr = &dummy;
+  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+  return dir + dummy;
 }
 
 #  endif /* STACK_DIRECTION == 0 */
@@ -154,10 +144,7 @@ alloca (size_t size)
 
 #  if STACK_DIRECTION == 0
   if (STACK_DIR == 0)           /* Unknown growth direction.  */
-    {
-      char *addr = NULL;        /* Address of first `dummy', once known.  */
-      find_stack_direction (&addr);
-    }
+    STACK_DIR = find_stack_direction (NULL, (size & 1) + 20);
 #  endif
 
   /* Reclaim garbage, defined as all alloca'd storage that
index 689da75..891fc8b 100644 (file)
@@ -1,4 +1,4 @@
-# alloca.m4 serial 11
+# alloca.m4 serial 12
 dnl Copyright (C) 2002-2004, 2006-2007, 2009-2011 Free Software Foundation,
 dnl Inc.
 dnl This file is free software; the Free Software Foundation
@@ -42,3 +42,80 @@ AC_DEFUN([gl_FUNC_ALLOCA],
 # Prerequisites of lib/alloca.c.
 # STACK_DIRECTION is already handled by AC_FUNC_ALLOCA.
 AC_DEFUN([gl_PREREQ_ALLOCA], [:])
+
+# This works around a bug in autoconf <= 2.68.
+# See <http://lists.gnu.org/archive/html/bug-gnulib/2011-06/msg00277.html>.
+
+m4_version_prereq([2.69], [] ,[
+
+# This is taken from the following Autoconf patch:
+# http://git.savannah.gnu.org/cgit/autoconf.git/commit/?id=6cd9f12520b0d6f76d3230d7565feba1ecf29497
+
+# _AC_LIBOBJ_ALLOCA
+# -----------------
+# Set up the LIBOBJ replacement of `alloca'.  Well, not exactly
+# AC_LIBOBJ since we actually set the output variable `ALLOCA'.
+# Nevertheless, for Automake, AC_LIBSOURCES it.
+m4_define([_AC_LIBOBJ_ALLOCA],
+[# The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+AC_LIBSOURCES(alloca.c)
+AC_SUBST([ALLOCA], [\${LIBOBJDIR}alloca.$ac_objext])dnl
+AC_DEFINE(C_ALLOCA, 1, [Define to 1 if using `alloca.c'.])
+
+AC_CACHE_CHECK(whether `alloca.c' needs Cray hooks, ac_cv_os_cray,
+[AC_EGREP_CPP(webecray,
+[#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+], ac_cv_os_cray=yes, ac_cv_os_cray=no)])
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    AC_CHECK_FUNC($ac_func,
+                 [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func,
+                                     [Define to one of `_getb67', `GETB67',
+                                      `getb67' for Cray-2 and Cray-YMP
+                                      systems. This function is required for
+                                      `alloca.c' support on those systems.])
+    break])
+  done
+fi
+
+AC_CACHE_CHECK([stack direction for C alloca],
+              [ac_cv_c_stack_direction],
+[AC_RUN_IFELSE([AC_LANG_SOURCE(
+[AC_INCLUDES_DEFAULT
+int
+find_stack_direction (int *addr, int depth)
+{
+  int dir, dummy = 0;
+  if (! addr)
+    addr = &dummy;
+  *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
+  dir = depth ? find_stack_direction (addr, depth - 1) : 0;
+  return dir + dummy;
+}
+
+int
+main (int argc, char **argv)
+{
+  return find_stack_direction (0, argc + !argv + 20) < 0;
+}])],
+              [ac_cv_c_stack_direction=1],
+              [ac_cv_c_stack_direction=-1],
+              [ac_cv_c_stack_direction=0])])
+AH_VERBATIM([STACK_DIRECTION],
+[/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
+@%:@undef STACK_DIRECTION])dnl
+AC_DEFINE_UNQUOTED(STACK_DIRECTION, $ac_cv_c_stack_direction)
+])# _AC_LIBOBJ_ALLOCA
+])