cgraph.h (struct cgraph_edge): Add prev_caller and prev_callee fields.

2005-03-02  Richard Guenther  <rguenth@gcc.gnu.org>

	* cgraph.h (struct cgraph_edge): Add prev_caller and
	prev_callee fields.
	(cgraph_node_remove_callees): Export.
	* cgraph.c (cgraph_create_edge): Initialize prev_caller
	and prev_callee.
	(cgraph_edge_remove_callee): New function.
	(cgraph_edge_remove_caller): Likewise.
	(cgraph_remove_edge): Use.
	(cgraph_redirect_edge_callee): Likewise.
	(cgraph_node_remove_callees): New function.
	(cgraph_node_remove_callers): Likewise.
	(cgraph_remove_node): Use.
	* tree-optimize.c (tree_rest_of_compilation): Use
	cgraph_node_remove_callees instead of manual loop.
	* cgraphunit.c (cgraph_finalize_function): Likewise.
	(cgraph_expand_function): Likewise.
	(cgraph_remove_unreachable_nodes): Likewise.

From-SVN: r95777
This commit is contained in:
Richard Guenther 2005-03-02 11:09:48 +00:00 committed by Richard Biener
parent ceccf46b10
commit 2563c2248f
5 changed files with 109 additions and 34 deletions

View File

@ -1,3 +1,23 @@
2005-03-02 Richard Guenther <rguenth@gcc.gnu.org>
* cgraph.h (struct cgraph_edge): Add prev_caller and
prev_callee fields.
(cgraph_node_remove_callees): Export.
* cgraph.c (cgraph_create_edge): Initialize prev_caller
and prev_callee.
(cgraph_edge_remove_callee): New function.
(cgraph_edge_remove_caller): Likewise.
(cgraph_remove_edge): Use.
(cgraph_redirect_edge_callee): Likewise.
(cgraph_node_remove_callees): New function.
(cgraph_node_remove_callers): Likewise.
(cgraph_remove_node): Use.
* tree-optimize.c (tree_rest_of_compilation): Use
cgraph_node_remove_callees instead of manual loop.
* cgraphunit.c (cgraph_finalize_function): Likewise.
(cgraph_expand_function): Likewise.
(cgraph_remove_unreachable_nodes): Likewise.
2005-03-02 Joseph S. Myers <joseph@codesourcery.com> 2005-03-02 Joseph S. Myers <joseph@codesourcery.com>
PR c/8927 PR c/8927

View File

@ -96,6 +96,10 @@ The varpool data structure:
#include "output.h" #include "output.h"
#include "intl.h" #include "intl.h"
static void cgraph_node_remove_callers (struct cgraph_node *node);
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
static inline void cgraph_edge_remove_callee (struct cgraph_edge *e);
/* Hash table used to convert declarations into nodes. */ /* Hash table used to convert declarations into nodes. */
static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash; static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
@ -289,30 +293,55 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
edge->caller = caller; edge->caller = caller;
edge->callee = callee; edge->callee = callee;
edge->call_expr = call_expr; edge->call_expr = call_expr;
edge->prev_caller = NULL;
edge->next_caller = callee->callers; edge->next_caller = callee->callers;
if (callee->callers)
callee->callers->prev_caller = edge;
edge->prev_callee = NULL;
edge->next_callee = caller->callees; edge->next_callee = caller->callees;
if (caller->callees)
caller->callees->prev_callee = edge;
caller->callees = edge; caller->callees = edge;
callee->callers = edge; callee->callers = edge;
return edge; return edge;
} }
/* Remove the edge E the cgraph. */ /* Remove the edge E from the list of the callers of the callee. */
static inline void
cgraph_edge_remove_callee (struct cgraph_edge *e)
{
if (e->prev_caller)
e->prev_caller->next_caller = e->next_caller;
if (e->next_caller)
e->next_caller->prev_caller = e->prev_caller;
if (!e->prev_caller)
e->callee->callers = e->next_caller;
}
/* Remove the edge E from the list of the callees of the caller. */
static inline void
cgraph_edge_remove_caller (struct cgraph_edge *e)
{
if (e->prev_callee)
e->prev_callee->next_callee = e->next_callee;
if (e->next_callee)
e->next_callee->prev_callee = e->prev_callee;
if (!e->prev_callee)
e->caller->callees = e->next_callee;
}
/* Remove the edge E in the cgraph. */
void void
cgraph_remove_edge (struct cgraph_edge *e) cgraph_remove_edge (struct cgraph_edge *e)
{ {
struct cgraph_edge **edge, **edge2; /* Remove from callers list of the callee. */
cgraph_edge_remove_callee (e);
for (edge = &e->callee->callers; *edge && *edge != e; /* Remove from callees list of the callers. */
edge = &((*edge)->next_caller)) cgraph_edge_remove_caller (e);
continue;
gcc_assert (*edge);
*edge = (*edge)->next_caller;
for (edge2 = &e->caller->callees; *edge2 && *edge2 != e;
edge2 = &(*edge2)->next_callee)
continue;
gcc_assert (*edge2);
*edge2 = (*edge2)->next_callee;
} }
/* Redirect callee of E to N. The function does not update underlying /* Redirect callee of E to N. The function does not update underlying
@ -321,16 +350,46 @@ cgraph_remove_edge (struct cgraph_edge *e)
void void
cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n) cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
{ {
struct cgraph_edge **edge; /* Remove from callers list of the current callee. */
cgraph_edge_remove_callee (e);
for (edge = &e->callee->callers; *edge && *edge != e; /* Insert to callers list of the new callee. */
edge = &((*edge)->next_caller)) e->prev_caller = NULL;
continue; if (n->callers)
gcc_assert (*edge); n->callers->prev_caller = e;
*edge = (*edge)->next_caller;
e->callee = n;
e->next_caller = n->callers; e->next_caller = n->callers;
n->callers = e; n->callers = e;
e->callee = n;
}
/* Remove all callees from the node. */
void
cgraph_node_remove_callees (struct cgraph_node *node)
{
struct cgraph_edge *e;
/* It is sufficient to remove the edges from the lists of callers of
the callees. The callee list of the node can be zapped with one
assignment. */
for (e = node->callees; e; e = e->next_callee)
cgraph_edge_remove_callee (e);
node->callees = NULL;
}
/* Remove all callers from the node. */
static void
cgraph_node_remove_callers (struct cgraph_node *node)
{
struct cgraph_edge *e;
/* It is sufficient to remove the edges from the lists of callees of
the callers. The caller list of the node can be zapped with one
assignment. */
for (e = node->callers; e; e = e->next_caller)
cgraph_edge_remove_caller (e);
node->callers = NULL;
} }
/* Remove the node from cgraph. */ /* Remove the node from cgraph. */
@ -341,10 +400,8 @@ cgraph_remove_node (struct cgraph_node *node)
void **slot; void **slot;
bool check_dead = 1; bool check_dead = 1;
while (node->callers) cgraph_node_remove_callers (node);
cgraph_remove_edge (node->callers); cgraph_node_remove_callees (node);
while (node->callees)
cgraph_remove_edge (node->callees);
while (node->nested) while (node->nested)
cgraph_remove_node (node->nested); cgraph_remove_node (node->nested);
if (node->origin) if (node->origin)

