GCC Middle and Back End API Reference
ipa-fnsummary.h
Go to the documentation of this file.
1/* IPA function body analysis.
2 Copyright (C) 2003-2024 Free Software Foundation, Inc.
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
28/* Hints are reasons why IPA heuristics should prefer specializing given
29 function. They are represented as bitmap of the following values. */
31 /* When specialization turns indirect call into a direct call,
32 it is good idea to do so. */
34 /* Inlining may make loop iterations or loop stride known. It is good idea
35 to do so because it enables loop optimizations. */
38 /* Inlining within same strongly connected component of callgraph is often
39 a loss due to increased stack frame usage and prologue setup costs. */
41 /* Inlining functions in strongly connected component is not such a great
42 win. */
44 /* If function is declared inline by user, it may be good idea to inline
45 it. Set by simple_edge_hints in ipa-inline-analysis.cc. */
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 Set by simple_edge_hints in ipa-inline-analysis.cc. */
51 /* We know that the callee is hot by profile. */
53 /* There is builtin_constant_p dependent on parameter which is usually
54 a strong hint to inline. */
56};
57
58typedef int ipa_hints;
59
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. */
64
66{
67 HOST_WIDE_INT offset;
69 bool by_ref;
70};
71
72/* Representation of function body size and time depending on the call
73 context. We keep simple array of record, every containing of predicate
74 and time/size to account. */
76{
77public:
78 /* Predicate for code to be executed. */
80 /* Predicate for value to be constant and optimized out in a specialized copy.
81 When deciding on specialization this makes it possible to see how much
82 the executed code paths will simplify. */
84 int size;
86};
87
88/* Summary about function and stack frame sizes. We keep this info
89 for inline clones and also for WPA streaming. For this reason this is not
90 part of ipa_fn_summary which exists only for offline functions. */
92{
93public:
94 /* Estimated stack frame consumption by the function. */
96 /* Size of the function body. */
98 /* Estimated size of the function after inlining. */
99 int size;
100
103 {
104 }
105};
106
107/* Structure to capture how frequently some interesting events occur given a
108 particular predicate. The structure is used to estimate how often we
109 encounter loops with known iteration count or stride in various
110 contexts. */
111
113{
114 /* The described event happens with this frequency... */
116 /* ...when this predicate evaluates to false. */
118};
119
120/* Function inlining information. */
122{
123public:
124 /* Keep all field empty so summary dumping works during its computation.
125 This is useful for debugging. */
127 : min_size (0),
128 inlinable (false), single_caller (false),
129 fp_expressions (false), safe_to_inline_to_always_inline (0),
130 target_info (0), estimated_stack_size (false),
131 time (0), conds (NULL),
132 size_time_table (), call_size_time_table (vNULL),
133 loop_iterations (NULL), loop_strides (NULL),
134 builtin_constant_p_parms (vNULL),
135 growth (0), scc_no (0)
136 {
137 }
138
139 /* Copy constructor. */
141 : min_size (s.min_size),
142 inlinable (s.inlinable), single_caller (s.single_caller),
143 fp_expressions (s.fp_expressions),
145 estimated_stack_size (s.estimated_stack_size),
146 time (s.time), conds (s.conds), size_time_table (),
147 call_size_time_table (vNULL),
148 loop_iterations (s.loop_iterations), loop_strides (s.loop_strides),
149 builtin_constant_p_parms (s.builtin_constant_p_parms),
150 growth (s.growth), scc_no (s.scc_no)
151 {}
152
153 /* Default constructor. */
155
156 /* Information about the function body itself. */
157
158 /* Minimal size increase after inlining. */
160
161 /* False when there something makes inlining impossible (such as va_arg). */
162 unsigned inlinable : 1;
163 /* True wen there is only one caller of the function before small function
164 inlining. */
165 unsigned int single_caller : 1;
166 /* True if function contains any floating point expressions. */
167 unsigned int fp_expressions : 1;
168 /* Cache for analysis of can_early_inline_edge_p. */
170 /* Like fp_expressions field above, but it's to hold some target specific
171 information, such as some target specific isa flags. Note that for
172 offloading target compilers, this field isn't streamed. */
173 unsigned int target_info;
174
175 /* Information about function that will result after applying all the
176 inline decisions present in the callgraph. Generally kept up to
177 date only for functions that are not inline clones. */
178
179 /* Estimated stack frame consumption by the function. */
180 HOST_WIDE_INT estimated_stack_size;
181 /* Estimated runtime of function after inlining. */
182 sreal GTY((skip)) time;
183
184 /* Conditional size/time information. The summaries are being
185 merged during inlining. */
187 /* Normal code is accounted in size_time_table, while calls are
188 accounted in call_size_time_table. This is because calls
189 are often adjusted by IPA optimizations and thus this summary
190 is generated from call summary information when needed. */
192 /* Unlike size_time_table that is initialized for all summaries
193 call_size_time_table is allocated only for functions with
194 many calls. Use effecient vl_ptr storage. */
196
197 /* Predicates on when some loops in the function can have known bounds. */
199 /* Predicates on when some loops in the function can have known strides. */
201 /* Parameters tested by builtin_constant_p. */
203 /* Estimated growth for inlining all copies of the function before start
204 of small functions inlining.
205 This value will get out of date as the callers are duplicated, but
206 using up-to-date value in the badness metric mean a lot of extra
207 expenses. */
209 /* Number of SCC on the beginning of inlining process. */
211
212 /* Record time and size under given predicates. */
213 void account_size_time (int, sreal, const ipa_predicate &,
214 const ipa_predicate &,
215 bool call = false);
216
217 /* We keep values scaled up, so fractional sizes can be accounted. */
218 static const int size_scale = 2;
219 /* Maximal size of size_time_table before we start to be conservative. */
220 static const int max_size_time_table_size = 256;
221};
222
223class GTY((user)) ipa_fn_summary_t:
224 public fast_function_summary <ipa_fn_summary *, va_gc>
225{
226public:
229
231 {
232 class ipa_fn_summary_t *summary
234 summary->disable_insertion_hook ();
235 return summary;
236 }
237
238 /* Remove ipa_fn_summary for all callees of NODE. */
239 void remove_callees (cgraph_node *node);
240
241 void insert (cgraph_node *, ipa_fn_summary *) final override;
242 void remove (cgraph_node *node, ipa_fn_summary *) final override
243 {
244 remove_callees (node);
245 }
246
247 void duplicate (cgraph_node *src, cgraph_node *dst,
248 ipa_fn_summary *src_data, ipa_fn_summary *dst_data)
249 final override;
250};
251
254
257{
258public:
261 {
262 disable_insertion_hook ();
263 }
264
266 ipa_size_summary *src_data,
267 ipa_size_summary *dst_data) final override
268 {
269 *dst_data = *src_data;
270 }
271};
272extern fast_function_summary <ipa_size_summary *, va_heap>
274
275/* Information kept about callgraph edges. */
277{
278public:
279 /* Keep all field empty so summary dumping works during its computation.
280 This is useful for debugging. */
286
287 /* Copy constructor. */
294
295 /* Default destructor. */
297
299 /* Vector indexed by parameters. */
301 /* Estimated size and time of the call statement. */
304 /* Depth of loop nest, 0 means no nesting. */
305 unsigned int loop_depth;
306 /* Indicates whether the caller returns the value of it's callee. */
308};
309
310class ipa_call_summary_t: public fast_call_summary <ipa_call_summary *, va_heap>
311{
312public:
315
316 /* Hook that is called by summary when an edge is duplicated. */
317 void duplicate (cgraph_edge *src, cgraph_edge *dst,
318 ipa_call_summary *src_data,
319 ipa_call_summary *dst_data) final override;
320};
321
322/* Estimated execution times, code sizes and other information about the
323 code executing a call described by ipa_call_context. */
324
326{
327 /* Estimated size needed to execute call in the given context. */
328 int size;
329
330 /* Minimal size needed for the call that is + independent on the call context
331 and can be used for fast estimates. */
333
334 /* Estimated time needed to execute call in the given context. */
336
337 /* Estimated time needed to execute the function when not ignoring
338 computations known to be constant in this context. */
340
341 /* Further discovered reasons why to inline or specialize the give calls. */
343
344 /* Frequency how often a loop with known number of iterations is encountered.
345 Calculated with hints. */
347
348 /* Frequency how often a loop with known strides is encountered. Calculated
349 with hints. */
351};
352
354
355/* This object describe a context of call. That is a summary of known
356 information about its parameters. Main purpose of this context is
357 to give more realistic estimations of function runtime, size and
358 inline hints. */
360{
361public:
363 clause_t possible_truths,
364 clause_t nonspec_possible_truths,
366 ipa_auto_call_arg_values *arg_values);
368 : m_node(NULL)
369 {
370 }
372 bool est_times = true, bool est_hints = true);
373 bool equal_to (const ipa_call_context &);
374 bool exists_p ()
375 {
376 return m_node != NULL;
377 }
378private:
379 /* Called function. */
381 /* Clause describing what predicate conditionals can be satisfied
382 in this context if function is inlined/specialized. */
384 /* Clause describing what predicate conditionals can be satisfied
385 in this context if function is kept offline. */
387 /* Inline summary maintains info about change probabilities. */
389
390 /* Even after having calculated clauses, the information about argument
391 values is used to resolve indirect calls. */
393
395};
396
397/* Variant of ipa_call_context that is stored in a cache over a longer period
398 of time. */
399
401{
402public:
403 void duplicate_from (const ipa_call_context &ctx);
404 void release ();
405};
406
407extern fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
408
409/* In ipa-fnsummary.cc */
410void ipa_debug_fn_summary (struct cgraph_node *);
411void ipa_dump_fn_summaries (FILE *f);
412void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
413void ipa_dump_hints (FILE *f, ipa_hints);
414void ipa_free_fn_summary (void);
415void ipa_free_size_summary (void);
416void inline_analyze_function (struct cgraph_node *node);
419 ipa_call_estimates *estimates);
421void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
422void compute_fn_summary (struct cgraph_node *, bool);
425
426
428 bool inline_p,
429 clause_t *clause_ptr,
430 clause_t *nonspec_clause_ptr,
432 bool compute_contexts);
433
434void ipa_fnsummary_cc_finalize (void);
435HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
437
438/* Return true if EDGE is a cross module call. */
439
440inline bool
442{
443 /* Here we do not want to walk to alias target becuase ICF may create
444 cross-unit aliases. */
445 if (edge->caller->unit_id == edge->callee->unit_id)
446 return false;
447 /* If the call is to a (former) comdat function or s symbol with mutiple
448 extern inline definitions then treat is as in-module call. */
449 if (edge->callee->merged_extern_inline || edge->callee->merged_comdat
450 || DECL_COMDAT (edge->callee->decl))
451 return false;
452 return true;
453}
454
455#endif /* GCC_IPA_FNSUMMARY_H */
symbol_table * symtab
Definition cgraph.cc:81
Definition vec.h:1656
Definition cgraph.h:1696
Definition symbol-summary.h:827
Definition symbol-summary.h:358
Definition ipa-prop.h:503
Definition ipa-fnsummary.h:401
void release()
Definition ipa-fnsummary.cc:3688
void duplicate_from(const ipa_call_context &ctx)
Definition ipa-fnsummary.cc:3616
Definition ipa-prop.h:539
Definition ipa-fnsummary.h:360
clause_t m_possible_truths
Definition ipa-fnsummary.h:383
vec< inline_param_summary > m_inline_param_summary
Definition ipa-fnsummary.h:388
cgraph_node * m_node
Definition ipa-fnsummary.h:380
bool equal_to(const ipa_call_context &)
Definition ipa-fnsummary.cc:3702
friend ipa_cached_call_context
Definition ipa-fnsummary.h:394
void estimate_size_and_time(ipa_call_estimates *estimates, bool est_times=true, bool est_hints=true)
Definition ipa-fnsummary.cc:3858
ipa_call_context()
Definition ipa-fnsummary.h:367
bool exists_p()
Definition ipa-fnsummary.h:374
clause_t m_nonspec_possible_truths
Definition ipa-fnsummary.h:386
ipa_call_arg_values m_avals
Definition ipa-fnsummary.h:392
Definition ipa-fnsummary.h:311
ipa_call_summary_t(symbol_table *symtab)
Definition ipa-fnsummary.h:313
void duplicate(cgraph_edge *src, cgraph_edge *dst, ipa_call_summary *src_data, ipa_call_summary *dst_data) final override
Definition ipa-fnsummary.cc:981
Definition ipa-fnsummary.h:277
bool is_return_callee_uncaptured
Definition ipa-fnsummary.h:307
unsigned int loop_depth
Definition ipa-fnsummary.h:305
int call_stmt_time
Definition ipa-fnsummary.h:303
ipa_call_summary(const ipa_call_summary &s)
Definition ipa-fnsummary.h:288
ipa_predicate * predicate
Definition ipa-fnsummary.h:298
~ipa_call_summary()
Definition ipa-fnsummary.cc:754
int call_stmt_size
Definition ipa-fnsummary.h:302
vec< inline_param_summary > param
Definition ipa-fnsummary.h:300
ipa_call_summary()
Definition ipa-fnsummary.h:281
Definition ipa-fnsummary.h:225
static ipa_fn_summary_t * create_ggc(symbol_table *symtab)
Definition ipa-fnsummary.h:230
ipa_fn_summary_t(symbol_table *symtab)
Definition ipa-fnsummary.h:227
void remove_callees(cgraph_node *node)
Definition ipa-fnsummary.cc:778
void duplicate(cgraph_node *src, cgraph_node *dst, ipa_fn_summary *src_data, ipa_fn_summary *dst_data) final override
Definition ipa-fnsummary.cc:819
void remove(cgraph_node *node, ipa_fn_summary *) final override
Definition ipa-fnsummary.h:242
Definition ipa-fnsummary.h:122
unsigned int target_info
Definition ipa-fnsummary.h:173
int scc_no
Definition ipa-fnsummary.h:210
static const int size_scale
Definition ipa-fnsummary.h:218
unsigned int safe_to_inline_to_always_inline
Definition ipa-fnsummary.h:169
HOST_WIDE_INT estimated_stack_size
Definition ipa-fnsummary.h:180
conditions conds
Definition ipa-fnsummary.h:186
vec< size_time_entry, va_heap, vl_ptr > call_size_time_table
Definition ipa-fnsummary.h:195
static const int max_size_time_table_size
Definition ipa-fnsummary.h:220
ipa_fn_summary(const ipa_fn_summary &s)
Definition ipa-fnsummary.h:140
sreal time
Definition ipa-fnsummary.h:182
void account_size_time(int, sreal, const ipa_predicate &, const ipa_predicate &, bool call=false)
Definition ipa-fnsummary.cc:167
int growth
Definition ipa-fnsummary.h:208
auto_vec< size_time_entry > size_time_table
Definition ipa-fnsummary.h:191
unsigned inlinable
Definition ipa-fnsummary.h:162
~ipa_fn_summary()
Definition ipa-fnsummary.cc:762
vec< ipa_freqcounting_predicate, va_gc > * loop_strides
Definition ipa-fnsummary.h:200
unsigned int fp_expressions
Definition ipa-fnsummary.h:167
int min_size
Definition ipa-fnsummary.h:159
vec< ipa_freqcounting_predicate, va_gc > * loop_iterations
Definition ipa-fnsummary.h:198
ipa_fn_summary()
Definition ipa-fnsummary.h:126
unsigned int single_caller
Definition ipa-fnsummary.h:165
vec< int, va_heap, vl_ptr > builtin_constant_p_parms
Definition ipa-fnsummary.h:202
Definition ipa-predicate.h:119
Definition ipa-fnsummary.h:257
ipa_size_summary_t(symbol_table *symtab)
Definition ipa-fnsummary.h:259
void duplicate(cgraph_node *, cgraph_node *, ipa_size_summary *src_data, ipa_size_summary *dst_data) final override
Definition ipa-fnsummary.h:265
Definition ipa-fnsummary.h:92
int size
Definition ipa-fnsummary.h:99
HOST_WIDE_INT estimated_self_stack_size
Definition ipa-fnsummary.h:95
ipa_size_summary()
Definition ipa-fnsummary.h:101
int self_size
Definition ipa-fnsummary.h:97
Definition genmatch.cc:834
Definition ipa-fnsummary.h:76
int size
Definition ipa-fnsummary.h:84
ipa_predicate exec_predicate
Definition ipa-fnsummary.h:79
sreal time
Definition ipa-fnsummary.h:85
ipa_predicate nonconst_predicate
Definition ipa-fnsummary.h:83
Definition sreal.h:41
Definition cgraph.h:2223
class edge_def * edge
Definition coretypes.h:343
#define GTY(x)
Definition coretypes.h:41
union tree_node * tree
Definition coretypes.h:97
T * ggc_alloc_no_dtor(ALONE_CXX_MEM_STAT_INFO)
Definition ggc.h:200
void ipa_remove_from_growth_caches(struct cgraph_edge *edge)
Definition ipa-inline-analysis.cc:304
void ipa_dump_fn_summaries(FILE *f)
Definition ipa-fnsummary.cc:1183
void ipa_free_fn_summary(void)
Definition ipa-fnsummary.cc:4924
HOST_WIDE_INT ipa_get_stack_frame_offset(struct cgraph_node *node)
Definition ipa-fnsummary.cc:4038
fast_function_summary< ipa_size_summary *, va_heap > * ipa_size_summaries
Definition ipa-fnsummary.cc:96
bool points_to_local_or_readonly_memory_p(tree)
Definition ipa-fnsummary.cc:2631
bool cross_module_call_p(struct cgraph_edge *edge)
Definition ipa-fnsummary.h:441
void ipa_update_overall_fn_summary(struct cgraph_node *node, bool reset=true)
Definition ipa-fnsummary.cc:4379
void ipa_dump_fn_summary(FILE *f, struct cgraph_node *node)
Definition ipa-fnsummary.cc:1090
void estimate_ipcp_clone_size_and_time(struct cgraph_node *node, ipa_auto_call_arg_values *avals, ipa_call_estimates *estimates)
Definition ipa-fnsummary.cc:4021
void ipa_free_size_summary(void)
Definition ipa-fnsummary.cc:4941
void ipa_debug_fn_summary(struct cgraph_node *)
Definition ipa-fnsummary.cc:1177
fast_call_summary< ipa_call_summary *, va_heap > * ipa_call_summaries
Definition ipa-fnsummary.cc:97
ipa_hints_vals
Definition ipa-fnsummary.h:30
@ INLINE_HINT_declared_inline
Definition ipa-fnsummary.h:46
@ INLINE_HINT_known_hot
Definition ipa-fnsummary.h:52
@ INLINE_HINT_same_scc
Definition ipa-fnsummary.h:40
@ INLINE_HINT_in_scc
Definition ipa-fnsummary.h:43
@ INLINE_HINT_builtin_constant_p
Definition ipa-fnsummary.h:55
@ INLINE_HINT_loop_iterations
Definition ipa-fnsummary.h:36
@ INLINE_HINT_loop_stride
Definition ipa-fnsummary.h:37
@ INLINE_HINT_cross_module
Definition ipa-fnsummary.h:50
@ INLINE_HINT_indirect_call
Definition ipa-fnsummary.h:33
void evaluate_properties_for_edge(struct cgraph_edge *e, bool inline_p, clause_t *clause_ptr, clause_t *nonspec_clause_ptr, ipa_auto_call_arg_values *avals, bool compute_contexts)
Definition ipa-fnsummary.cc:601
void ipa_dump_hints(FILE *f, ipa_hints)
Definition ipa-fnsummary.cc:105
bool refs_local_or_readonly_memory_p(tree)
Definition ipa-fnsummary.cc:2607
fast_function_summary< ipa_fn_summary *, va_gc > * ipa_fn_summaries
Definition ipa-fnsummary.cc:95
void ipa_merge_fn_summary_after_inlining(struct cgraph_edge *edge)
Definition ipa-fnsummary.cc:4232
void compute_fn_summary(struct cgraph_node *, bool)
Definition ipa-fnsummary.cc:3176
void inline_analyze_function(struct cgraph_node *node)
Definition ipa-fnsummary.cc:4424
int ipa_hints
Definition ipa-fnsummary.h:58
void ipa_fnsummary_cc_finalize(void)
Definition ipa-fnsummary.cc:5098
uint32_t clause_t
Definition ipa-predicate.h:117
Definition ipa-fnsummary.h:66
HOST_WIDE_INT offset
Definition ipa-fnsummary.h:67
bool agg_contents
Definition ipa-fnsummary.h:68
bool by_ref
Definition ipa-fnsummary.h:69
Definition cgraph.h:875
Definition ipa-predicate.h:71
Definition ipa-fnsummary.h:326
sreal loops_with_known_iterations
Definition ipa-fnsummary.h:346
int min_size
Definition ipa-fnsummary.h:332
ipa_hints hints
Definition ipa-fnsummary.h:342
sreal loops_with_known_strides
Definition ipa-fnsummary.h:350
sreal nonspecialized_time
Definition ipa-fnsummary.h:339
int size
Definition ipa-fnsummary.h:328
sreal time
Definition ipa-fnsummary.h:335
Definition ipa-fnsummary.h:113
sreal freq
Definition ipa-fnsummary.h:115
ipa_predicate * predicate
Definition ipa-fnsummary.h:117
Definition resource.cc:41
Definition vec.h:359
Definition vec.h:283
#define NULL
Definition system.h:50
#define false
Definition system.h:895
static void insert(void)
Definition tree-ssa-pre.cc:3800
#define DECL_COMDAT(NODE)
Definition tree.h:3181
constexpr vnull vNULL
Definition vec.h:569