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
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
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
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
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
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. */
68 #include "coretypes.h"
71 #include "tree-inline.h"
72 #include "langhooks.h"
75 #include "diagnostic.h"
80 #include "tree-pass.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
;
89 static gcov_type max_count
;
91 /* Estimate size of the function after inlining WHAT into TO. */
94 cgraph_estimate_size_after_inlining (int times
, struct cgraph_node
*to
,
95 struct cgraph_node
*what
)
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);
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.
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
))
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
++;
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
;
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. */
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);
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
,
172 gcc_assert (new_insns
>= 0);
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
;
182 /* Mark all calls of EDGE->CALLEE inlined into EDGE->CALLER.
183 Return following unredirected edge in the list of callers
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
;
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
);
211 /* Estimate the growth caused by inlining NODE into all callees. */
214 cgraph_estimate_growth (struct cgraph_node
*node
)
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
;
236 /* Return false when inlining WHAT into TO is not good idea
237 as it would cause too large growth of function bodies. */
240 cgraph_check_inline_limits (struct cgraph_node
*to
, struct cgraph_node
*what
,
244 struct cgraph_edge
*e
;
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
)
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
;
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
)
269 *reason
= N_("--param large-function-growth limit reached");
275 /* Return true when function N is small enough to be inlined. */
278 cgraph_default_inline_p (struct cgraph_node
*n
)
280 if (!DECL_INLINE (n
->decl
) || !DECL_SAVED_TREE (n
->decl
))
282 if (DECL_DECLARED_INLINE_P (n
->decl
))
283 return n
->global
.insns
< MAX_INLINE_INSNS_SINGLE
;
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. */
293 cgraph_recursive_inlining_p (struct cgraph_node
*to
,
294 struct cgraph_node
*what
,
298 if (to
->global
.inlined_to
)
299 recursive
= what
->decl
== to
->global
.inlined_to
->decl
;
301 recursive
= what
->decl
== to
->decl
;
302 /* Marking recursive function inline has sane semantic and thus we should
304 if (recursive
&& reason
)
305 *reason
= (what
->local
.disregard_inline_limits
306 ? N_("recursive inlining") : "");
310 /* Return true if the call can be hot. */
312 cgraph_maybe_hot_edge_p (struct cgraph_edge
*edge
)
314 if (profile_info
&& flag_branch_probabilities
316 <= profile_info
->sum_max
/ PARAM_VALUE (HOT_BB_COUNT_FRACTION
)))
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.
339 cgraph_edge_badness (struct cgraph_edge
*edge
)
344 cgraph_estimate_size_after_inlining (1, edge
->caller
, edge
->callee
);
345 growth
-= edge
->caller
->global
.insns
;
347 /* Always prefer inlining saving code size. */
349 return INT_MIN
- growth
;
350 return ((int)((double)edge
->count
* INT_MIN
/ max_count
)) / growth
;
354 int nest
= MIN (edge
->loop_nest
, 8);
355 int badness
= cgraph_estimate_growth (edge
->callee
) * 256;
359 /* Make recursive inlining happen always after other inlining is done. */
360 if (cgraph_recursive_inlining_p (edge
->caller
, edge
->callee
, NULL
))
367 /* Recompute heap nodes for each of caller edge. */
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
)
378 if (bitmap_bit_p (updated_nodes
, node
->uid
))
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
);
388 fibnode_t n
= edge
->aux
;
389 gcc_assert (n
->data
== edge
);
390 if (n
->key
== badness
)
393 /* fibheap_replace_key only increase the keys. */
394 if (fibheap_replace_key (heap
, n
, badness
))
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. */
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. */
422 lookup_recursive_calls (struct cgraph_node
*node
, struct cgraph_node
*where
,
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. */
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
);
449 struct cgraph_edge
*e
;
450 struct cgraph_node
*master_clone
;
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. */
462 || cgraph_estimate_size_after_inlining (1, node
, node
) >= limit
)
464 heap
= fibheap_new ();
465 lookup_recursive_calls (node
, node
, heap
);
466 if (fibheap_empty (heap
))
468 fibheap_delete (heap
);
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
;
492 for (node
= curr
->caller
;
493 node
; node
= node
->global
.inlined_to
)
494 if (node
->decl
== curr
->callee
->decl
)
496 if (depth
> max_depth
)
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
);
508 fibheap_delete (heap
);
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
517 for (node
= cgraph_nodes
; node
!= master_clone
;
519 if (node
->global
.inlined_to
== master_clone
)
520 cgraph_remove_node (node
);
521 cgraph_remove_node (master_clone
);
525 /* Set inline_failed for all callers of given function to REASON. */
528 cgraph_set_inline_failed (struct cgraph_node
*node
, const char *reason
)
530 struct cgraph_edge
*e
;
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. */
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
);
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
)
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"));
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
;
587 cgraph_estimate_size_after_inlining (1, edge
->caller
, edge
->callee
);
589 growth
-= edge
->caller
->global
.insns
;
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
));
603 fprintf (dump_file
," Called "HOST_WIDEST_INT_PRINT_DEC
"x\n", edge
->count
);
605 gcc_assert (edge
->aux
);
607 if (!edge
->inline_failed
)
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
621 where
= edge
->caller
;
622 while (where
->global
.inlined_to
)
624 if (where
->decl
== edge
->callee
->decl
)
626 where
= where
->callers
->caller
;
628 if (where
->global
.inlined_to
)
631 = (edge
->callee
->local
.disregard_inline_limits
? N_("recursive inlining") : "");
633 fprintf (dump_file
, " inline_failed:Recursive inlining performed only for function itself.\n");
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");
646 fprintf (dump_file
, " inline_failed:%s.\n", edge
->inline_failed
);
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");
658 fprintf (dump_file
, " inline_failed:%s.\n", edge
->inline_failed
);
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
))
670 update_callee_keys (heap
, where
, updated_nodes
);
674 if (!cgraph_check_inline_limits (edge
->caller
, edge
->callee
,
675 &edge
->inline_failed
))
678 fprintf (dump_file
, " Not inlining into %s:%s.\n",
679 cgraph_node_name (edge
->caller
), edge
->inline_failed
);
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
695 update_caller_keys (heap
, where
, updated_nodes
);
696 bitmap_clear (updated_nodes
);
700 " Inlined into %s which now has %i insns.\n",
701 cgraph_node_name (edge
->caller
),
702 edge
->caller
->global
.insns
);
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
);
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. */
725 cgraph_decide_inlining (void)
727 struct cgraph_node
*node
;
729 struct cgraph_node
**order
=
730 xcalloc (cgraph_n_nodes
, sizeof (struct cgraph_node
*));
734 timevar_push (TV_INLINE_HEURISTICS
);
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
);
754 "\nDeciding on inlining. Starting with %i insns.\n",
757 for (node
= cgraph_nodes
; node
; node
= node
->next
)
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
;
771 if (!node
->local
.disregard_inline_limits
)
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
)
783 if (cgraph_recursive_inlining_p (e
->caller
, e
->callee
,
786 cgraph_mark_inline_edge (e
);
789 " Inlined into %s which now has %i insns.\n",
790 cgraph_node_name (e
->caller
),
791 e
->caller
->global
.insns
);
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 ();
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
--)
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
))
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
)
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
,
840 cgraph_mark_inline (node
->callers
);
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
);
853 " Inline limit reached, not inlined.\n");
860 /* We will never output extern functions we didn't inline.
861 ??? Perhaps we can prevent accounting of growth of external
864 cgraph_remove_unreachable_nodes (false, dump_file
);
868 "\nInlined %i calls, eliminated %i functions, "
869 "%i insns turned to %i insns.\n\n",
870 ncalls_inlined
, nfunctions_inlined
, initial_insns
,
873 timevar_pop (TV_INLINE_HEURISTICS
);
876 /* Decide on the inlining. We do so in the topological order to avoid
877 expenses on updating data structures. */
880 cgraph_decide_inlining_incrementally (struct cgraph_node
*node
)
882 struct cgraph_edge
*e
;
884 /* First of all look for always inline functions. */
885 for (e
= node
->callees
; e
; e
= e
->next_callee
)
886 if (e
->callee
->local
.disregard_inline_limits
888 && !cgraph_recursive_inlining_p (node
, e
->callee
, &e
->inline_failed
)
889 /* ??? It is possible that renaming variable removed the function body
890 in duplicate_decls. See gcc.c-torture/compile/20011119-2.c */
891 && DECL_SAVED_TREE (e
->callee
->decl
))
892 cgraph_mark_inline (e
);
894 /* Now do the automatic inlining. */
895 if (!flag_really_no_inline
)
896 for (e
= node
->callees
; e
; e
= e
->next_callee
)
897 if (e
->callee
->local
.inlinable
899 && !e
->callee
->local
.disregard_inline_limits
900 && !cgraph_recursive_inlining_p (node
, e
->callee
, &e
->inline_failed
)
901 && cgraph_check_inline_limits (node
, e
->callee
, &e
->inline_failed
)
902 && DECL_SAVED_TREE (e
->callee
->decl
))
904 if (cgraph_default_inline_p (e
->callee
))
905 cgraph_mark_inline (e
);
908 = N_("--param max-inline-insns-single limit reached");
912 /* When inlining shall be performed. */
914 cgraph_gate_inlining (void)
916 return flag_inline_trees
;
919 struct tree_opt_pass pass_ipa_inline
=
922 cgraph_gate_inlining
, /* gate */
923 cgraph_decide_inlining
, /* execute */
926 0, /* static_pass_number */
927 TV_INTEGRATION
, /* tv_id */
928 0, /* properties_required */
929 PROP_trees
, /* properties_provided */
930 0, /* properties_destroyed */
931 0, /* todo_flags_start */
932 TODO_dump_cgraph
| TODO_dump_func
, /* todo_flags_finish */