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 "tree-inline.h"
28 #include "langhooks.h"
36 #include "diagnostic.h"
39 static void cgraph_expand_functions PARAMS ((void));
40 static void cgraph_mark_functions_to_output PARAMS ((void));
41 static void cgraph_expand_function PARAMS ((struct cgraph_node *));
42 static tree record_call_1 PARAMS ((tree *, int *, void *));
43 static void cgraph_mark_local_functions PARAMS ((void));
44 static void cgraph_mark_functions_to_inline_once PARAMS ((void));
45 static void cgraph_optimize_function PARAMS ((struct cgraph_node *));
47 /* Analyze function once it is parsed. Set up the local information
48 available - create cgraph edges for function calls via BODY. */
51 cgraph_finalize_function (decl, body)
53 tree body ATTRIBUTE_UNUSED;
55 struct cgraph_node *node = cgraph_node (decl);
58 node->local.finalized = true;
60 if (/* Externally visible functions must be output. The exception are
61 COMDAT functions that must be output only when they are needed.
62 Similarly are handled deferred functions and
63 external functions (GCC extension "extern inline") */
64 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
65 /* ??? Constructors and destructors not called otherwise can be inlined
66 into single construction/destruction function per section to save some
67 resources. For now just mark it as reachable. */
68 || DECL_STATIC_CONSTRUCTOR (decl)
69 || DECL_STATIC_DESTRUCTOR (decl)
70 /* Function whose name is output to the assembler file must be produced.
71 It is possible to assemble the name later after finalizing the function
72 and the fact is noticed in assemble_name then. */
73 || (DECL_ASSEMBLER_NAME_SET_P (decl)
74 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
76 cgraph_mark_needed_node (node, 1);
79 (*debug_hooks->deferred_inline_function) (decl);
82 /* Walk tree and record all calls. Called via walk_tree. */
84 record_call_1 (tp, walk_subtrees, data)
89 if (TREE_CODE (*tp) == VAR_DECL && TREE_STATIC (*tp))
90 cgraph_varpool_mark_needed_node (cgraph_varpool_node (*tp));
91 /* Record dereferences to the functions. This makes the functions
92 reachable unconditionally. */
93 else if (TREE_CODE (*tp) == ADDR_EXPR)
95 tree decl = TREE_OPERAND (*tp, 0);
96 if (TREE_CODE (decl) == FUNCTION_DECL)
97 cgraph_mark_needed_node (cgraph_node (decl), 1);
99 else if (TREE_CODE (*tp) == CALL_EXPR)
101 tree decl = get_callee_fndecl (*tp);
102 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
104 if (DECL_BUILT_IN (decl))
106 cgraph_record_call (data, decl);
108 /* When we see a function call, we don't want to look at the
109 function reference in the ADDR_EXPR that is hanging from
110 the CALL_EXPR we're examining here, because we would
111 conclude incorrectly that the function's address could be
112 taken by something that is not a function call. So only
113 walk the function parameter list, skip the other subtrees. */
115 walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data, NULL);
122 /* Create cgraph edges for function calls inside BODY from DECL. */
125 cgraph_create_edges (decl, body)
129 /* The nodes we're interested in are never shared, so walk
130 the tree ignoring duplicates. */
131 walk_tree_without_duplicates (&body, record_call_1, decl);
134 /* Analyze the whole compilation unit once it is parsed completely. */
137 cgraph_finalize_compilation_unit ()
139 struct cgraph_node *node;
140 struct cgraph_edge *edge;
142 cgraph_varpool_assemble_pending_decls ();
144 timevar_push (TV_CGRAPH);
145 if (cgraph_dump_file)
147 fprintf (cgraph_dump_file, "\nInitial entry points:");
148 for (node = cgraph_nodes; node; node = node->next)
149 if (node->needed && DECL_SAVED_TREE (node->decl))
150 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
151 fprintf (cgraph_dump_file, "\n");
154 /* Propagate reachability flag and lower representation of all reachable
155 functions. In the future, lowering will introduce new functions and
156 new entry points on the way (by template instantiation and virtual
157 method table generation for instance). */
158 while (cgraph_nodes_queue)
160 tree decl = cgraph_nodes_queue->decl;
162 node = cgraph_nodes_queue;
163 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
165 if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
168 if (lang_hooks.callgraph.lower_function)
169 (*lang_hooks.callgraph.lower_function) (decl);
171 current_function_decl = node->decl;
172 if (!node->needed && !DECL_COMDAT (node->decl))
173 node->local.can_inline_once = tree_inlinable_function_p (decl, 1);
175 node->local.can_inline_once = 0;
176 if (flag_inline_trees)
177 node->local.inline_many = tree_inlinable_function_p (decl, 0);
179 node->local.inline_many = 0;
181 /* At the moment frontend automatically emits all nested functions. */
184 struct cgraph_node *node2;
186 for (node2 = node->nested; node2; node2 = node2->next_nested)
187 if (!node2->reachable)
188 cgraph_mark_needed_node (node2, 0);
191 /* First kill forward declaration so reverse inling works properly. */
192 cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
194 for (edge = node->callees; edge; edge = edge->next_callee)
196 if (!edge->callee->reachable)
197 cgraph_mark_needed_node (edge->callee, 0);
199 node->lowered = true;
200 cgraph_varpool_assemble_pending_decls ();
202 /* Collect entry points to the unit. */
204 if (cgraph_dump_file)
206 fprintf (cgraph_dump_file, "\nUnit entry points:");
207 for (node = cgraph_nodes; node; node = node->next)
208 if (node->needed && DECL_SAVED_TREE (node->decl))
209 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
210 fprintf (cgraph_dump_file, "\n");
213 if (cgraph_dump_file)
214 fprintf (cgraph_dump_file, "\nReclaiming functions:");
216 for (node = cgraph_nodes; node; node = node->next)
218 tree decl = node->decl;
220 if (!node->reachable && DECL_SAVED_TREE (decl))
222 cgraph_remove_node (node);
223 if (cgraph_dump_file)
224 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
227 if (cgraph_dump_file)
228 fprintf (cgraph_dump_file, "\n");
230 timevar_pop (TV_CGRAPH);
233 /* Figure out what functions we want to assemble. */
236 cgraph_mark_functions_to_output ()
238 struct cgraph_node *node;
240 for (node = cgraph_nodes; node; node = node->next)
242 tree decl = node->decl;
244 /* We need to output all local functions that are used and not
245 always inlined, as well as those that are reachable from
246 outside the current compilation unit. */
247 if (DECL_SAVED_TREE (decl)
249 || (!node->local.inline_many && !node->global.inline_once
251 || (DECL_ASSEMBLER_NAME_SET_P (decl)
252 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
253 && !TREE_ASM_WRITTEN (decl) && !node->origin
254 && !DECL_EXTERNAL (decl))
259 /* Optimize the function before expansion. */
262 cgraph_optimize_function (node)
263 struct cgraph_node *node;
265 tree decl = node->decl;
267 timevar_push (TV_INTEGRATION);
268 if (flag_inline_trees)
269 optimize_inline_calls (decl);
272 for (node = node->nested; node; node = node->next_nested)
273 cgraph_optimize_function (node);
275 timevar_pop (TV_INTEGRATION);
278 /* Expand function specified by NODE. */
281 cgraph_expand_function (node)
282 struct cgraph_node *node;
284 tree decl = node->decl;
286 announce_function (decl);
288 cgraph_optimize_function (node);
290 /* Generate RTL for the body of DECL. Nested functions are expanded
291 via lang_expand_decl_stmt. */
292 (*lang_hooks.callgraph.expand_function) (decl);
294 /* When we decided to inline the function once, we never ever should
295 need to output it separately. */
296 if (node->global.inline_once)
298 if (!node->local.inline_many
300 DECL_SAVED_TREE (decl) = NULL;
301 current_function_decl = NULL;
305 /* Expand all functions that must be output.
307 Attempt to topologically sort the nodes so function is output when
308 all called functions are already assembled to allow data to be
309 propagated across the callgraph. Use a stack to get smaller distance
310 between a function and it's callees (later we may choose to use a more
311 sophisticated algorithm for function reordering; we will likely want
312 to use subsections to make the output functions appear in top-down
316 cgraph_expand_functions ()
318 struct cgraph_node *node, *node2;
319 struct cgraph_node **stack =
320 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
321 struct cgraph_node **order =
322 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
325 struct cgraph_edge *edge, last;
328 cgraph_mark_functions_to_output ();
330 /* We have to deal with cycles nicely, so use a depth first traversal
331 output algorithm. Ignore the fact that some functions won't need
332 to be output and put them into order as well, so we get dependencies
333 right through intline functions. */
334 for (node = cgraph_nodes; node; node = node->next)
336 for (node = cgraph_nodes; node; node = node->next)
343 node->aux = node->callers;
346 while (node2->aux != &last)
349 if (edge->next_caller)
350 node2->aux = edge->next_caller;
353 if (!edge->caller->aux)
355 if (!edge->caller->callers)
356 edge->caller->aux = &last;
358 edge->caller->aux = edge->caller->callers;
359 stack[stack_size++] = node2;
360 node2 = edge->caller;
364 if (node2->aux == &last)
366 order[order_pos++] = node2;
368 node2 = stack[--stack_size];
374 for (i = order_pos - 1; i >= 0; i--)
379 if (!node->reachable)
382 cgraph_expand_function (node);
389 /* Mark all local functions.
390 We can not use node->needed directly as it is modified during
391 execution of cgraph_optimize. */
394 cgraph_mark_local_functions ()
396 struct cgraph_node *node;
398 if (cgraph_dump_file)
399 fprintf (cgraph_dump_file, "Marking local functions:");
401 /* Figure out functions we want to assemble. */
402 for (node = cgraph_nodes; node; node = node->next)
404 node->local.local = (!node->needed
405 && DECL_SAVED_TREE (node->decl)
406 && !DECL_COMDAT (node->decl)
407 && !TREE_PUBLIC (node->decl));
408 if (cgraph_dump_file && node->local.local)
409 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
411 if (cgraph_dump_file)
412 fprintf (cgraph_dump_file, "\n");
415 /* Decide what function should be inlined because they are invoked once
416 (so inlining won't result in duplication of the code). */
419 cgraph_mark_functions_to_inline_once ()
421 struct cgraph_node *node, *node1;
423 if (cgraph_dump_file)
424 fprintf (cgraph_dump_file, "\n\nMarking functions to inline once:");
426 /* Now look for function called only once and mark them to inline.
427 From this point number of calls to given function won't grow. */
428 for (node = cgraph_nodes; node; node = node->next)
430 if (node->callers && !node->callers->next_caller && !node->needed
431 && node->local.can_inline_once)
435 /* Verify that we won't duplicate the caller. */
436 for (node1 = node->callers->caller;
437 node1->local.inline_many
440 node1 = node1->callers->caller)
441 if (node1->callers->next_caller || node1->needed)
445 node->global.inline_once = true;
446 if (cgraph_dump_file)
447 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
451 if (cgraph_dump_file)
452 fprintf (cgraph_dump_file, "\n");
456 /* Perform simple optimizations based on callgraph. */
461 struct cgraph_node *node;
464 timevar_push (TV_CGRAPHOPT);
465 if (cgraph_dump_file)
467 fprintf (cgraph_dump_file, "Initial callgraph:");
468 dump_cgraph (cgraph_dump_file);
470 cgraph_mark_local_functions ();
472 cgraph_mark_functions_to_inline_once ();
474 cgraph_global_info_ready = true;
475 if (cgraph_dump_file)
477 fprintf (cgraph_dump_file, "Optimized callgraph:");
478 dump_cgraph (cgraph_dump_file);
480 timevar_pop (TV_CGRAPHOPT);
482 fprintf (stderr, "\n\nAssembling functions:");
484 /* Output everything.
485 ??? Our inline heuristic may decide to not inline functions previously
486 marked as inlinable thus adding new function bodies that must be output.
487 Later we should move all inlining decisions to callgraph code to make
489 cgraph_expand_functions ();
491 fprintf (stderr, "\n\nAssembling functions that failed to inline:");
492 while (changed && !errorcount && !sorrycount)
495 for (node = cgraph_nodes; node; node = node->next)
497 tree decl = node->decl;
499 && !TREE_ASM_WRITTEN (decl)
500 && DECL_SAVED_TREE (decl)
501 && !DECL_EXTERNAL (decl))
503 struct cgraph_edge *edge;
505 for (edge = node->callers; edge; edge = edge->next_caller)
506 if (TREE_ASM_WRITTEN (edge->caller->decl))
509 cgraph_expand_function (node);
515 if (cgraph_dump_file)
517 fprintf (cgraph_dump_file, "Final callgraph:");
518 dump_cgraph (cgraph_dump_file);