1 /* Callgraph handling code.
2 Copyright (C) 2003 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
27 #include "langhooks.h"
38 /* The known declarations must not get garbage collected. Callgraph
39 datastructures should not get saved via PCH code since this would
40 make it difficult to extend into intra-module optimizer later. So
41 we store only the references into the array to prevent gabrage
42 collector from deleting live data. */
43 static GTY(()) varray_type known_decls;
45 /* Hash table used to convert declarations into nodes. */
46 static htab_t cgraph_hash = 0;
48 /* The linked list of cgraph nodes. */
49 struct cgraph_node *cgraph_nodes;
51 /* Queue of cgraph nodes scheduled to be lowered. */
52 struct cgraph_node *cgraph_nodes_queue;
54 /* Number of nodes in existence. */
57 /* Set when whole unit has been analyzed so we can access global info. */
58 bool cgraph_global_info_ready = false;
60 /* Hash table used to convert declarations into nodes. */
61 static htab_t cgraph_varpool_hash = 0;
63 /* Queue of cgraph nodes scheduled to be lowered and output. */
64 struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
66 /* Number of nodes in existence. */
67 int cgraph_varpool_n_nodes;
69 static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
70 struct cgraph_node *));
71 static void cgraph_remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
72 static hashval_t hash_node PARAMS ((const void *));
73 static int eq_node PARAMS ((const void *, const void *));
75 /* Returns a hash code for P. */
82 htab_hash_pointer (DECL_ASSEMBLER_NAME
83 (((struct cgraph_node *) p)->decl));
86 /* Returns nonzero if P1 and P2 are equal. */
93 return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
97 /* Return cgraph node assigned to DECL. Create new one when needed. */
102 struct cgraph_node *node;
103 struct cgraph_node **slot;
105 if (TREE_CODE (decl) != FUNCTION_DECL)
110 cgraph_hash = htab_create (10, hash_node, eq_node, NULL);
112 VARRAY_TREE_INIT (known_decls, 32, "known_decls");
116 (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash,
117 DECL_ASSEMBLER_NAME (decl),
123 node = xcalloc (sizeof (*node), 1);
125 node->next = cgraph_nodes;
127 cgraph_nodes->previous = node;
128 node->previous = NULL;
132 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
134 node->origin = cgraph_node (DECL_CONTEXT (decl));
135 node->next_nested = node->origin->nested;
136 node->origin->nested = node;
138 VARRAY_PUSH_TREE (known_decls, decl);
142 /* Try to find existing function for identifier ID. */
144 cgraph_node_for_identifier (id)
147 struct cgraph_node **slot;
149 if (TREE_CODE (id) != IDENTIFIER_NODE)
156 (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash, id,
157 htab_hash_pointer (id), 0);
163 /* Create edge from CALLER to CALLEE in the cgraph. */
165 static struct cgraph_edge *
166 create_edge (caller, callee)
167 struct cgraph_node *caller, *callee;
169 struct cgraph_edge *edge = xmalloc (sizeof (struct cgraph_edge));
171 edge->caller = caller;
172 edge->callee = callee;
173 edge->next_caller = callee->callers;
174 edge->next_callee = caller->callees;
175 caller->callees = edge;
176 callee->callers = edge;
180 /* Remove the edge from CALLER to CALLEE in the cgraph. */
183 cgraph_remove_edge (caller, callee)
184 struct cgraph_node *caller, *callee;
186 struct cgraph_edge **edge, **edge2;
188 for (edge = &callee->callers; *edge && (*edge)->caller != caller;
189 edge = &((*edge)->next_caller))
193 *edge = (*edge)->next_caller;
194 for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
195 edge2 = &(*edge2)->next_callee)
199 *edge2 = (*edge2)->next_callee;
202 /* Remove the node from cgraph. */
205 cgraph_remove_node (node)
206 struct cgraph_node *node;
208 while (node->callers)
209 cgraph_remove_edge (node->callers->caller, node);
210 while (node->callees)
211 cgraph_remove_edge (node, node->callees->callee);
213 cgraph_remove_node (node->nested);
216 struct cgraph_node **node2 = &node->origin->nested;
218 while (*node2 != node)
219 node2 = &(*node2)->next_nested;
220 *node2 = node->next_nested;
223 node->previous->next = node->next;
227 node->next->previous = node->previous;
228 DECL_SAVED_TREE (node->decl) = NULL;
229 /* Do not free the structure itself so the walk over chain can continue. */
232 /* Notify finalize_compilation_unit that given node is reachable
235 cgraph_mark_needed_node (node, needed)
236 struct cgraph_node *node;
243 if (!node->reachable)
246 if (DECL_SAVED_TREE (node->decl))
248 node->aux = cgraph_nodes_queue;
249 cgraph_nodes_queue = node;
255 /* Record call from CALLER to CALLEE */
258 cgraph_record_call (caller, callee)
261 return create_edge (cgraph_node (caller), cgraph_node (callee));
265 cgraph_remove_call (caller, callee)
268 cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
271 /* Return true when CALLER_DECL calls CALLEE_DECL. */
274 cgraph_calls_p (caller_decl, callee_decl)
275 tree caller_decl, callee_decl;
277 struct cgraph_node *caller = cgraph_node (caller_decl);
278 struct cgraph_node *callee = cgraph_node (callee_decl);
279 struct cgraph_edge *edge;
281 for (edge = callee->callers; edge && (edge)->caller != caller;
282 edge = (edge->next_caller))
287 /* Return local info for the compiled function. */
289 struct cgraph_local_info *
290 cgraph_local_info (decl)
293 struct cgraph_node *node;
294 if (TREE_CODE (decl) != FUNCTION_DECL)
296 node = cgraph_node (decl);
300 /* Return local info for the compiled function. */
302 struct cgraph_global_info *
303 cgraph_global_info (decl)
306 struct cgraph_node *node;
307 if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
309 node = cgraph_node (decl);
310 return &node->global;
313 /* Return local info for the compiled function. */
315 struct cgraph_rtl_info *
316 cgraph_rtl_info (decl)
319 struct cgraph_node *node;
320 if (TREE_CODE (decl) != FUNCTION_DECL)
322 node = cgraph_node (decl);
323 if (decl != current_function_decl
324 && !TREE_ASM_WRITTEN (node->decl))
330 /* Dump the callgraph. */
336 struct cgraph_node *node;
338 fprintf (f, "\nCallgraph:\n\n");
339 for (node = cgraph_nodes; node; node = node->next)
341 struct cgraph_edge *edge;
342 fprintf (f, "%s", IDENTIFIER_POINTER (DECL_NAME (node->decl)));
344 fprintf (f, " nested in: %s",
345 IDENTIFIER_POINTER (DECL_NAME (node->origin->decl)));
347 fprintf (f, " needed");
348 else if (node->reachable)
349 fprintf (f, " reachable");
350 if (DECL_SAVED_TREE (node->decl))
351 fprintf (f, " tree");
353 fprintf (f, "\n called by :");
354 for (edge = node->callers; edge; edge = edge->next_caller)
356 IDENTIFIER_POINTER (DECL_NAME (edge->caller->decl)));
358 fprintf (f, "\n calls: ");
359 for (edge = node->callees; edge; edge = edge->next_callee)
361 IDENTIFIER_POINTER (DECL_NAME (edge->callee->decl)));
366 /* Returns a hash code for P. */
369 cgraph_varpool_hash_node (const PTR p)
372 htab_hash_pointer (DECL_ASSEMBLER_NAME
373 (((struct cgraph_varpool_node *) p)->decl));
376 /* Returns non-zero if P1 and P2 are equal. */
379 eq_cgraph_varpool_node (const PTR p1, const PTR p2)
381 return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
385 /* Return cgraph_varpool node assigned to DECL. Create new one when needed. */
386 struct cgraph_varpool_node *
387 cgraph_varpool_node (tree decl)
389 struct cgraph_varpool_node *node;
390 struct cgraph_varpool_node **slot;
392 if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
395 if (!cgraph_varpool_hash)
397 cgraph_varpool_hash = htab_create (10, cgraph_varpool_hash_node, eq_cgraph_varpool_node, NULL);
399 VARRAY_TREE_INIT (known_decls, 32, "known_decls");
403 (struct cgraph_varpool_node **) htab_find_slot_with_hash (cgraph_varpool_hash,
404 DECL_ASSEMBLER_NAME (decl),
410 node = xcalloc (sizeof (*node), 1);
412 cgraph_varpool_n_nodes++;
414 VARRAY_PUSH_TREE (known_decls, decl);
418 /* Try to find existing function for identifier ID. */
419 struct cgraph_varpool_node *
420 cgraph_varpool_node_for_identifier (tree id)
422 struct cgraph_varpool_node **slot;
424 if (TREE_CODE (id) != IDENTIFIER_NODE)
427 if (!cgraph_varpool_hash)
431 (struct cgraph_varpool_node **) htab_find_slot_with_hash (cgraph_varpool_hash, id,
432 htab_hash_pointer (id), 0);
438 /* Notify finalize_compilation_unit that given node is reachable
441 cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
443 if (!node->needed && node->finalized)
445 node->aux = cgraph_varpool_nodes_queue;
446 cgraph_varpool_nodes_queue = node;
452 cgraph_varpool_finalize_decl (tree decl)
454 struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
456 if (node->needed && !node->finalized)
458 node->aux = cgraph_varpool_nodes_queue;
459 cgraph_varpool_nodes_queue = node;
461 node->finalized = true;
463 if (/* Externally visible variables must be output. The exception are
464 COMDAT functions that must be output only when they are needed. */
465 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
466 /* Function whose name is output to the assembler file must be produced.
467 It is possible to assemble the name later after finalizing the function
468 and the fact is noticed in assemble_name then. */
469 || (DECL_ASSEMBLER_NAME_SET_P (decl)
470 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
472 cgraph_varpool_mark_needed_node (node);
477 cgraph_varpool_assemble_pending_decls ()
479 bool changed = false;
481 while (cgraph_varpool_nodes_queue)
483 tree decl = cgraph_varpool_nodes_queue->decl;
484 struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
486 cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->aux;
487 if (!TREE_ASM_WRITTEN (decl))
489 assemble_variable (decl, 0, 1, 0);
498 #include "gt-cgraph.h"