1*e4b17023SJohn Marino /* Inlining decision heuristics.
2*e4b17023SJohn Marino Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
3*e4b17023SJohn Marino Free Software Foundation, Inc.
4*e4b17023SJohn Marino Contributed by Jan Hubicka
5*e4b17023SJohn Marino
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21*e4b17023SJohn Marino
22*e4b17023SJohn Marino /* Inlining decision heuristics
23*e4b17023SJohn Marino
24*e4b17023SJohn Marino The implementation of inliner is organized as follows:
25*e4b17023SJohn Marino
26*e4b17023SJohn Marino inlining heuristics limits
27*e4b17023SJohn Marino
28*e4b17023SJohn Marino can_inline_edge_p allow to check that particular inlining is allowed
29*e4b17023SJohn Marino by the limits specified by user (allowed function growth, growth and so
30*e4b17023SJohn Marino on).
31*e4b17023SJohn Marino
32*e4b17023SJohn Marino Functions are inlined when it is obvious the result is profitable (such
33*e4b17023SJohn Marino as functions called once or when inlining reduce code size).
34*e4b17023SJohn Marino In addition to that we perform inlining of small functions and recursive
35*e4b17023SJohn Marino inlining.
36*e4b17023SJohn Marino
37*e4b17023SJohn Marino inlining heuristics
38*e4b17023SJohn Marino
39*e4b17023SJohn Marino The inliner itself is split into two passes:
40*e4b17023SJohn Marino
41*e4b17023SJohn Marino pass_early_inlining
42*e4b17023SJohn Marino
43*e4b17023SJohn Marino Simple local inlining pass inlining callees into current function.
44*e4b17023SJohn Marino This pass makes no use of whole unit analysis and thus it can do only
45*e4b17023SJohn Marino very simple decisions based on local properties.
46*e4b17023SJohn Marino
47*e4b17023SJohn Marino The strength of the pass is that it is run in topological order
48*e4b17023SJohn Marino (reverse postorder) on the callgraph. Functions are converted into SSA
49*e4b17023SJohn Marino form just before this pass and optimized subsequently. As a result, the
50*e4b17023SJohn Marino callees of the function seen by the early inliner was already optimized
51*e4b17023SJohn Marino and results of early inlining adds a lot of optimization opportunities
52*e4b17023SJohn Marino for the local optimization.
53*e4b17023SJohn Marino
54*e4b17023SJohn Marino The pass handle the obvious inlining decisions within the compilation
55*e4b17023SJohn Marino unit - inlining auto inline functions, inlining for size and
56*e4b17023SJohn Marino flattening.
57*e4b17023SJohn Marino
58*e4b17023SJohn Marino main strength of the pass is the ability to eliminate abstraction
59*e4b17023SJohn Marino penalty in C++ code (via combination of inlining and early
60*e4b17023SJohn Marino optimization) and thus improve quality of analysis done by real IPA
61*e4b17023SJohn Marino optimizers.
62*e4b17023SJohn Marino
63*e4b17023SJohn Marino Because of lack of whole unit knowledge, the pass can not really make
64*e4b17023SJohn Marino good code size/performance tradeoffs. It however does very simple
65*e4b17023SJohn Marino speculative inlining allowing code size to grow by
66*e4b17023SJohn Marino EARLY_INLINING_INSNS when callee is leaf function. In this case the
67*e4b17023SJohn Marino optimizations performed later are very likely to eliminate the cost.
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino pass_ipa_inline
70*e4b17023SJohn Marino
71*e4b17023SJohn Marino This is the real inliner able to handle inlining with whole program
72*e4b17023SJohn Marino knowledge. It performs following steps:
73*e4b17023SJohn Marino
74*e4b17023SJohn Marino 1) inlining of small functions. This is implemented by greedy
75*e4b17023SJohn Marino algorithm ordering all inlinable cgraph edges by their badness and
76*e4b17023SJohn Marino inlining them in this order as long as inline limits allows doing so.
77*e4b17023SJohn Marino
78*e4b17023SJohn Marino This heuristics is not very good on inlining recursive calls. Recursive
79*e4b17023SJohn Marino calls can be inlined with results similar to loop unrolling. To do so,
80*e4b17023SJohn Marino special purpose recursive inliner is executed on function when
81*e4b17023SJohn Marino recursive edge is met as viable candidate.
82*e4b17023SJohn Marino
83*e4b17023SJohn Marino 2) Unreachable functions are removed from callgraph. Inlining leads
84*e4b17023SJohn Marino to devirtualization and other modification of callgraph so functions
85*e4b17023SJohn Marino may become unreachable during the process. Also functions declared as
86*e4b17023SJohn Marino extern inline or virtual functions are removed, since after inlining
87*e4b17023SJohn Marino we no longer need the offline bodies.
88*e4b17023SJohn Marino
89*e4b17023SJohn Marino 3) Functions called once and not exported from the unit are inlined.
90*e4b17023SJohn Marino This should almost always lead to reduction of code size by eliminating
91*e4b17023SJohn Marino the need for offline copy of the function. */
92*e4b17023SJohn Marino
93*e4b17023SJohn Marino #include "config.h"
94*e4b17023SJohn Marino #include "system.h"
95*e4b17023SJohn Marino #include "coretypes.h"
96*e4b17023SJohn Marino #include "tm.h"
97*e4b17023SJohn Marino #include "tree.h"
98*e4b17023SJohn Marino #include "tree-inline.h"
99*e4b17023SJohn Marino #include "langhooks.h"
100*e4b17023SJohn Marino #include "flags.h"
101*e4b17023SJohn Marino #include "cgraph.h"
102*e4b17023SJohn Marino #include "diagnostic.h"
103*e4b17023SJohn Marino #include "gimple-pretty-print.h"
104*e4b17023SJohn Marino #include "timevar.h"
105*e4b17023SJohn Marino #include "params.h"
106*e4b17023SJohn Marino #include "fibheap.h"
107*e4b17023SJohn Marino #include "intl.h"
108*e4b17023SJohn Marino #include "tree-pass.h"
109*e4b17023SJohn Marino #include "coverage.h"
110*e4b17023SJohn Marino #include "ggc.h"
111*e4b17023SJohn Marino #include "rtl.h"
112*e4b17023SJohn Marino #include "tree-flow.h"
113*e4b17023SJohn Marino #include "ipa-prop.h"
114*e4b17023SJohn Marino #include "except.h"
115*e4b17023SJohn Marino #include "target.h"
116*e4b17023SJohn Marino #include "ipa-inline.h"
117*e4b17023SJohn Marino #include "ipa-utils.h"
118*e4b17023SJohn Marino
119*e4b17023SJohn Marino /* Statistics we collect about inlining algorithm. */
120*e4b17023SJohn Marino static int overall_size;
121*e4b17023SJohn Marino static gcov_type max_count;
122*e4b17023SJohn Marino
123*e4b17023SJohn Marino /* Return false when inlining edge E would lead to violating
124*e4b17023SJohn Marino limits on function unit growth or stack usage growth.
125*e4b17023SJohn Marino
126*e4b17023SJohn Marino The relative function body growth limit is present generally
127*e4b17023SJohn Marino to avoid problems with non-linear behavior of the compiler.
128*e4b17023SJohn Marino To allow inlining huge functions into tiny wrapper, the limit
129*e4b17023SJohn Marino is always based on the bigger of the two functions considered.
130*e4b17023SJohn Marino
131*e4b17023SJohn Marino For stack growth limits we always base the growth in stack usage
132*e4b17023SJohn Marino of the callers. We want to prevent applications from segfaulting
133*e4b17023SJohn Marino on stack overflow when functions with huge stack frames gets
134*e4b17023SJohn Marino inlined. */
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino static bool
caller_growth_limits(struct cgraph_edge * e)137*e4b17023SJohn Marino caller_growth_limits (struct cgraph_edge *e)
138*e4b17023SJohn Marino {
139*e4b17023SJohn Marino struct cgraph_node *to = e->caller;
140*e4b17023SJohn Marino struct cgraph_node *what = cgraph_function_or_thunk_node (e->callee, NULL);
141*e4b17023SJohn Marino int newsize;
142*e4b17023SJohn Marino int limit = 0;
143*e4b17023SJohn Marino HOST_WIDE_INT stack_size_limit = 0, inlined_stack;
144*e4b17023SJohn Marino struct inline_summary *info, *what_info, *outer_info = inline_summary (to);
145*e4b17023SJohn Marino
146*e4b17023SJohn Marino /* Look for function e->caller is inlined to. While doing
147*e4b17023SJohn Marino so work out the largest function body on the way. As
148*e4b17023SJohn Marino described above, we want to base our function growth
149*e4b17023SJohn Marino limits based on that. Not on the self size of the
150*e4b17023SJohn Marino outer function, not on the self size of inline code
151*e4b17023SJohn Marino we immediately inline to. This is the most relaxed
152*e4b17023SJohn Marino interpretation of the rule "do not grow large functions
153*e4b17023SJohn Marino too much in order to prevent compiler from exploding". */
154*e4b17023SJohn Marino while (true)
155*e4b17023SJohn Marino {
156*e4b17023SJohn Marino info = inline_summary (to);
157*e4b17023SJohn Marino if (limit < info->self_size)
158*e4b17023SJohn Marino limit = info->self_size;
159*e4b17023SJohn Marino if (stack_size_limit < info->estimated_self_stack_size)
160*e4b17023SJohn Marino stack_size_limit = info->estimated_self_stack_size;
161*e4b17023SJohn Marino if (to->global.inlined_to)
162*e4b17023SJohn Marino to = to->callers->caller;
163*e4b17023SJohn Marino else
164*e4b17023SJohn Marino break;
165*e4b17023SJohn Marino }
166*e4b17023SJohn Marino
167*e4b17023SJohn Marino what_info = inline_summary (what);
168*e4b17023SJohn Marino
169*e4b17023SJohn Marino if (limit < what_info->self_size)
170*e4b17023SJohn Marino limit = what_info->self_size;
171*e4b17023SJohn Marino
172*e4b17023SJohn Marino limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
173*e4b17023SJohn Marino
174*e4b17023SJohn Marino /* Check the size after inlining against the function limits. But allow
175*e4b17023SJohn Marino the function to shrink if it went over the limits by forced inlining. */
176*e4b17023SJohn Marino newsize = estimate_size_after_inlining (to, e);
177*e4b17023SJohn Marino if (newsize >= info->size
178*e4b17023SJohn Marino && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
179*e4b17023SJohn Marino && newsize > limit)
180*e4b17023SJohn Marino {
181*e4b17023SJohn Marino e->inline_failed = CIF_LARGE_FUNCTION_GROWTH_LIMIT;
182*e4b17023SJohn Marino return false;
183*e4b17023SJohn Marino }
184*e4b17023SJohn Marino
185*e4b17023SJohn Marino if (!what_info->estimated_stack_size)
186*e4b17023SJohn Marino return true;
187*e4b17023SJohn Marino
188*e4b17023SJohn Marino /* FIXME: Stack size limit often prevents inlining in Fortran programs
189*e4b17023SJohn Marino due to large i/o datastructures used by the Fortran front-end.
190*e4b17023SJohn Marino We ought to ignore this limit when we know that the edge is executed
191*e4b17023SJohn Marino on every invocation of the caller (i.e. its call statement dominates
192*e4b17023SJohn Marino exit block). We do not track this information, yet. */
193*e4b17023SJohn Marino stack_size_limit += ((gcov_type)stack_size_limit
194*e4b17023SJohn Marino * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino inlined_stack = (outer_info->stack_frame_offset
197*e4b17023SJohn Marino + outer_info->estimated_self_stack_size
198*e4b17023SJohn Marino + what_info->estimated_stack_size);
199*e4b17023SJohn Marino /* Check new stack consumption with stack consumption at the place
200*e4b17023SJohn Marino stack is used. */
201*e4b17023SJohn Marino if (inlined_stack > stack_size_limit
202*e4b17023SJohn Marino /* If function already has large stack usage from sibling
203*e4b17023SJohn Marino inline call, we can inline, too.
204*e4b17023SJohn Marino This bit overoptimistically assume that we are good at stack
205*e4b17023SJohn Marino packing. */
206*e4b17023SJohn Marino && inlined_stack > info->estimated_stack_size
207*e4b17023SJohn Marino && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
208*e4b17023SJohn Marino {
209*e4b17023SJohn Marino e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;
210*e4b17023SJohn Marino return false;
211*e4b17023SJohn Marino }
212*e4b17023SJohn Marino return true;
213*e4b17023SJohn Marino }
214*e4b17023SJohn Marino
215*e4b17023SJohn Marino /* Dump info about why inlining has failed. */
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino static void
report_inline_failed_reason(struct cgraph_edge * e)218*e4b17023SJohn Marino report_inline_failed_reason (struct cgraph_edge *e)
219*e4b17023SJohn Marino {
220*e4b17023SJohn Marino if (dump_file)
221*e4b17023SJohn Marino {
222*e4b17023SJohn Marino fprintf (dump_file, " not inlinable: %s/%i -> %s/%i, %s\n",
223*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
224*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->callee)), e->callee->uid,
225*e4b17023SJohn Marino cgraph_inline_failed_string (e->inline_failed));
226*e4b17023SJohn Marino }
227*e4b17023SJohn Marino }
228*e4b17023SJohn Marino
229*e4b17023SJohn Marino /* Decide if we can inline the edge and possibly update
230*e4b17023SJohn Marino inline_failed reason.
231*e4b17023SJohn Marino We check whether inlining is possible at all and whether
232*e4b17023SJohn Marino caller growth limits allow doing so.
233*e4b17023SJohn Marino
234*e4b17023SJohn Marino if REPORT is true, output reason to the dump file. */
235*e4b17023SJohn Marino
236*e4b17023SJohn Marino static bool
can_inline_edge_p(struct cgraph_edge * e,bool report)237*e4b17023SJohn Marino can_inline_edge_p (struct cgraph_edge *e, bool report)
238*e4b17023SJohn Marino {
239*e4b17023SJohn Marino bool inlinable = true;
240*e4b17023SJohn Marino enum availability avail;
241*e4b17023SJohn Marino struct cgraph_node *callee
242*e4b17023SJohn Marino = cgraph_function_or_thunk_node (e->callee, &avail);
243*e4b17023SJohn Marino tree caller_tree = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (e->caller->decl);
244*e4b17023SJohn Marino tree callee_tree
245*e4b17023SJohn Marino = callee ? DECL_FUNCTION_SPECIFIC_OPTIMIZATION (callee->decl) : NULL;
246*e4b17023SJohn Marino struct function *caller_cfun = DECL_STRUCT_FUNCTION (e->caller->decl);
247*e4b17023SJohn Marino struct function *callee_cfun
248*e4b17023SJohn Marino = callee ? DECL_STRUCT_FUNCTION (callee->decl) : NULL;
249*e4b17023SJohn Marino
250*e4b17023SJohn Marino if (!caller_cfun && e->caller->clone_of)
251*e4b17023SJohn Marino caller_cfun = DECL_STRUCT_FUNCTION (e->caller->clone_of->decl);
252*e4b17023SJohn Marino
253*e4b17023SJohn Marino if (!callee_cfun && callee && callee->clone_of)
254*e4b17023SJohn Marino callee_cfun = DECL_STRUCT_FUNCTION (callee->clone_of->decl);
255*e4b17023SJohn Marino
256*e4b17023SJohn Marino gcc_assert (e->inline_failed);
257*e4b17023SJohn Marino
258*e4b17023SJohn Marino if (!callee || !callee->analyzed)
259*e4b17023SJohn Marino {
260*e4b17023SJohn Marino e->inline_failed = CIF_BODY_NOT_AVAILABLE;
261*e4b17023SJohn Marino inlinable = false;
262*e4b17023SJohn Marino }
263*e4b17023SJohn Marino else if (!inline_summary (callee)->inlinable)
264*e4b17023SJohn Marino {
265*e4b17023SJohn Marino e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
266*e4b17023SJohn Marino inlinable = false;
267*e4b17023SJohn Marino }
268*e4b17023SJohn Marino else if (avail <= AVAIL_OVERWRITABLE)
269*e4b17023SJohn Marino {
270*e4b17023SJohn Marino e->inline_failed = CIF_OVERWRITABLE;
271*e4b17023SJohn Marino return false;
272*e4b17023SJohn Marino }
273*e4b17023SJohn Marino else if (e->call_stmt_cannot_inline_p)
274*e4b17023SJohn Marino {
275*e4b17023SJohn Marino e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
276*e4b17023SJohn Marino inlinable = false;
277*e4b17023SJohn Marino }
278*e4b17023SJohn Marino /* Don't inline if the functions have different EH personalities. */
279*e4b17023SJohn Marino else if (DECL_FUNCTION_PERSONALITY (e->caller->decl)
280*e4b17023SJohn Marino && DECL_FUNCTION_PERSONALITY (callee->decl)
281*e4b17023SJohn Marino && (DECL_FUNCTION_PERSONALITY (e->caller->decl)
282*e4b17023SJohn Marino != DECL_FUNCTION_PERSONALITY (callee->decl)))
283*e4b17023SJohn Marino {
284*e4b17023SJohn Marino e->inline_failed = CIF_EH_PERSONALITY;
285*e4b17023SJohn Marino inlinable = false;
286*e4b17023SJohn Marino }
287*e4b17023SJohn Marino /* TM pure functions should not be inlined into non-TM_pure
288*e4b17023SJohn Marino functions. */
289*e4b17023SJohn Marino else if (is_tm_pure (callee->decl)
290*e4b17023SJohn Marino && !is_tm_pure (e->caller->decl))
291*e4b17023SJohn Marino {
292*e4b17023SJohn Marino e->inline_failed = CIF_UNSPECIFIED;
293*e4b17023SJohn Marino inlinable = false;
294*e4b17023SJohn Marino }
295*e4b17023SJohn Marino /* Don't inline if the callee can throw non-call exceptions but the
296*e4b17023SJohn Marino caller cannot.
297*e4b17023SJohn Marino FIXME: this is obviously wrong for LTO where STRUCT_FUNCTION is missing.
298*e4b17023SJohn Marino Move the flag into cgraph node or mirror it in the inline summary. */
299*e4b17023SJohn Marino else if (callee_cfun && callee_cfun->can_throw_non_call_exceptions
300*e4b17023SJohn Marino && !(caller_cfun && caller_cfun->can_throw_non_call_exceptions))
301*e4b17023SJohn Marino {
302*e4b17023SJohn Marino e->inline_failed = CIF_NON_CALL_EXCEPTIONS;
303*e4b17023SJohn Marino inlinable = false;
304*e4b17023SJohn Marino }
305*e4b17023SJohn Marino /* Check compatibility of target optimization options. */
306*e4b17023SJohn Marino else if (!targetm.target_option.can_inline_p (e->caller->decl,
307*e4b17023SJohn Marino callee->decl))
308*e4b17023SJohn Marino {
309*e4b17023SJohn Marino e->inline_failed = CIF_TARGET_OPTION_MISMATCH;
310*e4b17023SJohn Marino inlinable = false;
311*e4b17023SJohn Marino }
312*e4b17023SJohn Marino /* Check if caller growth allows the inlining. */
313*e4b17023SJohn Marino else if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl)
314*e4b17023SJohn Marino && !lookup_attribute ("flatten",
315*e4b17023SJohn Marino DECL_ATTRIBUTES
316*e4b17023SJohn Marino (e->caller->global.inlined_to
317*e4b17023SJohn Marino ? e->caller->global.inlined_to->decl
318*e4b17023SJohn Marino : e->caller->decl))
319*e4b17023SJohn Marino && !caller_growth_limits (e))
320*e4b17023SJohn Marino inlinable = false;
321*e4b17023SJohn Marino /* Don't inline a function with a higher optimization level than the
322*e4b17023SJohn Marino caller. FIXME: this is really just tip of iceberg of handling
323*e4b17023SJohn Marino optimization attribute. */
324*e4b17023SJohn Marino else if (caller_tree != callee_tree)
325*e4b17023SJohn Marino {
326*e4b17023SJohn Marino struct cl_optimization *caller_opt
327*e4b17023SJohn Marino = TREE_OPTIMIZATION ((caller_tree)
328*e4b17023SJohn Marino ? caller_tree
329*e4b17023SJohn Marino : optimization_default_node);
330*e4b17023SJohn Marino
331*e4b17023SJohn Marino struct cl_optimization *callee_opt
332*e4b17023SJohn Marino = TREE_OPTIMIZATION ((callee_tree)
333*e4b17023SJohn Marino ? callee_tree
334*e4b17023SJohn Marino : optimization_default_node);
335*e4b17023SJohn Marino
336*e4b17023SJohn Marino if (((caller_opt->x_optimize > callee_opt->x_optimize)
337*e4b17023SJohn Marino || (caller_opt->x_optimize_size != callee_opt->x_optimize_size))
338*e4b17023SJohn Marino /* gcc.dg/pr43564.c. Look at forced inline even in -O0. */
339*e4b17023SJohn Marino && !DECL_DISREGARD_INLINE_LIMITS (e->callee->decl))
340*e4b17023SJohn Marino {
341*e4b17023SJohn Marino e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
342*e4b17023SJohn Marino inlinable = false;
343*e4b17023SJohn Marino }
344*e4b17023SJohn Marino }
345*e4b17023SJohn Marino
346*e4b17023SJohn Marino if (!inlinable && report)
347*e4b17023SJohn Marino report_inline_failed_reason (e);
348*e4b17023SJohn Marino return inlinable;
349*e4b17023SJohn Marino }
350*e4b17023SJohn Marino
351*e4b17023SJohn Marino
352*e4b17023SJohn Marino /* Return true if the edge E is inlinable during early inlining. */
353*e4b17023SJohn Marino
354*e4b17023SJohn Marino static bool
can_early_inline_edge_p(struct cgraph_edge * e)355*e4b17023SJohn Marino can_early_inline_edge_p (struct cgraph_edge *e)
356*e4b17023SJohn Marino {
357*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee,
358*e4b17023SJohn Marino NULL);
359*e4b17023SJohn Marino /* Early inliner might get called at WPA stage when IPA pass adds new
360*e4b17023SJohn Marino function. In this case we can not really do any of early inlining
361*e4b17023SJohn Marino because function bodies are missing. */
362*e4b17023SJohn Marino if (!gimple_has_body_p (callee->decl))
363*e4b17023SJohn Marino {
364*e4b17023SJohn Marino e->inline_failed = CIF_BODY_NOT_AVAILABLE;
365*e4b17023SJohn Marino return false;
366*e4b17023SJohn Marino }
367*e4b17023SJohn Marino /* In early inliner some of callees may not be in SSA form yet
368*e4b17023SJohn Marino (i.e. the callgraph is cyclic and we did not process
369*e4b17023SJohn Marino the callee by early inliner, yet). We don't have CIF code for this
370*e4b17023SJohn Marino case; later we will re-do the decision in the real inliner. */
371*e4b17023SJohn Marino if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (e->caller->decl))
372*e4b17023SJohn Marino || !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
373*e4b17023SJohn Marino {
374*e4b17023SJohn Marino if (dump_file)
375*e4b17023SJohn Marino fprintf (dump_file, " edge not inlinable: not in SSA form\n");
376*e4b17023SJohn Marino return false;
377*e4b17023SJohn Marino }
378*e4b17023SJohn Marino if (!can_inline_edge_p (e, true))
379*e4b17023SJohn Marino return false;
380*e4b17023SJohn Marino return true;
381*e4b17023SJohn Marino }
382*e4b17023SJohn Marino
383*e4b17023SJohn Marino
384*e4b17023SJohn Marino /* Return true when N is leaf function. Accept cheap builtins
385*e4b17023SJohn Marino in leaf functions. */
386*e4b17023SJohn Marino
387*e4b17023SJohn Marino static bool
leaf_node_p(struct cgraph_node * n)388*e4b17023SJohn Marino leaf_node_p (struct cgraph_node *n)
389*e4b17023SJohn Marino {
390*e4b17023SJohn Marino struct cgraph_edge *e;
391*e4b17023SJohn Marino for (e = n->callees; e; e = e->next_callee)
392*e4b17023SJohn Marino if (!is_inexpensive_builtin (e->callee->decl))
393*e4b17023SJohn Marino return false;
394*e4b17023SJohn Marino return true;
395*e4b17023SJohn Marino }
396*e4b17023SJohn Marino
397*e4b17023SJohn Marino
398*e4b17023SJohn Marino /* Return true if we are interested in inlining small function. */
399*e4b17023SJohn Marino
400*e4b17023SJohn Marino static bool
want_early_inline_function_p(struct cgraph_edge * e)401*e4b17023SJohn Marino want_early_inline_function_p (struct cgraph_edge *e)
402*e4b17023SJohn Marino {
403*e4b17023SJohn Marino bool want_inline = true;
404*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
405*e4b17023SJohn Marino
406*e4b17023SJohn Marino if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
407*e4b17023SJohn Marino ;
408*e4b17023SJohn Marino else if (!DECL_DECLARED_INLINE_P (callee->decl)
409*e4b17023SJohn Marino && !flag_inline_small_functions)
410*e4b17023SJohn Marino {
411*e4b17023SJohn Marino e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
412*e4b17023SJohn Marino report_inline_failed_reason (e);
413*e4b17023SJohn Marino want_inline = false;
414*e4b17023SJohn Marino }
415*e4b17023SJohn Marino else
416*e4b17023SJohn Marino {
417*e4b17023SJohn Marino int growth = estimate_edge_growth (e);
418*e4b17023SJohn Marino if (growth <= 0)
419*e4b17023SJohn Marino ;
420*e4b17023SJohn Marino else if (!cgraph_maybe_hot_edge_p (e)
421*e4b17023SJohn Marino && growth > 0)
422*e4b17023SJohn Marino {
423*e4b17023SJohn Marino if (dump_file)
424*e4b17023SJohn Marino fprintf (dump_file, " will not early inline: %s/%i->%s/%i, "
425*e4b17023SJohn Marino "call is cold and code would grow by %i\n",
426*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
427*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)), callee->uid,
428*e4b17023SJohn Marino growth);
429*e4b17023SJohn Marino want_inline = false;
430*e4b17023SJohn Marino }
431*e4b17023SJohn Marino else if (!leaf_node_p (callee)
432*e4b17023SJohn Marino && growth > 0)
433*e4b17023SJohn Marino {
434*e4b17023SJohn Marino if (dump_file)
435*e4b17023SJohn Marino fprintf (dump_file, " will not early inline: %s/%i->%s/%i, "
436*e4b17023SJohn Marino "callee is not leaf and code would grow by %i\n",
437*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
438*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)), callee->uid,
439*e4b17023SJohn Marino growth);
440*e4b17023SJohn Marino want_inline = false;
441*e4b17023SJohn Marino }
442*e4b17023SJohn Marino else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))
443*e4b17023SJohn Marino {
444*e4b17023SJohn Marino if (dump_file)
445*e4b17023SJohn Marino fprintf (dump_file, " will not early inline: %s/%i->%s/%i, "
446*e4b17023SJohn Marino "growth %i exceeds --param early-inlining-insns\n",
447*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)), e->caller->uid,
448*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)), callee->uid,
449*e4b17023SJohn Marino growth);
450*e4b17023SJohn Marino want_inline = false;
451*e4b17023SJohn Marino }
452*e4b17023SJohn Marino }
453*e4b17023SJohn Marino return want_inline;
454*e4b17023SJohn Marino }
455*e4b17023SJohn Marino
456*e4b17023SJohn Marino /* Return true if we are interested in inlining small function.
457*e4b17023SJohn Marino When REPORT is true, report reason to dump file. */
458*e4b17023SJohn Marino
459*e4b17023SJohn Marino static bool
want_inline_small_function_p(struct cgraph_edge * e,bool report)460*e4b17023SJohn Marino want_inline_small_function_p (struct cgraph_edge *e, bool report)
461*e4b17023SJohn Marino {
462*e4b17023SJohn Marino bool want_inline = true;
463*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
464*e4b17023SJohn Marino
465*e4b17023SJohn Marino if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
466*e4b17023SJohn Marino ;
467*e4b17023SJohn Marino else if (!DECL_DECLARED_INLINE_P (callee->decl)
468*e4b17023SJohn Marino && !flag_inline_small_functions)
469*e4b17023SJohn Marino {
470*e4b17023SJohn Marino e->inline_failed = CIF_FUNCTION_NOT_INLINE_CANDIDATE;
471*e4b17023SJohn Marino want_inline = false;
472*e4b17023SJohn Marino }
473*e4b17023SJohn Marino else
474*e4b17023SJohn Marino {
475*e4b17023SJohn Marino int growth = estimate_edge_growth (e);
476*e4b17023SJohn Marino
477*e4b17023SJohn Marino if (growth <= 0)
478*e4b17023SJohn Marino ;
479*e4b17023SJohn Marino else if (DECL_DECLARED_INLINE_P (callee->decl)
480*e4b17023SJohn Marino && growth >= MAX_INLINE_INSNS_SINGLE)
481*e4b17023SJohn Marino {
482*e4b17023SJohn Marino e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
483*e4b17023SJohn Marino want_inline = false;
484*e4b17023SJohn Marino }
485*e4b17023SJohn Marino /* Before giving up based on fact that caller size will grow, allow
486*e4b17023SJohn Marino functions that are called few times and eliminating the offline
487*e4b17023SJohn Marino copy will lead to overall code size reduction.
488*e4b17023SJohn Marino Not all of these will be handled by subsequent inlining of functions
489*e4b17023SJohn Marino called once: in particular weak functions are not handled or funcitons
490*e4b17023SJohn Marino that inline to multiple calls but a lot of bodies is optimized out.
491*e4b17023SJohn Marino Finally we want to inline earlier to allow inlining of callbacks.
492*e4b17023SJohn Marino
493*e4b17023SJohn Marino This is slightly wrong on aggressive side: it is entirely possible
494*e4b17023SJohn Marino that function is called many times with a context where inlining
495*e4b17023SJohn Marino reduces code size and few times with a context where inlining increase
496*e4b17023SJohn Marino code size. Resoluting growth estimate will be negative even if it
497*e4b17023SJohn Marino would make more sense to keep offline copy and do not inline into the
498*e4b17023SJohn Marino call sites that makes the code size grow.
499*e4b17023SJohn Marino
500*e4b17023SJohn Marino When badness orders the calls in a way that code reducing calls come
501*e4b17023SJohn Marino first, this situation is not a problem at all: after inlining all
502*e4b17023SJohn Marino "good" calls, we will realize that keeping the function around is
503*e4b17023SJohn Marino better. */
504*e4b17023SJohn Marino else if (growth <= MAX_INLINE_INSNS_SINGLE
505*e4b17023SJohn Marino /* Unlike for functions called once, we play unsafe with
506*e4b17023SJohn Marino COMDATs. We can allow that since we know functions
507*e4b17023SJohn Marino in consideration are small (and thus risk is small) and
508*e4b17023SJohn Marino moreover grow estimates already accounts that COMDAT
509*e4b17023SJohn Marino functions may or may not disappear when eliminated from
510*e4b17023SJohn Marino current unit. With good probability making aggressive
511*e4b17023SJohn Marino choice in all units is going to make overall program
512*e4b17023SJohn Marino smaller.
513*e4b17023SJohn Marino
514*e4b17023SJohn Marino Consequently we ask cgraph_can_remove_if_no_direct_calls_p
515*e4b17023SJohn Marino instead of
516*e4b17023SJohn Marino cgraph_will_be_removed_from_program_if_no_direct_calls */
517*e4b17023SJohn Marino && !DECL_EXTERNAL (callee->decl)
518*e4b17023SJohn Marino && cgraph_can_remove_if_no_direct_calls_p (callee)
519*e4b17023SJohn Marino && estimate_growth (callee) <= 0)
520*e4b17023SJohn Marino ;
521*e4b17023SJohn Marino else if (!DECL_DECLARED_INLINE_P (callee->decl)
522*e4b17023SJohn Marino && !flag_inline_functions)
523*e4b17023SJohn Marino {
524*e4b17023SJohn Marino e->inline_failed = CIF_NOT_DECLARED_INLINED;
525*e4b17023SJohn Marino want_inline = false;
526*e4b17023SJohn Marino }
527*e4b17023SJohn Marino else if (!DECL_DECLARED_INLINE_P (callee->decl)
528*e4b17023SJohn Marino && growth >= MAX_INLINE_INSNS_AUTO)
529*e4b17023SJohn Marino {
530*e4b17023SJohn Marino e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
531*e4b17023SJohn Marino want_inline = false;
532*e4b17023SJohn Marino }
533*e4b17023SJohn Marino /* If call is cold, do not inline when function body would grow. */
534*e4b17023SJohn Marino else if (!cgraph_maybe_hot_edge_p (e))
535*e4b17023SJohn Marino {
536*e4b17023SJohn Marino e->inline_failed = CIF_UNLIKELY_CALL;
537*e4b17023SJohn Marino want_inline = false;
538*e4b17023SJohn Marino }
539*e4b17023SJohn Marino }
540*e4b17023SJohn Marino if (!want_inline && report)
541*e4b17023SJohn Marino report_inline_failed_reason (e);
542*e4b17023SJohn Marino return want_inline;
543*e4b17023SJohn Marino }
544*e4b17023SJohn Marino
545*e4b17023SJohn Marino /* EDGE is self recursive edge.
546*e4b17023SJohn Marino We hand two cases - when function A is inlining into itself
547*e4b17023SJohn Marino or when function A is being inlined into another inliner copy of function
548*e4b17023SJohn Marino A within function B.
549*e4b17023SJohn Marino
550*e4b17023SJohn Marino In first case OUTER_NODE points to the toplevel copy of A, while
551*e4b17023SJohn Marino in the second case OUTER_NODE points to the outermost copy of A in B.
552*e4b17023SJohn Marino
553*e4b17023SJohn Marino In both cases we want to be extra selective since
554*e4b17023SJohn Marino inlining the call will just introduce new recursive calls to appear. */
555*e4b17023SJohn Marino
556*e4b17023SJohn Marino static bool
want_inline_self_recursive_call_p(struct cgraph_edge * edge,struct cgraph_node * outer_node,bool peeling,int depth)557*e4b17023SJohn Marino want_inline_self_recursive_call_p (struct cgraph_edge *edge,
558*e4b17023SJohn Marino struct cgraph_node *outer_node,
559*e4b17023SJohn Marino bool peeling,
560*e4b17023SJohn Marino int depth)
561*e4b17023SJohn Marino {
562*e4b17023SJohn Marino char const *reason = NULL;
563*e4b17023SJohn Marino bool want_inline = true;
564*e4b17023SJohn Marino int caller_freq = CGRAPH_FREQ_BASE;
565*e4b17023SJohn Marino int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
566*e4b17023SJohn Marino
567*e4b17023SJohn Marino if (DECL_DECLARED_INLINE_P (edge->caller->decl))
568*e4b17023SJohn Marino max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
569*e4b17023SJohn Marino
570*e4b17023SJohn Marino if (!cgraph_maybe_hot_edge_p (edge))
571*e4b17023SJohn Marino {
572*e4b17023SJohn Marino reason = "recursive call is cold";
573*e4b17023SJohn Marino want_inline = false;
574*e4b17023SJohn Marino }
575*e4b17023SJohn Marino else if (max_count && !outer_node->count)
576*e4b17023SJohn Marino {
577*e4b17023SJohn Marino reason = "not executed in profile";
578*e4b17023SJohn Marino want_inline = false;
579*e4b17023SJohn Marino }
580*e4b17023SJohn Marino else if (depth > max_depth)
581*e4b17023SJohn Marino {
582*e4b17023SJohn Marino reason = "--param max-inline-recursive-depth exceeded.";
583*e4b17023SJohn Marino want_inline = false;
584*e4b17023SJohn Marino }
585*e4b17023SJohn Marino
586*e4b17023SJohn Marino if (outer_node->global.inlined_to)
587*e4b17023SJohn Marino caller_freq = outer_node->callers->frequency;
588*e4b17023SJohn Marino
589*e4b17023SJohn Marino if (!want_inline)
590*e4b17023SJohn Marino ;
591*e4b17023SJohn Marino /* Inlining of self recursive function into copy of itself within other function
592*e4b17023SJohn Marino is transformation similar to loop peeling.
593*e4b17023SJohn Marino
594*e4b17023SJohn Marino Peeling is profitable if we can inline enough copies to make probability
595*e4b17023SJohn Marino of actual call to the self recursive function very small. Be sure that
596*e4b17023SJohn Marino the probability of recursion is small.
597*e4b17023SJohn Marino
598*e4b17023SJohn Marino We ensure that the frequency of recursing is at most 1 - (1/max_depth).
599*e4b17023SJohn Marino This way the expected number of recision is at most max_depth. */
600*e4b17023SJohn Marino else if (peeling)
601*e4b17023SJohn Marino {
602*e4b17023SJohn Marino int max_prob = CGRAPH_FREQ_BASE - ((CGRAPH_FREQ_BASE + max_depth - 1)
603*e4b17023SJohn Marino / max_depth);
604*e4b17023SJohn Marino int i;
605*e4b17023SJohn Marino for (i = 1; i < depth; i++)
606*e4b17023SJohn Marino max_prob = max_prob * max_prob / CGRAPH_FREQ_BASE;
607*e4b17023SJohn Marino if (max_count
608*e4b17023SJohn Marino && (edge->count * CGRAPH_FREQ_BASE / outer_node->count
609*e4b17023SJohn Marino >= max_prob))
610*e4b17023SJohn Marino {
611*e4b17023SJohn Marino reason = "profile of recursive call is too large";
612*e4b17023SJohn Marino want_inline = false;
613*e4b17023SJohn Marino }
614*e4b17023SJohn Marino if (!max_count
615*e4b17023SJohn Marino && (edge->frequency * CGRAPH_FREQ_BASE / caller_freq
616*e4b17023SJohn Marino >= max_prob))
617*e4b17023SJohn Marino {
618*e4b17023SJohn Marino reason = "frequency of recursive call is too large";
619*e4b17023SJohn Marino want_inline = false;
620*e4b17023SJohn Marino }
621*e4b17023SJohn Marino }
622*e4b17023SJohn Marino /* Recursive inlining, i.e. equivalent of unrolling, is profitable if recursion
623*e4b17023SJohn Marino depth is large. We reduce function call overhead and increase chances that
624*e4b17023SJohn Marino things fit in hardware return predictor.
625*e4b17023SJohn Marino
626*e4b17023SJohn Marino Recursive inlining might however increase cost of stack frame setup
627*e4b17023SJohn Marino actually slowing down functions whose recursion tree is wide rather than
628*e4b17023SJohn Marino deep.
629*e4b17023SJohn Marino
630*e4b17023SJohn Marino Deciding reliably on when to do recursive inlining without profile feedback
631*e4b17023SJohn Marino is tricky. For now we disable recursive inlining when probability of self
632*e4b17023SJohn Marino recursion is low.
633*e4b17023SJohn Marino
634*e4b17023SJohn Marino Recursive inlining of self recursive call within loop also results in large loop
635*e4b17023SJohn Marino depths that generally optimize badly. We may want to throttle down inlining
636*e4b17023SJohn Marino in those cases. In particular this seems to happen in one of libstdc++ rb tree
637*e4b17023SJohn Marino methods. */
638*e4b17023SJohn Marino else
639*e4b17023SJohn Marino {
640*e4b17023SJohn Marino if (max_count
641*e4b17023SJohn Marino && (edge->count * 100 / outer_node->count
642*e4b17023SJohn Marino <= PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY)))
643*e4b17023SJohn Marino {
644*e4b17023SJohn Marino reason = "profile of recursive call is too small";
645*e4b17023SJohn Marino want_inline = false;
646*e4b17023SJohn Marino }
647*e4b17023SJohn Marino else if (!max_count
648*e4b17023SJohn Marino && (edge->frequency * 100 / caller_freq
649*e4b17023SJohn Marino <= PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY)))
650*e4b17023SJohn Marino {
651*e4b17023SJohn Marino reason = "frequency of recursive call is too small";
652*e4b17023SJohn Marino want_inline = false;
653*e4b17023SJohn Marino }
654*e4b17023SJohn Marino }
655*e4b17023SJohn Marino if (!want_inline && dump_file)
656*e4b17023SJohn Marino fprintf (dump_file, " not inlining recursively: %s\n", reason);
657*e4b17023SJohn Marino return want_inline;
658*e4b17023SJohn Marino }
659*e4b17023SJohn Marino
660*e4b17023SJohn Marino /* Return true when NODE has caller other than EDGE.
661*e4b17023SJohn Marino Worker for cgraph_for_node_and_aliases. */
662*e4b17023SJohn Marino
663*e4b17023SJohn Marino static bool
check_caller_edge(struct cgraph_node * node,void * edge)664*e4b17023SJohn Marino check_caller_edge (struct cgraph_node *node, void *edge)
665*e4b17023SJohn Marino {
666*e4b17023SJohn Marino return (node->callers
667*e4b17023SJohn Marino && node->callers != edge);
668*e4b17023SJohn Marino }
669*e4b17023SJohn Marino
670*e4b17023SJohn Marino
671*e4b17023SJohn Marino /* Decide if NODE is called once inlining it would eliminate need
672*e4b17023SJohn Marino for the offline copy of function. */
673*e4b17023SJohn Marino
674*e4b17023SJohn Marino static bool
want_inline_function_called_once_p(struct cgraph_node * node)675*e4b17023SJohn Marino want_inline_function_called_once_p (struct cgraph_node *node)
676*e4b17023SJohn Marino {
677*e4b17023SJohn Marino struct cgraph_node *function = cgraph_function_or_thunk_node (node, NULL);
678*e4b17023SJohn Marino /* Already inlined? */
679*e4b17023SJohn Marino if (function->global.inlined_to)
680*e4b17023SJohn Marino return false;
681*e4b17023SJohn Marino /* Zero or more then one callers? */
682*e4b17023SJohn Marino if (!node->callers
683*e4b17023SJohn Marino || node->callers->next_caller)
684*e4b17023SJohn Marino return false;
685*e4b17023SJohn Marino /* Maybe other aliases has more direct calls. */
686*e4b17023SJohn Marino if (cgraph_for_node_and_aliases (node, check_caller_edge, node->callers, true))
687*e4b17023SJohn Marino return false;
688*e4b17023SJohn Marino /* Recursive call makes no sense to inline. */
689*e4b17023SJohn Marino if (cgraph_edge_recursive_p (node->callers))
690*e4b17023SJohn Marino return false;
691*e4b17023SJohn Marino /* External functions are not really in the unit, so inlining
692*e4b17023SJohn Marino them when called once would just increase the program size. */
693*e4b17023SJohn Marino if (DECL_EXTERNAL (function->decl))
694*e4b17023SJohn Marino return false;
695*e4b17023SJohn Marino /* Offline body must be optimized out. */
696*e4b17023SJohn Marino if (!cgraph_will_be_removed_from_program_if_no_direct_calls (function))
697*e4b17023SJohn Marino return false;
698*e4b17023SJohn Marino if (!can_inline_edge_p (node->callers, true))
699*e4b17023SJohn Marino return false;
700*e4b17023SJohn Marino return true;
701*e4b17023SJohn Marino }
702*e4b17023SJohn Marino
703*e4b17023SJohn Marino
704*e4b17023SJohn Marino /* Return relative time improvement for inlining EDGE in range
705*e4b17023SJohn Marino 1...2^9. */
706*e4b17023SJohn Marino
707*e4b17023SJohn Marino static inline int
relative_time_benefit(struct inline_summary * callee_info,struct cgraph_edge * edge,int time_growth)708*e4b17023SJohn Marino relative_time_benefit (struct inline_summary *callee_info,
709*e4b17023SJohn Marino struct cgraph_edge *edge,
710*e4b17023SJohn Marino int time_growth)
711*e4b17023SJohn Marino {
712*e4b17023SJohn Marino int relbenefit;
713*e4b17023SJohn Marino gcov_type uninlined_call_time;
714*e4b17023SJohn Marino
715*e4b17023SJohn Marino uninlined_call_time =
716*e4b17023SJohn Marino ((gcov_type)
717*e4b17023SJohn Marino (callee_info->time
718*e4b17023SJohn Marino + inline_edge_summary (edge)->call_stmt_time) * edge->frequency
719*e4b17023SJohn Marino + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
720*e4b17023SJohn Marino /* Compute relative time benefit, i.e. how much the call becomes faster.
721*e4b17023SJohn Marino ??? perhaps computing how much the caller+calle together become faster
722*e4b17023SJohn Marino would lead to more realistic results. */
723*e4b17023SJohn Marino if (!uninlined_call_time)
724*e4b17023SJohn Marino uninlined_call_time = 1;
725*e4b17023SJohn Marino relbenefit =
726*e4b17023SJohn Marino (uninlined_call_time - time_growth) * 256 / (uninlined_call_time);
727*e4b17023SJohn Marino relbenefit = MIN (relbenefit, 512);
728*e4b17023SJohn Marino relbenefit = MAX (relbenefit, 1);
729*e4b17023SJohn Marino return relbenefit;
730*e4b17023SJohn Marino }
731*e4b17023SJohn Marino
732*e4b17023SJohn Marino
733*e4b17023SJohn Marino /* A cost model driving the inlining heuristics in a way so the edges with
734*e4b17023SJohn Marino smallest badness are inlined first. After each inlining is performed
735*e4b17023SJohn Marino the costs of all caller edges of nodes affected are recomputed so the
736*e4b17023SJohn Marino metrics may accurately depend on values such as number of inlinable callers
737*e4b17023SJohn Marino of the function or function body size. */
738*e4b17023SJohn Marino
739*e4b17023SJohn Marino static int
edge_badness(struct cgraph_edge * edge,bool dump)740*e4b17023SJohn Marino edge_badness (struct cgraph_edge *edge, bool dump)
741*e4b17023SJohn Marino {
742*e4b17023SJohn Marino gcov_type badness;
743*e4b17023SJohn Marino int growth, time_growth;
744*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (edge->callee,
745*e4b17023SJohn Marino NULL);
746*e4b17023SJohn Marino struct inline_summary *callee_info = inline_summary (callee);
747*e4b17023SJohn Marino
748*e4b17023SJohn Marino if (DECL_DISREGARD_INLINE_LIMITS (callee->decl))
749*e4b17023SJohn Marino return INT_MIN;
750*e4b17023SJohn Marino
751*e4b17023SJohn Marino growth = estimate_edge_growth (edge);
752*e4b17023SJohn Marino time_growth = estimate_edge_time (edge);
753*e4b17023SJohn Marino
754*e4b17023SJohn Marino if (dump)
755*e4b17023SJohn Marino {
756*e4b17023SJohn Marino fprintf (dump_file, " Badness calculation for %s -> %s\n",
757*e4b17023SJohn Marino xstrdup (cgraph_node_name (edge->caller)),
758*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)));
759*e4b17023SJohn Marino fprintf (dump_file, " size growth %i, time growth %i\n",
760*e4b17023SJohn Marino growth,
761*e4b17023SJohn Marino time_growth);
762*e4b17023SJohn Marino }
763*e4b17023SJohn Marino
764*e4b17023SJohn Marino /* Always prefer inlining saving code size. */
765*e4b17023SJohn Marino if (growth <= 0)
766*e4b17023SJohn Marino {
767*e4b17023SJohn Marino badness = INT_MIN / 2 + growth;
768*e4b17023SJohn Marino if (dump)
769*e4b17023SJohn Marino fprintf (dump_file, " %i: Growth %i <= 0\n", (int) badness,
770*e4b17023SJohn Marino growth);
771*e4b17023SJohn Marino }
772*e4b17023SJohn Marino
773*e4b17023SJohn Marino /* When profiling is available, compute badness as:
774*e4b17023SJohn Marino
775*e4b17023SJohn Marino relative_edge_count * relative_time_benefit
776*e4b17023SJohn Marino goodness = -------------------------------------------
777*e4b17023SJohn Marino edge_growth
778*e4b17023SJohn Marino badness = -goodness
779*e4b17023SJohn Marino
780*e4b17023SJohn Marino The fraction is upside down, becuase on edge counts and time beneits
781*e4b17023SJohn Marino the bounds are known. Edge growth is essentially unlimited. */
782*e4b17023SJohn Marino
783*e4b17023SJohn Marino else if (max_count)
784*e4b17023SJohn Marino {
785*e4b17023SJohn Marino int relbenefit = relative_time_benefit (callee_info, edge, time_growth);
786*e4b17023SJohn Marino badness =
787*e4b17023SJohn Marino ((int)
788*e4b17023SJohn Marino ((double) edge->count * INT_MIN / 2 / max_count / 512) *
789*e4b17023SJohn Marino relative_time_benefit (callee_info, edge, time_growth)) / growth;
790*e4b17023SJohn Marino
791*e4b17023SJohn Marino /* Be sure that insanity of the profile won't lead to increasing counts
792*e4b17023SJohn Marino in the scalling and thus to overflow in the computation above. */
793*e4b17023SJohn Marino gcc_assert (max_count >= edge->count);
794*e4b17023SJohn Marino if (dump)
795*e4b17023SJohn Marino {
796*e4b17023SJohn Marino fprintf (dump_file,
797*e4b17023SJohn Marino " %i (relative %f): profile info. Relative count %f"
798*e4b17023SJohn Marino " * Relative benefit %f\n",
799*e4b17023SJohn Marino (int) badness, (double) badness / INT_MIN,
800*e4b17023SJohn Marino (double) edge->count / max_count,
801*e4b17023SJohn Marino relbenefit * 100 / 256.0);
802*e4b17023SJohn Marino }
803*e4b17023SJohn Marino }
804*e4b17023SJohn Marino
805*e4b17023SJohn Marino /* When function local profile is available. Compute badness as:
806*e4b17023SJohn Marino
807*e4b17023SJohn Marino
808*e4b17023SJohn Marino growth_of_callee
809*e4b17023SJohn Marino badness = -------------------------------------- + growth_for-all
810*e4b17023SJohn Marino relative_time_benefit * edge_frequency
811*e4b17023SJohn Marino
812*e4b17023SJohn Marino */
813*e4b17023SJohn Marino else if (flag_guess_branch_prob)
814*e4b17023SJohn Marino {
815*e4b17023SJohn Marino int div = edge->frequency * (1<<10) / CGRAPH_FREQ_MAX;
816*e4b17023SJohn Marino
817*e4b17023SJohn Marino div = MAX (div, 1);
818*e4b17023SJohn Marino gcc_checking_assert (edge->frequency <= CGRAPH_FREQ_MAX);
819*e4b17023SJohn Marino div *= relative_time_benefit (callee_info, edge, time_growth);
820*e4b17023SJohn Marino
821*e4b17023SJohn Marino /* frequency is normalized in range 1...2^10.
822*e4b17023SJohn Marino relbenefit in range 1...2^9
823*e4b17023SJohn Marino DIV should be in range 1....2^19. */
824*e4b17023SJohn Marino gcc_checking_assert (div >= 1 && div <= (1<<19));
825*e4b17023SJohn Marino
826*e4b17023SJohn Marino /* Result must be integer in range 0...INT_MAX.
827*e4b17023SJohn Marino Set the base of fixed point calculation so we don't lose much of
828*e4b17023SJohn Marino precision for small bandesses (those are interesting) yet we don't
829*e4b17023SJohn Marino overflow for growths that are still in interesting range.
830*e4b17023SJohn Marino
831*e4b17023SJohn Marino Fixed point arithmetic with point at 8th bit. */
832*e4b17023SJohn Marino badness = ((gcov_type)growth) * (1<<(19+8));
833*e4b17023SJohn Marino badness = (badness + div / 2) / div;
834*e4b17023SJohn Marino
835*e4b17023SJohn Marino /* Overall growth of inlining all calls of function matters: we want to
836*e4b17023SJohn Marino inline so offline copy of function is no longer needed.
837*e4b17023SJohn Marino
838*e4b17023SJohn Marino Additionally functions that can be fully inlined without much of
839*e4b17023SJohn Marino effort are better inline candidates than functions that can be fully
840*e4b17023SJohn Marino inlined only after noticeable overall unit growths. The latter
841*e4b17023SJohn Marino are better in a sense compressing of code size by factoring out common
842*e4b17023SJohn Marino code into separate function shared by multiple code paths.
843*e4b17023SJohn Marino
844*e4b17023SJohn Marino We might mix the valud into the fraction by taking into account
845*e4b17023SJohn Marino relative growth of the unit, but for now just add the number
846*e4b17023SJohn Marino into resulting fraction. */
847*e4b17023SJohn Marino if (badness > INT_MAX / 2)
848*e4b17023SJohn Marino {
849*e4b17023SJohn Marino badness = INT_MAX / 2;
850*e4b17023SJohn Marino if (dump)
851*e4b17023SJohn Marino fprintf (dump_file, "Badness overflow\n");
852*e4b17023SJohn Marino }
853*e4b17023SJohn Marino if (dump)
854*e4b17023SJohn Marino {
855*e4b17023SJohn Marino fprintf (dump_file,
856*e4b17023SJohn Marino " %i: guessed profile. frequency %f,"
857*e4b17023SJohn Marino " benefit %f%%, divisor %i\n",
858*e4b17023SJohn Marino (int) badness, (double)edge->frequency / CGRAPH_FREQ_BASE,
859*e4b17023SJohn Marino relative_time_benefit (callee_info, edge, time_growth) * 100 / 256.0, div);
860*e4b17023SJohn Marino }
861*e4b17023SJohn Marino }
862*e4b17023SJohn Marino /* When function local profile is not available or it does not give
863*e4b17023SJohn Marino useful information (ie frequency is zero), base the cost on
864*e4b17023SJohn Marino loop nest and overall size growth, so we optimize for overall number
865*e4b17023SJohn Marino of functions fully inlined in program. */
866*e4b17023SJohn Marino else
867*e4b17023SJohn Marino {
868*e4b17023SJohn Marino int nest = MIN (inline_edge_summary (edge)->loop_depth, 8);
869*e4b17023SJohn Marino badness = growth * 256;
870*e4b17023SJohn Marino
871*e4b17023SJohn Marino /* Decrease badness if call is nested. */
872*e4b17023SJohn Marino if (badness > 0)
873*e4b17023SJohn Marino badness >>= nest;
874*e4b17023SJohn Marino else
875*e4b17023SJohn Marino {
876*e4b17023SJohn Marino badness <<= nest;
877*e4b17023SJohn Marino }
878*e4b17023SJohn Marino if (dump)
879*e4b17023SJohn Marino fprintf (dump_file, " %i: no profile. nest %i\n", (int) badness,
880*e4b17023SJohn Marino nest);
881*e4b17023SJohn Marino }
882*e4b17023SJohn Marino
883*e4b17023SJohn Marino /* Ensure that we did not overflow in all the fixed point math above. */
884*e4b17023SJohn Marino gcc_assert (badness >= INT_MIN);
885*e4b17023SJohn Marino gcc_assert (badness <= INT_MAX - 1);
886*e4b17023SJohn Marino /* Make recursive inlining happen always after other inlining is done. */
887*e4b17023SJohn Marino if (cgraph_edge_recursive_p (edge))
888*e4b17023SJohn Marino return badness + 1;
889*e4b17023SJohn Marino else
890*e4b17023SJohn Marino return badness;
891*e4b17023SJohn Marino }
892*e4b17023SJohn Marino
893*e4b17023SJohn Marino /* Recompute badness of EDGE and update its key in HEAP if needed. */
894*e4b17023SJohn Marino static inline void
update_edge_key(fibheap_t heap,struct cgraph_edge * edge)895*e4b17023SJohn Marino update_edge_key (fibheap_t heap, struct cgraph_edge *edge)
896*e4b17023SJohn Marino {
897*e4b17023SJohn Marino int badness = edge_badness (edge, false);
898*e4b17023SJohn Marino if (edge->aux)
899*e4b17023SJohn Marino {
900*e4b17023SJohn Marino fibnode_t n = (fibnode_t) edge->aux;
901*e4b17023SJohn Marino gcc_checking_assert (n->data == edge);
902*e4b17023SJohn Marino
903*e4b17023SJohn Marino /* fibheap_replace_key only decrease the keys.
904*e4b17023SJohn Marino When we increase the key we do not update heap
905*e4b17023SJohn Marino and instead re-insert the element once it becomes
906*e4b17023SJohn Marino a minimum of heap. */
907*e4b17023SJohn Marino if (badness < n->key)
908*e4b17023SJohn Marino {
909*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
910*e4b17023SJohn Marino {
911*e4b17023SJohn Marino fprintf (dump_file,
912*e4b17023SJohn Marino " decreasing badness %s/%i -> %s/%i, %i to %i\n",
913*e4b17023SJohn Marino xstrdup (cgraph_node_name (edge->caller)),
914*e4b17023SJohn Marino edge->caller->uid,
915*e4b17023SJohn Marino xstrdup (cgraph_node_name (edge->callee)),
916*e4b17023SJohn Marino edge->callee->uid,
917*e4b17023SJohn Marino (int)n->key,
918*e4b17023SJohn Marino badness);
919*e4b17023SJohn Marino }
920*e4b17023SJohn Marino fibheap_replace_key (heap, n, badness);
921*e4b17023SJohn Marino gcc_checking_assert (n->key == badness);
922*e4b17023SJohn Marino }
923*e4b17023SJohn Marino }
924*e4b17023SJohn Marino else
925*e4b17023SJohn Marino {
926*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
927*e4b17023SJohn Marino {
928*e4b17023SJohn Marino fprintf (dump_file,
929*e4b17023SJohn Marino " enqueuing call %s/%i -> %s/%i, badness %i\n",
930*e4b17023SJohn Marino xstrdup (cgraph_node_name (edge->caller)),
931*e4b17023SJohn Marino edge->caller->uid,
932*e4b17023SJohn Marino xstrdup (cgraph_node_name (edge->callee)),
933*e4b17023SJohn Marino edge->callee->uid,
934*e4b17023SJohn Marino badness);
935*e4b17023SJohn Marino }
936*e4b17023SJohn Marino edge->aux = fibheap_insert (heap, badness, edge);
937*e4b17023SJohn Marino }
938*e4b17023SJohn Marino }
939*e4b17023SJohn Marino
940*e4b17023SJohn Marino
941*e4b17023SJohn Marino /* NODE was inlined.
942*e4b17023SJohn Marino All caller edges needs to be resetted because
943*e4b17023SJohn Marino size estimates change. Similarly callees needs reset
944*e4b17023SJohn Marino because better context may be known. */
945*e4b17023SJohn Marino
946*e4b17023SJohn Marino static void
reset_edge_caches(struct cgraph_node * node)947*e4b17023SJohn Marino reset_edge_caches (struct cgraph_node *node)
948*e4b17023SJohn Marino {
949*e4b17023SJohn Marino struct cgraph_edge *edge;
950*e4b17023SJohn Marino struct cgraph_edge *e = node->callees;
951*e4b17023SJohn Marino struct cgraph_node *where = node;
952*e4b17023SJohn Marino int i;
953*e4b17023SJohn Marino struct ipa_ref *ref;
954*e4b17023SJohn Marino
955*e4b17023SJohn Marino if (where->global.inlined_to)
956*e4b17023SJohn Marino where = where->global.inlined_to;
957*e4b17023SJohn Marino
958*e4b17023SJohn Marino /* WHERE body size has changed, the cached growth is invalid. */
959*e4b17023SJohn Marino reset_node_growth_cache (where);
960*e4b17023SJohn Marino
961*e4b17023SJohn Marino for (edge = where->callers; edge; edge = edge->next_caller)
962*e4b17023SJohn Marino if (edge->inline_failed)
963*e4b17023SJohn Marino reset_edge_growth_cache (edge);
964*e4b17023SJohn Marino for (i = 0; ipa_ref_list_refering_iterate (&where->ref_list, i, ref); i++)
965*e4b17023SJohn Marino if (ref->use == IPA_REF_ALIAS)
966*e4b17023SJohn Marino reset_edge_caches (ipa_ref_refering_node (ref));
967*e4b17023SJohn Marino
968*e4b17023SJohn Marino if (!e)
969*e4b17023SJohn Marino return;
970*e4b17023SJohn Marino
971*e4b17023SJohn Marino while (true)
972*e4b17023SJohn Marino if (!e->inline_failed && e->callee->callees)
973*e4b17023SJohn Marino e = e->callee->callees;
974*e4b17023SJohn Marino else
975*e4b17023SJohn Marino {
976*e4b17023SJohn Marino if (e->inline_failed)
977*e4b17023SJohn Marino reset_edge_growth_cache (e);
978*e4b17023SJohn Marino if (e->next_callee)
979*e4b17023SJohn Marino e = e->next_callee;
980*e4b17023SJohn Marino else
981*e4b17023SJohn Marino {
982*e4b17023SJohn Marino do
983*e4b17023SJohn Marino {
984*e4b17023SJohn Marino if (e->caller == node)
985*e4b17023SJohn Marino return;
986*e4b17023SJohn Marino e = e->caller->callers;
987*e4b17023SJohn Marino }
988*e4b17023SJohn Marino while (!e->next_callee);
989*e4b17023SJohn Marino e = e->next_callee;
990*e4b17023SJohn Marino }
991*e4b17023SJohn Marino }
992*e4b17023SJohn Marino }
993*e4b17023SJohn Marino
994*e4b17023SJohn Marino /* Recompute HEAP nodes for each of caller of NODE.
995*e4b17023SJohn Marino UPDATED_NODES track nodes we already visited, to avoid redundant work.
996*e4b17023SJohn Marino When CHECK_INLINABLITY_FOR is set, re-check for specified edge that
997*e4b17023SJohn Marino it is inlinable. Otherwise check all edges. */
998*e4b17023SJohn Marino
999*e4b17023SJohn Marino static void
update_caller_keys(fibheap_t heap,struct cgraph_node * node,bitmap updated_nodes,struct cgraph_edge * check_inlinablity_for)1000*e4b17023SJohn Marino update_caller_keys (fibheap_t heap, struct cgraph_node *node,
1001*e4b17023SJohn Marino bitmap updated_nodes,
1002*e4b17023SJohn Marino struct cgraph_edge *check_inlinablity_for)
1003*e4b17023SJohn Marino {
1004*e4b17023SJohn Marino struct cgraph_edge *edge;
1005*e4b17023SJohn Marino int i;
1006*e4b17023SJohn Marino struct ipa_ref *ref;
1007*e4b17023SJohn Marino
1008*e4b17023SJohn Marino if ((!node->alias && !inline_summary (node)->inlinable)
1009*e4b17023SJohn Marino || cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
1010*e4b17023SJohn Marino || node->global.inlined_to)
1011*e4b17023SJohn Marino return;
1012*e4b17023SJohn Marino if (!bitmap_set_bit (updated_nodes, node->uid))
1013*e4b17023SJohn Marino return;
1014*e4b17023SJohn Marino
1015*e4b17023SJohn Marino for (i = 0; ipa_ref_list_refering_iterate (&node->ref_list, i, ref); i++)
1016*e4b17023SJohn Marino if (ref->use == IPA_REF_ALIAS)
1017*e4b17023SJohn Marino {
1018*e4b17023SJohn Marino struct cgraph_node *alias = ipa_ref_refering_node (ref);
1019*e4b17023SJohn Marino update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for);
1020*e4b17023SJohn Marino }
1021*e4b17023SJohn Marino
1022*e4b17023SJohn Marino for (edge = node->callers; edge; edge = edge->next_caller)
1023*e4b17023SJohn Marino if (edge->inline_failed)
1024*e4b17023SJohn Marino {
1025*e4b17023SJohn Marino if (!check_inlinablity_for
1026*e4b17023SJohn Marino || check_inlinablity_for == edge)
1027*e4b17023SJohn Marino {
1028*e4b17023SJohn Marino if (can_inline_edge_p (edge, false)
1029*e4b17023SJohn Marino && want_inline_small_function_p (edge, false))
1030*e4b17023SJohn Marino update_edge_key (heap, edge);
1031*e4b17023SJohn Marino else if (edge->aux)
1032*e4b17023SJohn Marino {
1033*e4b17023SJohn Marino report_inline_failed_reason (edge);
1034*e4b17023SJohn Marino fibheap_delete_node (heap, (fibnode_t) edge->aux);
1035*e4b17023SJohn Marino edge->aux = NULL;
1036*e4b17023SJohn Marino }
1037*e4b17023SJohn Marino }
1038*e4b17023SJohn Marino else if (edge->aux)
1039*e4b17023SJohn Marino update_edge_key (heap, edge);
1040*e4b17023SJohn Marino }
1041*e4b17023SJohn Marino }
1042*e4b17023SJohn Marino
1043*e4b17023SJohn Marino /* Recompute HEAP nodes for each uninlined call in NODE.
1044*e4b17023SJohn Marino This is used when we know that edge badnesses are going only to increase
1045*e4b17023SJohn Marino (we introduced new call site) and thus all we need is to insert newly
1046*e4b17023SJohn Marino created edges into heap. */
1047*e4b17023SJohn Marino
1048*e4b17023SJohn Marino static void
update_callee_keys(fibheap_t heap,struct cgraph_node * node,bitmap updated_nodes)1049*e4b17023SJohn Marino update_callee_keys (fibheap_t heap, struct cgraph_node *node,
1050*e4b17023SJohn Marino bitmap updated_nodes)
1051*e4b17023SJohn Marino {
1052*e4b17023SJohn Marino struct cgraph_edge *e = node->callees;
1053*e4b17023SJohn Marino
1054*e4b17023SJohn Marino if (!e)
1055*e4b17023SJohn Marino return;
1056*e4b17023SJohn Marino while (true)
1057*e4b17023SJohn Marino if (!e->inline_failed && e->callee->callees)
1058*e4b17023SJohn Marino e = e->callee->callees;
1059*e4b17023SJohn Marino else
1060*e4b17023SJohn Marino {
1061*e4b17023SJohn Marino enum availability avail;
1062*e4b17023SJohn Marino struct cgraph_node *callee;
1063*e4b17023SJohn Marino /* We do not reset callee growth cache here. Since we added a new call,
1064*e4b17023SJohn Marino growth chould have just increased and consequentely badness metric
1065*e4b17023SJohn Marino don't need updating. */
1066*e4b17023SJohn Marino if (e->inline_failed
1067*e4b17023SJohn Marino && (callee = cgraph_function_or_thunk_node (e->callee, &avail))
1068*e4b17023SJohn Marino && inline_summary (callee)->inlinable
1069*e4b17023SJohn Marino && cgraph_function_body_availability (callee) >= AVAIL_AVAILABLE
1070*e4b17023SJohn Marino && !bitmap_bit_p (updated_nodes, callee->uid))
1071*e4b17023SJohn Marino {
1072*e4b17023SJohn Marino if (can_inline_edge_p (e, false)
1073*e4b17023SJohn Marino && want_inline_small_function_p (e, false))
1074*e4b17023SJohn Marino update_edge_key (heap, e);
1075*e4b17023SJohn Marino else if (e->aux)
1076*e4b17023SJohn Marino {
1077*e4b17023SJohn Marino report_inline_failed_reason (e);
1078*e4b17023SJohn Marino fibheap_delete_node (heap, (fibnode_t) e->aux);
1079*e4b17023SJohn Marino e->aux = NULL;
1080*e4b17023SJohn Marino }
1081*e4b17023SJohn Marino }
1082*e4b17023SJohn Marino if (e->next_callee)
1083*e4b17023SJohn Marino e = e->next_callee;
1084*e4b17023SJohn Marino else
1085*e4b17023SJohn Marino {
1086*e4b17023SJohn Marino do
1087*e4b17023SJohn Marino {
1088*e4b17023SJohn Marino if (e->caller == node)
1089*e4b17023SJohn Marino return;
1090*e4b17023SJohn Marino e = e->caller->callers;
1091*e4b17023SJohn Marino }
1092*e4b17023SJohn Marino while (!e->next_callee);
1093*e4b17023SJohn Marino e = e->next_callee;
1094*e4b17023SJohn Marino }
1095*e4b17023SJohn Marino }
1096*e4b17023SJohn Marino }
1097*e4b17023SJohn Marino
1098*e4b17023SJohn Marino /* Recompute heap nodes for each of caller edges of each of callees.
1099*e4b17023SJohn Marino Walk recursively into all inline clones. */
1100*e4b17023SJohn Marino
1101*e4b17023SJohn Marino static void
update_all_callee_keys(fibheap_t heap,struct cgraph_node * node,bitmap updated_nodes)1102*e4b17023SJohn Marino update_all_callee_keys (fibheap_t heap, struct cgraph_node *node,
1103*e4b17023SJohn Marino bitmap updated_nodes)
1104*e4b17023SJohn Marino {
1105*e4b17023SJohn Marino struct cgraph_edge *e = node->callees;
1106*e4b17023SJohn Marino if (!e)
1107*e4b17023SJohn Marino return;
1108*e4b17023SJohn Marino while (true)
1109*e4b17023SJohn Marino if (!e->inline_failed && e->callee->callees)
1110*e4b17023SJohn Marino e = e->callee->callees;
1111*e4b17023SJohn Marino else
1112*e4b17023SJohn Marino {
1113*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee,
1114*e4b17023SJohn Marino NULL);
1115*e4b17023SJohn Marino
1116*e4b17023SJohn Marino /* We inlined and thus callees might have different number of calls.
1117*e4b17023SJohn Marino Reset their caches */
1118*e4b17023SJohn Marino reset_node_growth_cache (callee);
1119*e4b17023SJohn Marino if (e->inline_failed)
1120*e4b17023SJohn Marino update_caller_keys (heap, callee, updated_nodes, e);
1121*e4b17023SJohn Marino if (e->next_callee)
1122*e4b17023SJohn Marino e = e->next_callee;
1123*e4b17023SJohn Marino else
1124*e4b17023SJohn Marino {
1125*e4b17023SJohn Marino do
1126*e4b17023SJohn Marino {
1127*e4b17023SJohn Marino if (e->caller == node)
1128*e4b17023SJohn Marino return;
1129*e4b17023SJohn Marino e = e->caller->callers;
1130*e4b17023SJohn Marino }
1131*e4b17023SJohn Marino while (!e->next_callee);
1132*e4b17023SJohn Marino e = e->next_callee;
1133*e4b17023SJohn Marino }
1134*e4b17023SJohn Marino }
1135*e4b17023SJohn Marino }
1136*e4b17023SJohn Marino
1137*e4b17023SJohn Marino /* Enqueue all recursive calls from NODE into priority queue depending on
1138*e4b17023SJohn Marino how likely we want to recursively inline the call. */
1139*e4b17023SJohn Marino
1140*e4b17023SJohn Marino static void
lookup_recursive_calls(struct cgraph_node * node,struct cgraph_node * where,fibheap_t heap)1141*e4b17023SJohn Marino lookup_recursive_calls (struct cgraph_node *node, struct cgraph_node *where,
1142*e4b17023SJohn Marino fibheap_t heap)
1143*e4b17023SJohn Marino {
1144*e4b17023SJohn Marino struct cgraph_edge *e;
1145*e4b17023SJohn Marino enum availability avail;
1146*e4b17023SJohn Marino
1147*e4b17023SJohn Marino for (e = where->callees; e; e = e->next_callee)
1148*e4b17023SJohn Marino if (e->callee == node
1149*e4b17023SJohn Marino || (cgraph_function_or_thunk_node (e->callee, &avail) == node
1150*e4b17023SJohn Marino && avail > AVAIL_OVERWRITABLE))
1151*e4b17023SJohn Marino {
1152*e4b17023SJohn Marino /* When profile feedback is available, prioritize by expected number
1153*e4b17023SJohn Marino of calls. */
1154*e4b17023SJohn Marino fibheap_insert (heap,
1155*e4b17023SJohn Marino !max_count ? -e->frequency
1156*e4b17023SJohn Marino : -(e->count / ((max_count + (1<<24) - 1) / (1<<24))),
1157*e4b17023SJohn Marino e);
1158*e4b17023SJohn Marino }
1159*e4b17023SJohn Marino for (e = where->callees; e; e = e->next_callee)
1160*e4b17023SJohn Marino if (!e->inline_failed)
1161*e4b17023SJohn Marino lookup_recursive_calls (node, e->callee, heap);
1162*e4b17023SJohn Marino }
1163*e4b17023SJohn Marino
1164*e4b17023SJohn Marino /* Decide on recursive inlining: in the case function has recursive calls,
1165*e4b17023SJohn Marino inline until body size reaches given argument. If any new indirect edges
1166*e4b17023SJohn Marino are discovered in the process, add them to *NEW_EDGES, unless NEW_EDGES
1167*e4b17023SJohn Marino is NULL. */
1168*e4b17023SJohn Marino
1169*e4b17023SJohn Marino static bool
recursive_inlining(struct cgraph_edge * edge,VEC (cgraph_edge_p,heap)** new_edges)1170*e4b17023SJohn Marino recursive_inlining (struct cgraph_edge *edge,
1171*e4b17023SJohn Marino VEC (cgraph_edge_p, heap) **new_edges)
1172*e4b17023SJohn Marino {
1173*e4b17023SJohn Marino int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
1174*e4b17023SJohn Marino fibheap_t heap;
1175*e4b17023SJohn Marino struct cgraph_node *node;
1176*e4b17023SJohn Marino struct cgraph_edge *e;
1177*e4b17023SJohn Marino struct cgraph_node *master_clone = NULL, *next;
1178*e4b17023SJohn Marino int depth = 0;
1179*e4b17023SJohn Marino int n = 0;
1180*e4b17023SJohn Marino
1181*e4b17023SJohn Marino node = edge->caller;
1182*e4b17023SJohn Marino if (node->global.inlined_to)
1183*e4b17023SJohn Marino node = node->global.inlined_to;
1184*e4b17023SJohn Marino
1185*e4b17023SJohn Marino if (DECL_DECLARED_INLINE_P (node->decl))
1186*e4b17023SJohn Marino limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
1187*e4b17023SJohn Marino
1188*e4b17023SJohn Marino /* Make sure that function is small enough to be considered for inlining. */
1189*e4b17023SJohn Marino if (estimate_size_after_inlining (node, edge) >= limit)
1190*e4b17023SJohn Marino return false;
1191*e4b17023SJohn Marino heap = fibheap_new ();
1192*e4b17023SJohn Marino lookup_recursive_calls (node, node, heap);
1193*e4b17023SJohn Marino if (fibheap_empty (heap))
1194*e4b17023SJohn Marino {
1195*e4b17023SJohn Marino fibheap_delete (heap);
1196*e4b17023SJohn Marino return false;
1197*e4b17023SJohn Marino }
1198*e4b17023SJohn Marino
1199*e4b17023SJohn Marino if (dump_file)
1200*e4b17023SJohn Marino fprintf (dump_file,
1201*e4b17023SJohn Marino " Performing recursive inlining on %s\n",
1202*e4b17023SJohn Marino cgraph_node_name (node));
1203*e4b17023SJohn Marino
1204*e4b17023SJohn Marino /* Do the inlining and update list of recursive call during process. */
1205*e4b17023SJohn Marino while (!fibheap_empty (heap))
1206*e4b17023SJohn Marino {
1207*e4b17023SJohn Marino struct cgraph_edge *curr
1208*e4b17023SJohn Marino = (struct cgraph_edge *) fibheap_extract_min (heap);
1209*e4b17023SJohn Marino struct cgraph_node *cnode;
1210*e4b17023SJohn Marino
1211*e4b17023SJohn Marino if (estimate_size_after_inlining (node, curr) > limit)
1212*e4b17023SJohn Marino break;
1213*e4b17023SJohn Marino
1214*e4b17023SJohn Marino if (!can_inline_edge_p (curr, true))
1215*e4b17023SJohn Marino continue;
1216*e4b17023SJohn Marino
1217*e4b17023SJohn Marino depth = 1;
1218*e4b17023SJohn Marino for (cnode = curr->caller;
1219*e4b17023SJohn Marino cnode->global.inlined_to; cnode = cnode->callers->caller)
1220*e4b17023SJohn Marino if (node->decl
1221*e4b17023SJohn Marino == cgraph_function_or_thunk_node (curr->callee, NULL)->decl)
1222*e4b17023SJohn Marino depth++;
1223*e4b17023SJohn Marino
1224*e4b17023SJohn Marino if (!want_inline_self_recursive_call_p (curr, node, false, depth))
1225*e4b17023SJohn Marino continue;
1226*e4b17023SJohn Marino
1227*e4b17023SJohn Marino if (dump_file)
1228*e4b17023SJohn Marino {
1229*e4b17023SJohn Marino fprintf (dump_file,
1230*e4b17023SJohn Marino " Inlining call of depth %i", depth);
1231*e4b17023SJohn Marino if (node->count)
1232*e4b17023SJohn Marino {
1233*e4b17023SJohn Marino fprintf (dump_file, " called approx. %.2f times per call",
1234*e4b17023SJohn Marino (double)curr->count / node->count);
1235*e4b17023SJohn Marino }
1236*e4b17023SJohn Marino fprintf (dump_file, "\n");
1237*e4b17023SJohn Marino }
1238*e4b17023SJohn Marino if (!master_clone)
1239*e4b17023SJohn Marino {
1240*e4b17023SJohn Marino /* We need original clone to copy around. */
1241*e4b17023SJohn Marino master_clone = cgraph_clone_node (node, node->decl,
1242*e4b17023SJohn Marino node->count, CGRAPH_FREQ_BASE,
1243*e4b17023SJohn Marino false, NULL, true);
1244*e4b17023SJohn Marino for (e = master_clone->callees; e; e = e->next_callee)
1245*e4b17023SJohn Marino if (!e->inline_failed)
1246*e4b17023SJohn Marino clone_inlined_nodes (e, true, false, NULL);
1247*e4b17023SJohn Marino }
1248*e4b17023SJohn Marino
1249*e4b17023SJohn Marino cgraph_redirect_edge_callee (curr, master_clone);
1250*e4b17023SJohn Marino inline_call (curr, false, new_edges, &overall_size);
1251*e4b17023SJohn Marino lookup_recursive_calls (node, curr->callee, heap);
1252*e4b17023SJohn Marino n++;
1253*e4b17023SJohn Marino }
1254*e4b17023SJohn Marino
1255*e4b17023SJohn Marino if (!fibheap_empty (heap) && dump_file)
1256*e4b17023SJohn Marino fprintf (dump_file, " Recursive inlining growth limit met.\n");
1257*e4b17023SJohn Marino fibheap_delete (heap);
1258*e4b17023SJohn Marino
1259*e4b17023SJohn Marino if (!master_clone)
1260*e4b17023SJohn Marino return false;
1261*e4b17023SJohn Marino
1262*e4b17023SJohn Marino if (dump_file)
1263*e4b17023SJohn Marino fprintf (dump_file,
1264*e4b17023SJohn Marino "\n Inlined %i times, "
1265*e4b17023SJohn Marino "body grown from size %i to %i, time %i to %i\n", n,
1266*e4b17023SJohn Marino inline_summary (master_clone)->size, inline_summary (node)->size,
1267*e4b17023SJohn Marino inline_summary (master_clone)->time, inline_summary (node)->time);
1268*e4b17023SJohn Marino
1269*e4b17023SJohn Marino /* Remove master clone we used for inlining. We rely that clones inlined
1270*e4b17023SJohn Marino into master clone gets queued just before master clone so we don't
1271*e4b17023SJohn Marino need recursion. */
1272*e4b17023SJohn Marino for (node = cgraph_nodes; node != master_clone;
1273*e4b17023SJohn Marino node = next)
1274*e4b17023SJohn Marino {
1275*e4b17023SJohn Marino next = node->next;
1276*e4b17023SJohn Marino if (node->global.inlined_to == master_clone)
1277*e4b17023SJohn Marino cgraph_remove_node (node);
1278*e4b17023SJohn Marino }
1279*e4b17023SJohn Marino cgraph_remove_node (master_clone);
1280*e4b17023SJohn Marino return true;
1281*e4b17023SJohn Marino }
1282*e4b17023SJohn Marino
1283*e4b17023SJohn Marino
1284*e4b17023SJohn Marino /* Given whole compilation unit estimate of INSNS, compute how large we can
1285*e4b17023SJohn Marino allow the unit to grow. */
1286*e4b17023SJohn Marino
1287*e4b17023SJohn Marino static int
compute_max_insns(int insns)1288*e4b17023SJohn Marino compute_max_insns (int insns)
1289*e4b17023SJohn Marino {
1290*e4b17023SJohn Marino int max_insns = insns;
1291*e4b17023SJohn Marino if (max_insns < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
1292*e4b17023SJohn Marino max_insns = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
1293*e4b17023SJohn Marino
1294*e4b17023SJohn Marino return ((HOST_WIDEST_INT) max_insns
1295*e4b17023SJohn Marino * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
1296*e4b17023SJohn Marino }
1297*e4b17023SJohn Marino
1298*e4b17023SJohn Marino
1299*e4b17023SJohn Marino /* Compute badness of all edges in NEW_EDGES and add them to the HEAP. */
1300*e4b17023SJohn Marino
1301*e4b17023SJohn Marino static void
add_new_edges_to_heap(fibheap_t heap,VEC (cgraph_edge_p,heap)* new_edges)1302*e4b17023SJohn Marino add_new_edges_to_heap (fibheap_t heap, VEC (cgraph_edge_p, heap) *new_edges)
1303*e4b17023SJohn Marino {
1304*e4b17023SJohn Marino while (VEC_length (cgraph_edge_p, new_edges) > 0)
1305*e4b17023SJohn Marino {
1306*e4b17023SJohn Marino struct cgraph_edge *edge = VEC_pop (cgraph_edge_p, new_edges);
1307*e4b17023SJohn Marino
1308*e4b17023SJohn Marino gcc_assert (!edge->aux);
1309*e4b17023SJohn Marino if (edge->inline_failed
1310*e4b17023SJohn Marino && can_inline_edge_p (edge, true)
1311*e4b17023SJohn Marino && want_inline_small_function_p (edge, true))
1312*e4b17023SJohn Marino edge->aux = fibheap_insert (heap, edge_badness (edge, false), edge);
1313*e4b17023SJohn Marino }
1314*e4b17023SJohn Marino }
1315*e4b17023SJohn Marino
1316*e4b17023SJohn Marino
1317*e4b17023SJohn Marino /* We use greedy algorithm for inlining of small functions:
1318*e4b17023SJohn Marino All inline candidates are put into prioritized heap ordered in
1319*e4b17023SJohn Marino increasing badness.
1320*e4b17023SJohn Marino
1321*e4b17023SJohn Marino The inlining of small functions is bounded by unit growth parameters. */
1322*e4b17023SJohn Marino
1323*e4b17023SJohn Marino static void
inline_small_functions(void)1324*e4b17023SJohn Marino inline_small_functions (void)
1325*e4b17023SJohn Marino {
1326*e4b17023SJohn Marino struct cgraph_node *node;
1327*e4b17023SJohn Marino struct cgraph_edge *edge;
1328*e4b17023SJohn Marino fibheap_t heap = fibheap_new ();
1329*e4b17023SJohn Marino bitmap updated_nodes = BITMAP_ALLOC (NULL);
1330*e4b17023SJohn Marino int min_size, max_size;
1331*e4b17023SJohn Marino VEC (cgraph_edge_p, heap) *new_indirect_edges = NULL;
1332*e4b17023SJohn Marino int initial_size = 0;
1333*e4b17023SJohn Marino
1334*e4b17023SJohn Marino if (flag_indirect_inlining)
1335*e4b17023SJohn Marino new_indirect_edges = VEC_alloc (cgraph_edge_p, heap, 8);
1336*e4b17023SJohn Marino
1337*e4b17023SJohn Marino if (dump_file)
1338*e4b17023SJohn Marino fprintf (dump_file,
1339*e4b17023SJohn Marino "\nDeciding on inlining of small functions. Starting with size %i.\n",
1340*e4b17023SJohn Marino initial_size);
1341*e4b17023SJohn Marino
1342*e4b17023SJohn Marino /* Compute overall unit size and other global parameters used by badness
1343*e4b17023SJohn Marino metrics. */
1344*e4b17023SJohn Marino
1345*e4b17023SJohn Marino max_count = 0;
1346*e4b17023SJohn Marino initialize_growth_caches ();
1347*e4b17023SJohn Marino
1348*e4b17023SJohn Marino FOR_EACH_DEFINED_FUNCTION (node)
1349*e4b17023SJohn Marino if (!node->global.inlined_to)
1350*e4b17023SJohn Marino {
1351*e4b17023SJohn Marino if (cgraph_function_with_gimple_body_p (node)
1352*e4b17023SJohn Marino || node->thunk.thunk_p)
1353*e4b17023SJohn Marino {
1354*e4b17023SJohn Marino struct inline_summary *info = inline_summary (node);
1355*e4b17023SJohn Marino
1356*e4b17023SJohn Marino if (!DECL_EXTERNAL (node->decl))
1357*e4b17023SJohn Marino initial_size += info->size;
1358*e4b17023SJohn Marino }
1359*e4b17023SJohn Marino
1360*e4b17023SJohn Marino for (edge = node->callers; edge; edge = edge->next_caller)
1361*e4b17023SJohn Marino if (max_count < edge->count)
1362*e4b17023SJohn Marino max_count = edge->count;
1363*e4b17023SJohn Marino }
1364*e4b17023SJohn Marino
1365*e4b17023SJohn Marino overall_size = initial_size;
1366*e4b17023SJohn Marino max_size = compute_max_insns (overall_size);
1367*e4b17023SJohn Marino min_size = overall_size;
1368*e4b17023SJohn Marino
1369*e4b17023SJohn Marino /* Populate the heeap with all edges we might inline. */
1370*e4b17023SJohn Marino
1371*e4b17023SJohn Marino FOR_EACH_DEFINED_FUNCTION (node)
1372*e4b17023SJohn Marino if (!node->global.inlined_to)
1373*e4b17023SJohn Marino {
1374*e4b17023SJohn Marino if (dump_file)
1375*e4b17023SJohn Marino fprintf (dump_file, "Enqueueing calls of %s/%i.\n",
1376*e4b17023SJohn Marino cgraph_node_name (node), node->uid);
1377*e4b17023SJohn Marino
1378*e4b17023SJohn Marino for (edge = node->callers; edge; edge = edge->next_caller)
1379*e4b17023SJohn Marino if (edge->inline_failed
1380*e4b17023SJohn Marino && can_inline_edge_p (edge, true)
1381*e4b17023SJohn Marino && want_inline_small_function_p (edge, true)
1382*e4b17023SJohn Marino && edge->inline_failed)
1383*e4b17023SJohn Marino {
1384*e4b17023SJohn Marino gcc_assert (!edge->aux);
1385*e4b17023SJohn Marino update_edge_key (heap, edge);
1386*e4b17023SJohn Marino }
1387*e4b17023SJohn Marino }
1388*e4b17023SJohn Marino
1389*e4b17023SJohn Marino gcc_assert (in_lto_p
1390*e4b17023SJohn Marino || !max_count
1391*e4b17023SJohn Marino || (profile_info && flag_branch_probabilities));
1392*e4b17023SJohn Marino
1393*e4b17023SJohn Marino while (!fibheap_empty (heap))
1394*e4b17023SJohn Marino {
1395*e4b17023SJohn Marino int old_size = overall_size;
1396*e4b17023SJohn Marino struct cgraph_node *where, *callee;
1397*e4b17023SJohn Marino int badness = fibheap_min_key (heap);
1398*e4b17023SJohn Marino int current_badness;
1399*e4b17023SJohn Marino int cached_badness;
1400*e4b17023SJohn Marino int growth;
1401*e4b17023SJohn Marino
1402*e4b17023SJohn Marino edge = (struct cgraph_edge *) fibheap_extract_min (heap);
1403*e4b17023SJohn Marino gcc_assert (edge->aux);
1404*e4b17023SJohn Marino edge->aux = NULL;
1405*e4b17023SJohn Marino if (!edge->inline_failed)
1406*e4b17023SJohn Marino continue;
1407*e4b17023SJohn Marino
1408*e4b17023SJohn Marino /* Be sure that caches are maintained consistent.
1409*e4b17023SJohn Marino We can not make this ENABLE_CHECKING only because it cause differnt
1410*e4b17023SJohn Marino updates of the fibheap queue. */
1411*e4b17023SJohn Marino cached_badness = edge_badness (edge, false);
1412*e4b17023SJohn Marino reset_edge_growth_cache (edge);
1413*e4b17023SJohn Marino reset_node_growth_cache (edge->callee);
1414*e4b17023SJohn Marino
1415*e4b17023SJohn Marino /* When updating the edge costs, we only decrease badness in the keys.
1416*e4b17023SJohn Marino Increases of badness are handled lazilly; when we see key with out
1417*e4b17023SJohn Marino of date value on it, we re-insert it now. */
1418*e4b17023SJohn Marino current_badness = edge_badness (edge, false);
1419*e4b17023SJohn Marino gcc_assert (cached_badness == current_badness);
1420*e4b17023SJohn Marino gcc_assert (current_badness >= badness);
1421*e4b17023SJohn Marino if (current_badness != badness)
1422*e4b17023SJohn Marino {
1423*e4b17023SJohn Marino edge->aux = fibheap_insert (heap, current_badness, edge);
1424*e4b17023SJohn Marino continue;
1425*e4b17023SJohn Marino }
1426*e4b17023SJohn Marino
1427*e4b17023SJohn Marino if (!can_inline_edge_p (edge, true))
1428*e4b17023SJohn Marino continue;
1429*e4b17023SJohn Marino
1430*e4b17023SJohn Marino callee = cgraph_function_or_thunk_node (edge->callee, NULL);
1431*e4b17023SJohn Marino growth = estimate_edge_growth (edge);
1432*e4b17023SJohn Marino if (dump_file)
1433*e4b17023SJohn Marino {
1434*e4b17023SJohn Marino fprintf (dump_file,
1435*e4b17023SJohn Marino "\nConsidering %s with %i size\n",
1436*e4b17023SJohn Marino cgraph_node_name (callee),
1437*e4b17023SJohn Marino inline_summary (callee)->size);
1438*e4b17023SJohn Marino fprintf (dump_file,
1439*e4b17023SJohn Marino " to be inlined into %s in %s:%i\n"
1440*e4b17023SJohn Marino " Estimated growth after inlined into all is %+i insns.\n"
1441*e4b17023SJohn Marino " Estimated badness is %i, frequency %.2f.\n",
1442*e4b17023SJohn Marino cgraph_node_name (edge->caller),
1443*e4b17023SJohn Marino flag_wpa ? "unknown"
1444*e4b17023SJohn Marino : gimple_filename ((const_gimple) edge->call_stmt),
1445*e4b17023SJohn Marino flag_wpa ? -1
1446*e4b17023SJohn Marino : gimple_lineno ((const_gimple) edge->call_stmt),
1447*e4b17023SJohn Marino estimate_growth (callee),
1448*e4b17023SJohn Marino badness,
1449*e4b17023SJohn Marino edge->frequency / (double)CGRAPH_FREQ_BASE);
1450*e4b17023SJohn Marino if (edge->count)
1451*e4b17023SJohn Marino fprintf (dump_file," Called "HOST_WIDEST_INT_PRINT_DEC"x\n",
1452*e4b17023SJohn Marino edge->count);
1453*e4b17023SJohn Marino if (dump_flags & TDF_DETAILS)
1454*e4b17023SJohn Marino edge_badness (edge, true);
1455*e4b17023SJohn Marino }
1456*e4b17023SJohn Marino
1457*e4b17023SJohn Marino if (overall_size + growth > max_size
1458*e4b17023SJohn Marino && !DECL_DISREGARD_INLINE_LIMITS (callee->decl))
1459*e4b17023SJohn Marino {
1460*e4b17023SJohn Marino edge->inline_failed = CIF_INLINE_UNIT_GROWTH_LIMIT;
1461*e4b17023SJohn Marino report_inline_failed_reason (edge);
1462*e4b17023SJohn Marino continue;
1463*e4b17023SJohn Marino }
1464*e4b17023SJohn Marino
1465*e4b17023SJohn Marino if (!want_inline_small_function_p (edge, true))
1466*e4b17023SJohn Marino continue;
1467*e4b17023SJohn Marino
1468*e4b17023SJohn Marino /* Heuristics for inlining small functions works poorly for
1469*e4b17023SJohn Marino recursive calls where we do efect similar to loop unrolling.
1470*e4b17023SJohn Marino When inliing such edge seems profitable, leave decision on
1471*e4b17023SJohn Marino specific inliner. */
1472*e4b17023SJohn Marino if (cgraph_edge_recursive_p (edge))
1473*e4b17023SJohn Marino {
1474*e4b17023SJohn Marino where = edge->caller;
1475*e4b17023SJohn Marino if (where->global.inlined_to)
1476*e4b17023SJohn Marino where = where->global.inlined_to;
1477*e4b17023SJohn Marino if (!recursive_inlining (edge,
1478*e4b17023SJohn Marino flag_indirect_inlining
1479*e4b17023SJohn Marino ? &new_indirect_edges : NULL))
1480*e4b17023SJohn Marino {
1481*e4b17023SJohn Marino edge->inline_failed = CIF_RECURSIVE_INLINING;
1482*e4b17023SJohn Marino continue;
1483*e4b17023SJohn Marino }
1484*e4b17023SJohn Marino reset_edge_caches (where);
1485*e4b17023SJohn Marino /* Recursive inliner inlines all recursive calls of the function
1486*e4b17023SJohn Marino at once. Consequently we need to update all callee keys. */
1487*e4b17023SJohn Marino if (flag_indirect_inlining)
1488*e4b17023SJohn Marino add_new_edges_to_heap (heap, new_indirect_edges);
1489*e4b17023SJohn Marino update_all_callee_keys (heap, where, updated_nodes);
1490*e4b17023SJohn Marino }
1491*e4b17023SJohn Marino else
1492*e4b17023SJohn Marino {
1493*e4b17023SJohn Marino struct cgraph_node *outer_node = NULL;
1494*e4b17023SJohn Marino int depth = 0;
1495*e4b17023SJohn Marino
1496*e4b17023SJohn Marino /* Consider the case where self recursive function A is inlined into B.
1497*e4b17023SJohn Marino This is desired optimization in some cases, since it leads to effect
1498*e4b17023SJohn Marino similar of loop peeling and we might completely optimize out the
1499*e4b17023SJohn Marino recursive call. However we must be extra selective. */
1500*e4b17023SJohn Marino
1501*e4b17023SJohn Marino where = edge->caller;
1502*e4b17023SJohn Marino while (where->global.inlined_to)
1503*e4b17023SJohn Marino {
1504*e4b17023SJohn Marino if (where->decl == callee->decl)
1505*e4b17023SJohn Marino outer_node = where, depth++;
1506*e4b17023SJohn Marino where = where->callers->caller;
1507*e4b17023SJohn Marino }
1508*e4b17023SJohn Marino if (outer_node
1509*e4b17023SJohn Marino && !want_inline_self_recursive_call_p (edge, outer_node,
1510*e4b17023SJohn Marino true, depth))
1511*e4b17023SJohn Marino {
1512*e4b17023SJohn Marino edge->inline_failed
1513*e4b17023SJohn Marino = (DECL_DISREGARD_INLINE_LIMITS (edge->callee->decl)
1514*e4b17023SJohn Marino ? CIF_RECURSIVE_INLINING : CIF_UNSPECIFIED);
1515*e4b17023SJohn Marino continue;
1516*e4b17023SJohn Marino }
1517*e4b17023SJohn Marino else if (depth && dump_file)
1518*e4b17023SJohn Marino fprintf (dump_file, " Peeling recursion with depth %i\n", depth);
1519*e4b17023SJohn Marino
1520*e4b17023SJohn Marino gcc_checking_assert (!callee->global.inlined_to);
1521*e4b17023SJohn Marino inline_call (edge, true, &new_indirect_edges, &overall_size);
1522*e4b17023SJohn Marino if (flag_indirect_inlining)
1523*e4b17023SJohn Marino add_new_edges_to_heap (heap, new_indirect_edges);
1524*e4b17023SJohn Marino
1525*e4b17023SJohn Marino reset_edge_caches (edge->callee);
1526*e4b17023SJohn Marino reset_node_growth_cache (callee);
1527*e4b17023SJohn Marino
1528*e4b17023SJohn Marino /* We inlined last offline copy to the body. This might lead
1529*e4b17023SJohn Marino to callees of function having fewer call sites and thus they
1530*e4b17023SJohn Marino may need updating.
1531*e4b17023SJohn Marino
1532*e4b17023SJohn Marino FIXME: the callee size could also shrink because more information
1533*e4b17023SJohn Marino is propagated from caller. We don't track when this happen and
1534*e4b17023SJohn Marino thus we need to recompute everything all the time. Once this is
1535*e4b17023SJohn Marino solved, "|| 1" should go away. */
1536*e4b17023SJohn Marino if (callee->global.inlined_to || 1)
1537*e4b17023SJohn Marino update_all_callee_keys (heap, callee, updated_nodes);
1538*e4b17023SJohn Marino else
1539*e4b17023SJohn Marino update_callee_keys (heap, edge->callee, updated_nodes);
1540*e4b17023SJohn Marino }
1541*e4b17023SJohn Marino where = edge->caller;
1542*e4b17023SJohn Marino if (where->global.inlined_to)
1543*e4b17023SJohn Marino where = where->global.inlined_to;
1544*e4b17023SJohn Marino
1545*e4b17023SJohn Marino /* Our profitability metric can depend on local properties
1546*e4b17023SJohn Marino such as number of inlinable calls and size of the function body.
1547*e4b17023SJohn Marino After inlining these properties might change for the function we
1548*e4b17023SJohn Marino inlined into (since it's body size changed) and for the functions
1549*e4b17023SJohn Marino called by function we inlined (since number of it inlinable callers
1550*e4b17023SJohn Marino might change). */
1551*e4b17023SJohn Marino update_caller_keys (heap, where, updated_nodes, NULL);
1552*e4b17023SJohn Marino
1553*e4b17023SJohn Marino /* We removed one call of the function we just inlined. If offline
1554*e4b17023SJohn Marino copy is still needed, be sure to update the keys. */
1555*e4b17023SJohn Marino if (callee != where && !callee->global.inlined_to)
1556*e4b17023SJohn Marino update_caller_keys (heap, callee, updated_nodes, NULL);
1557*e4b17023SJohn Marino bitmap_clear (updated_nodes);
1558*e4b17023SJohn Marino
1559*e4b17023SJohn Marino if (dump_file)
1560*e4b17023SJohn Marino {
1561*e4b17023SJohn Marino fprintf (dump_file,
1562*e4b17023SJohn Marino " Inlined into %s which now has time %i and size %i,"
1563*e4b17023SJohn Marino "net change of %+i.\n",
1564*e4b17023SJohn Marino cgraph_node_name (edge->caller),
1565*e4b17023SJohn Marino inline_summary (edge->caller)->time,
1566*e4b17023SJohn Marino inline_summary (edge->caller)->size,
1567*e4b17023SJohn Marino overall_size - old_size);
1568*e4b17023SJohn Marino }
1569*e4b17023SJohn Marino if (min_size > overall_size)
1570*e4b17023SJohn Marino {
1571*e4b17023SJohn Marino min_size = overall_size;
1572*e4b17023SJohn Marino max_size = compute_max_insns (min_size);
1573*e4b17023SJohn Marino
1574*e4b17023SJohn Marino if (dump_file)
1575*e4b17023SJohn Marino fprintf (dump_file, "New minimal size reached: %i\n", min_size);
1576*e4b17023SJohn Marino }
1577*e4b17023SJohn Marino }
1578*e4b17023SJohn Marino
1579*e4b17023SJohn Marino free_growth_caches ();
1580*e4b17023SJohn Marino if (new_indirect_edges)
1581*e4b17023SJohn Marino VEC_free (cgraph_edge_p, heap, new_indirect_edges);
1582*e4b17023SJohn Marino fibheap_delete (heap);
1583*e4b17023SJohn Marino if (dump_file)
1584*e4b17023SJohn Marino fprintf (dump_file,
1585*e4b17023SJohn Marino "Unit growth for small function inlining: %i->%i (%i%%)\n",
1586*e4b17023SJohn Marino initial_size, overall_size,
1587*e4b17023SJohn Marino initial_size ? overall_size * 100 / (initial_size) - 100: 0);
1588*e4b17023SJohn Marino BITMAP_FREE (updated_nodes);
1589*e4b17023SJohn Marino }
1590*e4b17023SJohn Marino
1591*e4b17023SJohn Marino /* Flatten NODE. Performed both during early inlining and
1592*e4b17023SJohn Marino at IPA inlining time. */
1593*e4b17023SJohn Marino
1594*e4b17023SJohn Marino static void
flatten_function(struct cgraph_node * node,bool early)1595*e4b17023SJohn Marino flatten_function (struct cgraph_node *node, bool early)
1596*e4b17023SJohn Marino {
1597*e4b17023SJohn Marino struct cgraph_edge *e;
1598*e4b17023SJohn Marino
1599*e4b17023SJohn Marino /* We shouldn't be called recursively when we are being processed. */
1600*e4b17023SJohn Marino gcc_assert (node->aux == NULL);
1601*e4b17023SJohn Marino
1602*e4b17023SJohn Marino node->aux = (void *) node;
1603*e4b17023SJohn Marino
1604*e4b17023SJohn Marino for (e = node->callees; e; e = e->next_callee)
1605*e4b17023SJohn Marino {
1606*e4b17023SJohn Marino struct cgraph_node *orig_callee;
1607*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
1608*e4b17023SJohn Marino
1609*e4b17023SJohn Marino /* We've hit cycle? It is time to give up. */
1610*e4b17023SJohn Marino if (callee->aux)
1611*e4b17023SJohn Marino {
1612*e4b17023SJohn Marino if (dump_file)
1613*e4b17023SJohn Marino fprintf (dump_file,
1614*e4b17023SJohn Marino "Not inlining %s into %s to avoid cycle.\n",
1615*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)),
1616*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)));
1617*e4b17023SJohn Marino e->inline_failed = CIF_RECURSIVE_INLINING;
1618*e4b17023SJohn Marino continue;
1619*e4b17023SJohn Marino }
1620*e4b17023SJohn Marino
1621*e4b17023SJohn Marino /* When the edge is already inlined, we just need to recurse into
1622*e4b17023SJohn Marino it in order to fully flatten the leaves. */
1623*e4b17023SJohn Marino if (!e->inline_failed)
1624*e4b17023SJohn Marino {
1625*e4b17023SJohn Marino flatten_function (callee, early);
1626*e4b17023SJohn Marino continue;
1627*e4b17023SJohn Marino }
1628*e4b17023SJohn Marino
1629*e4b17023SJohn Marino /* Flatten attribute needs to be processed during late inlining. For
1630*e4b17023SJohn Marino extra code quality we however do flattening during early optimization,
1631*e4b17023SJohn Marino too. */
1632*e4b17023SJohn Marino if (!early
1633*e4b17023SJohn Marino ? !can_inline_edge_p (e, true)
1634*e4b17023SJohn Marino : !can_early_inline_edge_p (e))
1635*e4b17023SJohn Marino continue;
1636*e4b17023SJohn Marino
1637*e4b17023SJohn Marino if (cgraph_edge_recursive_p (e))
1638*e4b17023SJohn Marino {
1639*e4b17023SJohn Marino if (dump_file)
1640*e4b17023SJohn Marino fprintf (dump_file, "Not inlining: recursive call.\n");
1641*e4b17023SJohn Marino continue;
1642*e4b17023SJohn Marino }
1643*e4b17023SJohn Marino
1644*e4b17023SJohn Marino if (gimple_in_ssa_p (DECL_STRUCT_FUNCTION (node->decl))
1645*e4b17023SJohn Marino != gimple_in_ssa_p (DECL_STRUCT_FUNCTION (callee->decl)))
1646*e4b17023SJohn Marino {
1647*e4b17023SJohn Marino if (dump_file)
1648*e4b17023SJohn Marino fprintf (dump_file, "Not inlining: SSA form does not match.\n");
1649*e4b17023SJohn Marino continue;
1650*e4b17023SJohn Marino }
1651*e4b17023SJohn Marino
1652*e4b17023SJohn Marino /* Inline the edge and flatten the inline clone. Avoid
1653*e4b17023SJohn Marino recursing through the original node if the node was cloned. */
1654*e4b17023SJohn Marino if (dump_file)
1655*e4b17023SJohn Marino fprintf (dump_file, " Inlining %s into %s.\n",
1656*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)),
1657*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)));
1658*e4b17023SJohn Marino orig_callee = callee;
1659*e4b17023SJohn Marino inline_call (e, true, NULL, NULL);
1660*e4b17023SJohn Marino if (e->callee != orig_callee)
1661*e4b17023SJohn Marino orig_callee->aux = (void *) node;
1662*e4b17023SJohn Marino flatten_function (e->callee, early);
1663*e4b17023SJohn Marino if (e->callee != orig_callee)
1664*e4b17023SJohn Marino orig_callee->aux = NULL;
1665*e4b17023SJohn Marino }
1666*e4b17023SJohn Marino
1667*e4b17023SJohn Marino node->aux = NULL;
1668*e4b17023SJohn Marino }
1669*e4b17023SJohn Marino
1670*e4b17023SJohn Marino /* Decide on the inlining. We do so in the topological order to avoid
1671*e4b17023SJohn Marino expenses on updating data structures. */
1672*e4b17023SJohn Marino
1673*e4b17023SJohn Marino static unsigned int
ipa_inline(void)1674*e4b17023SJohn Marino ipa_inline (void)
1675*e4b17023SJohn Marino {
1676*e4b17023SJohn Marino struct cgraph_node *node;
1677*e4b17023SJohn Marino int nnodes;
1678*e4b17023SJohn Marino struct cgraph_node **order =
1679*e4b17023SJohn Marino XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
1680*e4b17023SJohn Marino int i;
1681*e4b17023SJohn Marino
1682*e4b17023SJohn Marino if (in_lto_p && optimize)
1683*e4b17023SJohn Marino ipa_update_after_lto_read ();
1684*e4b17023SJohn Marino
1685*e4b17023SJohn Marino if (dump_file)
1686*e4b17023SJohn Marino dump_inline_summaries (dump_file);
1687*e4b17023SJohn Marino
1688*e4b17023SJohn Marino nnodes = ipa_reverse_postorder (order);
1689*e4b17023SJohn Marino
1690*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next)
1691*e4b17023SJohn Marino node->aux = 0;
1692*e4b17023SJohn Marino
1693*e4b17023SJohn Marino if (dump_file)
1694*e4b17023SJohn Marino fprintf (dump_file, "\nFlattening functions:\n");
1695*e4b17023SJohn Marino
1696*e4b17023SJohn Marino /* In the first pass handle functions to be flattened. Do this with
1697*e4b17023SJohn Marino a priority so none of our later choices will make this impossible. */
1698*e4b17023SJohn Marino for (i = nnodes - 1; i >= 0; i--)
1699*e4b17023SJohn Marino {
1700*e4b17023SJohn Marino node = order[i];
1701*e4b17023SJohn Marino
1702*e4b17023SJohn Marino /* Handle nodes to be flattened.
1703*e4b17023SJohn Marino Ideally when processing callees we stop inlining at the
1704*e4b17023SJohn Marino entry of cycles, possibly cloning that entry point and
1705*e4b17023SJohn Marino try to flatten itself turning it into a self-recursive
1706*e4b17023SJohn Marino function. */
1707*e4b17023SJohn Marino if (lookup_attribute ("flatten",
1708*e4b17023SJohn Marino DECL_ATTRIBUTES (node->decl)) != NULL)
1709*e4b17023SJohn Marino {
1710*e4b17023SJohn Marino if (dump_file)
1711*e4b17023SJohn Marino fprintf (dump_file,
1712*e4b17023SJohn Marino "Flattening %s\n", cgraph_node_name (node));
1713*e4b17023SJohn Marino flatten_function (node, false);
1714*e4b17023SJohn Marino }
1715*e4b17023SJohn Marino }
1716*e4b17023SJohn Marino
1717*e4b17023SJohn Marino inline_small_functions ();
1718*e4b17023SJohn Marino cgraph_remove_unreachable_nodes (true, dump_file);
1719*e4b17023SJohn Marino free (order);
1720*e4b17023SJohn Marino
1721*e4b17023SJohn Marino /* We already perform some inlining of functions called once during
1722*e4b17023SJohn Marino inlining small functions above. After unreachable nodes are removed,
1723*e4b17023SJohn Marino we still might do a quick check that nothing new is found. */
1724*e4b17023SJohn Marino if (flag_inline_functions_called_once)
1725*e4b17023SJohn Marino {
1726*e4b17023SJohn Marino int cold;
1727*e4b17023SJohn Marino if (dump_file)
1728*e4b17023SJohn Marino fprintf (dump_file, "\nDeciding on functions called once:\n");
1729*e4b17023SJohn Marino
1730*e4b17023SJohn Marino /* Inlining one function called once has good chance of preventing
1731*e4b17023SJohn Marino inlining other function into the same callee. Ideally we should
1732*e4b17023SJohn Marino work in priority order, but probably inlining hot functions first
1733*e4b17023SJohn Marino is good cut without the extra pain of maintaining the queue.
1734*e4b17023SJohn Marino
1735*e4b17023SJohn Marino ??? this is not really fitting the bill perfectly: inlining function
1736*e4b17023SJohn Marino into callee often leads to better optimization of callee due to
1737*e4b17023SJohn Marino increased context for optimization.
1738*e4b17023SJohn Marino For example if main() function calls a function that outputs help
1739*e4b17023SJohn Marino and then function that does the main optmization, we should inline
1740*e4b17023SJohn Marino the second with priority even if both calls are cold by themselves.
1741*e4b17023SJohn Marino
1742*e4b17023SJohn Marino We probably want to implement new predicate replacing our use of
1743*e4b17023SJohn Marino maybe_hot_edge interpreted as maybe_hot_edge || callee is known
1744*e4b17023SJohn Marino to be hot. */
1745*e4b17023SJohn Marino for (cold = 0; cold <= 1; cold ++)
1746*e4b17023SJohn Marino {
1747*e4b17023SJohn Marino for (node = cgraph_nodes; node; node = node->next)
1748*e4b17023SJohn Marino {
1749*e4b17023SJohn Marino if (want_inline_function_called_once_p (node)
1750*e4b17023SJohn Marino && (cold
1751*e4b17023SJohn Marino || cgraph_maybe_hot_edge_p (node->callers)))
1752*e4b17023SJohn Marino {
1753*e4b17023SJohn Marino struct cgraph_node *caller = node->callers->caller;
1754*e4b17023SJohn Marino
1755*e4b17023SJohn Marino if (dump_file)
1756*e4b17023SJohn Marino {
1757*e4b17023SJohn Marino fprintf (dump_file,
1758*e4b17023SJohn Marino "\nInlining %s size %i.\n",
1759*e4b17023SJohn Marino cgraph_node_name (node),
1760*e4b17023SJohn Marino inline_summary (node)->size);
1761*e4b17023SJohn Marino fprintf (dump_file,
1762*e4b17023SJohn Marino " Called once from %s %i insns.\n",
1763*e4b17023SJohn Marino cgraph_node_name (node->callers->caller),
1764*e4b17023SJohn Marino inline_summary (node->callers->caller)->size);
1765*e4b17023SJohn Marino }
1766*e4b17023SJohn Marino
1767*e4b17023SJohn Marino inline_call (node->callers, true, NULL, NULL);
1768*e4b17023SJohn Marino if (dump_file)
1769*e4b17023SJohn Marino fprintf (dump_file,
1770*e4b17023SJohn Marino " Inlined into %s which now has %i size\n",
1771*e4b17023SJohn Marino cgraph_node_name (caller),
1772*e4b17023SJohn Marino inline_summary (caller)->size);
1773*e4b17023SJohn Marino }
1774*e4b17023SJohn Marino }
1775*e4b17023SJohn Marino }
1776*e4b17023SJohn Marino }
1777*e4b17023SJohn Marino
1778*e4b17023SJohn Marino /* Free ipa-prop structures if they are no longer needed. */
1779*e4b17023SJohn Marino if (optimize)
1780*e4b17023SJohn Marino ipa_free_all_structures_after_iinln ();
1781*e4b17023SJohn Marino
1782*e4b17023SJohn Marino if (dump_file)
1783*e4b17023SJohn Marino fprintf (dump_file,
1784*e4b17023SJohn Marino "\nInlined %i calls, eliminated %i functions\n\n",
1785*e4b17023SJohn Marino ncalls_inlined, nfunctions_inlined);
1786*e4b17023SJohn Marino
1787*e4b17023SJohn Marino if (dump_file)
1788*e4b17023SJohn Marino dump_inline_summaries (dump_file);
1789*e4b17023SJohn Marino /* In WPA we use inline summaries for partitioning process. */
1790*e4b17023SJohn Marino if (!flag_wpa)
1791*e4b17023SJohn Marino inline_free_summary ();
1792*e4b17023SJohn Marino return 0;
1793*e4b17023SJohn Marino }
1794*e4b17023SJohn Marino
1795*e4b17023SJohn Marino /* Inline always-inline function calls in NODE. */
1796*e4b17023SJohn Marino
1797*e4b17023SJohn Marino static bool
inline_always_inline_functions(struct cgraph_node * node)1798*e4b17023SJohn Marino inline_always_inline_functions (struct cgraph_node *node)
1799*e4b17023SJohn Marino {
1800*e4b17023SJohn Marino struct cgraph_edge *e;
1801*e4b17023SJohn Marino bool inlined = false;
1802*e4b17023SJohn Marino
1803*e4b17023SJohn Marino for (e = node->callees; e; e = e->next_callee)
1804*e4b17023SJohn Marino {
1805*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
1806*e4b17023SJohn Marino if (!DECL_DISREGARD_INLINE_LIMITS (callee->decl))
1807*e4b17023SJohn Marino continue;
1808*e4b17023SJohn Marino
1809*e4b17023SJohn Marino if (cgraph_edge_recursive_p (e))
1810*e4b17023SJohn Marino {
1811*e4b17023SJohn Marino if (dump_file)
1812*e4b17023SJohn Marino fprintf (dump_file, " Not inlining recursive call to %s.\n",
1813*e4b17023SJohn Marino cgraph_node_name (e->callee));
1814*e4b17023SJohn Marino e->inline_failed = CIF_RECURSIVE_INLINING;
1815*e4b17023SJohn Marino continue;
1816*e4b17023SJohn Marino }
1817*e4b17023SJohn Marino
1818*e4b17023SJohn Marino if (!can_early_inline_edge_p (e))
1819*e4b17023SJohn Marino continue;
1820*e4b17023SJohn Marino
1821*e4b17023SJohn Marino if (dump_file)
1822*e4b17023SJohn Marino fprintf (dump_file, " Inlining %s into %s (always_inline).\n",
1823*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->callee)),
1824*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)));
1825*e4b17023SJohn Marino inline_call (e, true, NULL, NULL);
1826*e4b17023SJohn Marino inlined = true;
1827*e4b17023SJohn Marino }
1828*e4b17023SJohn Marino
1829*e4b17023SJohn Marino return inlined;
1830*e4b17023SJohn Marino }
1831*e4b17023SJohn Marino
1832*e4b17023SJohn Marino /* Decide on the inlining. We do so in the topological order to avoid
1833*e4b17023SJohn Marino expenses on updating data structures. */
1834*e4b17023SJohn Marino
1835*e4b17023SJohn Marino static bool
early_inline_small_functions(struct cgraph_node * node)1836*e4b17023SJohn Marino early_inline_small_functions (struct cgraph_node *node)
1837*e4b17023SJohn Marino {
1838*e4b17023SJohn Marino struct cgraph_edge *e;
1839*e4b17023SJohn Marino bool inlined = false;
1840*e4b17023SJohn Marino
1841*e4b17023SJohn Marino for (e = node->callees; e; e = e->next_callee)
1842*e4b17023SJohn Marino {
1843*e4b17023SJohn Marino struct cgraph_node *callee = cgraph_function_or_thunk_node (e->callee, NULL);
1844*e4b17023SJohn Marino if (!inline_summary (callee)->inlinable
1845*e4b17023SJohn Marino || !e->inline_failed)
1846*e4b17023SJohn Marino continue;
1847*e4b17023SJohn Marino
1848*e4b17023SJohn Marino /* Do not consider functions not declared inline. */
1849*e4b17023SJohn Marino if (!DECL_DECLARED_INLINE_P (callee->decl)
1850*e4b17023SJohn Marino && !flag_inline_small_functions
1851*e4b17023SJohn Marino && !flag_inline_functions)
1852*e4b17023SJohn Marino continue;
1853*e4b17023SJohn Marino
1854*e4b17023SJohn Marino if (dump_file)
1855*e4b17023SJohn Marino fprintf (dump_file, "Considering inline candidate %s.\n",
1856*e4b17023SJohn Marino cgraph_node_name (callee));
1857*e4b17023SJohn Marino
1858*e4b17023SJohn Marino if (!can_early_inline_edge_p (e))
1859*e4b17023SJohn Marino continue;
1860*e4b17023SJohn Marino
1861*e4b17023SJohn Marino if (cgraph_edge_recursive_p (e))
1862*e4b17023SJohn Marino {
1863*e4b17023SJohn Marino if (dump_file)
1864*e4b17023SJohn Marino fprintf (dump_file, " Not inlining: recursive call.\n");
1865*e4b17023SJohn Marino continue;
1866*e4b17023SJohn Marino }
1867*e4b17023SJohn Marino
1868*e4b17023SJohn Marino if (!want_early_inline_function_p (e))
1869*e4b17023SJohn Marino continue;
1870*e4b17023SJohn Marino
1871*e4b17023SJohn Marino if (dump_file)
1872*e4b17023SJohn Marino fprintf (dump_file, " Inlining %s into %s.\n",
1873*e4b17023SJohn Marino xstrdup (cgraph_node_name (callee)),
1874*e4b17023SJohn Marino xstrdup (cgraph_node_name (e->caller)));
1875*e4b17023SJohn Marino inline_call (e, true, NULL, NULL);
1876*e4b17023SJohn Marino inlined = true;
1877*e4b17023SJohn Marino }
1878*e4b17023SJohn Marino
1879*e4b17023SJohn Marino return inlined;
1880*e4b17023SJohn Marino }
1881*e4b17023SJohn Marino
1882*e4b17023SJohn Marino /* Do inlining of small functions. Doing so early helps profiling and other
1883*e4b17023SJohn Marino passes to be somewhat more effective and avoids some code duplication in
1884*e4b17023SJohn Marino later real inlining pass for testcases with very many function calls. */
1885*e4b17023SJohn Marino static unsigned int
early_inliner(void)1886*e4b17023SJohn Marino early_inliner (void)
1887*e4b17023SJohn Marino {
1888*e4b17023SJohn Marino struct cgraph_node *node = cgraph_get_node (current_function_decl);
1889*e4b17023SJohn Marino struct cgraph_edge *edge;
1890*e4b17023SJohn Marino unsigned int todo = 0;
1891*e4b17023SJohn Marino int iterations = 0;
1892*e4b17023SJohn Marino bool inlined = false;
1893*e4b17023SJohn Marino
1894*e4b17023SJohn Marino if (seen_error ())
1895*e4b17023SJohn Marino return 0;
1896*e4b17023SJohn Marino
1897*e4b17023SJohn Marino /* Do nothing if datastructures for ipa-inliner are already computed. This
1898*e4b17023SJohn Marino happens when some pass decides to construct new function and
1899*e4b17023SJohn Marino cgraph_add_new_function calls lowering passes and early optimization on
1900*e4b17023SJohn Marino it. This may confuse ourself when early inliner decide to inline call to
1901*e4b17023SJohn Marino function clone, because function clones don't have parameter list in
1902*e4b17023SJohn Marino ipa-prop matching their signature. */
1903*e4b17023SJohn Marino if (ipa_node_params_vector)
1904*e4b17023SJohn Marino return 0;
1905*e4b17023SJohn Marino
1906*e4b17023SJohn Marino #ifdef ENABLE_CHECKING
1907*e4b17023SJohn Marino verify_cgraph_node (node);
1908*e4b17023SJohn Marino #endif
1909*e4b17023SJohn Marino
1910*e4b17023SJohn Marino /* Even when not optimizing or not inlining inline always-inline
1911*e4b17023SJohn Marino functions. */
1912*e4b17023SJohn Marino inlined = inline_always_inline_functions (node);
1913*e4b17023SJohn Marino
1914*e4b17023SJohn Marino if (!optimize
1915*e4b17023SJohn Marino || flag_no_inline
1916*e4b17023SJohn Marino || !flag_early_inlining
1917*e4b17023SJohn Marino /* Never inline regular functions into always-inline functions
1918*e4b17023SJohn Marino during incremental inlining. This sucks as functions calling
1919*e4b17023SJohn Marino always inline functions will get less optimized, but at the
1920*e4b17023SJohn Marino same time inlining of functions calling always inline
1921*e4b17023SJohn Marino function into an always inline function might introduce
1922*e4b17023SJohn Marino cycles of edges to be always inlined in the callgraph.
1923*e4b17023SJohn Marino
1924*e4b17023SJohn Marino We might want to be smarter and just avoid this type of inlining. */
1925*e4b17023SJohn Marino || DECL_DISREGARD_INLINE_LIMITS (node->decl))
1926*e4b17023SJohn Marino ;
1927*e4b17023SJohn Marino else if (lookup_attribute ("flatten",
1928*e4b17023SJohn Marino DECL_ATTRIBUTES (node->decl)) != NULL)
1929*e4b17023SJohn Marino {
1930*e4b17023SJohn Marino /* When the function is marked to be flattened, recursively inline
1931*e4b17023SJohn Marino all calls in it. */
1932*e4b17023SJohn Marino if (dump_file)
1933*e4b17023SJohn Marino fprintf (dump_file,
1934*e4b17023SJohn Marino "Flattening %s\n", cgraph_node_name (node));
1935*e4b17023SJohn Marino flatten_function (node, true);
1936*e4b17023SJohn Marino inlined = true;
1937*e4b17023SJohn Marino }
1938*e4b17023SJohn Marino else
1939*e4b17023SJohn Marino {
1940*e4b17023SJohn Marino /* We iterate incremental inlining to get trivial cases of indirect
1941*e4b17023SJohn Marino inlining. */
1942*e4b17023SJohn Marino while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS)
1943*e4b17023SJohn Marino && early_inline_small_functions (node))
1944*e4b17023SJohn Marino {
1945*e4b17023SJohn Marino timevar_push (TV_INTEGRATION);
1946*e4b17023SJohn Marino todo |= optimize_inline_calls (current_function_decl);
1947*e4b17023SJohn Marino
1948*e4b17023SJohn Marino /* Technically we ought to recompute inline parameters so the new
1949*e4b17023SJohn Marino iteration of early inliner works as expected. We however have
1950*e4b17023SJohn Marino values approximately right and thus we only need to update edge
1951*e4b17023SJohn Marino info that might be cleared out for newly discovered edges. */
1952*e4b17023SJohn Marino for (edge = node->callees; edge; edge = edge->next_callee)
1953*e4b17023SJohn Marino {
1954*e4b17023SJohn Marino struct inline_edge_summary *es = inline_edge_summary (edge);
1955*e4b17023SJohn Marino es->call_stmt_size
1956*e4b17023SJohn Marino = estimate_num_insns (edge->call_stmt, &eni_size_weights);
1957*e4b17023SJohn Marino es->call_stmt_time
1958*e4b17023SJohn Marino = estimate_num_insns (edge->call_stmt, &eni_time_weights);
1959*e4b17023SJohn Marino if (edge->callee->decl
1960*e4b17023SJohn Marino && !gimple_check_call_matching_types (edge->call_stmt,
1961*e4b17023SJohn Marino edge->callee->decl))
1962*e4b17023SJohn Marino edge->call_stmt_cannot_inline_p = true;
1963*e4b17023SJohn Marino }
1964*e4b17023SJohn Marino timevar_pop (TV_INTEGRATION);
1965*e4b17023SJohn Marino iterations++;
1966*e4b17023SJohn Marino inlined = false;
1967*e4b17023SJohn Marino }
1968*e4b17023SJohn Marino if (dump_file)
1969*e4b17023SJohn Marino fprintf (dump_file, "Iterations: %i\n", iterations);
1970*e4b17023SJohn Marino }
1971*e4b17023SJohn Marino
1972*e4b17023SJohn Marino if (inlined)
1973*e4b17023SJohn Marino {
1974*e4b17023SJohn Marino timevar_push (TV_INTEGRATION);
1975*e4b17023SJohn Marino todo |= optimize_inline_calls (current_function_decl);
1976*e4b17023SJohn Marino timevar_pop (TV_INTEGRATION);
1977*e4b17023SJohn Marino }
1978*e4b17023SJohn Marino
1979*e4b17023SJohn Marino cfun->always_inline_functions_inlined = true;
1980*e4b17023SJohn Marino
1981*e4b17023SJohn Marino return todo;
1982*e4b17023SJohn Marino }
1983*e4b17023SJohn Marino
1984*e4b17023SJohn Marino struct gimple_opt_pass pass_early_inline =
1985*e4b17023SJohn Marino {
1986*e4b17023SJohn Marino {
1987*e4b17023SJohn Marino GIMPLE_PASS,
1988*e4b17023SJohn Marino "einline", /* name */
1989*e4b17023SJohn Marino NULL, /* gate */
1990*e4b17023SJohn Marino early_inliner, /* execute */
1991*e4b17023SJohn Marino NULL, /* sub */
1992*e4b17023SJohn Marino NULL, /* next */
1993*e4b17023SJohn Marino 0, /* static_pass_number */
1994*e4b17023SJohn Marino TV_INLINE_HEURISTICS, /* tv_id */
1995*e4b17023SJohn Marino PROP_ssa, /* properties_required */
1996*e4b17023SJohn Marino 0, /* properties_provided */
1997*e4b17023SJohn Marino 0, /* properties_destroyed */
1998*e4b17023SJohn Marino 0, /* todo_flags_start */
1999*e4b17023SJohn Marino 0 /* todo_flags_finish */
2000*e4b17023SJohn Marino }
2001*e4b17023SJohn Marino };
2002*e4b17023SJohn Marino
2003*e4b17023SJohn Marino
2004*e4b17023SJohn Marino /* When to run IPA inlining. Inlining of always-inline functions
2005*e4b17023SJohn Marino happens during early inlining.
2006*e4b17023SJohn Marino
2007*e4b17023SJohn Marino Enable inlining unconditoinally at -flto. We need size estimates to
2008*e4b17023SJohn Marino drive partitioning. */
2009*e4b17023SJohn Marino
2010*e4b17023SJohn Marino static bool
gate_ipa_inline(void)2011*e4b17023SJohn Marino gate_ipa_inline (void)
2012*e4b17023SJohn Marino {
2013*e4b17023SJohn Marino return optimize || flag_lto || flag_wpa;
2014*e4b17023SJohn Marino }
2015*e4b17023SJohn Marino
2016*e4b17023SJohn Marino struct ipa_opt_pass_d pass_ipa_inline =
2017*e4b17023SJohn Marino {
2018*e4b17023SJohn Marino {
2019*e4b17023SJohn Marino IPA_PASS,
2020*e4b17023SJohn Marino "inline", /* name */
2021*e4b17023SJohn Marino gate_ipa_inline, /* gate */
2022*e4b17023SJohn Marino ipa_inline, /* execute */
2023*e4b17023SJohn Marino NULL, /* sub */
2024*e4b17023SJohn Marino NULL, /* next */
2025*e4b17023SJohn Marino 0, /* static_pass_number */
2026*e4b17023SJohn Marino TV_INLINE_HEURISTICS, /* tv_id */
2027*e4b17023SJohn Marino 0, /* properties_required */
2028*e4b17023SJohn Marino 0, /* properties_provided */
2029*e4b17023SJohn Marino 0, /* properties_destroyed */
2030*e4b17023SJohn Marino TODO_remove_functions, /* todo_flags_finish */
2031*e4b17023SJohn Marino TODO_dump_cgraph
2032*e4b17023SJohn Marino | TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */
2033*e4b17023SJohn Marino },
2034*e4b17023SJohn Marino inline_generate_summary, /* generate_summary */
2035*e4b17023SJohn Marino inline_write_summary, /* write_summary */
2036*e4b17023SJohn Marino inline_read_summary, /* read_summary */
2037*e4b17023SJohn Marino NULL, /* write_optimization_summary */
2038*e4b17023SJohn Marino NULL, /* read_optimization_summary */
2039*e4b17023SJohn Marino NULL, /* stmt_fixup */
2040*e4b17023SJohn Marino 0, /* TODOs */
2041*e4b17023SJohn Marino inline_transform, /* function_transform */
2042*e4b17023SJohn Marino NULL, /* variable_transform */
2043*e4b17023SJohn Marino };
2044