* gcc.dg/const-elim-1.c: xfail for xtensa.
[official-gcc.git] / gcc / cgraph.c
blob8cee3dfbffb76545077349ea1d56f1995429c3f8
1 /* Callgraph handling code.
2 Copyright (C) 2003, 2004 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
10 version.
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
15 for more details.
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
20 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "langhooks.h"
28 #include "hashtab.h"
29 #include "toplev.h"
30 #include "flags.h"
31 #include "ggc.h"
32 #include "debug.h"
33 #include "target.h"
34 #include "cgraph.h"
35 #include "varray.h"
36 #include "output.h"
37 #include "intl.h"
40 /* Hash table used to convert declarations into nodes. */
41 static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
43 /* The linked list of cgraph nodes. */
44 struct cgraph_node *cgraph_nodes;
46 /* Queue of cgraph nodes scheduled to be lowered. */
47 struct cgraph_node *cgraph_nodes_queue;
49 /* Number of nodes in existence. */
50 int cgraph_n_nodes;
52 /* Maximal uid used in cgraph nodes. */
53 int cgraph_max_uid;
55 /* Set when whole unit has been analyzed so we can access global info. */
56 bool cgraph_global_info_ready = false;
58 /* Hash table used to convert declarations into nodes. */
59 static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
61 /* Queue of cgraph nodes scheduled to be lowered and output. */
62 struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
64 /* Number of nodes in existence. */
65 int cgraph_varpool_n_nodes;
67 /* The linked list of cgraph varpool nodes. */
68 static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
70 static struct cgraph_edge *create_edge (struct cgraph_node *,
71 struct cgraph_node *);
72 static hashval_t hash_node (const void *);
73 static int eq_node (const void *, const void *);
75 /* Returns a hash code for P. */
77 static hashval_t
78 hash_node (const void *p)
80 return ((hashval_t)
81 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
82 (((struct cgraph_node *) p)->decl)));
85 /* Returns nonzero if P1 and P2 are equal. */
87 static int
88 eq_node (const void *p1, const void *p2)
90 return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
91 (tree) p2);
94 /* Return cgraph node assigned to DECL. Create new one when needed. */
95 struct cgraph_node *
96 cgraph_node (tree decl)
98 struct cgraph_node *node;
99 struct cgraph_node **slot;
101 if (TREE_CODE (decl) != FUNCTION_DECL)
102 abort ();
104 if (!cgraph_hash)
105 cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
107 slot = (struct cgraph_node **)
108 htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
109 IDENTIFIER_HASH_VALUE
110 (DECL_ASSEMBLER_NAME (decl)), INSERT);
111 if (*slot)
112 return *slot;
113 node = ggc_alloc_cleared (sizeof (*node));
114 node->decl = decl;
115 node->next = cgraph_nodes;
116 node->uid = cgraph_max_uid++;
117 if (cgraph_nodes)
118 cgraph_nodes->previous = node;
119 node->previous = NULL;
120 cgraph_nodes = node;
121 cgraph_n_nodes++;
122 *slot = node;
123 if (DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)
125 node->origin = cgraph_node (DECL_CONTEXT (decl));
126 node->next_nested = node->origin->nested;
127 node->origin->nested = node;
129 return node;
132 /* Try to find existing function for identifier ID. */
133 struct cgraph_node *
134 cgraph_node_for_identifier (tree id)
136 struct cgraph_node **slot;
138 if (TREE_CODE (id) != IDENTIFIER_NODE)
139 abort ();
141 if (!cgraph_hash)
142 return NULL;
144 slot = (struct cgraph_node **)
145 htab_find_slot_with_hash (cgraph_hash, id,
146 IDENTIFIER_HASH_VALUE (id), NO_INSERT);
147 if (!slot)
148 return NULL;
149 return *slot;
152 /* Create edge from CALLER to CALLEE in the cgraph. */
154 static struct cgraph_edge *
155 create_edge (struct cgraph_node *caller, struct cgraph_node *callee)
157 struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
158 struct cgraph_edge *edge2;
160 if (!DECL_SAVED_TREE (callee->decl))
161 edge->inline_failed = N_("function body not available");
162 else if (callee->local.redefined_extern_inline)
163 edge->inline_failed = N_("redefined extern inline functions are not "
164 "considered for inlining");
165 else if (callee->local.inlinable)
166 edge->inline_failed = N_("function not considered for inlining");
167 else
168 edge->inline_failed = N_("function not inlinable");
170 /* At the moment we don't associate calls with specific CALL_EXPRs
171 as we probably ought to, so we must preserve inline_call flags to
172 be the same in all copies of the same edge. */
173 if (cgraph_global_info_ready)
174 for (edge2 = caller->callees; edge2; edge2 = edge2->next_callee)
175 if (edge2->callee == callee)
177 edge->inline_failed = edge2->inline_failed;
178 break;
181 edge->caller = caller;
182 edge->callee = callee;
183 edge->next_caller = callee->callers;
184 edge->next_callee = caller->callees;
185 caller->callees = edge;
186 callee->callers = edge;
187 return edge;
190 /* Remove the edge from CALLER to CALLEE in the cgraph. */
192 void
193 cgraph_remove_edge (struct cgraph_node *caller, struct cgraph_node *callee)
195 struct cgraph_edge **edge, **edge2;
197 for (edge = &callee->callers; *edge && (*edge)->caller != caller;
198 edge = &((*edge)->next_caller))
199 continue;
200 if (!*edge)
201 abort ();
202 *edge = (*edge)->next_caller;
203 for (edge2 = &caller->callees; *edge2 && (*edge2)->callee != callee;
204 edge2 = &(*edge2)->next_callee)
205 continue;
206 if (!*edge2)
207 abort ();
208 *edge2 = (*edge2)->next_callee;
211 /* Remove the node from cgraph. */
213 void
214 cgraph_remove_node (struct cgraph_node *node)
216 void **slot;
217 while (node->callers)
218 cgraph_remove_edge (node->callers->caller, node);
219 while (node->callees)
220 cgraph_remove_edge (node, node->callees->callee);
221 while (node->nested)
222 cgraph_remove_node (node->nested);
223 if (node->origin)
225 struct cgraph_node **node2 = &node->origin->nested;
227 while (*node2 != node)
228 node2 = &(*node2)->next_nested;
229 *node2 = node->next_nested;
231 if (node->previous)
232 node->previous->next = node->next;
233 else
234 cgraph_nodes = node->next;
235 if (node->next)
236 node->next->previous = node->previous;
237 DECL_SAVED_TREE (node->decl) = NULL;
238 DECL_STRUCT_FUNCTION (node->decl) = NULL;
239 DECL_ARGUMENTS (node->decl) = NULL;
240 DECL_INITIAL (node->decl) = error_mark_node;
241 slot =
242 htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (node->decl),
243 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
244 (node->decl)), NO_INSERT);
245 htab_clear_slot (cgraph_hash, slot);
246 /* Do not free the structure itself so the walk over chain can continue. */
249 /* Notify finalize_compilation_unit that given node is reachable. */
251 void
252 cgraph_mark_reachable_node (struct cgraph_node *node)
254 if (!node->reachable && node->local.finalized)
256 notice_global_symbol (node->decl);
257 node->reachable = 1;
259 node->next_needed = cgraph_nodes_queue;
260 cgraph_nodes_queue = node;
262 /* At the moment frontend automatically emits all nested functions. */
263 if (node->nested)
265 struct cgraph_node *node2;
267 for (node2 = node->nested; node2; node2 = node2->next_nested)
268 if (!node2->reachable)
269 cgraph_mark_reachable_node (node2);
274 /* Likewise indicate that a node is needed, i.e. reachable via some
275 external means. */
277 void
278 cgraph_mark_needed_node (struct cgraph_node *node)
280 node->needed = 1;
281 cgraph_mark_reachable_node (node);
284 /* Record call from CALLER to CALLEE. */
286 struct cgraph_edge *
287 cgraph_record_call (tree caller, tree callee)
289 return create_edge (cgraph_node (caller), cgraph_node (callee));
292 void
293 cgraph_remove_call (tree caller, tree callee)
295 cgraph_remove_edge (cgraph_node (caller), cgraph_node (callee));
298 /* Return true when CALLER_DECL calls CALLEE_DECL. */
300 bool
301 cgraph_calls_p (tree caller_decl, tree callee_decl)
303 struct cgraph_node *caller = cgraph_node (caller_decl);
304 struct cgraph_node *callee = cgraph_node (callee_decl);
305 struct cgraph_edge *edge;
307 for (edge = callee->callers; edge && (edge)->caller != caller;
308 edge = (edge->next_caller))
309 continue;
310 return edge != NULL;
313 /* Return local info for the compiled function. */
315 struct cgraph_local_info *
316 cgraph_local_info (tree decl)
318 struct cgraph_node *node;
319 if (TREE_CODE (decl) != FUNCTION_DECL)
320 abort ();
321 node = cgraph_node (decl);
322 return &node->local;
325 /* Return local info for the compiled function. */
327 struct cgraph_global_info *
328 cgraph_global_info (tree decl)
330 struct cgraph_node *node;
331 if (TREE_CODE (decl) != FUNCTION_DECL || !cgraph_global_info_ready)
332 abort ();
333 node = cgraph_node (decl);
334 return &node->global;
337 /* Return local info for the compiled function. */
339 struct cgraph_rtl_info *
340 cgraph_rtl_info (tree decl)
342 struct cgraph_node *node;
343 if (TREE_CODE (decl) != FUNCTION_DECL)
344 abort ();
345 node = cgraph_node (decl);
346 if (decl != current_function_decl
347 && !TREE_ASM_WRITTEN (node->decl))
348 return NULL;
349 return &node->rtl;
352 /* Return name of the node used in debug output. */
353 const char *
354 cgraph_node_name (struct cgraph_node *node)
356 return (*lang_hooks.decl_printable_name) (node->decl, 2);
359 /* Dump the callgraph. */
361 void
362 dump_cgraph (FILE *f)
364 struct cgraph_node *node;
366 fprintf (f, "callgraph:\n\n");
367 for (node = cgraph_nodes; node; node = node->next)
369 struct cgraph_edge *edge;
370 fprintf (f, "%s:", cgraph_node_name (node));
371 if (node->local.self_insns)
372 fprintf (f, " %i insns", node->local.self_insns);
373 if (node->global.insns && node->global.insns != node->local.self_insns)
374 fprintf (f, " (%i after inlining)", node->global.insns);
375 if (node->origin)
376 fprintf (f, " nested in: %s", cgraph_node_name (node->origin));
377 if (node->needed)
378 fprintf (f, " needed");
379 else if (node->reachable)
380 fprintf (f, " reachable");
381 if (DECL_SAVED_TREE (node->decl))
382 fprintf (f, " tree");
384 if (node->local.local)
385 fprintf (f, " local");
386 if (node->local.disregard_inline_limits)
387 fprintf (f, " always_inline");
388 else if (node->local.inlinable)
389 fprintf (f, " inlinable");
390 if (node->global.cloned_times > 1)
391 fprintf (f, " cloned %ix", node->global.cloned_times);
393 fprintf (f, "\n called by: ");
394 for (edge = node->callers; edge; edge = edge->next_caller)
396 fprintf (f, "%s ", cgraph_node_name (edge->caller));
397 if (!edge->inline_failed)
398 fprintf(f, "(inlined) ");
401 fprintf (f, "\n calls: ");
402 for (edge = node->callees; edge; edge = edge->next_callee)
404 fprintf (f, "%s ", cgraph_node_name (edge->callee));
405 if (!edge->inline_failed)
406 fprintf(f, "(inlined) ");
408 fprintf (f, "\n");
412 /* Returns a hash code for P. */
414 static hashval_t
415 cgraph_varpool_hash_node (const void *p)
417 return ((hashval_t)
418 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
419 (((struct cgraph_varpool_node *) p)->decl)));
422 /* Returns nonzero if P1 and P2 are equal. */
424 static int
425 eq_cgraph_varpool_node (const void *p1, const void *p2)
427 return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
428 (tree) p2);
431 /* Return cgraph_varpool node assigned to DECL. Create new one when needed. */
432 struct cgraph_varpool_node *
433 cgraph_varpool_node (tree decl)
435 struct cgraph_varpool_node *node;
436 struct cgraph_varpool_node **slot;
438 if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
439 abort ();
441 if (!cgraph_varpool_hash)
442 cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
443 eq_cgraph_varpool_node, NULL);
444 slot = (struct cgraph_varpool_node **)
445 htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
446 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
447 INSERT);
448 if (*slot)
449 return *slot;
450 node = ggc_alloc_cleared (sizeof (*node));
451 node->decl = decl;
452 cgraph_varpool_n_nodes++;
453 cgraph_varpool_nodes = node;
454 *slot = node;
455 return node;
458 /* Set the DECL_ASSEMBLER_NAME and update cgraph hashtables. */
459 void
460 change_decl_assembler_name (tree decl, tree name)
462 struct cgraph_node *node = NULL;
463 struct cgraph_varpool_node *vnode = NULL;
464 void **slot;
466 if (!DECL_ASSEMBLER_NAME_SET_P (decl))
468 SET_DECL_ASSEMBLER_NAME (decl, name);
469 return;
471 if (name == DECL_ASSEMBLER_NAME (decl))
472 return;
474 if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
475 && DECL_RTL_SET_P (decl))
476 warning ("%D renamed after being referenced in assembly", decl);
478 if (TREE_CODE (decl) == FUNCTION_DECL && cgraph_hash)
480 /* Take a look whether declaration is in the cgraph structure. */
481 slot =
482 htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
483 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
484 (decl)), NO_INSERT);
485 if (slot)
486 node = *slot;
488 /* It is, verify that we are the canonical node for this decl. */
489 if (node && node->decl == decl)
491 node = *slot;
492 htab_clear_slot (cgraph_hash, slot);
494 else
495 node = NULL;
497 if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl) && cgraph_varpool_hash)
499 /* Take a look whether declaration is in the cgraph structure. */
500 slot =
501 htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
502 IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
503 (decl)), NO_INSERT);
504 if (slot)
505 vnode = *slot;
507 /* It is, verify that we are the canonical vnode for this decl. */
508 if (vnode && vnode->decl == decl)
510 vnode = *slot;
511 htab_clear_slot (cgraph_varpool_hash, slot);
513 else
514 vnode = NULL;
516 SET_DECL_ASSEMBLER_NAME (decl, name);
517 if (node)
519 slot =
520 htab_find_slot_with_hash (cgraph_hash, name,
521 IDENTIFIER_HASH_VALUE (name), INSERT);
522 if (*slot)
523 abort ();
524 *slot = node;
526 if (vnode)
528 slot =
529 htab_find_slot_with_hash (cgraph_varpool_hash, name,
530 IDENTIFIER_HASH_VALUE (name), INSERT);
531 if (*slot)
532 abort ();
533 *slot = vnode;
537 /* Try to find existing function for identifier ID. */
538 struct cgraph_varpool_node *
539 cgraph_varpool_node_for_identifier (tree id)
541 struct cgraph_varpool_node **slot;
543 if (TREE_CODE (id) != IDENTIFIER_NODE)
544 abort ();
546 if (!cgraph_varpool_hash)
547 return NULL;
549 slot = (struct cgraph_varpool_node **)
550 htab_find_slot_with_hash (cgraph_varpool_hash, id,
551 IDENTIFIER_HASH_VALUE (id), NO_INSERT);
552 if (!slot)
553 return NULL;
554 return *slot;
557 /* Notify finalize_compilation_unit that given node is reachable
558 or needed. */
559 void
560 cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
562 if (!node->needed && node->finalized)
564 node->next_needed = cgraph_varpool_nodes_queue;
565 cgraph_varpool_nodes_queue = node;
566 notice_global_symbol (node->decl);
568 node->needed = 1;
571 void
572 cgraph_varpool_finalize_decl (tree decl)
574 struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
576 /* The first declaration of a variable that comes through this function
577 decides whether it is global (in C, has external linkage)
578 or local (in C, has internal linkage). So do nothing more
579 if this function has already run. */
580 if (node->finalized)
581 return;
582 if (node->needed)
584 node->next_needed = cgraph_varpool_nodes_queue;
585 cgraph_varpool_nodes_queue = node;
586 notice_global_symbol (decl);
588 node->finalized = true;
590 if (/* Externally visible variables must be output. The exception are
591 COMDAT functions that must be output only when they are needed. */
592 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
593 /* Function whose name is output to the assembler file must be produced.
594 It is possible to assemble the name later after finalizing the function
595 and the fact is noticed in assemble_name then. */
596 || (DECL_ASSEMBLER_NAME_SET_P (decl)
597 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
599 cgraph_varpool_mark_needed_node (node);
603 bool
604 cgraph_varpool_assemble_pending_decls (void)
606 bool changed = false;
608 while (cgraph_varpool_nodes_queue)
610 tree decl = cgraph_varpool_nodes_queue->decl;
611 struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
613 cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
614 if (!TREE_ASM_WRITTEN (decl))
616 assemble_variable (decl, 0, 1, 0);
617 changed = true;
619 node->next_needed = NULL;
621 return changed;
624 /* Return true when the DECL can possibly be inlined. */
625 bool
626 cgraph_function_possibly_inlined_p (tree decl)
628 if (!cgraph_global_info_ready)
629 return (DECL_INLINE (decl)
630 && (!flag_really_no_inline
631 || (*lang_hooks.tree_inlining.disregard_inline_limits) (decl)));
632 return cgraph_node (decl)->global.inlined;
635 #include "gt-cgraph.h"