diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2e2db7b87c9..01aa28ec476 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-09-25 Martin Jambor + + * cgraph.c (free_nodes): New variable. + (NEXT_FREE_NODE): New macro. + (cgraph_create_node): Reuse nodes from the free list. Do not + update uid if doing so. + (cgraph_remove_node): Add the node to the free list. + 2008-09-25 Gerald Pfeifer * config/freebsd.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 163ab9dd39f..73dbfb3aa8b 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -177,11 +177,16 @@ struct cgraph_2node_hook_list *first_cgraph_node_duplicated_hook; /* List of hooks triggered when an function is inserted. */ struct cgraph_node_hook_list *first_cgraph_function_insertion_hook; +/* Head of a linked list of unused (freed) call graph nodes. + Do not GTY((delete)) this list so UIDs gets reliably recycled. */ +static GTY(()) struct cgraph_node *free_nodes; /* Head of a linked list of unused (freed) call graph edges. Do not GTY((delete)) this list so UIDs gets reliably recycled. */ static GTY(()) struct cgraph_edge *free_edges; -/* Macro to access the next item in the list of free cgraph edges. */ +/* Macros to access the next item in the list of free cgraph nodes and + edges. */ +#define NEXT_FREE_NODE(NODE) (NODE)->next #define NEXT_FREE_EDGE(EDGE) (EDGE)->prev_caller /* Register HOOK to be called with DATA on each removed edge. */ @@ -417,9 +422,18 @@ cgraph_create_node (void) { struct cgraph_node *node; - node = GGC_CNEW (struct cgraph_node); + if (free_nodes) + { + node = free_nodes; + free_nodes = NEXT_FREE_NODE (node); + } + else + { + node = GGC_CNEW (struct cgraph_node); + node->uid = cgraph_max_uid++; + } + node->next = cgraph_nodes; - node->uid = cgraph_max_uid++; node->pid = -1; node->order = cgraph_order++; if (cgraph_nodes) @@ -933,6 +947,7 @@ cgraph_remove_node (struct cgraph_node *node) void **slot; bool kill_body = false; struct cgraph_node *n; + int uid = node->uid; cgraph_call_node_removal_hooks (node); cgraph_node_remove_callers (node); @@ -1020,7 +1035,13 @@ cgraph_remove_node (struct cgraph_node *node) node->call_site_hash = NULL; } cgraph_n_nodes--; - /* Do not free the structure itself so the walk over chain can continue. */ + + /* Clear out the node to NULL all pointers and add the node to the free + list. */ + memset (node, 0, sizeof(*node)); + node->uid = uid; + NEXT_FREE_NODE (node) = free_nodes; + free_nodes = node; } /* Notify finalize_compilation_unit that given node is reachable. */