aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-02-19 11:24:56 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2003-02-19 10:24:56 +0000
commitc001c39bbbd67012dc85d861be94c41a67ee7063 (patch)
treec7d690d5f5278e78050af52ff4cb43db39d2106c /gcc/cgraph.c
parent8d928fb1404300cdd23a636fd0d7ce70773d4f53 (diff)
downloadgcc-c001c39bbbd67012dc85d861be94c41a67ee7063.zip
gcc-c001c39bbbd67012dc85d861be94c41a67ee7063.tar.gz
gcc-c001c39bbbd67012dc85d861be94c41a67ee7063.tar.bz2
cgraph.c (NPREDECESORC, [...]): Kill.
* cgraph.c (NPREDECESORC, SET_NPREDECESORS): Kill. (cgraph_expand_function): Rewrite. * gcc.dg/funcorder.c: New test. From-SVN: r63098
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c92
1 files changed, 53 insertions, 39 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 5b58049..f1fffca 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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. */