* combine.c (try_combine): Use hard_regno_nregs array instead of
[official-gcc.git] / gcc / ipa-inline.c
blob5a336ff1b1b3ba2e575ea19527288b92512c37d5
1 /* Inlining decision heuristics.
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 /* Inlining decision heuristics
24 We separate inlining decisions from the inliner itself and store it
25 inside callgraph as so called inline plan. Refer to cgraph.c
26 documentation about particular representation of inline plans in the
27 callgraph.
29 There are three major parts of this file:
31 cgraph_mark_inline implementation
33 This function allows to mark given call inline and performs necessary
34 modifications of cgraph (production of the clones and updating overall
35 statistics)
37 inlining heuristics limits
39 These functions allow to check that particular inlining is allowed
40 by the limits specified by user (allowed function growth, overall unit
41 growth and so on).
43 inlining heuristics
45 This is implementation of IPA pass aiming to get as much of benefit
46 from inlining obeying the limits checked above.
48 The implementation of particular heuristics is separated from
49 the rest of code to make it easier to replace it with more complicated
50 implementation in the future. The rest of inlining code acts as a
51 library aimed to modify the callgraph and verify that the parameters
52 on code size growth fits.
54 To mark given call inline, use cgraph_mark_inline function, the
55 verification is performed by cgraph_default_inline_p and
56 cgraph_check_inline_limits.
58 The heuristics implements simple knapsack style algorithm ordering
59 all functions by their "profitability" (estimated by code size growth)
60 and inlining them in priority order.
62 cgraph_decide_inlining implements heuristics taking whole callgraph
63 into account, while cgraph_decide_inlining_incrementally considers
64 only one function at a time and is used in non-unit-at-a-time mode. */
66 #include "config.h"
67 #include "system.h"
68 #include "coretypes.h"
69 #include "tm.h"
70 #include "tree.h"
71 #include "tree-inline.h"
72 #include "langhooks.h"
73 #include "flags.h"
74 #include "cgraph.h"
75 #include "diagnostic.h"
76 #include "timevar.h"
77 #include "params.h"
78 #include "fibheap.h"
79 #include "intl.h"
80 #include "tree-pass.h"
81 #include "coverage.h"
83 /* Statistics we collect about inlining algorithm. */
84 static int ncalls_inlined;
85 static int nfunctions_inlined;
86 static int initial_insns;
87 static int overall_insns;
88 static int max_insns;
89 static gcov_type max_count;
91 /* Estimate size of the function after inlining WHAT into TO. */
93 static int
94 cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
95 struct cgraph_node *what)
97 int size;
98 tree fndecl = what->decl, arg;
99 int call_insns = PARAM_VALUE (PARAM_INLINE_CALL_COST);
101 for (arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
102 call_insns += estimate_move_cost (TREE_TYPE (arg));
103 size = (what->global.insns - call_insns) * times + to->global.insns;
104 gcc_assert (size >= 0);
105 return size;
108 /* E is expected to be an edge being inlined. Clone destination node of
109 the edge and redirect it to the new clone.
110 DUPLICATE is used for bookkeeping on whether we are actually creating new
111 clones or re-using node originally representing out-of-line function call.
113 void
114 cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate)
116 struct cgraph_node *n;
118 /* We may eliminate the need for out-of-line copy to be output. In that
119 case just go ahead and re-use it. */
120 if (!e->callee->callers->next_caller
121 && (!e->callee->needed || DECL_EXTERNAL (e->callee->decl))
122 && duplicate
123 && flag_unit_at_a_time)
125 gcc_assert (!e->callee->global.inlined_to);
126 if (!DECL_EXTERNAL (e->callee->decl))
127 overall_insns -= e->callee->global.insns, nfunctions_inlined++;
128 duplicate = 0;
130 else if (duplicate)
132 n = cgraph_clone_node (e->callee, e->count, e->loop_nest);
133 cgraph_redirect_edge_callee (e, n);
136 if (e->caller->global.inlined_to)
137 e->callee->global.inlined_to = e->caller->global.inlined_to;
138 else
139 e->callee->global.inlined_to = e->caller;
141 /* Recursively clone all bodies. */
142 for (e = e->callee->callees; e; e = e->next_callee)
143 if (!e->inline_failed)
144 cgraph_clone_inlined_nodes (e, duplicate);
147 /* Mark edge E as inlined and update callgraph accordingly. */
149 void
150 cgraph_mark_inline_edge (struct cgraph_edge *e)
152 int old_insns = 0, new_insns = 0;
153 struct cgraph_node *to = NULL, *what;
155 gcc_assert (e->inline_failed);
156 e->inline_failed = NULL;
158 if (!e->callee->global.inlined && flag_unit_at_a_time)
159 DECL_POSSIBLY_INLINED (e->callee->decl) = true;
160 e->callee->global.inlined = true;
162 cgraph_clone_inlined_nodes (e, true);
164 what = e->callee;
166 /* Now update size of caller and all functions caller is inlined into. */
167 for (;e && !e->inline_failed; e = e->caller->callers)
169 old_insns = e->caller->global.insns;
170 new_insns = cgraph_estimate_size_after_inlining (1, e->caller,
171 what);
172 gcc_assert (new_insns >= 0);
173 to = e->caller;
174 to->global.insns = new_insns;
176 gcc_assert (what->global.inlined_to == to);
177 if (new_insns > old_insns)
178 overall_insns += new_insns - old_insns;
179 ncalls_inlined++;
182 /* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.
183 Return following unredirected edge in the list of callers
184 of EDGE->CALLEE */
186 static struct cgraph_edge *
187 cgraph_mark_inline (struct cgraph_edge *edge)
189 struct cgraph_node *to = edge->caller;
190 struct cgraph_node *what = edge->callee;
191 struct cgraph_edge *e, *next;
192 int times = 0;
194 /* Look for all calls, mark them inline and clone recursively
195 all inlined functions. */
196 for (e = what->callers; e; e = next)
198 next = e->next_caller;
199 if (e->caller == to && e->inline_failed)
201 cgraph_mark_inline_edge (e);
202 if (e == edge)
203 edge = next;
204 times++;
207 gcc_assert (times);
208 return edge;
211 /* Estimate the growth caused by inlining NODE into all callees. */
213 static int
214 cgraph_estimate_growth (struct cgraph_node *node)
216 int growth = 0;
217 struct cgraph_edge *e;
218 if (node->global.estimated_growth != INT_MIN)
219 return node->global.estimated_growth;
221 for (e = node->callers; e; e = e->next_caller)
222 if (e->inline_failed)
223 growth += (cgraph_estimate_size_after_inlining (1, e->caller, node)
224 - e->caller->global.insns);
226 /* ??? Wrong for self recursive functions or cases where we decide to not
227 inline for different reasons, but it is not big deal as in that case
228 we will keep the body around, but we will also avoid some inlining. */
229 if (!node->needed && !DECL_EXTERNAL (node->decl))
230 growth -= node->global.insns;
232 node->global.estimated_growth = growth;
233 return growth;
236 /* Return false when inlining WHAT into TO is not good idea
237 as it would cause too large growth of function bodies. */
239 static bool
240 cgraph_check_inline_limits (struct cgraph_node *to, struct cgraph_node *what,
241 const char **reason)
243 int times = 0;
244 struct cgraph_edge *e;
245 int newsize;
246 int limit;
248 if (to->global.inlined_to)
249 to = to->global.inlined_to;
251 for (e = to->callees; e; e = e->next_callee)
252 if (e->callee == what)
253 times++;
255 /* When inlining large function body called once into small function,
256 take the inlined function as base for limiting the growth. */
257 if (to->local.self_insns > what->local.self_insns)
258 limit = to->local.self_insns;
259 else
260 limit = what->local.self_insns;
262 limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
264 newsize = cgraph_estimate_size_after_inlining (times, to, what);
265 if (newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
266 && newsize > limit)
268 if (reason)
269 *reason = N_("--param large-function-growth limit reached");
270 return false;
272 return true;
275 /* Return true when function N is small enough to be inlined. */
277 bool
278 cgraph_default_inline_p (struct cgraph_node *n)
280 if (!DECL_INLINE (n->decl) || !DECL_SAVED_TREE (n->decl))
281 return false;
282 if (DECL_DECLARED_INLINE_P (n->decl))
283 return n->global.insns < MAX_INLINE_INSNS_SINGLE;
284 else
285 return n->global.insns < MAX_INLINE_INSNS_AUTO;
288 /* Return true when inlining WHAT would create recursive inlining.
289 We call recursive inlining all cases where same function appears more than
290 once in the single recursion nest path in the inline graph. */
292 static bool
293 cgraph_recursive_inlining_p (struct cgraph_node *to,
294 struct cgraph_node *what,
295 const char **reason)
297 bool recursive;
298 if (to->global.inlined_to)
299 recursive = what->decl == to->global.inlined_to->decl;
300 else
301 recursive = what->decl == to->decl;
302 /* Marking recursive function inline has sane semantic and thus we should
303 not warn on it. */
304 if (recursive && reason)
305 *reason = (what->local.disregard_inline_limits
306 ? N_("recursive inlining") : "");
307 return recursive;
310 /* Return true if the call can be hot. */
311 static bool
312 cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
314 if (profile_info && flag_branch_probabilities
315 && (edge->count
316 <= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
317 return false;
318 return true;
321 /* A cost model driving the inlining heuristics in a way so the edges with
322 smallest badness are inlined first. After each inlining is performed
323 the costs of all caller edges of nodes affected are recomputed so the
324 metrics may accurately depend on values such as number of inlinable callers
325 of the function or function body size.
327 For the moment we use estimated growth caused by inlining callee into all
328 it's callers for driving the inlining but once we have loop depth or
329 frequency information readily available we should do better.
331 With profiling we use number of executions of each edge to drive the cost.
332 We also should distinguish hot and cold calls where the cold calls are
333 inlined into only when code size is overall improved.
335 Value INT_MAX can be returned to prevent function from being inlined.
338 static int
339 cgraph_edge_badness (struct cgraph_edge *edge)
341 if (max_count)
343 int growth =
344 cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
345 growth -= edge->caller->global.insns;
347 /* Always prefer inlining saving code size. */
348 if (growth <= 0)
349 return INT_MIN - growth;
350 return ((int)((double)edge->count * INT_MIN / max_count)) / growth;
352 else
354 int nest = MIN (edge->loop_nest, 8);
355 int badness = cgraph_estimate_growth (edge->callee) * 256;
357 badness >>= nest;
359 /* Make recursive inlining happen always after other inlining is done. */
360 if (cgraph_recursive_inlining_p (edge->caller, edge->callee, NULL))
361 return badness + 1;
362 else
363 return badness;
367 /* Recompute heap nodes for each of caller edge. */
369 static void
370 update_caller_keys (fibheap_t heap, struct cgraph_node *node,
371 bitmap updated_nodes)
373 struct cgraph_edge *edge;
375 if (!node->local.inlinable || node->local.disregard_inline_limits
376 || node->global.inlined_to)
377 return;
378 if (bitmap_bit_p (updated_nodes, node->uid))
379 return;
380 bitmap_set_bit (updated_nodes, node->uid);
382 for (edge = node->callers; edge; edge = edge->next_caller)
383 if (edge->inline_failed)
385 int badness = cgraph_edge_badness (edge);
386 if (edge->aux)
388 fibnode_t n = edge->aux;
389 gcc_assert (n->data == edge);
390 if (n->key == badness)
391 continue;
393 /* fibheap_replace_key only increase the keys. */
394 if (fibheap_replace_key (heap, n, badness))
395 continue;
396 fibheap_delete_node (heap, edge->aux);
398 edge->aux = fibheap_insert (heap, badness, edge);
402 /* Recompute heap nodes for each of caller edges of each of callees. */
404 static void
405 update_callee_keys (fibheap_t heap, struct cgraph_node *node,
406 bitmap updated_nodes)
408 struct cgraph_edge *e;
409 node->global.estimated_growth = INT_MIN;
411 for (e = node->callees; e; e = e->next_callee)
412 if (e->inline_failed)
413 update_caller_keys (heap, e->callee, updated_nodes);
414 else if (!e->inline_failed)
415 update_callee_keys (heap, e->callee, updated_nodes);
418 /* Enqueue all recursive calls from NODE into priority queue depending on
419 how likely we want to recursively inline the call. */
421 static void
422 lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
423 fibheap_t heap)
425 static int priority;
426 struct cgraph_edge *e;
427 for (e = where->callees; e; e = e->next_callee)
428 if (e->callee == node)
430 /* FIXME: Once counts and frequencies are available we should drive the
431 order by these. For now force the order to be simple queue since
432 we get order dependent on recursion depth for free by this. */
433 fibheap_insert (heap, priority++, e);
435 for (e = where->callees; e; e = e->next_callee)
436 if (!e->inline_failed)
437 lookup_recursive_calls (node, e->callee, heap);
440 /* Decide on recursive inlining: in the case function has recursive calls,
441 inline until body size reaches given argument. */
443 static bool
444 cgraph_decide_recursive_inlining (struct cgraph_node *node)
446 int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
447 int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
448 fibheap_t heap;
449 struct cgraph_edge *e;
450 struct cgraph_node *master_clone;
451 int depth = 0;
452 int n = 0;
454 if (DECL_DECLARED_INLINE_P (node->decl))
456 limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
457 max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
460 /* Make sure that function is small enough to be considered for inlining. */
461 if (!max_depth
462 || cgraph_estimate_size_after_inlining (1, node, node) >= limit)
463 return false;
464 heap = fibheap_new ();
465 lookup_recursive_calls (node, node, heap);
466 if (fibheap_empty (heap))
468 fibheap_delete (heap);
469 return false;
472 if (dump_file)
473 fprintf (dump_file,
474 " Performing recursive inlining on %s\n",
475 cgraph_node_name (node));
477 /* We need original clone to copy around. */
478 master_clone = cgraph_clone_node (node, 0, 1);
479 master_clone->needed = true;
480 for (e = master_clone->callees; e; e = e->next_callee)
481 if (!e->inline_failed)
482 cgraph_clone_inlined_nodes (e, true);
484 /* Do the inlining and update list of recursive call during process. */
485 while (!fibheap_empty (heap)
486 && cgraph_estimate_size_after_inlining (1, node, master_clone) <= limit)
488 struct cgraph_edge *curr = fibheap_extract_min (heap);
489 struct cgraph_node *node;
491 depth = 0;
492 for (node = curr->caller;
493 node; node = node->global.inlined_to)
494 if (node->decl == curr->callee->decl)
495 depth++;
496 if (depth > max_depth)
497 continue;
499 if (dump_file)
500 fprintf (dump_file,
501 " Inlining call of depth %i\n", depth);
502 cgraph_redirect_edge_callee (curr, master_clone);
503 cgraph_mark_inline_edge (curr);
504 lookup_recursive_calls (node, curr->callee, heap);
505 n++;
508 fibheap_delete (heap);
509 if (dump_file)
510 fprintf (dump_file,
511 "\n Inlined %i times, body grown from %i to %i insns\n", n,
512 master_clone->global.insns, node->global.insns);
514 /* Remove master clone we used for inlining. We rely that clones inlined
515 into master clone gets queued just before master clone so we don't
516 need recursion. */
517 for (node = cgraph_nodes; node != master_clone;
518 node = node->next)
519 if (node->global.inlined_to == master_clone)
520 cgraph_remove_node (node);
521 cgraph_remove_node (master_clone);
522 return true;
525 /* Set inline_failed for all callers of given function to REASON. */
527 static void
528 cgraph_set_inline_failed (struct cgraph_node *node, const char *reason)
530 struct cgraph_edge *e;
532 if (dump_file)
533 fprintf (dump_file, "Inlining failed: %s\n", reason);
534 for (e = node->callers; e; e = e->next_caller)
535 if (e->inline_failed)
536 e->inline_failed = reason;
539 /* We use greedy algorithm for inlining of small functions:
540 All inline candidates are put into prioritized heap based on estimated
541 growth of the overall number of instructions and then update the estimates.
543 INLINED and INLINED_CALEES are just pointers to arrays large enough
544 to be passed to cgraph_inlined_into and cgraph_inlined_callees. */
546 static void
547 cgraph_decide_inlining_of_small_functions (void)
549 struct cgraph_node *node;
550 struct cgraph_edge *edge;
551 fibheap_t heap = fibheap_new ();
552 bitmap updated_nodes = BITMAP_ALLOC (NULL);
554 if (dump_file)
555 fprintf (dump_file, "\nDeciding on smaller functions:\n");
557 /* Put all inline candidates into the heap. */
559 for (node = cgraph_nodes; node; node = node->next)
561 if (!node->local.inlinable || !node->callers
562 || node->local.disregard_inline_limits)
563 continue;
564 if (dump_file)
565 fprintf (dump_file, "Considering inline candidate %s.\n", cgraph_node_name (node));
567 node->global.estimated_growth = INT_MIN;
568 if (!cgraph_default_inline_p (node))
570 cgraph_set_inline_failed (node,
571 N_("--param max-inline-insns-single limit reached"));
572 continue;
575 for (edge = node->callers; edge; edge = edge->next_caller)
576 if (edge->inline_failed)
578 gcc_assert (!edge->aux);
579 edge->aux = fibheap_insert (heap, cgraph_edge_badness (edge), edge);
582 while (overall_insns <= max_insns && (edge = fibheap_extract_min (heap)))
584 int old_insns = overall_insns;
585 struct cgraph_node *where;
586 int growth =
587 cgraph_estimate_size_after_inlining (1, edge->caller, edge->callee);
589 growth -= edge->caller->global.insns;
591 if (dump_file)
593 fprintf (dump_file,
594 "\nConsidering %s with %i insns to be inlined into %s\n"
595 " Estimated growth after inlined into all callees is %+i insns.\n"
596 " Estimated badness is %i.\n",
597 cgraph_node_name (edge->callee),
598 edge->callee->global.insns,
599 cgraph_node_name (edge->caller),
600 cgraph_estimate_growth (edge->callee),
601 cgraph_edge_badness (edge));
602 if (edge->count)
603 fprintf (dump_file," Called "HOST_WIDEST_INT_PRINT_DEC"x\n", edge->count);
605 gcc_assert (edge->aux);
606 edge->aux = NULL;
607 if (!edge->inline_failed)
608 continue;
610 /* When not having profile info ready we don't weight by any way the
611 position of call in procedure itself. This means if call of
612 function A from function B seems profitable to inline, the recursive
613 call of function A in inline copy of A in B will look profitable too
614 and we end up inlining until reaching maximal function growth. This
615 is not good idea so prohibit the recursive inlining.
617 ??? When the frequencies are taken into account we might not need this
618 restriction. */
619 if (!max_count)
621 where = edge->caller;
622 while (where->global.inlined_to)
624 if (where->decl == edge->callee->decl)
625 break;
626 where = where->callers->caller;
628 if (where->global.inlined_to)
630 edge->inline_failed
631 = (edge->callee->local.disregard_inline_limits ? N_("recursive inlining") : "");
632 if (dump_file)
633 fprintf (dump_file, " inline_failed:Recursive inlining performed only for function itself.\n");
634 continue;
638 if (!cgraph_maybe_hot_edge_p (edge) && growth > 0)
640 if (!cgraph_recursive_inlining_p (edge->caller, edge->callee,
641 &edge->inline_failed))
643 edge->inline_failed =
644 N_("call is unlikely");
645 if (dump_file)
646 fprintf (dump_file, " inline_failed:%s.\n", edge->inline_failed);
648 continue;
650 if (!cgraph_default_inline_p (edge->callee))
652 if (!cgraph_recursive_inlining_p (edge->caller, edge->callee,
653 &edge->inline_failed))
655 edge->inline_failed =
656 N_("--param max-inline-insns-single limit reached after inlining into the callee");
657 if (dump_file)
658 fprintf (dump_file, " inline_failed:%s.\n", edge->inline_failed);
660 continue;
662 if (cgraph_recursive_inlining_p (edge->caller, edge->callee,
663 &edge->inline_failed))
665 where = edge->caller;
666 if (where->global.inlined_to)
667 where = where->global.inlined_to;
668 if (!cgraph_decide_recursive_inlining (where))
669 continue;
670 update_callee_keys (heap, where, updated_nodes);
672 else
674 if (!cgraph_check_inline_limits (edge->caller, edge->callee,
675 &edge->inline_failed))
677 if (dump_file)
678 fprintf (dump_file, " Not inlining into %s:%s.\n",
679 cgraph_node_name (edge->caller), edge->inline_failed);
680 continue;
682 cgraph_mark_inline_edge (edge);
683 update_callee_keys (heap, edge->callee, updated_nodes);
685 where = edge->caller;
686 if (where->global.inlined_to)
687 where = where->global.inlined_to;
689 /* Our profitability metric can depend on local properties
690 such as number of inlinable calls and size of the function body.
691 After inlining these properties might change for the function we
692 inlined into (since it's body size changed) and for the functions
693 called by function we inlined (since number of it inlinable callers
694 might change). */
695 update_caller_keys (heap, where, updated_nodes);
696 bitmap_clear (updated_nodes);
698 if (dump_file)
699 fprintf (dump_file,
700 " Inlined into %s which now has %i insns.\n",
701 cgraph_node_name (edge->caller),
702 edge->caller->global.insns);
703 if (dump_file)
704 fprintf (dump_file,
705 " Inlined for a net change of %+i insns.\n",
706 overall_insns - old_insns);
708 while ((edge = fibheap_extract_min (heap)) != NULL)
710 gcc_assert (edge->aux);
711 edge->aux = NULL;
712 if (!edge->callee->local.disregard_inline_limits && edge->inline_failed
713 && !cgraph_recursive_inlining_p (edge->caller, edge->callee,
714 &edge->inline_failed))
715 edge->inline_failed = N_("--param inline-unit-growth limit reached");
717 fibheap_delete (heap);
718 BITMAP_FREE (updated_nodes);
721 /* Decide on the inlining. We do so in the topological order to avoid
722 expenses on updating data structures. */
724 static void
725 cgraph_decide_inlining (void)
727 struct cgraph_node *node;
728 int nnodes;
729 struct cgraph_node **order =
730 xcalloc (cgraph_n_nodes, sizeof (struct cgraph_node *));
731 int old_insns = 0;
732 int i;
734 timevar_push (TV_INLINE_HEURISTICS);
735 max_count = 0;
736 for (node = cgraph_nodes; node; node = node->next)
738 struct cgraph_edge *e;
739 initial_insns += node->local.self_insns;
740 for (e = node->callees; e; e = e->next_callee)
741 if (max_count < e->count)
742 max_count = e->count;
744 overall_insns = initial_insns;
745 gcc_assert (!max_count || (profile_info && flag_branch_probabilities));
747 max_insns = ((HOST_WIDEST_INT) overall_insns
748 * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
750 nnodes = cgraph_postorder (order);
752 if (dump_file)
753 fprintf (dump_file,
754 "\nDeciding on inlining. Starting with %i insns.\n",
755 initial_insns);
757 for (node = cgraph_nodes; node; node = node->next)
758 node->aux = 0;
760 if (dump_file)
761 fprintf (dump_file, "\nInlining always_inline functions:\n");
763 /* In the first pass mark all always_inline edges. Do this with a priority
764 so none of our later choices will make this impossible. */
765 for (i = nnodes - 1; i >= 0; i--)
767 struct cgraph_edge *e, *next;
769 node = order[i];
771 if (!node->local.disregard_inline_limits)
772 continue;
773 if (dump_file)
774 fprintf (dump_file,
775 "\nConsidering %s %i insns (always inline)\n",
776 cgraph_node_name (node), node->global.insns);
777 old_insns = overall_insns;
778 for (e = node->callers; e; e = next)
780 next = e->next_caller;
781 if (!e->inline_failed)
782 continue;
783 if (cgraph_recursive_inlining_p (e->caller, e->callee,
784 &e->inline_failed))
785 continue;
786 cgraph_mark_inline_edge (e);
787 if (dump_file)
788 fprintf (dump_file,
789 " Inlined into %s which now has %i insns.\n",
790 cgraph_node_name (e->caller),
791 e->caller->global.insns);
793 if (dump_file)
794 fprintf (dump_file,
795 " Inlined for a net change of %+i insns.\n",
796 overall_insns - old_insns);
799 if (!flag_really_no_inline)
801 cgraph_decide_inlining_of_small_functions ();
803 if (dump_file)
804 fprintf (dump_file, "\nDeciding on functions called once:\n");
806 /* And finally decide what functions are called once. */
808 for (i = nnodes - 1; i >= 0; i--)
810 node = order[i];
812 if (node->callers && !node->callers->next_caller && !node->needed
813 && node->local.inlinable && node->callers->inline_failed
814 && !DECL_EXTERNAL (node->decl) && !DECL_COMDAT (node->decl))
816 bool ok = true;
817 struct cgraph_node *node1;
819 /* Verify that we won't duplicate the caller. */
820 for (node1 = node->callers->caller;
821 node1->callers && !node1->callers->inline_failed
822 && ok; node1 = node1->callers->caller)
823 if (node1->callers->next_caller || node1->needed)
824 ok = false;
825 if (ok)
827 if (dump_file)
828 fprintf (dump_file,
829 "\nConsidering %s %i insns.\n"
830 " Called once from %s %i insns.\n",
831 cgraph_node_name (node), node->global.insns,
832 cgraph_node_name (node->callers->caller),
833 node->callers->caller->global.insns);
835 old_insns = overall_insns;
837 if (cgraph_check_inline_limits (node->callers->caller, node,
838 NULL))
840 cgraph_mark_inline (node->callers);
841 if (dump_file)
842 fprintf (dump_file,
843 " Inlined into %s which now has %i insns"
844 " for a net change of %+i insns.\n",
845 cgraph_node_name (node->callers->caller),
846 node->callers->caller->global.insns,
847 overall_insns - old_insns);
849 else
851 if (dump_file)
852 fprintf (dump_file,
853 " Inline limit reached, not inlined.\n");
860 if (dump_file)
861 fprintf (dump_file,
862 "\nInlined %i calls, eliminated %i functions, "
863 "%i insns turned to %i insns.\n\n",
864 ncalls_inlined, nfunctions_inlined, initial_insns,
865 overall_insns);
866 free (order);
867 timevar_pop (TV_INLINE_HEURISTICS);
870 /* Decide on the inlining. We do so in the topological order to avoid
871 expenses on updating data structures. */
873 void
874 cgraph_decide_inlining_incrementally (struct cgraph_node *node)
876 struct cgraph_edge *e;
878 /* First of all look for always inline functions. */
879 for (e = node->callees; e; e = e->next_callee)
880 if (e->callee->local.disregard_inline_limits
881 && e->inline_failed
882 && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
883 /* ??? It is possible that renaming variable removed the function body
884 in duplicate_decls. See gcc.c-torture/compile/20011119-2.c */
885 && DECL_SAVED_TREE (e->callee->decl))
886 cgraph_mark_inline (e);
888 /* Now do the automatic inlining. */
889 if (!flag_really_no_inline)
890 for (e = node->callees; e; e = e->next_callee)
891 if (e->callee->local.inlinable
892 && e->inline_failed
893 && !e->callee->local.disregard_inline_limits
894 && !cgraph_recursive_inlining_p (node, e->callee, &e->inline_failed)
895 && cgraph_check_inline_limits (node, e->callee, &e->inline_failed)
896 && DECL_SAVED_TREE (e->callee->decl))
898 if (cgraph_default_inline_p (e->callee))
899 cgraph_mark_inline (e);
900 else
901 e->inline_failed
902 = N_("--param max-inline-insns-single limit reached");
906 /* When inlining shall be performed. */
907 static bool
908 cgraph_gate_inlining (void)
910 return flag_inline_trees;
913 struct tree_opt_pass pass_ipa_inline =
915 "inline", /* name */
916 cgraph_gate_inlining, /* gate */
917 cgraph_decide_inlining, /* execute */
918 NULL, /* sub */
919 NULL, /* next */
920 0, /* static_pass_number */
921 TV_INTEGRATION, /* tv_id */
922 0, /* properties_required */
923 PROP_trees, /* properties_provided */
924 0, /* properties_destroyed */
925 0, /* todo_flags_start */
926 TODO_dump_cgraph | TODO_dump_func, /* todo_flags_finish */
927 0 /* letter */