View File

@ -119,11 +119,13 @@ struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
bool output; bool output;
}; };
struct cgraph_edge GTY((chain_next ("%h.next_caller"))) struct cgraph_edge GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller")))
{ {
struct cgraph_node *caller; struct cgraph_node *caller;
struct cgraph_node *callee; struct cgraph_node *callee;
struct cgraph_edge *prev_caller;
struct cgraph_edge *next_caller; struct cgraph_edge *next_caller;
struct cgraph_edge *prev_callee;
struct cgraph_edge *next_callee; struct cgraph_edge *next_callee;
tree call_expr; tree call_expr;
PTR GTY ((skip (""))) aux; PTR GTY ((skip (""))) aux;
@ -165,6 +167,7 @@ void dump_cgraph (FILE *);
void dump_cgraph_node (FILE *, struct cgraph_node *); void dump_cgraph_node (FILE *, struct cgraph_node *);
void cgraph_remove_edge (struct cgraph_edge *); void cgraph_remove_edge (struct cgraph_edge *);
void cgraph_remove_node (struct cgraph_node *); void cgraph_remove_node (struct cgraph_node *);
void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *, struct cgraph_node *,
tree); tree);

View File

@ -356,8 +356,7 @@ cgraph_finalize_function (tree decl, bool nested)
cgraph_remove_node (n); cgraph_remove_node (n);
} }
while (node->callees) cgraph_node_remove_callees (node);
cgraph_remove_edge (node->callees);
/* We may need to re-queue the node for assembling in case /* We may need to re-queue the node for assembling in case
we already proceeded it and ignored as not needed. */ we already proceeded it and ignored as not needed. */
@ -843,8 +842,7 @@ cgraph_expand_function (struct cgraph_node *node)
DECL_INITIAL (node->decl) = error_mark_node; DECL_INITIAL (node->decl) = error_mark_node;
/* Eliminate all call edges. This is important so the call_expr no longer /* Eliminate all call edges. This is important so the call_expr no longer
points to the dead function body. */ points to the dead function body. */
while (node->callees) cgraph_node_remove_callees (node);
cgraph_remove_edge (node->callees);
} }
} }
@ -1006,8 +1004,7 @@ cgraph_remove_unreachable_nodes (void)
DECL_STRUCT_FUNCTION (node->decl) = NULL; DECL_STRUCT_FUNCTION (node->decl) = NULL;
DECL_INITIAL (node->decl) = error_mark_node; DECL_INITIAL (node->decl) = error_mark_node;
} }
while (node->callees) cgraph_node_remove_callees (node);
cgraph_remove_edge (node->callees);
node->analyzed = false; node->analyzed = false;
} }
else else

View File

@ -656,8 +656,7 @@ tree_rest_of_compilation (tree fndecl)
/* We are not going to maintain the cgraph edges up to date. /* We are not going to maintain the cgraph edges up to date.
Kill it so it won't confuse us. */ Kill it so it won't confuse us. */
while (node->callees) cgraph_node_remove_callees (node);
cgraph_remove_edge (node->callees);
/* Initialize the default bitmap obstack. */ /* Initialize the default bitmap obstack. */
@ -688,8 +687,7 @@ tree_rest_of_compilation (tree fndecl)
{ {
struct cgraph_edge *e; struct cgraph_edge *e;
while (node->callees) cgraph_node_remove_callees (node);
cgraph_remove_edge (node->callees);
node->callees = saved_node->callees; node->callees = saved_node->callees;
saved_node->callees = NULL; saved_node->callees = NULL;
update_inlined_to_pointers (node, node); update_inlined_to_pointers (node, node);