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"
38 static void cgraph_expand_functions
PARAMS ((void));
39 static void cgraph_mark_functions_to_output
PARAMS ((void));
40 static void cgraph_expand_function
PARAMS ((struct cgraph_node
*));
41 static tree record_call_1
PARAMS ((tree
*, int *, void *));
42 static void cgraph_mark_local_functions
PARAMS ((void));
43 static void cgraph_mark_functions_to_inline_once
PARAMS ((void));
44 static void cgraph_optimize_function
PARAMS ((struct cgraph_node
*));
46 /* Analyze function once it is parsed. Set up the local information
47 available - create cgraph edges for function calles via BODY. */
50 cgraph_finalize_function (decl
, body
)
52 tree body ATTRIBUTE_UNUSED
;
54 struct cgraph_node
*node
= cgraph_node (decl
);
58 node
->local
.can_inline_once
= tree_inlinable_function_p (decl
, 1);
59 if (flag_inline_trees
)
60 node
->local
.inline_many
= tree_inlinable_function_p (decl
, 0);
62 node
->local
.inline_many
= 0;
64 (*debug_hooks
->deferred_inline_function
) (decl
);
67 static struct cgraph_node
*queue
= NULL
;
69 /* Notify finalize_compilation_unit that given node is reachable
73 cgraph_mark_needed_node (node
, needed
)
74 struct cgraph_node
*node
;
79 if (DECL_SAVED_TREE (node
->decl
))
80 announce_function (node
->decl
);
86 if (DECL_SAVED_TREE (node
->decl
))
94 /* Walk tree and record all calls. Called via walk_tree. */
96 record_call_1 (tp
, walk_subtrees
, data
)
101 /* Record dereferences to the functions. This makes the functions
102 reachable unconditionally. */
103 if (TREE_CODE (*tp
) == ADDR_EXPR
)
105 tree decl
= TREE_OPERAND (*tp
, 0);
106 if (TREE_CODE (decl
) == FUNCTION_DECL
)
107 cgraph_mark_needed_node (cgraph_node (decl
), 1);
109 else if (TREE_CODE (*tp
) == CALL_EXPR
)
111 /* We cannot use get_callee_fndecl here because it actually tries
112 too hard to get the function declaration, looking for indirect
113 references and stripping NOPS. As a result, get_callee_fndecl
114 finds calls that shouldn't be in the call graph. */
116 tree decl
= TREE_OPERAND (*tp
, 0);
117 if (TREE_CODE (decl
) == ADDR_EXPR
)
118 decl
= TREE_OPERAND (decl
, 0);
119 if (TREE_CODE (decl
) == FUNCTION_DECL
)
121 if (DECL_BUILT_IN (decl
))
123 cgraph_record_call (data
, decl
);
125 /* When we see a function call, we don't want to look at the
126 function reference in the ADDR_EXPR that is hanging from
127 the CALL_EXPR we're examining here, because we would
128 conclude incorrectly that the function's address could be
129 taken by something that is not a function call. So only
130 walk the function parameter list, skip the other subtrees. */
132 walk_tree (&TREE_OPERAND (*tp
, 1), record_call_1
, data
, NULL
);
139 /* Create cgraph edges for function calls inside BODY from DECL. */
142 cgraph_create_edges (decl
, body
)
146 /* The nodes we're interested in are never shared, so walk
147 the tree ignoring duplicates. */
148 walk_tree_without_duplicates (&body
, record_call_1
, decl
);
151 /* Analyze the whole compilation unit once it is parsed completely. */
154 cgraph_finalize_compilation_unit ()
156 struct cgraph_node
*node
;
157 struct cgraph_edge
*edge
;
159 /* Collect entry points to the unit. */
162 fprintf (stderr
, "\n\nUnit entry points:");
164 for (node
= cgraph_nodes
; node
; node
= node
->next
)
166 tree decl
= node
->decl
;
168 if (!DECL_SAVED_TREE (decl
))
170 if ((TREE_PUBLIC (decl
) && !DECL_COMDAT (decl
) && !DECL_EXTERNAL (decl
))
171 || (DECL_ASSEMBLER_NAME_SET_P (decl
)
172 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
))))
174 /* This function can be called from outside this compliation
175 unit, so it most definitely is needed. */
176 cgraph_mark_needed_node (node
, 1);
180 /* Propagate reachability flag and lower representation of all reachable
181 functions. In the future, lowering will introduce new functions and
182 new entry points on the way (by template instantiation and virtual
183 method table generation for instance). */
186 tree decl
= queue
->decl
;
190 if (node
->lowered
|| !node
->reachable
|| !DECL_SAVED_TREE (decl
))
193 /* At the moment frontend automatically emits all nested functions. */
196 struct cgraph_node
*node2
;
198 for (node2
= node
->nested
; node2
; node2
= node2
->next_nested
)
199 if (!node2
->reachable
)
200 cgraph_mark_needed_node (node2
, 0);
203 if (lang_hooks
.callgraph
.lower_function
)
204 (*lang_hooks
.callgraph
.lower_function
) (decl
);
206 /* First kill forward declaration so reverse inling works properly. */
207 cgraph_create_edges (decl
, DECL_SAVED_TREE (decl
));
209 for (edge
= node
->callees
; edge
; edge
= edge
->next_callee
)
211 if (!edge
->callee
->reachable
)
212 cgraph_mark_needed_node (edge
->callee
, 0);
214 node
->lowered
= true;
218 fprintf (stderr
, "\n\nReclaiming functions:");
220 for (node
= cgraph_nodes
; node
; node
= node
->next
)
222 tree decl
= node
->decl
;
224 if (!node
->reachable
&& DECL_SAVED_TREE (decl
))
226 cgraph_remove_node (node
);
227 announce_function (decl
);
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 || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl
)))
252 && !TREE_ASM_WRITTEN (decl
) && !node
->origin
253 && !DECL_EXTERNAL (decl
))
258 /* Optimize the function before expansion. */
261 cgraph_optimize_function (node
)
262 struct cgraph_node
*node
;
264 tree decl
= node
->decl
;
266 if (flag_inline_trees
)
267 optimize_inline_calls (decl
);
270 for (node
= node
->nested
; node
; node
= node
->next_nested
)
271 cgraph_optimize_function (node
);
275 /* Expand function specified by NODE. */
278 cgraph_expand_function (node
)
279 struct cgraph_node
*node
;
281 tree decl
= node
->decl
;
283 announce_function (decl
);
285 cgraph_optimize_function (node
);
287 /* Generate RTL for the body of DECL. Nested functions are expanded
288 via lang_expand_decl_stmt. */
289 (*lang_hooks
.callgraph
.expand_function
) (decl
);
291 /* When we decided to inline the function once, we never ever should
292 need to output it separately. */
293 if (node
->global
.inline_once
)
295 if (!node
->local
.inline_many
297 DECL_SAVED_TREE (decl
) = NULL
;
298 current_function_decl
= NULL
;
302 /* Expand all functions that must be output.
304 Attempt to topologically sort the nodes so function is output when
305 all called functions are already assembled to allow data to be
306 propagated accross the callgraph. Use a stack to get smaller distance
307 between a function and it's callees (later we may choose to use a more
308 sophisticated algorithm for function reordering; we will likely want
309 to use subsections to make the output functions appear in top-down
313 cgraph_expand_functions ()
315 struct cgraph_node
*node
, *node2
;
316 struct cgraph_node
**stack
=
317 xcalloc (sizeof (struct cgraph_node
*), cgraph_n_nodes
);
318 struct cgraph_node
**order
=
319 xcalloc (sizeof (struct cgraph_node
*), cgraph_n_nodes
);
322 struct cgraph_edge
*edge
, last
;
325 cgraph_mark_functions_to_output ();
327 /* We have to deal with cycles nicely, so use a depth first traversal
328 output algorithm. Ignore the fact that some functions won't need
329 to be output and put them into order as well, so we get dependencies
330 right through intline functions. */
331 for (node
= cgraph_nodes
; node
; node
= node
->next
)
333 for (node
= cgraph_nodes
; node
; node
= node
->next
)
334 if (node
->output
&& !node
->aux
)
340 node
->aux
= node
->callers
;
343 while (node2
->aux
!= &last
)
346 if (edge
->next_caller
)
347 node2
->aux
= edge
->next_caller
;
350 if (!edge
->caller
->aux
)
352 if (!edge
->caller
->callers
)
353 edge
->caller
->aux
= &last
;
355 edge
->caller
->aux
= edge
->caller
->callers
;
356 stack
[stack_size
++] = node2
;
357 node2
= edge
->caller
;
361 if (node2
->aux
== &last
)
363 order
[order_pos
++] = node2
;
365 node2
= stack
[--stack_size
];
371 for (i
= order_pos
- 1; i
>= 0; i
--)
376 if (!node
->reachable
)
379 cgraph_expand_function (node
);
386 /* Mark all local functions.
387 We can not use node->needed directly as it is modified during
388 execution of cgraph_optimize. */
391 cgraph_mark_local_functions ()
393 struct cgraph_node
*node
;
396 fprintf (stderr
, "\n\nMarking local functions:");
398 /* Figure out functions we want to assemble. */
399 for (node
= cgraph_nodes
; node
; node
= node
->next
)
401 node
->local
.local
= (!node
->needed
402 && DECL_SAVED_TREE (node
->decl
)
403 && !TREE_PUBLIC (node
->decl
));
404 if (node
->local
.local
)
405 announce_function (node
->decl
);
409 /* Decide what function should be inlined because they are invoked once
410 (so inlining won't result in duplication of the code). */
413 cgraph_mark_functions_to_inline_once ()
415 struct cgraph_node
*node
, *node1
;
418 fprintf (stderr
, "\n\nMarking functions to inline once:");
420 /* Now look for function called only once and mark them to inline.
421 From this point number of calls to given function won't grow. */
422 for (node
= cgraph_nodes
; node
; node
= node
->next
)
424 if (node
->callers
&& !node
->callers
->next_caller
&& !node
->needed
425 && node
->local
.can_inline_once
)
429 /* Verify that we won't duplicate the caller. */
430 for (node1
= node
->callers
->caller
;
431 node1
->local
.inline_many
434 node1
= node1
->callers
->caller
)
435 if (node1
->callers
->next_caller
|| node1
->needed
)
439 node
->global
.inline_once
= true;
440 announce_function (node
->decl
);
447 /* Perform simple optimizations based on callgraph. */
452 struct cgraph_node
*node
;
455 cgraph_mark_local_functions ();
457 cgraph_mark_functions_to_inline_once ();
459 cgraph_global_info_ready
= true;
461 fprintf (stderr
, "\n\nAssembling functions:");
463 /* Output everything.
464 ??? Our inline heuristic may decide to not inline functions previously
465 marked as inlinable thus adding new function bodies that must be output.
466 Later we should move all inlining decisions to callgraph code to make
468 cgraph_expand_functions ();
470 fprintf (stderr
, "\n\nAssembling functions that failed to inline:");
471 while (changed
&& !errorcount
&& !sorrycount
)
474 for (node
= cgraph_nodes
; node
; node
= node
->next
)
476 tree decl
= node
->decl
;
478 && !TREE_ASM_WRITTEN (decl
)
479 && DECL_SAVED_TREE (decl
)
480 && !DECL_EXTERNAL (decl
))
482 struct cgraph_edge
*edge
;
484 for (edge
= node
->callers
; edge
; edge
= edge
->next_caller
)
485 if (TREE_ASM_WRITTEN (edge
->caller
->decl
))
488 cgraph_expand_function (node
);