On Mon, Jul 18, 2011 at 11:58:38PM +0200, Jakub Jelinek wrote:
> Especially the FEs and gimplification are highly recursive on more complex
> (especially badly generated) testcases, the following patch attempts to
> increase stack size to 64MB if possible.  It is done in the driver
> (where it can affect the children of the driver early) and also in
> toplev_main to make similar results when invoking the compiler by hand,
> unless mmap of some shared library or some other mmap make it impossible
> to have such a large stack.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, cures
> gcc.c-torture/compile/limits-exprparen.c ICEs on x86_64-linux on all
> -O* levels as well as the testcase from this PR (which is quite large and
> compile time consuming, so not including it in this testcase).

Here is a slightly modified variant which will avoid the setrlimit syscall
if it wouldn't change anything (which is either if the soft limit is already
>= 64MB or the hard limit is not infinity and equal to the soft limit).
At least in toplev_main it is very likely the setrlimit will not be needed
if it has been done in the driver already.

2011-07-19  Jakub Jelinek  <ja...@redhat.com>

        PR c++/49756
        * gcc.c (main): Try to increase RLIMIT_STACK to at least
        64MB if possible.
        * toplev.c (toplev_main): Likewise.

--- gcc/gcc.c.jj        2011-07-08 15:09:38.000000000 +0200
+++ gcc/gcc.c   2011-07-19 10:15:25.000000000 +0200
@@ -6156,6 +6156,24 @@ main (int argc, char **argv)
   signal (SIGCHLD, SIG_DFL);
 #endif
 
+#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) && defined(RLIM_INFINITY)
+  {
+    /* Parsing and gimplification sometimes need quite large stack.
+       Increase stack size limits if possible.  */
+    struct rlimit rlim;
+    if (getrlimit (RLIMIT_STACK, &rlim) == 0
+       && rlim.rlim_cur != RLIM_INFINITY
+       && rlim.rlim_cur < 64 * 1024 * 1024
+       && (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_cur < rlim.rlim_max))
+      {
+       rlim.rlim_cur = 64 * 1024 * 1024;
+       if (rlim.rlim_max != RLIM_INFINITY)
+         rlim.rlim_cur = MIN (rlim.rlim_cur, rlim.rlim_max);
+       setrlimit (RLIMIT_STACK, &rlim);
+      }
+  }
+#endif
+
   /* Allocate the argument vector.  */
   alloc_args ();
 
--- gcc/toplev.c.jj     2011-07-11 10:39:50.000000000 +0200
+++ gcc/toplev.c        2011-07-19 10:15:37.000000000 +0200
@@ -1911,6 +1911,24 @@ do_compile (void)
 int
 toplev_main (int argc, char **argv)
 {
+#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) && defined(RLIM_INFINITY)
+  {
+    /* Parsing and gimplification sometimes need quite large stack.
+       Increase stack size limits if possible.  */
+    struct rlimit rlim;
+    if (getrlimit (RLIMIT_STACK, &rlim) == 0
+       && rlim.rlim_cur != RLIM_INFINITY
+       && rlim.rlim_cur < 64 * 1024 * 1024
+       && (rlim.rlim_max == RLIM_INFINITY || rlim.rlim_cur < rlim.rlim_max))
+      {
+       rlim.rlim_cur = 64 * 1024 * 1024;
+       if (rlim.rlim_max != RLIM_INFINITY)
+         rlim.rlim_cur = MIN (rlim.rlim_cur, rlim.rlim_max);
+       setrlimit (RLIMIT_STACK, &rlim);
+      }
+  }
+#endif
+
   expandargv (&argc, &argv);
 
   /* Initialization of GCC's environment, and diagnostics.  */

        Jakub

Reply via email to