This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix tree-stdarg (PR middle-end/34934)


Hi!

As pointed by richi, in corner cases we might need up to O(n_basic_blocks^2)
edges on the stack in reachable_at_most_once.  Fixed by using VEC instead
of fixed XVECNEW.  Bootstrapped/regtested on x86_64-linux (and the testcase
verified also with --target_board=unix/-m32).  Ok for trunk?

2008-01-24  Jakub Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/34934
	* tree-stdarg.c (reachable_at_most_once): Use VEC vector instead of
	a fixed vector for stack.

	* gcc.c-torture/compile/20080124-1.c: New test.

--- gcc/tree-stdarg.c.jj	2007-11-18 20:14:58.000000000 +0100
+++ gcc/tree-stdarg.c	2008-01-24 13:23:15.000000000 +0100
@@ -1,5 +1,5 @@
 /* Pass computing data for optimizing stdarg functions.
-   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
    Contributed by Jakub Jelinek <jakub@redhat.com>
 
 This file is part of GCC.
@@ -46,9 +46,9 @@ along with GCC; see the file COPYING3.  
 static bool
 reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
 {
-  edge *stack, e;
+  VEC (edge, heap) *stack = NULL;
+  edge e;
   edge_iterator ei;
-  int sp;
   sbitmap visited;
   bool ret;
 
@@ -58,22 +58,18 @@ reachable_at_most_once (basic_block va_a
   if (! dominated_by_p (CDI_DOMINATORS, va_arg_bb, va_start_bb))
     return false;
 
-  stack = XNEWVEC (edge, n_basic_blocks + 1);
-  sp = 0;
-
   visited = sbitmap_alloc (last_basic_block);
   sbitmap_zero (visited);
   ret = true;
 
   FOR_EACH_EDGE (e, ei, va_arg_bb->preds)
-    stack[sp++] = e;
+    VEC_safe_push (edge, heap, stack, e);
 
-  while (sp)
+  while (! VEC_empty (edge, stack))
     {
       basic_block src;
 
-      --sp;
-      e = stack[sp];
+      e = VEC_pop (edge, stack);
       src = e->src;
 
       if (e->flags & EDGE_COMPLEX)
@@ -98,11 +94,11 @@ reachable_at_most_once (basic_block va_a
 	{
 	  SET_BIT (visited, src->index);
 	  FOR_EACH_EDGE (e, ei, src->preds)
-	    stack[sp++] = e;
+	    VEC_safe_push (edge, heap, stack, e);
 	}
     }
 
-  free (stack);
+  VEC_free (edge, heap, stack);
   sbitmap_free (visited);
   return ret;
 }
--- gcc/testsuite/gcc.c-torture/compile/20080124-1.c.jj	2008-01-24 13:35:00.000000000 +0100
+++ gcc/testsuite/gcc.c-torture/compile/20080124-1.c	2008-01-24 13:34:16.000000000 +0100
@@ -0,0 +1,52 @@
+/* PR middle-end/34934 */
+
+#include <stdarg.h>
+
+typedef struct
+{
+  int e[1024];
+  int f;
+} S;
+
+void foo (long *, va_list);
+
+void
+bar (long *x, S *y, int z, ...)
+{
+  int i, j;
+  va_list ap;
+  va_start (ap, z);
+  for (j = y->e[i = 1]; i <= y->f; j = y->e[++i])
+    {
+      switch (z)
+	{
+	case 1:
+	  if (!(*x & 0x00000020))
+	    continue;
+	case 3:
+	  if (!(*x & 0x00000080))
+	    continue;
+	case 9:
+	  if (!(*x & 0x04000000))
+	    continue;
+	case 4:
+	  if (!(*x & 0x00000200))
+	    continue;
+	case 8:
+	  if (!(*x & 0x00100000))
+	    continue;
+	case 6:
+	  if (!(*x & 0x00000100))
+	    continue;
+	case 7:
+	  if (!(*x & 0x00040000))
+	    continue;
+	case 10:
+	  if (!(*x & 0x00000020)
+	      && ((*x & 0x00008000) || (*x & 0x08000000)))
+	    continue;
+	}
+      foo (x, ap);
+    }
+  va_end (ap);
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]