comparison lib/alloca.c @ 15304:578f64214a48

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.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 20 Jun 2011 15:03:03 -0700
parents f3a03b79bd9b
children be4eea839ea6
comparison
equal deleted inserted replaced
15303:5fa23c9b72d6 15304:578f64214a48
91 # else /* STACK_DIRECTION == 0; need run-time code. */ 91 # else /* STACK_DIRECTION == 0; need run-time code. */
92 92
93 static int stack_dir; /* 1 or -1 once known. */ 93 static int stack_dir; /* 1 or -1 once known. */
94 # define STACK_DIR stack_dir 94 # define STACK_DIR stack_dir
95 95
96 static void 96 static int
97 find_stack_direction (char **ptr) 97 find_stack_direction (int *addr, int depth)
98 { 98 {
99 auto char dummy; /* To get stack address. */ 99 int dir, dummy = 0;
100 100 if (! addr)
101 if (*ptr == NULL) 101 addr = &dummy;
102 { /* Initial entry. */ 102 *addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
103 *ptr = ADDRESS_FUNCTION (dummy); 103 dir = depth ? find_stack_direction (addr, depth - 1) : 0;
104 104 return dir + dummy;
105 find_stack_direction (ptr); /* Recurse once. */
106 }
107 else
108 {
109 /* Second entry. */
110 if (ADDRESS_FUNCTION (dummy) > *ptr)
111 stack_dir = 1; /* Stack grew upward. */
112 else
113 stack_dir = -1; /* Stack grew downward. */
114 }
115 } 105 }
116 106
117 # endif /* STACK_DIRECTION == 0 */ 107 # endif /* STACK_DIRECTION == 0 */
118 108
119 /* An "alloca header" is used to: 109 /* An "alloca header" is used to:
152 auto char probe; /* Probes stack depth: */ 142 auto char probe; /* Probes stack depth: */
153 register char *depth = ADDRESS_FUNCTION (probe); 143 register char *depth = ADDRESS_FUNCTION (probe);
154 144
155 # if STACK_DIRECTION == 0 145 # if STACK_DIRECTION == 0
156 if (STACK_DIR == 0) /* Unknown growth direction. */ 146 if (STACK_DIR == 0) /* Unknown growth direction. */
157 { 147 STACK_DIR = find_stack_direction (NULL, (size & 1) + 20);
158 char *addr = NULL; /* Address of first `dummy', once known. */
159 find_stack_direction (&addr);
160 }
161 # endif 148 # endif
162 149
163 /* Reclaim garbage, defined as all alloca'd storage that 150 /* Reclaim garbage, defined as all alloca'd storage that
164 was allocated from deeper in the stack than currently. */ 151 was allocated from deeper in the stack than currently. */
165 152