1*38fd1498Szrj /* Inlining decision heuristics.
2*38fd1498Szrj Copyright (C) 2003-2018 Free Software Foundation, Inc.
3*38fd1498Szrj Contributed by Jan Hubicka
4*38fd1498Szrj
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3. If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>. */
20*38fd1498Szrj
21*38fd1498Szrj #ifndef GCC_IPA_INLINE_H
22*38fd1498Szrj #define GCC_IPA_INLINE_H
23*38fd1498Szrj
24*38fd1498Szrj /* Data we cache about callgraph edges during inlining to avoid expensive
25*38fd1498Szrj re-computations during the greedy algorithm. */
26*38fd1498Szrj struct edge_growth_cache_entry
27*38fd1498Szrj {
28*38fd1498Szrj sreal time, nonspec_time;
29*38fd1498Szrj int size;
30*38fd1498Szrj ipa_hints hints;
31*38fd1498Szrj
edge_growth_cache_entryedge_growth_cache_entry32*38fd1498Szrj edge_growth_cache_entry()
33*38fd1498Szrj : size (0), hints (0) {}
34*38fd1498Szrj
edge_growth_cache_entryedge_growth_cache_entry35*38fd1498Szrj edge_growth_cache_entry(int64_t time, int64_t nonspec_time,
36*38fd1498Szrj int size, ipa_hints hints)
37*38fd1498Szrj : time (time), nonspec_time (nonspec_time), size (size),
38*38fd1498Szrj hints (hints) {}
39*38fd1498Szrj };
40*38fd1498Szrj
41*38fd1498Szrj extern vec<edge_growth_cache_entry> edge_growth_cache;
42*38fd1498Szrj
43*38fd1498Szrj /* In ipa-inline-analysis.c */
44*38fd1498Szrj int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
45*38fd1498Szrj int estimate_growth (struct cgraph_node *);
46*38fd1498Szrj bool growth_likely_positive (struct cgraph_node *, int);
47*38fd1498Szrj int do_estimate_edge_size (struct cgraph_edge *edge);
48*38fd1498Szrj sreal do_estimate_edge_time (struct cgraph_edge *edge);
49*38fd1498Szrj ipa_hints do_estimate_edge_hints (struct cgraph_edge *edge);
50*38fd1498Szrj void initialize_growth_caches (void);
51*38fd1498Szrj void free_growth_caches (void);
52*38fd1498Szrj
53*38fd1498Szrj /* In ipa-inline.c */
54*38fd1498Szrj unsigned int early_inliner (function *fun);
55*38fd1498Szrj bool inline_account_function_p (struct cgraph_node *node);
56*38fd1498Szrj
57*38fd1498Szrj
58*38fd1498Szrj /* In ipa-inline-transform.c */
59*38fd1498Szrj bool inline_call (struct cgraph_edge *, bool, vec<cgraph_edge *> *, int *, bool,
60*38fd1498Szrj bool *callee_removed = NULL);
61*38fd1498Szrj unsigned int inline_transform (struct cgraph_node *);
62*38fd1498Szrj void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *);
63*38fd1498Szrj
64*38fd1498Szrj extern int ncalls_inlined;
65*38fd1498Szrj extern int nfunctions_inlined;
66*38fd1498Szrj
67*38fd1498Szrj /* Return estimated size of the inline sequence of EDGE. */
68*38fd1498Szrj
69*38fd1498Szrj static inline int
estimate_edge_size(struct cgraph_edge * edge)70*38fd1498Szrj estimate_edge_size (struct cgraph_edge *edge)
71*38fd1498Szrj {
72*38fd1498Szrj int ret;
73*38fd1498Szrj if ((int)edge_growth_cache.length () <= edge->uid
74*38fd1498Szrj || !(ret = edge_growth_cache[edge->uid].size))
75*38fd1498Szrj return do_estimate_edge_size (edge);
76*38fd1498Szrj return ret - (ret > 0);
77*38fd1498Szrj }
78*38fd1498Szrj
79*38fd1498Szrj /* Return estimated callee growth after inlining EDGE. */
80*38fd1498Szrj
81*38fd1498Szrj static inline int
estimate_edge_growth(struct cgraph_edge * edge)82*38fd1498Szrj estimate_edge_growth (struct cgraph_edge *edge)
83*38fd1498Szrj {
84*38fd1498Szrj gcc_checking_assert (ipa_call_summaries->get (edge)->call_stmt_size
85*38fd1498Szrj || !edge->callee->analyzed);
86*38fd1498Szrj return (estimate_edge_size (edge)
87*38fd1498Szrj - ipa_call_summaries->get (edge)->call_stmt_size);
88*38fd1498Szrj }
89*38fd1498Szrj
90*38fd1498Szrj /* Return estimated callee runtime increase after inlining
91*38fd1498Szrj EDGE. */
92*38fd1498Szrj
93*38fd1498Szrj static inline sreal
94*38fd1498Szrj estimate_edge_time (struct cgraph_edge *edge, sreal *nonspec_time = NULL)
95*38fd1498Szrj {
96*38fd1498Szrj sreal ret;
97*38fd1498Szrj if ((int)edge_growth_cache.length () <= edge->uid
98*38fd1498Szrj || !edge_growth_cache[edge->uid].size)
99*38fd1498Szrj return do_estimate_edge_time (edge);
100*38fd1498Szrj if (nonspec_time)
101*38fd1498Szrj *nonspec_time = edge_growth_cache[edge->uid].nonspec_time;
102*38fd1498Szrj return edge_growth_cache[edge->uid].time;
103*38fd1498Szrj }
104*38fd1498Szrj
105*38fd1498Szrj
106*38fd1498Szrj /* Return estimated callee runtime increase after inlining
107*38fd1498Szrj EDGE. */
108*38fd1498Szrj
109*38fd1498Szrj static inline ipa_hints
estimate_edge_hints(struct cgraph_edge * edge)110*38fd1498Szrj estimate_edge_hints (struct cgraph_edge *edge)
111*38fd1498Szrj {
112*38fd1498Szrj ipa_hints ret;
113*38fd1498Szrj if ((int)edge_growth_cache.length () <= edge->uid
114*38fd1498Szrj || !(ret = edge_growth_cache[edge->uid].hints))
115*38fd1498Szrj return do_estimate_edge_hints (edge);
116*38fd1498Szrj return ret - 1;
117*38fd1498Szrj }
118*38fd1498Szrj
119*38fd1498Szrj /* Reset cached value for EDGE. */
120*38fd1498Szrj
121*38fd1498Szrj static inline void
reset_edge_growth_cache(struct cgraph_edge * edge)122*38fd1498Szrj reset_edge_growth_cache (struct cgraph_edge *edge)
123*38fd1498Szrj {
124*38fd1498Szrj if ((int)edge_growth_cache.length () > edge->uid)
125*38fd1498Szrj {
126*38fd1498Szrj struct edge_growth_cache_entry zero (0, 0, 0, 0);
127*38fd1498Szrj edge_growth_cache[edge->uid] = zero;
128*38fd1498Szrj }
129*38fd1498Szrj }
130*38fd1498Szrj
131*38fd1498Szrj #endif /* GCC_IPA_INLINE_H */
132