xref: /dflybsd-src/contrib/gcc-8.0/gcc/ipa-inline.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
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