static struct cgraph_edge *create_edge (struct cgraph_node *,
struct cgraph_node *);
-static void cgraph_remove_edge (struct cgraph_node *, struct cgraph_node *);
static hashval_t hash_node (const void *);
static int eq_node (const void *, const void *);
slot = (struct cgraph_node **)
htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE
- (DECL_ASSEMBLER_NAME (decl)), 1);
+ (DECL_ASSEMBLER_NAME (decl)), INSERT);
if (*slot)
return *slot;
node = ggc_alloc_cleared (sizeof (*node));
slot = (struct cgraph_node **)
htab_find_slot_with_hash (cgraph_hash, id,
- IDENTIFIER_HASH_VALUE (id), 0);
+ IDENTIFIER_HASH_VALUE (id), NO_INSERT);
if (!slot)
return NULL;
return *slot;
/* Remove the edge from CALLER to CALLEE in the cgraph. */
-static void
+void
cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee)
{
struct cgraph_edge **edge, **edge2;
slot =
htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
- (node->decl)), 1);
+ (node->decl)), NO_INSERT);
htab_clear_slot (cgraph_hash, slot);
/* Do not free the structure itself so the walk over chain can continue. */
}
-/* Notify finalize_compilation_unit that given node is reachable
- or needed. */
+/* Notify finalize_compilation_unit that given node is reachable. */
+
void
-cgraph_mark_needed_node (struct cgraph_node *node, int needed)
+cgraph_mark_reachable_node (struct cgraph_node *node)
{
- if (needed)
- node->needed = 1;
-
- if (!node->reachable && DECL_SAVED_TREE (node->decl))
+ if (!node->reachable && node->local.finalized)
{
+ notice_global_symbol (node->decl);
node->reachable = 1;
node->next_needed = cgraph_nodes_queue;
cgraph_nodes_queue = node;
- notice_global_symbol (node->decl);
/* At the moment frontend automatically emits all nested functions. */
if (node->nested)
for (node2 = node->nested; node2; node2 = node2->next_nested)
if (!node2->reachable)
- cgraph_mark_needed_node (node2, 0);
+ cgraph_mark_reachable_node (node2);
}
}
}
+/* Likewise indicate that a node is needed, i.e. reachable via some
+ external means. */
+
+void
+cgraph_mark_needed_node (struct cgraph_node *node)
+{
+ node->needed = 1;
+ cgraph_mark_reachable_node (node);
+}
/* Record call from CALLER to CALLEE */
{
struct cgraph_node *node;
- fprintf (f, "\nCallgraph:\n\n");
+ fprintf (f, "callgraph:\n\n");
for (node = cgraph_nodes; node; node = node->next)
{
struct cgraph_edge *edge;
- fprintf (f, "%s", cgraph_node_name (node));
+ fprintf (f, "%s:", cgraph_node_name (node));
if (node->local.self_insns)
fprintf (f, " %i insns", node->local.self_insns);
+ if (node->global.insns && node->global.insns != node->local.self_insns)
+ fprintf (f, " (%i after inlining)", node->global.insns);
if (node->origin)
fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
if (node->needed)
if (DECL_SAVED_TREE (node->decl))
fprintf (f, " tree");
+ if (node->local.local)
+ fprintf (f, " local");
if (node->local.disregard_inline_limits)
fprintf (f, " always_inline");
else if (node->local.inlinable)
fprintf (f, " inlinable");
- if (node->global.insns && node->global.insns != node->local.self_insns)
- fprintf (f, " %i insns after inlining", node->global.insns);
if (node->global.cloned_times > 1)
fprintf (f, " cloned %ix", node->global.cloned_times);
- fprintf (f, "\n called by :");
+ fprintf (f, "\n called by: ");
for (edge = node->callers; edge; edge = edge->next_caller)
{
fprintf (f, "%s ", cgraph_node_name (edge->caller));
slot = (struct cgraph_varpool_node **)
htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
- 1);
+ INSERT);
if (*slot)
return *slot;
node = ggc_alloc_cleared (sizeof (*node));
slot = (struct cgraph_varpool_node **)
htab_find_slot_with_hash (cgraph_varpool_hash, id,
- IDENTIFIER_HASH_VALUE (id), 0);
+ IDENTIFIER_HASH_VALUE (id), NO_INSERT);
if (!slot)
return NULL;
return *slot;
cgraph_varpool_finalize_decl (tree decl)
{
struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
-
- if (node->needed && !node->finalized)
+
+ /* The first declaration of a variable that comes through this function
+ decides whether it is global (in C, has external linkage)
+ or local (in C, has internal linkage). So do nothing more
+ if this function has already run. */
+ if (node->finalized)
+ return;
+ if (node->needed)
{
node->next_needed = cgraph_varpool_nodes_queue;
cgraph_varpool_nodes_queue = node;
+ notice_global_symbol (decl);
}
node->finalized = true;