OSDN Git Service

* cgraph.c (NPREDECESORC, SET_NPREDECESORS): Kill.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Feb 2003 10:24:56 +0000 (10:24 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Feb 2003 10:24:56 +0000 (10:24 +0000)
(cgraph_expand_function): Rewrite.

* gcc.dg/funcorder.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63098 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/funcorder.c [new file with mode: 0644]

index 22d7092..34696c6 100644 (file)
@@ -1,3 +1,8 @@
+Tue Feb 18 23:50:59 CET 2003  Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.c (NPREDECESORC, SET_NPREDECESORS): Kill.
+       (cgraph_expand_function): Rewrite.
+
 2003-02-18  Matt Austern <austern@apple.com>
        * toplev.c, langhooks.c, langhooks-def.h: Move
        write_global_declarations from toplev.c to langhooks.c. 
index 5b58049..f1fffca 100644 (file)
@@ -420,11 +420,6 @@ cgraph_finalize_compilation_unit ()
   ggc_collect ();
 }
 
-/* Expand all functions that must be output.  */
-
-#define NPREDECESORS(node) ((size_t) (node)->aux)
-#define SET_NPREDECESORS(node, n) ((node)->aux = (void *) (size_t) (n))
-
 /* Figure out what functions we want to assemble.  */
 
 static void
@@ -476,56 +471,75 @@ cgraph_expand_function (node)
 static void
 cgraph_expand_functions ()
 {
-  struct cgraph_node *node;
+  struct cgraph_node *node, *node2;
   struct cgraph_node **stack =
     xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
+  struct cgraph_node **order =
+    xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
   int stack_size = 0;
-  struct cgraph_edge *edge;
+  int order_pos = 0;
+  struct cgraph_edge *edge, last;
+  int i;
 
   cgraph_mark_functions_to_output ();
 
+  /*  We have to deal with cycles nicely, so use depth first traversal
+      algorithm.  Ignore the fact that some functions won't need to be output
+      and put them into order as well, so we get dependencies right trought inlined
+      functions.  */
+  for (node = cgraph_nodes; node; node = node->next)
+    node->aux = NULL;
   for (node = cgraph_nodes; node; node = node->next)
-    if (node->output)
+    if (node->output && !node->aux)
       {
-       int n = 0;
-       for (edge = node->callees; edge; edge = edge->next_callee)
-         if (edge->callee->output)
-           n++;
-       SET_NPREDECESORS (node, n);
-       if (n == 0)
-         stack[stack_size++] = node;
+       node2 = node;
+       if (!node->callers)
+         node->aux = &last;
+       else
+         node->aux = node->callers;
+       while (node2)
+         {
+           while (node2->aux != &last)
+             {
+               edge = node2->aux;
+               if (edge->next_caller)
+                 node2->aux = edge->next_caller;
+               else
+                 node2->aux = &last;
+               if (!edge->caller->aux)
+                 {
+                   if (!edge->caller->callers)
+                     edge->caller->aux = &last;
+                   else
+                     edge->caller->aux = edge->caller->callers;
+                   stack[stack_size++] = node2;
+                   node2 = edge->caller;
+                   break;
+                 }
+             }
+           if (node2->aux == &last)
+             {
+               order[order_pos++] = node2;
+               if (stack_size)
+                 node2 = stack[--stack_size];
+               else
+                 node2 = NULL;
+             }
+         }
       }
-  while (1)
+  for (i = order_pos - 1; i >=0; i--)
     {
-      struct cgraph_node *minnode;
-      while (stack_size)
+      node = order[i];
+      if (node->output)
        {
-         node = stack[--stack_size];
-         node->output = 0;
-
-         for (edge = node->callers; edge; edge = edge->next_caller)
-           if (edge->caller->output)
-             {
-               SET_NPREDECESORS (edge->caller,
-                                 NPREDECESORS (edge->caller) - 1);
-               if (!NPREDECESORS (edge->caller))
-                 stack[stack_size++] = edge->caller;
-             }
          if (!node->reachable)
            abort ();
+         node->output = 0;
          cgraph_expand_function (node);
        }
-      minnode = NULL;
-      /* We found cycle.  Break it and try again.  */
-      for (node = cgraph_nodes; node; node = node->next)
-       if (node->output
-           && (!minnode
-               || NPREDECESORS (minnode) > NPREDECESORS (node)))
-         minnode = node;
-      if (!minnode)
-       return;
-      stack[stack_size++] = minnode;
     }
+  free (stack);
+  free (order);
 }
 
 /* Perform simple optimizations based on callgraph.  */
index 9d41b1a..0c352ae 100644 (file)
@@ -1,3 +1,7 @@
+Tue Feb 18 23:28:53 CET 2003  Jan Hubicka  <jh@suse.cz>
+
+       * gcc.dg/funcorder.c: New test.
+
 2003-02-18  Kazu Hirata  <kazu@cs.umass.edu>
 
        * gcc.c-torture/execute/20030218-1.c: New.
diff --git a/gcc/testsuite/gcc.dg/funcorder.c b/gcc/testsuite/gcc.dg/funcorder.c
new file mode 100644 (file)
index 0000000..0dec72c
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funit-at-a-time" } */
+/* { dg-final { scan-assembler-not "link_error" } } */
+/*  In unit-at-time the functions should be assembled in order
+    e q t main, so we realize that they are pure.  */
+static int mem;
+static int e(void) __attribute__ ((noinline));
+static int q(void) __attribute__ ((noinline));
+static int t(void) __attribute__ ((noinline));
+main()
+{
+       return t();
+}
+static t()
+{
+       int r,e;
+       if (mem)
+               t();
+       e=mem;
+       r=q();
+       if (e!=mem)
+               link_error();
+       return r;
+}
+static int e()
+{
+       return 0;
+}
+static int q()
+{
+       int t=mem,r;
+       r=e();
+       if (t!=mem)
+               link_error();
+       return r;
+}