summaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-13 14:35:10 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2008-09-13 14:35:10 +0000
commite83fcabc74404211d634ff3d313368bb86cb3fb3 (patch)
tree3fc2f320e79fec412a2671fffbe0c677f5c15b35 /gcc/cgraph.c
parent0db724d8ccfe1bb6340d96218e9b947587f5201b (diff)
downloadgcc-e83fcabc74404211d634ff3d313368bb86cb3fb3.tar.gz
* cgraph.c (free_edges): New variable.
(NEXT_FREE_EDGE): New macro. (cgraph_free_edge): New function. (cgraph_remove_edge): Call cgraph_remove_edge_1. (cgraph_node_remove_callees): Likewise. (cgraph_node_remove_callers): Likewise. (cgraph_create_edge): Reuse edges from the free list. Do not update uid if doing so. (cgraph_remove_*_hook): Add free call. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140341 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 67a42ffba6b..89a083a8a17 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -176,6 +176,12 @@ 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 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. */
+#define NEXT_FREE_EDGE(EDGE) (EDGE)->prev_caller
/* Register HOOK to be called with DATA on each removed edge. */
struct cgraph_edge_hook_list *
@@ -203,6 +209,7 @@ cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *entry)
while (*ptr != entry)
ptr = &(*ptr)->next;
*ptr = entry->next;
+ free (entry);
}
/* Call all edge removal hooks. */
@@ -243,6 +250,7 @@ cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *entry)
while (*ptr != entry)
ptr = &(*ptr)->next;
*ptr = entry->next;
+ free (entry);
}
/* Call all node removal hooks. */
@@ -283,6 +291,7 @@ cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *entry)
while (*ptr != entry)
ptr = &(*ptr)->next;
*ptr = entry->next;
+ free (entry);
}
/* Call all node removal hooks. */
@@ -323,6 +332,7 @@ cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *entry)
while (*ptr != entry)
ptr = &(*ptr)->next;
*ptr = entry->next;
+ free (entry);
}
/* Call all edge duplication hooks. */
@@ -364,6 +374,7 @@ cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *entry)
while (*ptr != entry)
ptr = &(*ptr)->next;
*ptr = entry->next;
+ free (entry);
}
/* Call all node duplication hooks. */
@@ -635,7 +646,7 @@ struct cgraph_edge *
cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gimple call_stmt, gcov_type count, int freq, int nest)
{
- struct cgraph_edge *edge = GGC_NEW (struct cgraph_edge);
+ struct cgraph_edge *edge;
#ifdef ENABLE_CHECKING
/* This is rather pricely check possibly trigerring construction of call stmt
@@ -645,6 +656,17 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (is_gimple_call (call_stmt));
+ if (free_edges)
+ {
+ edge = free_edges;
+ free_edges = NEXT_FREE_EDGE (edge);
+ }
+ else
+ {
+ edge = GGC_NEW (struct cgraph_edge);
+ edge->uid = cgraph_edge_max_uid++;
+ }
+
if (!callee->analyzed)
edge->inline_failed = N_("function body not available");
else if (callee->local.redefined_extern_inline)
@@ -677,7 +699,6 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (freq <= CGRAPH_FREQ_MAX);
edge->loop_nest = nest;
edge->indirect_call = 0;
- edge->uid = cgraph_edge_max_uid++;
if (caller->call_site_hash)
{
void **slot;
@@ -722,17 +743,36 @@ cgraph_edge_remove_caller (struct cgraph_edge *e)
htab_hash_pointer (e->call_stmt));
}
+/* Put the edge onto the free list. */
+
+static void
+cgraph_free_edge (struct cgraph_edge *e)
+{
+ int uid = e->uid;
+
+ /* Clear out the edge so we do not dangle pointers. */
+ memset (e, 0, sizeof (e));
+ e->uid = uid;
+ NEXT_FREE_EDGE (e) = free_edges;
+ free_edges = e;
+}
+
/* Remove the edge E in the cgraph. */
void
cgraph_remove_edge (struct cgraph_edge *e)
{
+ /* Call all edge removal hooks. */
cgraph_call_edge_removal_hooks (e);
+
/* Remove from callers list of the callee. */
cgraph_edge_remove_callee (e);
/* Remove from callees list of the callers. */
cgraph_edge_remove_caller (e);
+
+ /* Put the edge onto the free list. */
+ cgraph_free_edge (e);
}
/* Redirect callee of E to N. The function does not update underlying
@@ -814,6 +854,7 @@ cgraph_node_remove_callees (struct cgraph_node *node)
{
cgraph_call_edge_removal_hooks (e);
cgraph_edge_remove_callee (e);
+ cgraph_free_edge (e);
}
node->callees = NULL;
if (node->call_site_hash)
@@ -837,6 +878,7 @@ cgraph_node_remove_callers (struct cgraph_node *node)
{
cgraph_call_edge_removal_hooks (e);
cgraph_edge_remove_caller (e);
+ cgraph_free_edge (e);
}
node->callers = NULL;
}