gccrs: Add get_locus function for abstract class MetaItemInner.
[official-gcc.git] / gcc / ipa-fnsummary.h
blobfcc01167d0d2889b945e8644d86c582f1cac3fce
1 /* IPA function body analysis.
2 Copyright (C) 2003-2023 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #ifndef GCC_IPA_SUMMARY_H
22 #define GCC_IPA_SUMMARY_H
24 #include "sreal.h"
25 #include "ipa-predicate.h"
28 /* Hints are reasons why IPA heuristics should prefer specializing given
29 function. They are represented as bitmap of the following values. */
30 enum ipa_hints_vals {
31 /* When specialization turns indirect call into a direct call,
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
35 to do so because it enables loop optimizations. */
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
45 it. Set by simple_edge_hints in ipa-inline-analysis.cc. */
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.
49 Set by simple_edge_hints in ipa-inline-analysis.cc. */
50 INLINE_HINT_cross_module = 64,
51 /* We know that the callee is hot by profile. */
52 INLINE_HINT_known_hot = 128,
53 /* There is builtin_constant_p dependent on parameter which is usually
54 a strong hint to inline. */
55 INLINE_HINT_builtin_constant_p = 256
58 typedef int ipa_hints;
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. */
65 struct agg_position_info
67 HOST_WIDE_INT offset;
68 bool agg_contents;
69 bool by_ref;
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. */
75 class size_time_entry
77 public:
78 /* Predicate for code to be executed. */
79 ipa_predicate exec_predicate;
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. */
83 ipa_predicate nonconst_predicate;
84 int size;
85 sreal time;
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. */
91 class ipa_size_summary
93 public:
94 /* Estimated stack frame consumption by the function. */
95 HOST_WIDE_INT estimated_self_stack_size;
96 /* Size of the function body. */
97 int self_size;
98 /* Estimated size of the function after inlining. */
99 int size;
101 ipa_size_summary ()
102 : estimated_self_stack_size (0), self_size (0), size (0)
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. */
112 struct GTY(()) ipa_freqcounting_predicate
114 /* The described event happens with this frequency... */
115 sreal freq;
116 /* ...when this predicate evaluates to false. */
117 ipa_predicate * GTY((skip)) predicate;
120 /* Function inlining information. */
121 class GTY(()) ipa_fn_summary
123 public:
124 /* Keep all field empty so summary dumping works during its computation.
125 This is useful for debugging. */
126 ipa_fn_summary ()
127 : min_size (0),
128 inlinable (false), single_caller (false),
129 fp_expressions (false), target_info (0),
130 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)
139 /* Copy constructor. */
140 ipa_fn_summary (const ipa_fn_summary &s)
141 : min_size (s.min_size),
142 inlinable (s.inlinable), single_caller (s.single_caller),
143 fp_expressions (s.fp_expressions),
144 target_info (s.target_info),
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)
153 /* Default constructor. */
154 ~ipa_fn_summary ();
156 /* Information about the function body itself. */
158 /* Minimal size increase after inlining. */
159 int min_size;
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 /* Like fp_expressions field above, but it's to hold some target specific
169 information, such as some target specific isa flags. Note that for
170 offloading target compilers, this field isn't streamed. */
171 unsigned int target_info;
173 /* Information about function that will result after applying all the
174 inline decisions present in the callgraph. Generally kept up to
175 date only for functions that are not inline clones. */
177 /* Estimated stack frame consumption by the function. */
178 HOST_WIDE_INT estimated_stack_size;
179 /* Estimated runtime of function after inlining. */
180 sreal GTY((skip)) time;
182 /* Conditional size/time information. The summaries are being
183 merged during inlining. */
184 conditions conds;
185 /* Normal code is accounted in size_time_table, while calls are
186 accounted in call_size_time_table. This is because calls
187 are often adjusted by IPA optimizations and thus this summary
188 is generated from call summary information when needed. */
189 auto_vec<size_time_entry> GTY((skip)) size_time_table;
190 /* Unlike size_time_table that is initialized for all summaries
191 call_size_time_table is allocated only for functions with
192 many calls. Use effecient vl_ptr storage. */
193 vec<size_time_entry, va_heap, vl_ptr> GTY((skip)) call_size_time_table;
195 /* Predicates on when some loops in the function can have known bounds. */
196 vec<ipa_freqcounting_predicate, va_gc> *loop_iterations;
197 /* Predicates on when some loops in the function can have known strides. */
198 vec<ipa_freqcounting_predicate, va_gc> *loop_strides;
199 /* Parameters tested by builtin_constant_p. */
200 vec<int, va_heap, vl_ptr> GTY((skip)) builtin_constant_p_parms;
201 /* Estimated growth for inlining all copies of the function before start
202 of small functions inlining.
203 This value will get out of date as the callers are duplicated, but
204 using up-to-date value in the badness metric mean a lot of extra
205 expenses. */
206 int growth;
207 /* Number of SCC on the beginning of inlining process. */
208 int scc_no;
210 /* Record time and size under given predicates. */
211 void account_size_time (int, sreal, const ipa_predicate &,
212 const ipa_predicate &,
213 bool call = false);
215 /* We keep values scaled up, so fractional sizes can be accounted. */
216 static const int size_scale = 2;
217 /* Maximal size of size_time_table before we start to be conservative. */
218 static const int max_size_time_table_size = 256;
221 class GTY((user)) ipa_fn_summary_t:
222 public fast_function_summary <ipa_fn_summary *, va_gc>
224 public:
225 ipa_fn_summary_t (symbol_table *symtab):
226 fast_function_summary <ipa_fn_summary *, va_gc> (symtab) {}
228 static ipa_fn_summary_t *create_ggc (symbol_table *symtab)
230 class ipa_fn_summary_t *summary
231 = new (ggc_alloc_no_dtor<ipa_fn_summary_t> ()) ipa_fn_summary_t (symtab);
232 summary->disable_insertion_hook ();
233 return summary;
236 /* Remove ipa_fn_summary for all callees of NODE. */
237 void remove_callees (cgraph_node *node);
239 void insert (cgraph_node *, ipa_fn_summary *) final override;
240 void remove (cgraph_node *node, ipa_fn_summary *) final override
242 remove_callees (node);
245 void duplicate (cgraph_node *src, cgraph_node *dst,
246 ipa_fn_summary *src_data, ipa_fn_summary *dst_data)
247 final override;
250 extern GTY(()) fast_function_summary <ipa_fn_summary *, va_gc>
251 *ipa_fn_summaries;
253 class ipa_size_summary_t:
254 public fast_function_summary <ipa_size_summary *, va_heap>
256 public:
257 ipa_size_summary_t (symbol_table *symtab):
258 fast_function_summary <ipa_size_summary *, va_heap> (symtab)
260 disable_insertion_hook ();
263 void duplicate (cgraph_node *, cgraph_node *,
264 ipa_size_summary *src_data,
265 ipa_size_summary *dst_data) final override
267 *dst_data = *src_data;
270 extern fast_function_summary <ipa_size_summary *, va_heap>
271 *ipa_size_summaries;
273 /* Information kept about callgraph edges. */
274 class ipa_call_summary
276 public:
277 /* Keep all field empty so summary dumping works during its computation.
278 This is useful for debugging. */
279 ipa_call_summary ()
280 : predicate (NULL), param (vNULL), call_stmt_size (0), call_stmt_time (0),
281 loop_depth (0), is_return_callee_uncaptured (false)
285 /* Copy constructor. */
286 ipa_call_summary (const ipa_call_summary &s):
287 predicate (s.predicate), param (s.param), call_stmt_size (s.call_stmt_size),
288 call_stmt_time (s.call_stmt_time), loop_depth (s.loop_depth),
289 is_return_callee_uncaptured (s.is_return_callee_uncaptured)
293 /* Default destructor. */
294 ~ipa_call_summary ();
296 ipa_predicate *predicate;
297 /* Vector indexed by parameters. */
298 vec<inline_param_summary> param;
299 /* Estimated size and time of the call statement. */
300 int call_stmt_size;
301 int call_stmt_time;
302 /* Depth of loop nest, 0 means no nesting. */
303 unsigned int loop_depth;
304 /* Indicates whether the caller returns the value of it's callee. */
305 bool is_return_callee_uncaptured;
308 class ipa_call_summary_t: public fast_call_summary <ipa_call_summary *, va_heap>
310 public:
311 ipa_call_summary_t (symbol_table *symtab):
312 fast_call_summary <ipa_call_summary *, va_heap> (symtab) {}
314 /* Hook that is called by summary when an edge is duplicated. */
315 void duplicate (cgraph_edge *src, cgraph_edge *dst,
316 ipa_call_summary *src_data,
317 ipa_call_summary *dst_data) final override;
320 /* Estimated execution times, code sizes and other information about the
321 code executing a call described by ipa_call_context. */
323 struct ipa_call_estimates
325 /* Estimated size needed to execute call in the given context. */
326 int size;
328 /* Minimal size needed for the call that is + independent on the call context
329 and can be used for fast estimates. */
330 int min_size;
332 /* Estimated time needed to execute call in the given context. */
333 sreal time;
335 /* Estimated time needed to execute the function when not ignoring
336 computations known to be constant in this context. */
337 sreal nonspecialized_time;
339 /* Further discovered reasons why to inline or specialize the give calls. */
340 ipa_hints hints;
342 /* Frequency how often a loop with known number of iterations is encountered.
343 Calculated with hints. */
344 sreal loops_with_known_iterations;
346 /* Frequency how often a loop with known strides is encountered. Calculated
347 with hints. */
348 sreal loops_with_known_strides;
351 class ipa_cached_call_context;
353 /* This object describe a context of call. That is a summary of known
354 information about its parameters. Main purpose of this context is
355 to give more realistic estimations of function runtime, size and
356 inline hints. */
357 class ipa_call_context
359 public:
360 ipa_call_context (cgraph_node *node,
361 clause_t possible_truths,
362 clause_t nonspec_possible_truths,
363 vec<inline_param_summary> inline_param_summary,
364 ipa_auto_call_arg_values *arg_values);
365 ipa_call_context ()
366 : m_node(NULL)
369 void estimate_size_and_time (ipa_call_estimates *estimates,
370 bool est_times = true, bool est_hints = true);
371 bool equal_to (const ipa_call_context &);
372 bool exists_p ()
374 return m_node != NULL;
376 private:
377 /* Called function. */
378 cgraph_node *m_node;
379 /* Clause describing what predicate conditionals can be satisfied
380 in this context if function is inlined/specialized. */
381 clause_t m_possible_truths;
382 /* Clause describing what predicate conditionals can be satisfied
383 in this context if function is kept offline. */
384 clause_t m_nonspec_possible_truths;
385 /* Inline summary maintains info about change probabilities. */
386 vec<inline_param_summary> m_inline_param_summary;
388 /* Even after having calculated clauses, the information about argument
389 values is used to resolve indirect calls. */
390 ipa_call_arg_values m_avals;
392 friend ipa_cached_call_context;
395 /* Variant of ipa_call_context that is stored in a cache over a longer period
396 of time. */
398 class ipa_cached_call_context : public ipa_call_context
400 public:
401 void duplicate_from (const ipa_call_context &ctx);
402 void release ();
405 extern fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
407 /* In ipa-fnsummary.cc */
408 void ipa_debug_fn_summary (struct cgraph_node *);
409 void ipa_dump_fn_summaries (FILE *f);
410 void ipa_dump_fn_summary (FILE *f, struct cgraph_node *node);
411 void ipa_dump_hints (FILE *f, ipa_hints);
412 void ipa_free_fn_summary (void);
413 void ipa_free_size_summary (void);
414 void inline_analyze_function (struct cgraph_node *node);
415 void estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
416 ipa_auto_call_arg_values *avals,
417 ipa_call_estimates *estimates);
418 void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge);
419 void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true);
420 void compute_fn_summary (struct cgraph_node *, bool);
421 bool refs_local_or_readonly_memory_p (tree);
422 bool points_to_local_or_readonly_memory_p (tree);
425 void evaluate_properties_for_edge (struct cgraph_edge *e,
426 bool inline_p,
427 clause_t *clause_ptr,
428 clause_t *nonspec_clause_ptr,
429 ipa_auto_call_arg_values *avals,
430 bool compute_contexts);
432 void ipa_fnsummary_cc_finalize (void);
433 HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node);
434 void ipa_remove_from_growth_caches (struct cgraph_edge *edge);
436 /* Return true if EDGE is a cross module call. */
438 inline bool
439 cross_module_call_p (struct cgraph_edge *edge)
441 /* Here we do not want to walk to alias target becuase ICF may create
442 cross-unit aliases. */
443 if (edge->caller->unit_id == edge->callee->unit_id)
444 return false;
445 /* If the call is to a (former) comdat function or s symbol with mutiple
446 extern inline definitions then treat is as in-module call. */
447 if (edge->callee->merged_extern_inline || edge->callee->merged_comdat
448 || DECL_COMDAT (edge->callee->decl))
449 return false;
450 return true;
453 #endif /* GCC_IPA_FNSUMMARY_H */