* fixinc/inclhack.def (avoid_bool_define, avoid_bool_type): Bypass
[official-gcc.git] / gcc / cgraphunit.c
blob4f51e5d0e07c933d1355d365740ec8ee3a28e3f5
1 /* Callgraph based intraprocedural optimizations.
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
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 "tree-inline.h"
28 #include "langhooks.h"
29 #include "hashtab.h"
30 #include "toplev.h"
31 #include "flags.h"
32 #include "ggc.h"
33 #include "debug.h"
34 #include "target.h"
35 #include "cgraph.h"
36 #include "diagnostic.h"
37 #include "timevar.h"
38 #include "params.h"
39 #include "fibheap.h"
40 #include "c-common.h"
42 #define INSNS_PER_CALL 10
44 static void cgraph_expand_functions (void);
45 static void cgraph_mark_functions_to_output (void);
46 static void cgraph_expand_function (struct cgraph_node *);
47 static tree record_call_1 (tree *, int *, void *);
48 static void cgraph_mark_local_functions (void);
49 static void cgraph_optimize_function (struct cgraph_node *);
51 /* Statistics we collect about inlining algorithm. */
52 static int ncalls_inlined;
53 static int nfunctions_inlined;
54 static int initial_insns;
55 static int overall_insns;
57 /* Analyze function once it is parsed. Set up the local information
58 available - create cgraph edges for function calls via BODY. */
60 void
61 cgraph_finalize_function (tree decl, tree body ATTRIBUTE_UNUSED)
63 struct cgraph_node *node = cgraph_node (decl);
65 node->decl = decl;
66 node->local.finalized = true;
68 if (/* Externally visible functions must be output. The exception are
69 COMDAT functions that must be output only when they are needed.
70 Similarly are handled deferred functions and
71 external functions (GCC extension "extern inline") */
72 (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
73 /* ??? Constructors and destructors not called otherwise can be inlined
74 into single construction/destruction function per section to save some
75 resources. For now just mark it as reachable. */
76 || DECL_STATIC_CONSTRUCTOR (decl)
77 || DECL_STATIC_DESTRUCTOR (decl)
78 /* Function whose name is output to the assembler file must be produced.
79 It is possible to assemble the name later after finalizing the function
80 and the fact is noticed in assemble_name then. */
81 || (DECL_ASSEMBLER_NAME_SET_P (decl)
82 && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
83 || lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
85 cgraph_mark_needed_node (node, 1);
88 (*debug_hooks->deferred_inline_function) (decl);
91 /* Walk tree and record all calls. Called via walk_tree. */
92 static tree
93 record_call_1 (tree *tp, int *walk_subtrees, void *data)
95 if (TREE_CODE (*tp) == VAR_DECL && TREE_STATIC (*tp))
96 cgraph_varpool_mark_needed_node (cgraph_varpool_node (*tp));
97 /* Record dereferences to the functions. This makes the functions
98 reachable unconditionally. */
99 else if (TREE_CODE (*tp) == ADDR_EXPR)
101 tree decl = TREE_OPERAND (*tp, 0);
102 if (TREE_CODE (decl) == FUNCTION_DECL)
103 cgraph_mark_needed_node (cgraph_node (decl), 1);
105 else if (TREE_CODE (*tp) == CALL_EXPR)
107 tree decl = get_callee_fndecl (*tp);
108 if (decl && TREE_CODE (decl) == FUNCTION_DECL)
110 if (DECL_BUILT_IN (decl))
111 return NULL;
112 cgraph_record_call (data, decl);
114 /* When we see a function call, we don't want to look at the
115 function reference in the ADDR_EXPR that is hanging from
116 the CALL_EXPR we're examining here, because we would
117 conclude incorrectly that the function's address could be
118 taken by something that is not a function call. So only
119 walk the function parameter list, skip the other subtrees. */
121 walk_tree (&TREE_OPERAND (*tp, 1), record_call_1, data, NULL);
122 *walk_subtrees = 0;
125 return NULL;
128 /* Create cgraph edges for function calls inside BODY from DECL. */
130 void
131 cgraph_create_edges (tree decl, tree body)
133 /* The nodes we're interested in are never shared, so walk
134 the tree ignoring duplicates. */
135 walk_tree_without_duplicates (&body, record_call_1, decl);
138 /* Analyze the whole compilation unit once it is parsed completely. */
140 void
141 cgraph_finalize_compilation_unit (void)
143 struct cgraph_node *node;
144 struct cgraph_edge *edge;
146 cgraph_varpool_assemble_pending_decls ();
147 if (!quiet_flag)
148 fprintf (stderr, "\nAnalyzing compilation unit\n");
150 timevar_push (TV_CGRAPH);
151 if (cgraph_dump_file)
153 fprintf (cgraph_dump_file, "\nInitial entry points:");
154 for (node = cgraph_nodes; node; node = node->next)
155 if (node->needed && DECL_SAVED_TREE (node->decl))
156 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
157 fprintf (cgraph_dump_file, "\n");
160 /* Propagate reachability flag and lower representation of all reachable
161 functions. In the future, lowering will introduce new functions and
162 new entry points on the way (by template instantiation and virtual
163 method table generation for instance). */
164 while (cgraph_nodes_queue)
166 tree decl = cgraph_nodes_queue->decl;
168 node = cgraph_nodes_queue;
169 cgraph_nodes_queue = cgraph_nodes_queue->next_needed;
171 if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
172 abort ();
174 if (lang_hooks.callgraph.lower_function)
175 (*lang_hooks.callgraph.lower_function) (decl);
177 current_function_decl = node->decl;
179 /* At the moment frontend automatically emits all nested functions. */
180 if (node->nested)
182 struct cgraph_node *node2;
184 for (node2 = node->nested; node2; node2 = node2->next_nested)
185 if (!node2->reachable)
186 cgraph_mark_needed_node (node2, 0);
189 /* First kill forward declaration so reverse inlining works properly. */
190 cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
192 node->local.inlinable = tree_inlinable_function_p (decl, 1);
193 if (!DECL_ESTIMATED_INSNS (decl))
194 DECL_ESTIMATED_INSNS (decl)
195 = (*lang_hooks.tree_inlining.estimate_num_insns) (decl);
196 node->local.self_insns = DECL_ESTIMATED_INSNS (decl);
197 if (node->local.inlinable)
198 node->local.disgread_inline_limits
199 = (*lang_hooks.tree_inlining.disregard_inline_limits) (decl);
201 for (edge = node->callees; edge; edge = edge->next_callee)
203 if (!edge->callee->reachable)
204 cgraph_mark_needed_node (edge->callee, 0);
206 node->lowered = true;
207 cgraph_varpool_assemble_pending_decls ();
209 /* Collect entry points to the unit. */
211 if (cgraph_dump_file)
213 fprintf (cgraph_dump_file, "\nUnit entry points:");
214 for (node = cgraph_nodes; node; node = node->next)
215 if (node->needed && DECL_SAVED_TREE (node->decl))
216 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
217 fprintf (cgraph_dump_file, "\n");
220 if (cgraph_dump_file)
221 fprintf (cgraph_dump_file, "\nReclaiming functions:");
223 for (node = cgraph_nodes; node; node = node->next)
225 tree decl = node->decl;
227 if (!node->reachable && DECL_SAVED_TREE (decl))
229 cgraph_remove_node (node);
230 if (cgraph_dump_file)
231 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
234 if (cgraph_dump_file)
235 fprintf (cgraph_dump_file, "\n");
236 ggc_collect ();
237 timevar_pop (TV_CGRAPH);
240 /* Figure out what functions we want to assemble. */
242 static void
243 cgraph_mark_functions_to_output (void)
245 struct cgraph_node *node;
247 for (node = cgraph_nodes; node; node = node->next)
249 tree decl = node->decl;
250 struct cgraph_edge *e;
251 if (node->output)
252 abort ();
254 for (e = node->callers; e; e = e->next_caller)
255 if (!e->inline_call)
256 break;
258 /* We need to output all local functions that are used and not
259 always inlined, as well as those that are reachable from
260 outside the current compilation unit. */
261 if (DECL_SAVED_TREE (decl)
262 && (node->needed
263 || (e && node->reachable))
264 && !TREE_ASM_WRITTEN (decl) && !node->origin
265 && !DECL_EXTERNAL (decl))
266 node->output = 1;
270 /* Optimize the function before expansion. */
272 static void
273 cgraph_optimize_function (struct cgraph_node *node)
275 tree decl = node->decl;
277 timevar_push (TV_INTEGRATION);
278 /* optimize_inline_calls avoids inlining of current_function_decl. */
279 current_function_decl = 0;
280 if (flag_inline_trees)
281 optimize_inline_calls (decl);
282 if (node->nested)
284 for (node = node->nested; node; node = node->next_nested)
285 cgraph_optimize_function (node);
287 timevar_pop (TV_INTEGRATION);
290 /* Expand function specified by NODE. */
292 static void
293 cgraph_expand_function (struct cgraph_node *node)
295 tree decl = node->decl;
296 struct cgraph_edge *e;
298 announce_function (decl);
300 cgraph_optimize_function (node);
302 /* Generate RTL for the body of DECL. Nested functions are expanded
303 via lang_expand_decl_stmt. */
304 (*lang_hooks.callgraph.expand_function) (decl);
306 for (e = node->callers; e; e = e->next_caller)
307 if (e->inline_call)
308 break;
309 if (!e)
310 DECL_SAVED_TREE (decl) = NULL;
311 current_function_decl = NULL;
314 /* Fill array order with all nodes with output flag set in the reverse
315 topological order. */
316 static int
317 cgraph_postorder (struct cgraph_node **order)
319 struct cgraph_node *node, *node2;
320 int stack_size = 0;
321 int order_pos = 0;
322 struct cgraph_edge *edge, last;
324 struct cgraph_node **stack =
325 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
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)
332 node->aux = NULL;
333 for (node = cgraph_nodes; node; node = node->next)
334 if (!node->aux)
336 node2 = node;
337 if (!node->callers)
338 node->aux = &last;
339 else
340 node->aux = node->callers;
341 while (node2)
343 while (node2->aux != &last)
345 edge = node2->aux;
346 if (edge->next_caller)
347 node2->aux = edge->next_caller;
348 else
349 node2->aux = &last;
350 if (!edge->caller->aux)
352 if (!edge->caller->callers)
353 edge->caller->aux = &last;
354 else
355 edge->caller->aux = edge->caller->callers;
356 stack[stack_size++] = node2;
357 node2 = edge->caller;
358 break;
361 if (node2->aux == &last)
363 order[order_pos++] = node2;
364 if (stack_size)
365 node2 = stack[--stack_size];
366 else
367 node2 = NULL;
371 free (stack);
372 return order_pos;
375 #define INLINED_TIMES(node) ((size_t)(node)->aux)
376 #define SET_INLINED_TIMES(node,times) ((node)->aux = (void *)(times))
378 /* Return list of nodes we decided to inline NODE into, set their output
379 flag and compute INLINED_TIMES.
381 We do simple backtracing to get INLINED_TIMES right. This should not be
382 expensive as we limit the amount of inlining. Alternatively we may first
383 discover set of nodes, topologically sort these and propagate
384 INLINED_TIMES */
386 static int
387 cgraph_inlined_into (struct cgraph_node *node, struct cgraph_node **array)
389 int nfound = 0;
390 struct cgraph_edge **stack;
391 struct cgraph_edge *e, *e1;
392 int sp;
393 int i;
395 /* Fast path: since we traverse in mostly topological order, we will likely
396 find no edges. */
397 for (e = node->callers; e; e = e->next_caller)
398 if (e->inline_call)
399 break;
401 if (!e)
402 return 0;
404 /* Allocate stack for back-tracking up callgraph. */
405 stack = xmalloc ((cgraph_n_nodes + 1) * sizeof (struct cgraph_edge));
406 sp = 0;
408 /* Push the first edge on to the stack. */
409 stack[sp++] = e;
411 while (sp)
413 struct cgraph_node *caller;
415 /* Look at the edge on the top of the stack. */
416 e = stack[sp - 1];
417 caller = e->caller;
419 /* Check if the caller destination has been visited yet. */
420 if (!caller->output)
422 array[nfound++] = e->caller;
423 /* Mark that we have visited the destination. */
424 caller->output = true;
425 SET_INLINED_TIMES (caller, 0);
427 SET_INLINED_TIMES (caller, INLINED_TIMES (caller) + 1);
429 for (e1 = caller->callers; e1; e1 = e1->next_caller)
430 if (e1->inline_call)
431 break;
432 if (e1)
433 stack[sp++] = e1;
434 else
436 while (true)
438 for (e1 = e->next_caller; e1; e1 = e1->next_caller)
439 if (e1->inline_call)
440 break;
442 if (e1)
444 stack[sp - 1] = e1;
445 break;
447 else
449 sp--;
450 if (!sp)
451 break;
452 e = stack[sp - 1];
458 free (stack);
461 if (cgraph_dump_file)
463 fprintf (cgraph_dump_file, "Found inline predecesors of %s:",
464 cgraph_node_name (node));
465 for (i = 0; i < nfound; i++)
467 fprintf (cgraph_dump_file, " %s", cgraph_node_name (array[i]));
468 if (INLINED_TIMES (array[i]) != 1)
469 fprintf (cgraph_dump_file, " (%i times)",
470 (int)INLINED_TIMES (array[i]));
472 fprintf (cgraph_dump_file, "\n");
475 return nfound;
478 /* Return list of nodes we decided to inline into NODE, set their output
479 flag and compute INLINED_TIMES.
481 This function is identical to cgraph_inlined_into with callers and callees
482 nodes swapped. */
484 static int
485 cgraph_inlined_callees (struct cgraph_node *node, struct cgraph_node **array)
487 int nfound = 0;
488 struct cgraph_edge **stack;
489 struct cgraph_edge *e, *e1;
490 int sp;
491 int i;
493 /* Fast path: since we traverse in mostly topological order, we will likely
494 find no edges. */
495 for (e = node->callees; e; e = e->next_callee)
496 if (e->inline_call)
497 break;
499 if (!e)
500 return 0;
502 /* Allocate stack for back-tracking up callgraph. */
503 stack = xmalloc ((cgraph_n_nodes + 1) * sizeof (struct cgraph_edge));
504 sp = 0;
506 /* Push the first edge on to the stack. */
507 stack[sp++] = e;
509 while (sp)
511 struct cgraph_node *callee;
513 /* Look at the edge on the top of the stack. */
514 e = stack[sp - 1];
515 callee = e->callee;
517 /* Check if the callee destination has been visited yet. */
518 if (!callee->output)
520 array[nfound++] = e->callee;
521 /* Mark that we have visited the destination. */
522 callee->output = true;
523 SET_INLINED_TIMES (callee, 0);
525 SET_INLINED_TIMES (callee, INLINED_TIMES (callee) + 1);
527 for (e1 = callee->callees; e1; e1 = e1->next_callee)
528 if (e1->inline_call)
529 break;
530 if (e1)
531 stack[sp++] = e1;
532 else
534 while (true)
536 for (e1 = e->next_callee; e1; e1 = e1->next_callee)
537 if (e1->inline_call)
538 break;
540 if (e1)
542 stack[sp - 1] = e1;
543 break;
545 else
547 sp--;
548 if (!sp)
549 break;
550 e = stack[sp - 1];
556 free (stack);
558 if (cgraph_dump_file)
560 fprintf (cgraph_dump_file, "Found inline successors of %s:",
561 cgraph_node_name (node));
562 for (i = 0; i < nfound; i++)
564 fprintf (cgraph_dump_file, " %s", cgraph_node_name (array[i]));
565 if (INLINED_TIMES (array[i]) != 1)
566 fprintf (cgraph_dump_file, " (%i times)",
567 (int)INLINED_TIMES (array[i]));
569 fprintf (cgraph_dump_file, "\n");
572 return nfound;
575 /* Estimate size of the function after inlining WHAT into TO. */
577 static int
578 cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
579 struct cgraph_node *what)
581 return (what->global.insns - INSNS_PER_CALL) *times + to->global.insns;
584 /* Estimate the growth caused by inlining NODE into all callees. */
586 static int
587 cgraph_estimate_growth (struct cgraph_node *node)
589 int growth = 0;
590 int calls_saved = 0;
591 int clones_added = 0;
592 struct cgraph_edge *e;
594 for (e = node->callers; e; e = e->next_caller)
595 if (!e->inline_call)
597 growth += ((cgraph_estimate_size_after_inlining (1, e->caller, node)
599 e->caller->global.insns) *e->caller->global.cloned_times);
600 calls_saved += e->caller->global.cloned_times;
601 clones_added += e->caller->global.cloned_times;
604 /* ??? Wrong for self recursive functions or cases where we decide to not
605 inline for different reasons, but it is not big deal as in that case
606 we will keep the body around, but we will also avoid some inlining. */
607 if (!node->needed && !node->origin && !DECL_EXTERNAL (node->decl))
608 growth -= node->global.insns, clones_added--;
610 if (!calls_saved)
611 calls_saved = 1;
613 return growth;
616 /* Update insn sizes after inlining WHAT into TO that is already inlined into
617 all nodes in INLINED array. */
619 static void
620 cgraph_mark_inline (struct cgraph_node *to, struct cgraph_node *what,
621 struct cgraph_node **inlined, int ninlined,
622 struct cgraph_node **inlined_callees,
623 int ninlined_callees)
625 int i;
626 int times = 0;
627 int clones = 0;
628 struct cgraph_edge *e;
629 bool called = false;
630 int new_insns;
632 for (e = what->callers; e; e = e->next_caller)
634 if (e->caller == to)
636 if (e->inline_call)
637 abort ();
638 e->inline_call = true;
639 times++;
640 clones += e->caller->global.cloned_times;
642 else if (!e->inline_call)
643 called = true;
645 if (!times)
646 abort ();
647 ncalls_inlined += times;
649 new_insns = cgraph_estimate_size_after_inlining (times, to, what);
650 if (to->global.will_be_output)
651 overall_insns += new_insns - to->global.insns;
652 to->global.insns = new_insns;
654 to->global.calls += (what->global.calls - 1) *times;
655 if (!called && !what->needed && !what->origin
656 && !DECL_EXTERNAL (what->decl))
658 if (!what->global.will_be_output)
659 abort ();
660 clones--;
661 nfunctions_inlined++;
662 what->global.will_be_output = 0;
663 overall_insns -= what->global.insns;
665 what->global.cloned_times += clones;
666 if (to->global.calls < 0)
667 abort ();
668 for (i = 0; i < ninlined; i++)
670 new_insns =
671 cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
672 times, inlined[i], what);
673 if (inlined[i]->global.will_be_output)
674 overall_insns += new_insns - inlined[i]->global.insns;
675 inlined[i]->global.insns = new_insns;
676 inlined[i]->global.calls +=
677 (what->global.calls - 1) *INLINED_TIMES (inlined[i]) * times;
678 if (inlined[i]->global.calls < 0)
679 abort ();
681 for (i = 0; i < ninlined_callees; i++)
683 inlined_callees[i]->global.cloned_times +=
684 INLINED_TIMES (inlined_callees[i]) * clones;
688 /* Return false when inlining WHAT into TO is not good idea as it would cause
689 too large growth of function bodies. */
691 static bool
692 cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
693 struct cgraph_node **inlined, int ninlined)
695 int i;
696 int times = 0;
697 struct cgraph_edge *e;
698 int newsize;
699 int limit;
701 for (e = to->callees; e; e = e->next_callee)
702 if (e->callee == what)
703 times++;
705 /* When inlining large function body called once into small function,
706 take the inlined function as base for limiting the growth. */
707 if (to->local.self_insns > what->local.self_insns)
708 limit = to->local.self_insns;
709 else
710 limit = what->local.self_insns;
712 limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
714 newsize = cgraph_estimate_size_after_inlining (times, to, what);
715 if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
716 && newsize > limit)
717 return false;
718 for (i = 0; i < ninlined; i++)
720 newsize =
721 cgraph_estimate_size_after_inlining (INLINED_TIMES (inlined[i]) *
722 times, inlined[i], what);
723 if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
724 && newsize >
725 inlined[i]->local.self_insns *
726 (100 + PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH)) / 100)
727 return false;
729 return true;
732 /* Return true when function N is small enought to be inlined. */
734 static bool
735 cgraph_default_inline_p (struct cgraph_node *n)
737 if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
738 return false;
739 if (DID_INLINE_FUNC (n->decl))
740 return n->global.insns < MAX_INLINE_INSNS_AUTO;
741 else
742 return n->global.insns < MAX_INLINE_INSNS_SINGLE;
745 /* We use greedy algorithm for inlining of small functions:
746 All inline candidates are put into prioritized heap based on estimated
747 growth of the overall number of instructions and then update the estimates.
749 INLINED and INLINED_CALEES are just pointers to arrays large enought
750 to be passed to cgraph_inlined_into and cgraph_inlined_callees. */
752 static void
753 cgraph_decide_inlining_of_small_functions (struct cgraph_node **inlined,
754 struct cgraph_node **inlined_callees)
756 int i;
757 struct cgraph_node *node;
758 fibheap_t heap = fibheap_new ();
759 struct fibnode **heap_node =
760 xcalloc (sizeof (struct fibnode *), cgraph_max_uid);
761 int ninlined, ninlined_callees;
762 int max_insns = ((HOST_WIDEST_INT) initial_insns
763 * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
765 /* Put all inline candidates into the heap. */
767 for (node = cgraph_nodes; node; node = node->next)
769 struct cgraph_edge *e;
771 if (!node->local.inlinable || !node->callers
772 || !cgraph_default_inline_p (node))
773 continue;
775 /* Rule out always_inline functions we dealt with earler. */
776 for (e = node->callers; e; e = e->next_caller)
777 if (e->inline_call)
778 break;
779 if (e)
780 continue;
781 heap_node[node->uid] =
782 fibheap_insert (heap, cgraph_estimate_growth (node), node);
785 if (cgraph_dump_file)
786 fprintf (cgraph_dump_file, "\n\nDeciding on inlining: ");
787 while ((node = fibheap_extract_min (heap)) && overall_insns <= max_insns)
789 struct cgraph_edge *e;
790 int old_insns = overall_insns;
792 heap_node[node->uid] = NULL;
793 if (cgraph_dump_file)
794 fprintf (cgraph_dump_file, "Considering %s %i insns, growth %i.\n",
795 cgraph_node_name (node), node->global.insns,
796 cgraph_estimate_growth (node));
797 if (!cgraph_default_inline_p (node))
799 if (cgraph_dump_file)
800 fprintf (cgraph_dump_file, "Function too large.\n");
801 continue;
803 ninlined_callees = cgraph_inlined_callees (node, inlined_callees);
804 for (e = node->callers; e; e = e->next_caller)
805 if (!e->inline_call && e->caller != node)
807 ninlined = cgraph_inlined_into (e->caller, inlined);
808 if (e->callee->output
809 || !cgraph_check_inline_limits (e->caller, node, inlined,
810 ninlined))
812 for (i = 0; i < ninlined; i++)
813 inlined[i]->output = 0, node->aux = 0;
814 if (cgraph_dump_file)
815 fprintf (cgraph_dump_file, "Not inlining into %s\n",
816 cgraph_node_name (e->caller));
817 continue;
819 cgraph_mark_inline (e->caller, node, inlined, ninlined,
820 inlined_callees, ninlined_callees);
821 if (heap_node[e->caller->uid])
822 fibheap_replace_key (heap, heap_node[e->caller->uid],
823 cgraph_estimate_growth (e->caller));
825 /* Size of the functions we updated into has changed, so update
826 the keys. */
827 for (i = 0; i < ninlined; i++)
829 inlined[i]->output = 0, node->aux = 0;
830 if (heap_node[inlined[i]->uid])
831 fibheap_replace_key (heap, heap_node[inlined[i]->uid],
832 cgraph_estimate_growth (inlined[i]));
836 /* Similarly all functions called by function we just inlined
837 are now called more times; update keys. */
839 for (e = node->callees; e; e = e->next_callee)
840 if (!e->inline_call && heap_node[e->callee->uid])
841 fibheap_replace_key (heap, heap_node[e->callee->uid],
842 cgraph_estimate_growth (e->callee));
844 for (i = 0; i < ninlined_callees; i++)
846 struct cgraph_edge *e;
848 for (e = inlined_callees[i]->callees; e; e = e->next_callee)
849 if (!e->inline_call && heap_node[e->callee->uid])
850 fibheap_replace_key (heap, heap_node[e->callee->uid],
851 cgraph_estimate_growth (e->callee));
853 inlined_callees[i]->output = 0, node->aux = 0;
855 if (cgraph_dump_file)
856 fprintf (cgraph_dump_file,
857 "Created %i clones, Num insns:%i (%+i), %.2f%%.\n\n",
858 node->global.cloned_times - 1,
859 overall_insns, overall_insns - old_insns,
860 overall_insns * 100.0 / initial_insns);
862 if (cgraph_dump_file && !fibheap_empty (heap))
863 fprintf (cgraph_dump_file, "inline-unit-growth limit reached.\n");
864 fibheap_delete (heap);
865 free (heap_node);
868 /* Decide on the inlining. We do so in the topological order to avoid
869 expenses on updating datastructures. */
871 static void
872 cgraph_decide_inlining (void)
874 struct cgraph_node *node;
875 int nnodes;
876 struct cgraph_node **order =
877 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
878 struct cgraph_node **inlined =
879 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
880 struct cgraph_node **inlined_callees =
881 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
882 int ninlined;
883 int ninlined_callees;
884 int i, y;
886 for (node = cgraph_nodes; node; node = node->next)
888 int ncalls = 0;
889 struct cgraph_edge *e;
891 node->global.insns = node->local.self_insns;
892 for (e = node->callees; e; e = e->next_callee)
893 ncalls++;
894 node->global.calls = ncalls;
895 if (!DECL_EXTERNAL (node->decl))
897 node->global.cloned_times = 1;
898 initial_insns += node->local.self_insns;
899 node->global.will_be_output = true;
902 overall_insns = initial_insns;
904 nnodes = cgraph_postorder (order);
906 for (node = cgraph_nodes; node; node = node->next)
907 node->aux = 0;
909 if (cgraph_dump_file)
910 fprintf (cgraph_dump_file, "\n\nDeciding on always_inline functions:\n");
912 /* In the first pass mark all always_inline edges. Do this with a priority
913 so no our decisions makes this impossible. */
914 for (i = nnodes - 1; i >= 0; i--)
916 struct cgraph_edge *e;
918 node = order[i];
920 for (e = node->callees; e; e = e->next_callee)
921 if (e->callee->local.disgread_inline_limits)
922 break;
923 if (!e)
924 continue;
925 if (cgraph_dump_file)
926 fprintf (cgraph_dump_file,
927 "Considering %s %i insns (always inline)\n",
928 cgraph_node_name (node), node->global.insns);
929 ninlined = cgraph_inlined_into (order[i], inlined);
930 for (; e; e = e->next_callee)
932 if (e->inline_call || !e->callee->local.disgread_inline_limits)
933 continue;
934 if (e->callee->output || e->callee == node)
935 continue;
936 ninlined_callees =
937 cgraph_inlined_callees (e->callee, inlined_callees);
938 cgraph_mark_inline (node, e->callee, inlined, ninlined,
939 inlined_callees, ninlined_callees);
940 for (y = 0; y < ninlined_callees; y++)
941 inlined_callees[y]->output = 0, node->aux = 0;
942 if (cgraph_dump_file)
943 fprintf (cgraph_dump_file, "Inlined %i times. Now %i insns\n\n",
944 node->global.cloned_times, overall_insns);
946 for (y = 0; y < ninlined; y++)
947 inlined[y]->output = 0, node->aux = 0;
950 cgraph_decide_inlining_of_small_functions (inlined, inlined_callees);
952 if (cgraph_dump_file)
953 fprintf (cgraph_dump_file, "\n\nFunctions to inline once:\n");
955 /* And finally decide what functions are called once. */
957 for (i = nnodes - 1; i >= 0; i--)
959 node = order[i];
961 if (node->callers && !node->callers->next_caller && !node->needed
962 && node->local.inlinable && !node->callers->inline_call
963 && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
965 bool ok = true;
966 struct cgraph_node *node1;
968 /* Verify that we won't duplicate the caller. */
969 for (node1 = node->callers->caller;
970 node1->callers && node1->callers->inline_call
971 && ok; node1 = node1->callers->caller)
972 if (node1->callers->next_caller || node1->needed)
973 ok = false;
974 if (ok)
976 if (cgraph_dump_file)
977 fprintf (cgraph_dump_file,
978 "Considering %s %i insns (called once)\n",
979 cgraph_node_name (node), node->global.insns);
980 ninlined = cgraph_inlined_into (node->callers->caller, inlined);
981 if (cgraph_check_inline_limits
982 (node->callers->caller, node, inlined, ninlined))
984 ninlined_callees =
985 cgraph_inlined_callees (node, inlined_callees);
986 cgraph_mark_inline (node->callers->caller, node, inlined,
987 ninlined, inlined_callees,
988 ninlined_callees);
989 for (y = 0; y < ninlined_callees; y++)
990 inlined_callees[y]->output = 0, node->aux = 0;
991 if (cgraph_dump_file)
992 fprintf (cgraph_dump_file, "Inlined. Now %i insns\n\n", overall_insns);
994 for (y = 0; y < ninlined; y++)
995 inlined[y]->output = 0, node->aux = 0;
1000 if (cgraph_dump_file)
1001 fprintf (cgraph_dump_file,
1002 "\nInlined %i calls, elliminated %i functions, %i insns turned to %i insns.\n",
1003 ncalls_inlined, nfunctions_inlined, initial_insns,
1004 overall_insns);
1005 free (order);
1006 free (inlined);
1007 free (inlined_callees);
1010 /* Return true when CALLER_DECL should be inlined into CALLEE_DECL. */
1012 bool
1013 cgraph_inline_p (tree caller_decl, tree callee_decl)
1015 struct cgraph_node *caller = cgraph_node (caller_decl);
1016 struct cgraph_node *callee = cgraph_node (callee_decl);
1017 struct cgraph_edge *e;
1019 for (e = caller->callees; e; e = e->next_callee)
1020 if (e->callee == callee)
1021 return e->inline_call;
1022 /* We do not record builtins in the callgraph. Perhaps it would make more
1023 sense to do so and then prune out those not overwriten by explicit
1024 function body. */
1025 return false;
1027 /* Expand all functions that must be output.
1029 Attempt to topologically sort the nodes so function is output when
1030 all called functions are already assembled to allow data to be
1031 propagated accross the callgraph. Use a stack to get smaller distance
1032 between a function and it's callees (later we may choose to use a more
1033 sophisticated algorithm for function reordering; we will likely want
1034 to use subsections to make the output functions appear in top-down
1035 order). */
1037 static void
1038 cgraph_expand_functions (void)
1040 struct cgraph_node *node;
1041 struct cgraph_node **order =
1042 xcalloc (sizeof (struct cgraph_node *), cgraph_n_nodes);
1043 int order_pos = 0;
1044 int i;
1046 cgraph_mark_functions_to_output ();
1048 order_pos = cgraph_postorder (order);
1050 for (i = order_pos - 1; i >= 0; i--)
1052 node = order[i];
1053 if (node->output)
1055 if (!node->reachable)
1056 abort ();
1057 node->output = 0;
1058 cgraph_expand_function (node);
1061 free (order);
1064 /* Mark all local functions.
1066 Local function is function whose calls can occur only in the
1067 current compilation unit so we change it's calling convetion.
1068 We simply mark all static functions whose address is not taken
1069 as local. */
1071 static void
1072 cgraph_mark_local_functions (void)
1074 struct cgraph_node *node;
1076 if (cgraph_dump_file)
1077 fprintf (cgraph_dump_file, "Marking local functions:");
1079 /* Figure out functions we want to assemble. */
1080 for (node = cgraph_nodes; node; node = node->next)
1082 node->local.local = (!node->needed
1083 && DECL_SAVED_TREE (node->decl)
1084 && !TREE_PUBLIC (node->decl));
1085 if (cgraph_dump_file && node->local.local)
1086 fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
1088 if (cgraph_dump_file)
1089 fprintf (cgraph_dump_file, "\n");
1092 /* Perform simple optimizations based on callgraph. */
1094 void
1095 cgraph_optimize (void)
1097 timevar_push (TV_CGRAPHOPT);
1098 if (!quiet_flag)
1099 fprintf (stderr, "Performing intraprocedural optimizations\n");
1100 if (cgraph_dump_file)
1102 fprintf (cgraph_dump_file, "Initial callgraph:");
1103 dump_cgraph (cgraph_dump_file);
1105 cgraph_mark_local_functions ();
1107 cgraph_decide_inlining ();
1109 cgraph_global_info_ready = true;
1110 if (cgraph_dump_file)
1112 fprintf (cgraph_dump_file, "Optimized callgraph:");
1113 dump_cgraph (cgraph_dump_file);
1115 timevar_pop (TV_CGRAPHOPT);
1116 if (!quiet_flag)
1117 fprintf (stderr, "Assembling functions:");
1119 /* Output everything. */
1120 cgraph_expand_functions ();
1121 if (cgraph_dump_file)
1123 fprintf (cgraph_dump_file, "Final callgraph:");
1124 dump_cgraph (cgraph_dump_file);