]> gcc.gnu.org Git - gcc.git/blame - gcc/ipa-inline.h
Makefile.in: Add ipa-predicate.o and ipa-predicate.h
[gcc.git] / gcc / ipa-inline.h
CommitLineData
03dfc36d 1/* Inlining decision heuristics.
cbe34bb5 2 Copyright (C) 2003-2017 Free Software Foundation, Inc.
03dfc36d
JH
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
f1717f8d
KC
21#ifndef GCC_IPA_INLINE_H
22#define GCC_IPA_INLINE_H
23
ffb77fd6 24#include "sreal.h"
b679b55b 25#include "ipa-predicate.h"
ffb77fd6 26
2c9561b5 27
52843a47
JH
28/* Inline hints are reasons why inline heuristics should preffer inlining given
29 function. They are represtented as bitmap of the following values. */
37678631 30enum inline_hints_vals {
52843a47
JH
31 /* When inlining turns indirect call into a direct call,
32 it is good idea to do so. */
2daffc47 33 INLINE_HINT_indirect_call = 1,
52843a47
JH
34 /* Inlining may make loop iterations or loop stride known. It is good idea
35 to do so because it enables loop optimizatoins. */
128e0d89 36 INLINE_HINT_loop_iterations = 2,
b48ccf0d 37 INLINE_HINT_loop_stride = 4,
688010ba 38 /* Inlining within same strongly connected component of callgraph is often
52843a47 39 a loss due to increased stack frame usage and prologue setup costs. */
b48ccf0d 40 INLINE_HINT_same_scc = 8,
52843a47
JH
41 /* Inlining functions in strongly connected component is not such a great
42 win. */
d59171da 43 INLINE_HINT_in_scc = 16,
52843a47
JH
44 /* If function is declared inline by user, it may be good idea to inline
45 it. */
d59171da 46 INLINE_HINT_declared_inline = 32,
52843a47
JH
47 /* Programs are usually still organized for non-LTO compilation and thus
48 if functions are in different modules, inlining may not be so important.
49 */
50 INLINE_HINT_cross_module = 64,
51 /* If array indexes of loads/stores become known there may be room for
688010ba 52 further optimization. */
b6d627e4
JH
53 INLINE_HINT_array_index = 128,
54 /* We know that the callee is hot by profile. */
55 INLINE_HINT_known_hot = 256
37678631 56};
dbcb3c74 57
b679b55b 58typedef int inline_hints;
632b4f8e 59
b679b55b
JH
60/* Simple description of whether a memory load or a condition refers to a load
61 from an aggregate and if so, how and where from in the aggregate.
62 Individual fields have the same meaning like fields with the same name in
63 struct condition. */
dbcb3c74 64
b679b55b 65struct agg_position_info
632b4f8e 66{
b679b55b
JH
67 HOST_WIDE_INT offset;
68 bool agg_contents;
69 bool by_ref;
632b4f8e
JH
70};
71
72/* Represnetation of function body size and time depending on the inline
73 context. We keep simple array of record, every containing of predicate
74 and time/size to account.
10a5dd5d 75
4adaad64 76 We keep values scaled up, so fractional sizes can be accounted. */
632b4f8e 77#define INLINE_SIZE_SCALE 2
84562394 78struct GTY(()) size_time_entry
632b4f8e 79{
4adaad64 80 /* Predicate for code to be executed. */
dbcb3c74 81 predicate exec_predicate;
4adaad64
JH
82 /* Predicate for value to be constant and optimized out in a specialized copy.
83 When deciding on specialization this makes it possible to see how much
84 the executed code paths will simplify. */
dbcb3c74 85 predicate nonconst_predicate;
632b4f8e 86 int size;
ffb77fd6 87 sreal GTY((skip)) time;
84562394 88};
632b4f8e
JH
89
90/* Function inlining information. */
91struct GTY(()) inline_summary
10a5dd5d 92{
e7f23018
JH
93 /* Information about the function body itself. */
94
10a5dd5d
JH
95 /* Estimated stack frame consumption by the function. */
96 HOST_WIDE_INT estimated_self_stack_size;
10a5dd5d
JH
97 /* Size of the function body. */
98 int self_size;
632b4f8e 99 /* Time of the function body. */
ffb77fd6 100 sreal GTY((skip)) self_time;
4cd8957f
JH
101 /* Minimal size increase after inlining. */
102 int min_size;
e7f23018
JH
103
104 /* False when there something makes inlining impossible (such as va_arg). */
105 unsigned inlinable : 1;
5058c037
JH
106 /* True when function contains cilk spawn (and thus we can not inline
107 into it). */
108 unsigned contains_cilk_spawn : 1;
41f669d8
JH
109 /* True wen there is only one caller of the function before small function
110 inlining. */
111 unsigned int single_caller : 1;
818b88a7
JH
112 /* True if function contains any floating point expressions. */
113 unsigned int fp_expressions : 1;
e7f23018
JH
114
115 /* Information about function that will result after applying all the
116 inline decisions present in the callgraph. Generally kept up to
117 date only for functions that are not inline clones. */
118
119 /* Estimated stack frame consumption by the function. */
120 HOST_WIDE_INT estimated_stack_size;
121 /* Expected offset of the stack frame of inlined function. */
122 HOST_WIDE_INT stack_frame_offset;
123 /* Estimated size of the function after inlining. */
ffb77fd6 124 sreal GTY((skip)) time;
e7f23018 125 int size;
632b4f8e 126
898b8927
JH
127 /* Conditional size/time information. The summaries are being
128 merged during inlining. */
632b4f8e 129 conditions conds;
9771b263 130 vec<size_time_entry, va_gc> *entry;
2daffc47 131
128e0d89 132 /* Predicate on when some loop in the function becomes to have known
2daffc47 133 bounds. */
dbcb3c74 134 predicate * GTY((skip)) loop_iterations;
128e0d89
JH
135 /* Predicate on when some loop in the function becomes to have known
136 stride. */
dbcb3c74 137 predicate * GTY((skip)) loop_stride;
52843a47 138 /* Predicate on when some array indexes become constants. */
dbcb3c74 139 predicate * GTY((skip)) array_index;
d59171da
JH
140 /* Estimated growth for inlining all copies of the function before start
141 of small functions inlining.
142 This value will get out of date as the callers are duplicated, but
143 using up-to-date value in the badness metric mean a lot of extra
144 expenses. */
145 int growth;
688010ba 146 /* Number of SCC on the beginning of inlining process. */
b48ccf0d 147 int scc_no;
5386abe0
JH
148
149 /* Keep all field empty so summary dumping works during its computation.
150 This is useful for debugging. */
151 inline_summary ()
152 : estimated_self_stack_size (0), self_size (0), self_time (0), min_size (0),
153 inlinable (false), contains_cilk_spawn (false), single_caller (false),
154 fp_expressions (false), estimated_stack_size (false),
155 stack_frame_offset (false), time (0), size (0), conds (NULL),
156 entry (NULL), loop_iterations (NULL), loop_stride (NULL),
157 array_index (NULL), growth (0), scc_no (0)
158 {
159 }
10a5dd5d
JH
160};
161
9a1e784a
ML
162class GTY((user)) inline_summary_t: public function_summary <inline_summary *>
163{
164public:
165 inline_summary_t (symbol_table *symtab, bool ggc):
166 function_summary <inline_summary *> (symtab, ggc) {}
167
168 static inline_summary_t *create_ggc (symbol_table *symtab)
169 {
5386abe0 170 struct inline_summary_t *summary = new (ggc_alloc <inline_summary_t> ())
9a1e784a
ML
171 inline_summary_t(symtab, true);
172 summary->disable_insertion_hook ();
173 return summary;
174 }
175
176
177 virtual void insert (cgraph_node *, inline_summary *);
178 virtual void remove (cgraph_node *node, inline_summary *);
179 virtual void duplicate (cgraph_node *src, cgraph_node *dst,
180 inline_summary *src_data, inline_summary *dst_data);
181};
182
183extern GTY(()) function_summary <inline_summary *> *inline_summaries;
632b4f8e 184
898b8927
JH
185/* Information kept about callgraph edges. */
186struct inline_edge_summary
187{
188 /* Estimated size and time of the call statement. */
189 int call_stmt_size;
190 int call_stmt_time;
191 /* Depth of loop nest, 0 means no nesting. */
192 unsigned short int loop_depth;
dbcb3c74 193 class predicate *predicate;
25837a2f
JH
194 /* Array indexed by parameters.
195 0 means that parameter change all the time, REG_BR_PROB_BASE means
196 that parameter is constant. */
84562394 197 vec<inline_param_summary> param;
898b8927
JH
198};
199
84562394
OE
200/* Need a typedef for inline_edge_summary because of inline function
201 'inline_edge_summary' below. */
898b8927 202typedef struct inline_edge_summary inline_edge_summary_t;
9771b263 203extern vec<inline_edge_summary_t> inline_edge_summary_vec;
898b8927 204
4adaad64
JH
205/* Data we cache about callgraph edges during inlining to avoid expensive
206 re-computations during the greedy algorithm. */
84562394 207struct edge_growth_cache_entry
632b4f8e 208{
4adaad64 209 sreal time, nonspec_time;
ab38481c 210 int size;
37678631 211 inline_hints hints;
84562394 212};
632b4f8e 213
9771b263 214extern vec<edge_growth_cache_entry> edge_growth_cache;
10a5dd5d 215
fee8b6da 216/* In ipa-inline-analysis.c */
10a5dd5d
JH
217void debug_inline_summary (struct cgraph_node *);
218void dump_inline_summaries (FILE *f);
37678631
JH
219void dump_inline_summary (FILE *f, struct cgraph_node *node);
220void dump_inline_hints (FILE *f, inline_hints);
03dfc36d
JH
221void inline_generate_summary (void);
222void inline_read_summary (void);
f27c1867 223void inline_write_summary (void);
03dfc36d 224void inline_free_summary (void);
8be2dc8c 225void inline_analyze_function (struct cgraph_node *node);
e7f23018 226void initialize_inline_failed (struct cgraph_edge *);
03dfc36d 227int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
411a20d6 228void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
44210a96
MJ
229 vec<tree>,
230 vec<ipa_polymorphic_call_context>,
9771b263 231 vec<ipa_agg_jump_function_p>,
26f1a658
JH
232 int *, sreal *, sreal *,
233 inline_hints *);
0d92b555 234int estimate_growth (struct cgraph_node *);
4cd8957f 235bool growth_likely_positive (struct cgraph_node *, int);
632b4f8e 236void inline_merge_summary (struct cgraph_edge *edge);
c170d40f 237void inline_update_overall_summary (struct cgraph_node *node);
ed901e4c 238int do_estimate_edge_size (struct cgraph_edge *edge);
ab38481c 239sreal do_estimate_edge_time (struct cgraph_edge *edge);
37678631 240inline_hints do_estimate_edge_hints (struct cgraph_edge *edge);
632b4f8e
JH
241void initialize_growth_caches (void);
242void free_growth_caches (void);
243void compute_inline_parameters (struct cgraph_node *, bool);
09ce3660 244bool speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining);
be3c16c4 245unsigned int early_inliner (function *fun);
bb1e543c
JH
246bool inline_account_function_p (struct cgraph_node *node);
247
03dfc36d 248
fee8b6da 249/* In ipa-inline-transform.c */
d52f5295 250bool inline_call (struct cgraph_edge *, bool, vec<cgraph_edge *> *, int *, bool,
1bbb87c4 251 bool *callee_removed = NULL);
fee8b6da 252unsigned int inline_transform (struct cgraph_node *);
bd936951
JH
253void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *,
254 int freq_scale);
fee8b6da
JH
255
256extern int ncalls_inlined;
257extern int nfunctions_inlined;
258
898b8927
JH
259static inline struct inline_edge_summary *
260inline_edge_summary (struct cgraph_edge *edge)
261{
9771b263 262 return &inline_edge_summary_vec[edge->uid];
898b8927 263}
632b4f8e 264
632b4f8e 265
ed901e4c 266/* Return estimated size of the inline sequence of EDGE. */
03dfc36d
JH
267
268static inline int
ed901e4c 269estimate_edge_size (struct cgraph_edge *edge)
03dfc36d 270{
632b4f8e 271 int ret;
9771b263
DN
272 if ((int)edge_growth_cache.length () <= edge->uid
273 || !(ret = edge_growth_cache[edge->uid].size))
ed901e4c 274 return do_estimate_edge_size (edge);
632b4f8e
JH
275 return ret - (ret > 0);
276}
277
ed901e4c
JH
278/* Return estimated callee growth after inlining EDGE. */
279
280static inline int
281estimate_edge_growth (struct cgraph_edge *edge)
282{
9de6f6c3
JH
283 gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size
284 || !edge->callee->analyzed);
ed901e4c
JH
285 return (estimate_edge_size (edge)
286 - inline_edge_summary (edge)->call_stmt_size);
287}
632b4f8e 288
5764ee3c 289/* Return estimated callee runtime increase after inlining
632b4f8e
JH
290 EDGE. */
291
ab38481c 292static inline sreal
4adaad64 293estimate_edge_time (struct cgraph_edge *edge, sreal *nonspec_time = NULL)
632b4f8e 294{
ab38481c 295 sreal ret;
9771b263 296 if ((int)edge_growth_cache.length () <= edge->uid
ab38481c 297 || !edge_growth_cache[edge->uid].size)
632b4f8e 298 return do_estimate_edge_time (edge);
4adaad64
JH
299 if (nonspec_time)
300 *nonspec_time = edge_growth_cache[edge->uid].nonspec_time;
ab38481c 301 return edge_growth_cache[edge->uid].time;
632b4f8e
JH
302}
303
304
5764ee3c 305/* Return estimated callee runtime increase after inlining
37678631
JH
306 EDGE. */
307
308static inline inline_hints
309estimate_edge_hints (struct cgraph_edge *edge)
310{
311 inline_hints ret;
9771b263
DN
312 if ((int)edge_growth_cache.length () <= edge->uid
313 || !(ret = edge_growth_cache[edge->uid].hints))
de99ac70 314 return do_estimate_edge_hints (edge);
37678631
JH
315 return ret - 1;
316}
317
632b4f8e
JH
318/* Reset cached value for EDGE. */
319
320static inline void
321reset_edge_growth_cache (struct cgraph_edge *edge)
322{
9771b263 323 if ((int)edge_growth_cache.length () > edge->uid)
632b4f8e 324 {
4adaad64 325 struct edge_growth_cache_entry zero = {0, 0, 0, 0};
9771b263 326 edge_growth_cache[edge->uid] = zero;
632b4f8e 327 }
03dfc36d 328}
f1717f8d
KC
329
330#endif /* GCC_IPA_INLINE_H */
This page took 3.018208 seconds and 5 git commands to generate.