]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-fnsummary.h
PR fortran/95090 - ICE: identifier overflow
[thirdparty/gcc.git] / gcc / ipa-fnsummary.h
CommitLineData
27d020cf 1/* IPA function body analysis.
8d9254fc 2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
27d020cf
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
21#ifndef GCC_IPA_SUMMARY_H
22#define GCC_IPA_SUMMARY_H
23
24#include "sreal.h"
25#include "ipa-predicate.h"
26
27
e4112065 28/* Hints are reasons why IPA heuristics should prefer specializing given
956d615d 29 function. They are represented as bitmap of the following values. */
0bceb671
JH
30enum ipa_hints_vals {
31 /* When specialization turns indirect call into a direct call,
27d020cf
JH
32 it is good idea to do so. */
33 INLINE_HINT_indirect_call = 1,
34 /* Inlining may make loop iterations or loop stride known. It is good idea
956d615d 35 to do so because it enables loop optimizations. */
27d020cf
JH
36 INLINE_HINT_loop_iterations = 2,
37 INLINE_HINT_loop_stride = 4,
38 /* Inlining within same strongly connected component of callgraph is often
39 a loss due to increased stack frame usage and prologue setup costs. */
40 INLINE_HINT_same_scc = 8,
41 /* Inlining functions in strongly connected component is not such a great
42 win. */
43 INLINE_HINT_in_scc = 16,
44 /* If function is declared inline by user, it may be good idea to inline
0bceb671 45 it. Set by simple_edge_hints in ipa-inline-analysis.c. */
27d020cf
JH
46 INLINE_HINT_declared_inline = 32,
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.
0bceb671 49 Set by simple_edge_hints in ipa-inline-analysis.c. */
27d020cf 50 INLINE_HINT_cross_module = 64,
27d020cf 51 /* We know that the callee is hot by profile. */
a20f263b 52 INLINE_HINT_known_hot = 128
27d020cf
JH
53};
54
0bceb671 55typedef int ipa_hints;
27d020cf
JH
56
57/* Simple description of whether a memory load or a condition refers to a load
58 from an aggregate and if so, how and where from in the aggregate.
59 Individual fields have the same meaning like fields with the same name in
60 struct condition. */
61
62struct agg_position_info
63{
64 HOST_WIDE_INT offset;
65 bool agg_contents;
66 bool by_ref;
67};
68
0bceb671 69/* Representation of function body size and time depending on the call
27d020cf 70 context. We keep simple array of record, every containing of predicate
0bceb671 71 and time/size to account. */
6c1dae73 72class GTY(()) size_time_entry
27d020cf 73{
6c1dae73 74public:
27d020cf
JH
75 /* Predicate for code to be executed. */
76 predicate exec_predicate;
77 /* Predicate for value to be constant and optimized out in a specialized copy.
78 When deciding on specialization this makes it possible to see how much
79 the executed code paths will simplify. */
80 predicate nonconst_predicate;
81 int size;
82 sreal GTY((skip)) time;
83};
84
f658ad30
JH
85/* Summary about function and stack frame sizes. We keep this info
86 for inline clones and also for WPA streaming. For this reason this is not
87 part of ipa_fn_summary which exists only for offline functions. */
88class ipa_size_summary
89{
90public:
91 /* Estimated stack frame consumption by the function. */
92 HOST_WIDE_INT estimated_self_stack_size;
93 /* Size of the function body. */
94 int self_size;
95 /* Estimated size of the function after inlining. */
96 int size;
97
98 ipa_size_summary ()
99 : estimated_self_stack_size (0), self_size (0), size (0)
100 {
101 }
f658ad30
JH
102};
103
27d020cf 104/* Function inlining information. */
6c1dae73 105class GTY(()) ipa_fn_summary
27d020cf 106{
6c1dae73 107public:
56f62793
ML
108 /* Keep all field empty so summary dumping works during its computation.
109 This is useful for debugging. */
110 ipa_fn_summary ()
f658ad30 111 : min_size (0),
56f62793
ML
112 inlinable (false), single_caller (false),
113 fp_expressions (false), estimated_stack_size (false),
f658ad30 114 time (0), conds (NULL),
070e3489
JH
115 size_time_table (NULL), call_size_time_table (NULL), loop_iterations (NULL),
116 loop_stride (NULL), growth (0), scc_no (0)
56f62793
ML
117 {
118 }
119
120 /* Copy constructor. */
121 ipa_fn_summary (const ipa_fn_summary &s)
f658ad30 122 : min_size (s.min_size),
56f62793
ML
123 inlinable (s.inlinable), single_caller (s.single_caller),
124 fp_expressions (s.fp_expressions),
125 estimated_stack_size (s.estimated_stack_size),
f658ad30 126 time (s.time), conds (s.conds), size_time_table (s.size_time_table),
070e3489 127 call_size_time_table (NULL),
56f62793 128 loop_iterations (s.loop_iterations), loop_stride (s.loop_stride),
a20f263b 129 growth (s.growth), scc_no (s.scc_no)
56f62793
ML
130 {}
131
132 /* Default constructor. */
133 ~ipa_fn_summary ();
134
27d020cf
JH
135 /* Information about the function body itself. */
136
27d020cf
JH
137 /* Minimal size increase after inlining. */
138 int min_size;
139
140 /* False when there something makes inlining impossible (such as va_arg). */
141 unsigned inlinable : 1;
27d020cf
JH
142 /* True wen there is only one caller of the function before small function
143 inlining. */
144 unsigned int single_caller : 1;
145 /* True if function contains any floating point expressions. */
146 unsigned int fp_expressions : 1;
147
148 /* Information about function that will result after applying all the
149 inline decisions present in the callgraph. Generally kept up to
150 date only for functions that are not inline clones. */
151
152 /* Estimated stack frame consumption by the function. */
153 HOST_WIDE_INT estimated_stack_size;
f658ad30 154 /* Estimated runtime of function after inlining. */
27d020cf 155 sreal GTY((skip)) time;
27d020cf
JH
156
157 /* Conditional size/time information. The summaries are being
158 merged during inlining. */
159 conditions conds;
956d615d 160 /* Normal code is accounted in size_time_table, while calls are
070e3489
JH
161 accounted in call_size_time_table. This is because calls
162 are often adjusted by IPA optimizations and thus this summary
163 is generated from call summary information when needed. */
27d020cf 164 vec<size_time_entry, va_gc> *size_time_table;
070e3489 165 vec<size_time_entry, va_gc> *call_size_time_table;
27d020cf
JH
166
167 /* Predicate on when some loop in the function becomes to have known
168 bounds. */
169 predicate * GTY((skip)) loop_iterations;
170 /* Predicate on when some loop in the function becomes to have known
171 stride. */
172 predicate * GTY((skip)) loop_stride;
27d020cf
JH
173 /* Estimated growth for inlining all copies of the function before start
174 of small functions inlining.
175 This value will get out of date as the callers are duplicated, but
176 using up-to-date value in the badness metric mean a lot of extra
177 expenses. */
178 int growth;
179 /* Number of SCC on the beginning of inlining process. */
180 int scc_no;
181
27d020cf 182 /* Record time and size under given predicates. */
070e3489
JH
183 void account_size_time (int, sreal, const predicate &, const predicate &,
184 bool call = false);
27d020cf 185
0bceb671
JH
186 /* We keep values scaled up, so fractional sizes can be accounted. */
187 static const int size_scale = 2;
070e3489
JH
188 /* Maximal size of size_time_table before we start to be conservative. */
189 static const int max_size_time_table_size = 256;
27d020cf
JH
190};
191
db30281f
ML
192class GTY((user)) ipa_fn_summary_t:
193 public fast_function_summary <ipa_fn_summary *, va_gc>
27d020cf
JH
194{
195public:
db30281f
ML
196 ipa_fn_summary_t (symbol_table *symtab):
197 fast_function_summary <ipa_fn_summary *, va_gc> (symtab) {}
27d020cf 198
0bceb671 199 static ipa_fn_summary_t *create_ggc (symbol_table *symtab)
27d020cf 200 {
78cd68c0
ML
201 class ipa_fn_summary_t *summary
202 = new (ggc_alloc_no_dtor<ipa_fn_summary_t> ()) ipa_fn_summary_t (symtab);
27d020cf
JH
203 summary->disable_insertion_hook ();
204 return summary;
205 }
206
56f62793
ML
207 /* Remove ipa_fn_summary for all callees of NODE. */
208 void remove_callees (cgraph_node *node);
27d020cf 209
0bceb671 210 virtual void insert (cgraph_node *, ipa_fn_summary *);
56f62793
ML
211 virtual void remove (cgraph_node *node, ipa_fn_summary *)
212 {
213 remove_callees (node);
214 }
215
27d020cf 216 virtual void duplicate (cgraph_node *src, cgraph_node *dst,
0bceb671 217 ipa_fn_summary *src_data, ipa_fn_summary *dst_data);
27d020cf
JH
218};
219
db30281f
ML
220extern GTY(()) fast_function_summary <ipa_fn_summary *, va_gc>
221 *ipa_fn_summaries;
27d020cf 222
f658ad30 223class ipa_size_summary_t:
44fca832 224 public fast_function_summary <ipa_size_summary *, va_heap>
f658ad30
JH
225{
226public:
227 ipa_size_summary_t (symbol_table *symtab):
44fca832
JH
228 fast_function_summary <ipa_size_summary *, va_heap> (symtab)
229 {
230 disable_insertion_hook ();
231 }
f658ad30 232
44fca832
JH
233 virtual void duplicate (cgraph_node *, cgraph_node *,
234 ipa_size_summary *src_data,
235 ipa_size_summary *dst_data)
f658ad30 236 {
44fca832 237 *dst_data = *src_data;
f658ad30
JH
238 }
239};
240extern fast_function_summary <ipa_size_summary *, va_heap>
241 *ipa_size_summaries;
242
27d020cf 243/* Information kept about callgraph edges. */
6c1dae73 244class ipa_call_summary
27d020cf 245{
6c1dae73 246public:
56f62793
ML
247 /* Keep all field empty so summary dumping works during its computation.
248 This is useful for debugging. */
249 ipa_call_summary ()
250 : predicate (NULL), param (vNULL), call_stmt_size (0), call_stmt_time (0),
251 loop_depth (0), is_return_callee_uncaptured (false)
252 {
253 }
254
255 /* Copy constructor. */
256 ipa_call_summary (const ipa_call_summary &s):
257 predicate (s.predicate), param (s.param), call_stmt_size (s.call_stmt_size),
258 call_stmt_time (s.call_stmt_time), loop_depth (s.loop_depth),
259 is_return_callee_uncaptured (s.is_return_callee_uncaptured)
260 {
261 }
262
263 /* Default destructor. */
264 ~ipa_call_summary ();
265
27d020cf
JH
266 class predicate *predicate;
267 /* Vector indexed by parameters. */
268 vec<inline_param_summary> param;
269 /* Estimated size and time of the call statement. */
270 int call_stmt_size;
271 int call_stmt_time;
272 /* Depth of loop nest, 0 means no nesting. */
273 unsigned int loop_depth;
0fab169b
PK
274 /* Indicates whether the caller returns the value of it's callee. */
275 bool is_return_callee_uncaptured;
27d020cf
JH
276};
277
db30281f 278class ipa_call_summary_t: public fast_call_summary <ipa_call_summary *, va_heap>
27d020cf
JH
279{
280public:
db30281f
ML
281 ipa_call_summary_t (symbol_table *symtab):
282 fast_call_summary <ipa_call_summary *, va_heap> (symtab) {}
27d020cf 283
27d020cf
JH
284 /* Hook that is called by summary when an edge is duplicated. */
285 virtual void duplicate (cgraph_edge *src, cgraph_edge *dst,
286 ipa_call_summary *src_data,
287 ipa_call_summary *dst_data);
288};
289
1532500e
JH
290/* This object describe a context of call. That is a summary of known
291 information about its parameters. Main purpose of this context is
956d615d 292 to give more realistic estimations of function runtime, size and
1532500e
JH
293 inline hints. */
294class ipa_call_context
295{
296public:
297 ipa_call_context (cgraph_node *node,
298 clause_t possible_truths,
299 clause_t nonspec_possible_truths,
300 vec<tree> known_vals,
301 vec<ipa_polymorphic_call_context> known_contexts,
eb270950 302 vec<ipa_agg_value_set> known_aggs,
1532500e 303 vec<inline_param_summary> m_inline_param_summary);
ac6f2e59
JH
304 ipa_call_context ()
305 : m_node(NULL)
306 {
307 }
1532500e
JH
308 void estimate_size_and_time (int *ret_size, int *ret_min_size,
309 sreal *ret_time,
310 sreal *ret_nonspecialized_time,
311 ipa_hints *ret_hints);
ac6f2e59
JH
312 void duplicate_from (const ipa_call_context &ctx);
313 void release (bool all = false);
314 bool equal_to (const ipa_call_context &);
315 bool exists_p ()
316 {
317 return m_node != NULL;
318 }
1532500e
JH
319private:
320 /* Called function. */
321 cgraph_node *m_node;
322 /* Clause describing what predicate conditionals can be satisfied
956d615d 323 in this context if function is inlined/specialized. */
1532500e
JH
324 clause_t m_possible_truths;
325 /* Clause describing what predicate conditionals can be satisfied
326 in this context if function is kept offline. */
327 clause_t m_nonspec_possible_truths;
328 /* Inline summary maintains info about change probabilities. */
329 vec<inline_param_summary> m_inline_param_summary;
330
331 /* The following is used only to resolve indirect calls. */
332
333 /* Vector describing known values of parameters. */
334 vec<tree> m_known_vals;
335 /* Vector describing known polymorphic call contexts. */
336 vec<ipa_polymorphic_call_context> m_known_contexts;
337 /* Vector describing known aggregate values. */
eb270950 338 vec<ipa_agg_value_set> m_known_aggs;
1532500e
JH
339};
340
db30281f 341extern fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
27d020cf
JH
342
343/* In ipa-fnsummary.c */
0bceb671
JH
344void ipa_debug_fn_summary (struct cgraph_node *);
345void ipa_dump_fn_summaries (FILE *f);
346void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
347void ipa_dump_hints (FILE *f, ipa_hints);
d2db2e6b 348void ipa_free_fn_summary (void);
f658ad30 349void ipa_free_size_summary (void);
27d020cf 350void inline_analyze_function (struct cgraph_node *node);
27d020cf
JH
351void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
352 vec<tree>,
353 vec<ipa_polymorphic_call_context>,
eb270950 354 vec<ipa_agg_value_set>,
27d020cf 355 int *, sreal *, sreal *,
0bceb671
JH
356 ipa_hints *);
357void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
d2bcf46c 358void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
0bceb671 359void compute_fn_summary (struct cgraph_node *, bool);
27d020cf
JH
360
361
1532500e
JH
362void evaluate_properties_for_edge (struct cgraph_edge *e,
363 bool inline_p,
27d020cf
JH
364 clause_t *clause_ptr,
365 clause_t *nonspec_clause_ptr,
366 vec<tree> *known_vals_ptr,
367 vec<ipa_polymorphic_call_context>
368 *known_contexts_ptr,
eb270950 369 vec<ipa_agg_value_set> *);
27d020cf 370
de4381a4 371void ipa_fnsummary_c_finalize (void);
f658ad30 372HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
7237f93e 373void ipa_remove_from_growth_caches (struct cgraph_edge *edge);
de4381a4 374
b74d8dc4
JH
375/* Return true if EDGE is a cross module call. */
376
377static inline bool
378cross_module_call_p (struct cgraph_edge *edge)
379{
380 /* Here we do not want to walk to alias target becuase ICF may create
381 cross-unit aliases. */
382 if (edge->caller->unit_id == edge->callee->unit_id)
383 return false;
384 /* If the call is to a (former) comdat function or s symbol with mutiple
385 extern inline definitions then treat is as in-module call. */
386 if (edge->callee->merged_extern_inline || edge->callee->merged_comdat
387 || DECL_COMDAT (edge->callee->decl))
388 return false;
389 return true;
390}
391
27d020cf 392#endif /* GCC_IPA_FNSUMMARY_H */