]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-fnsummary.cc
Rename .c files to .cc files.
[thirdparty/gcc.git] / gcc / ipa-fnsummary.cc
CommitLineData
27d020cf 1/* Function summary pass.
7adcbafe 2 Copyright (C) 2003-2022 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/* Analysis of function bodies used by inter-procedural passes
22
23 We estimate for each function
24 - function body size and size after specializing into given context
25 - average function execution time in a given context
26 - function frame size
27 For each call
28 - call statement size, time and how often the parameters change
29
0bceb671 30 ipa_fn_summary data structures store above information locally (i.e.
27d020cf
JH
31 parameters of the function itself) and globally (i.e. parameters of
32 the function created by applying all the inline decisions already
33 present in the callgraph).
34
0bceb671 35 We provide access to the ipa_fn_summary data structure and
27d020cf
JH
36 basic logic updating the parameters when inlining is performed.
37
38 The summaries are context sensitive. Context means
39 1) partial assignment of known constant values of operands
40 2) whether function is inlined into the call or not.
41 It is easy to add more variants. To represent function size and time
42 that depends on context (i.e. it is known to be optimized away when
43 context is known either by inlining or from IP-CP and cloning),
44 we use predicates.
45
46 estimate_edge_size_and_time can be used to query
0bceb671 47 function size/time in the given context. ipa_merge_fn_summary_after_inlining merges
27d020cf
JH
48 properties of caller and callee after inlining.
49
50 Finally pass_inline_parameters is exported. This is used to drive
51 computation of function parameters used by the early inliner. IPA
52 inlined performs analysis via its analyze_function method. */
53
54#include "config.h"
85245bda 55#define INCLUDE_VECTOR
27d020cf
JH
56#include "system.h"
57#include "coretypes.h"
58#include "backend.h"
0fc60c18 59#include "target.h"
27d020cf
JH
60#include "tree.h"
61#include "gimple.h"
62#include "alloc-pool.h"
63#include "tree-pass.h"
64#include "ssa.h"
65#include "tree-streamer.h"
66#include "cgraph.h"
67#include "diagnostic.h"
68#include "fold-const.h"
69#include "print-tree.h"
70#include "tree-inline.h"
71#include "gimple-pretty-print.h"
27d020cf
JH
72#include "cfganal.h"
73#include "gimple-iterator.h"
74#include "tree-cfg.h"
75#include "tree-ssa-loop-niter.h"
76#include "tree-ssa-loop.h"
77#include "symbol-summary.h"
78#include "ipa-prop.h"
79#include "ipa-fnsummary.h"
80#include "cfgloop.h"
81#include "tree-scalar-evolution.h"
82#include "ipa-utils.h"
27d020cf
JH
83#include "cfgexpand.h"
84#include "gimplify.h"
314e6352
ML
85#include "stringpool.h"
86#include "attribs.h"
ac0573de 87#include "tree-into-ssa.h"
ae7a23a3 88#include "symtab-clones.h"
45f4e2b0 89#include "gimple-range.h"
ca84f393 90#include "tree-dfa.h"
27d020cf
JH
91
92/* Summaries. */
db30281f 93fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
f658ad30 94fast_function_summary <ipa_size_summary *, va_heap> *ipa_size_summaries;
db30281f 95fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
27d020cf
JH
96
97/* Edge predicates goes here. */
2d01bef2 98static object_allocator<ipa_predicate> edge_predicate_pool ("edge predicates");
27d020cf
JH
99
100
0bceb671 101/* Dump IPA hints. */
27d020cf 102void
0bceb671 103ipa_dump_hints (FILE *f, ipa_hints hints)
27d020cf
JH
104{
105 if (!hints)
106 return;
0bceb671 107 fprintf (f, "IPA hints:");
27d020cf
JH
108 if (hints & INLINE_HINT_indirect_call)
109 {
110 hints &= ~INLINE_HINT_indirect_call;
111 fprintf (f, " indirect_call");
112 }
113 if (hints & INLINE_HINT_loop_iterations)
114 {
115 hints &= ~INLINE_HINT_loop_iterations;
116 fprintf (f, " loop_iterations");
117 }
118 if (hints & INLINE_HINT_loop_stride)
119 {
120 hints &= ~INLINE_HINT_loop_stride;
121 fprintf (f, " loop_stride");
122 }
123 if (hints & INLINE_HINT_same_scc)
124 {
125 hints &= ~INLINE_HINT_same_scc;
126 fprintf (f, " same_scc");
127 }
128 if (hints & INLINE_HINT_in_scc)
129 {
130 hints &= ~INLINE_HINT_in_scc;
131 fprintf (f, " in_scc");
132 }
133 if (hints & INLINE_HINT_cross_module)
134 {
135 hints &= ~INLINE_HINT_cross_module;
136 fprintf (f, " cross_module");
137 }
138 if (hints & INLINE_HINT_declared_inline)
139 {
140 hints &= ~INLINE_HINT_declared_inline;
141 fprintf (f, " declared_inline");
142 }
27d020cf
JH
143 if (hints & INLINE_HINT_known_hot)
144 {
145 hints &= ~INLINE_HINT_known_hot;
146 fprintf (f, " known_hot");
147 }
caaa218f
JH
148 if (hints & INLINE_HINT_builtin_constant_p)
149 {
150 hints &= ~INLINE_HINT_builtin_constant_p;
151 fprintf (f, " builtin_constant_p");
152 }
27d020cf
JH
153 gcc_assert (!hints);
154}
155
156
157/* Record SIZE and TIME to SUMMARY.
158 The accounted code will be executed when EXEC_PRED is true.
956d615d 159 When NONCONST_PRED is false the code will evaluate to constant and
070e3489
JH
160 will get optimized out in specialized clones of the function.
161 If CALL is true account to call_size_time_table rather than
162 size_time_table. */
27d020cf
JH
163
164void
0bceb671 165ipa_fn_summary::account_size_time (int size, sreal time,
2d01bef2
ML
166 const ipa_predicate &exec_pred,
167 const ipa_predicate &nonconst_pred_in,
070e3489 168 bool call)
27d020cf
JH
169{
170 size_time_entry *e;
171 bool found = false;
172 int i;
2d01bef2 173 ipa_predicate nonconst_pred;
366099ff 174 vec<size_time_entry> *table = call ? &call_size_time_table : &size_time_table;
27d020cf
JH
175
176 if (exec_pred == false)
177 return;
178
179 nonconst_pred = nonconst_pred_in & exec_pred;
180
181 if (nonconst_pred == false)
182 return;
183
956d615d 184 /* We need to create initial empty unconditional clause, but otherwise
27d020cf 185 we don't need to account empty times and sizes. */
366099ff 186 if (!size && time == 0 && table->length ())
27d020cf
JH
187 return;
188
956d615d 189 /* Only for calls we are unaccounting what we previously recorded. */
d2bcf46c 190 gcc_checking_assert (time >= 0 || call);
27d020cf 191
366099ff 192 for (i = 0; table->iterate (i, &e); i++)
27d020cf
JH
193 if (e->exec_predicate == exec_pred
194 && e->nonconst_predicate == nonconst_pred)
195 {
196 found = true;
197 break;
198 }
070e3489 199 if (i == max_size_time_table_size)
27d020cf
JH
200 {
201 i = 0;
202 found = true;
070e3489 203 e = &(*table)[0];
27d020cf
JH
204 if (dump_file && (dump_flags & TDF_DETAILS))
205 fprintf (dump_file,
206 "\t\tReached limit on number of entries, "
207 "ignoring the predicate.");
208 }
209 if (dump_file && (dump_flags & TDF_DETAILS) && (time != 0 || size))
210 {
211 fprintf (dump_file,
212 "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
0bceb671 213 ((double) size) / ipa_fn_summary::size_scale,
27d020cf
JH
214 (time.to_double ()), found ? "" : "new ");
215 exec_pred.dump (dump_file, conds, 0);
216 if (exec_pred != nonconst_pred)
217 {
218 fprintf (dump_file, " nonconst:");
219 nonconst_pred.dump (dump_file, conds);
220 }
221 else
222 fprintf (dump_file, "\n");
223 }
224 if (!found)
225 {
99b1c316 226 class size_time_entry new_entry;
27d020cf
JH
227 new_entry.size = size;
228 new_entry.time = time;
229 new_entry.exec_predicate = exec_pred;
230 new_entry.nonconst_predicate = nonconst_pred;
070e3489 231 if (call)
366099ff 232 call_size_time_table.safe_push (new_entry);
070e3489 233 else
366099ff 234 size_time_table.safe_push (new_entry);
27d020cf
JH
235 }
236 else
237 {
238 e->size += size;
239 e->time += time;
dd86c8da 240 /* FIXME: PR bootstrap/92653 gcc_checking_assert (e->time >= -1); */
d2bcf46c
JH
241 /* Tolerate small roundoff issues. */
242 if (e->time < 0)
243 e->time = 0;
27d020cf
JH
244 }
245}
246
956d615d 247/* We proved E to be unreachable, redirect it to __builtin_unreachable. */
27d020cf
JH
248
249static struct cgraph_edge *
250redirect_to_unreachable (struct cgraph_edge *e)
251{
252 struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
253 struct cgraph_node *target = cgraph_node::get_create
254 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
255
256 if (e->speculative)
27c5a177 257 e = cgraph_edge::resolve_speculation (e, target->decl);
27d020cf 258 else if (!e->callee)
27c5a177 259 e = cgraph_edge::make_direct (e, target);
27d020cf
JH
260 else
261 e->redirect_callee (target);
99b1c316 262 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf 263 e->inline_failed = CIF_UNREACHABLE;
3995f3a2 264 e->count = profile_count::zero ();
27d020cf
JH
265 es->call_stmt_size = 0;
266 es->call_stmt_time = 0;
267 if (callee)
268 callee->remove_symbol_and_inline_clones ();
269 return e;
270}
271
272/* Set predicate for edge E. */
273
274static void
2d01bef2 275edge_set_predicate (struct cgraph_edge *e, ipa_predicate *predicate)
27d020cf
JH
276{
277 /* If the edge is determined to be never executed, redirect it
0bceb671
JH
278 to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
279 be optimized out. */
27d020cf
JH
280 if (predicate && *predicate == false
281 /* When handling speculative edges, we need to do the redirection
282 just once. Do it always on the direct edge, so we do not
283 attempt to resolve speculation while duplicating the edge. */
284 && (!e->speculative || e->callee))
285 e = redirect_to_unreachable (e);
286
99b1c316 287 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
288 if (predicate && *predicate != true)
289 {
290 if (!es->predicate)
291 es->predicate = edge_predicate_pool.allocate ();
292 *es->predicate = *predicate;
293 }
294 else
295 {
296 if (es->predicate)
297 edge_predicate_pool.remove (es->predicate);
298 es->predicate = NULL;
299 }
300}
301
302/* Set predicate for hint *P. */
303
304static void
2d01bef2 305set_hint_predicate (ipa_predicate **p, ipa_predicate new_predicate)
27d020cf
JH
306{
307 if (new_predicate == false || new_predicate == true)
308 {
309 if (*p)
310 edge_predicate_pool.remove (*p);
311 *p = NULL;
312 }
313 else
314 {
315 if (!*p)
316 *p = edge_predicate_pool.allocate ();
317 **p = new_predicate;
318 }
319}
320
67ce9099
MJ
321/* Find if NEW_PREDICATE is already in V and if so, increment its freq.
322 Otherwise add a new item to the vector with this predicate and frerq equal
323 to add_freq, unless the number of predicates would exceed MAX_NUM_PREDICATES
324 in which case the function does nothing. */
325
326static void
327add_freqcounting_predicate (vec<ipa_freqcounting_predicate, va_gc> **v,
2d01bef2 328 const ipa_predicate &new_predicate, sreal add_freq,
67ce9099
MJ
329 unsigned max_num_predicates)
330{
331 if (new_predicate == false || new_predicate == true)
332 return;
333 ipa_freqcounting_predicate *f;
334 for (int i = 0; vec_safe_iterate (*v, i, &f); i++)
335 if (new_predicate == f->predicate)
336 {
337 f->freq += add_freq;
338 return;
339 }
340 if (vec_safe_length (*v) >= max_num_predicates)
341 /* Too many different predicates to account for. */
342 return;
343
344 ipa_freqcounting_predicate fcp;
345 fcp.predicate = NULL;
346 set_hint_predicate (&fcp.predicate, new_predicate);
347 fcp.freq = add_freq;
348 vec_safe_push (*v, fcp);
349 return;
350}
27d020cf 351
956d615d 352/* Compute what conditions may or may not hold given information about
27d020cf 353 parameters. RET_CLAUSE returns truths that may hold in a specialized copy,
956d615d 354 while RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
27d020cf
JH
355 copy when called in a given context. It is a bitmask of conditions. Bit
356 0 means that condition is known to be false, while bit 1 means that condition
357 may or may not be true. These differs - for example NOT_INLINED condition
67914693 358 is always false in the second and also builtin_constant_p tests cannot use
27d020cf
JH
359 the fact that parameter is indeed a constant.
360
9d5af1db
MJ
361 When INLINE_P is true, assume that we are inlining. AVAL contains known
362 information about argument values. The function does not modify its content
363 and so AVALs could also be of type ipa_call_arg_values but so far all
364 callers work with the auto version and so we avoid the conversion for
365 convenience.
27d020cf 366
9d5af1db 367 ERROR_MARK value of an argument means compile time invariant. */
27d020cf
JH
368
369static void
370evaluate_conditions_for_known_args (struct cgraph_node *node,
371 bool inline_p,
9d5af1db 372 ipa_auto_call_arg_values *avals,
27d020cf
JH
373 clause_t *ret_clause,
374 clause_t *ret_nonspec_clause)
375{
2d01bef2
ML
376 clause_t clause = inline_p ? 0 : 1 << ipa_predicate::not_inlined_condition;
377 clause_t nonspec_clause = 1 << ipa_predicate::not_inlined_condition;
99b1c316 378 class ipa_fn_summary *info = ipa_fn_summaries->get (node);
27d020cf
JH
379 int i;
380 struct condition *c;
381
382 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
383 {
b0d55476 384 tree val = NULL;
27d020cf 385 tree res;
4307a485
FX
386 int j;
387 struct expr_eval_op *op;
27d020cf
JH
388
389 /* We allow call stmt to have fewer arguments than the callee function
390 (especially for K&R style programs). So bound check here (we assume
9d5af1db
MJ
391 m_known_aggs vector is either empty or has the same length as
392 m_known_vals). */
393 gcc_checking_assert (!avals->m_known_aggs.length ()
394 || !avals->m_known_vals.length ()
395 || (avals->m_known_vals.length ()
396 == avals->m_known_aggs.length ()));
27d020cf
JH
397
398 if (c->agg_contents)
399 {
2d01bef2 400 if (c->code == ipa_predicate::changed
27d020cf 401 && !c->by_ref
9d5af1db 402 && (avals->safe_sval_at(c->operand_num) == error_mark_node))
27d020cf
JH
403 continue;
404
9d5af1db 405 if (ipa_agg_value_set *agg = avals->safe_aggval_at (c->operand_num))
27d020cf 406 {
9d5af1db
MJ
407 tree sval = avals->safe_sval_at (c->operand_num);
408 val = ipa_find_agg_cst_for_param (agg, sval, c->offset,
409 c->by_ref);
27d020cf
JH
410 }
411 else
412 val = NULL_TREE;
413 }
9d5af1db 414 else
27d020cf 415 {
9d5af1db 416 val = avals->safe_sval_at (c->operand_num);
2d01bef2
ML
417 if (val && val == error_mark_node
418 && c->code != ipa_predicate::changed)
27d020cf
JH
419 val = NULL_TREE;
420 }
421
68718e8e 422 if (!val
2d01bef2
ML
423 && (c->code == ipa_predicate::changed
424 || c->code == ipa_predicate::is_not_constant))
27d020cf 425 {
2d01bef2
ML
426 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
427 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
27d020cf
JH
428 continue;
429 }
2d01bef2 430 if (c->code == ipa_predicate::changed)
27d020cf 431 {
2d01bef2 432 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
27d020cf
JH
433 continue;
434 }
435
2d01bef2 436 if (c->code == ipa_predicate::is_not_constant)
27d020cf 437 {
2d01bef2 438 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
27d020cf
JH
439 continue;
440 }
441
68718e8e 442 if (val && TYPE_SIZE (c->type) == TYPE_SIZE (TREE_TYPE (val)))
4307a485 443 {
68718e8e
JH
444 if (c->type != TREE_TYPE (val))
445 val = fold_unary (VIEW_CONVERT_EXPR, c->type, val);
446 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
447 {
448 if (!val)
449 break;
450 if (!op->val[0])
451 val = fold_unary (op->code, op->type, val);
452 else if (!op->val[1])
453 val = fold_binary (op->code, op->type,
454 op->index ? op->val[0] : val,
455 op->index ? val : op->val[0]);
456 else if (op->index == 0)
457 val = fold_ternary (op->code, op->type,
458 val, op->val[0], op->val[1]);
459 else if (op->index == 1)
460 val = fold_ternary (op->code, op->type,
461 op->val[0], val, op->val[1]);
462 else if (op->index == 2)
463 val = fold_ternary (op->code, op->type,
464 op->val[0], op->val[1], val);
465 else
466 val = NULL_TREE;
467 }
468
469 res = val
470 ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
471 : NULL;
472
473 if (res && integer_zerop (res))
474 continue;
475 if (res && integer_onep (res))
476 {
2d01bef2
ML
477 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
478 nonspec_clause
479 |= 1 << (i + ipa_predicate::first_dynamic_condition);
68718e8e
JH
480 continue;
481 }
4307a485 482 }
9d5af1db 483 if (c->operand_num < (int) avals->m_known_value_ranges.length ()
68718e8e 484 && !c->agg_contents
68718e8e
JH
485 && (!val || TREE_CODE (val) != INTEGER_CST))
486 {
9d5af1db
MJ
487 value_range vr = avals->m_known_value_ranges[c->operand_num];
488 if (!vr.undefined_p ()
489 && !vr.varying_p ()
490 && (TYPE_SIZE (c->type) == TYPE_SIZE (vr.type ())))
68718e8e 491 {
9d5af1db
MJ
492 if (!useless_type_conversion_p (c->type, vr.type ()))
493 {
494 value_range res;
495 range_fold_unary_expr (&res, NOP_EXPR,
68718e8e 496 c->type, &vr, vr.type ());
9d5af1db
MJ
497 vr = res;
498 }
499 tree type = c->type;
4307a485 500
9d5af1db
MJ
501 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
502 {
503 if (vr.varying_p () || vr.undefined_p ())
504 break;
27d020cf 505
9d5af1db
MJ
506 value_range res;
507 if (!op->val[0])
508 range_fold_unary_expr (&res, op->code, op->type, &vr, type);
509 else if (!op->val[1])
510 {
511 value_range op0 (op->val[0], op->val[0]);
512 range_fold_binary_expr (&res, op->code, op->type,
513 op->index ? &op0 : &vr,
514 op->index ? &vr : &op0);
515 }
516 else
3b61f06b 517 res.set_varying (op->type);
9d5af1db
MJ
518 type = op->type;
519 vr = res;
520 }
521 if (!vr.varying_p () && !vr.undefined_p ())
68718e8e 522 {
9d5af1db
MJ
523 value_range res;
524 value_range val_vr (c->val, c->val);
525 range_fold_binary_expr (&res, c->code, boolean_type_node,
526 &vr,
527 &val_vr);
528 if (res.zero_p ())
529 continue;
68718e8e 530 }
68718e8e
JH
531 }
532 }
27d020cf 533
2d01bef2
ML
534 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
535 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
27d020cf
JH
536 }
537 *ret_clause = clause;
538 if (ret_nonspec_clause)
539 *ret_nonspec_clause = nonspec_clause;
540}
541
2523d721
JH
542/* Return true if VRP will be exectued on the function.
543 We do not want to anticipate optimizations that will not happen.
544
545 FIXME: This can be confused with -fdisable and debug counters and thus
546 it should not be used for correctness (only to make heuristics work).
547 This means that inliner should do its own optimizations of expressions
548 that it predicts to be constant so wrong code can not be triggered by
549 builtin_constant_p. */
550
551static bool
552vrp_will_run_p (struct cgraph_node *node)
553{
554 return (opt_for_fn (node->decl, optimize)
555 && !opt_for_fn (node->decl, optimize_debug)
556 && opt_for_fn (node->decl, flag_tree_vrp));
557}
558
559/* Similarly about FRE. */
560
561static bool
562fre_will_run_p (struct cgraph_node *node)
563{
564 return (opt_for_fn (node->decl, optimize)
565 && !opt_for_fn (node->decl, optimize_debug)
566 && opt_for_fn (node->decl, flag_tree_fre));
567}
27d020cf 568
b0d55476
JH
569/* Work out what conditions might be true at invocation of E.
570 Compute costs for inlined edge if INLINE_P is true.
571
956d615d 572 Return in CLAUSE_PTR the evaluated conditions and in NONSPEC_CLAUSE_PTR
b0d55476
JH
573 (if non-NULL) conditions evaluated for nonspecialized clone called
574 in a given context.
575
9d5af1db
MJ
576 Vectors in AVALS will be populated with useful known information about
577 argument values - information not known to have any uses will be omitted -
578 except for m_known_contexts which will only be calculated if
579 COMPUTE_CONTEXTS is true. */
27d020cf
JH
580
581void
582evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
583 clause_t *clause_ptr,
584 clause_t *nonspec_clause_ptr,
9d5af1db
MJ
585 ipa_auto_call_arg_values *avals,
586 bool compute_contexts)
27d020cf
JH
587{
588 struct cgraph_node *callee = e->callee->ultimate_alias_target ();
99b1c316 589 class ipa_fn_summary *info = ipa_fn_summaries->get (callee);
a33c028e 590 class ipa_edge_args *args;
27d020cf
JH
591
592 if (clause_ptr)
2d01bef2 593 *clause_ptr = inline_p ? 0 : 1 << ipa_predicate::not_inlined_condition;
27d020cf
JH
594
595 if (ipa_node_params_sum
596 && !e->call_stmt_cannot_inline_p
9d5af1db 597 && (info->conds || compute_contexts)
a4a3cdd0 598 && (args = ipa_edge_args_sum->get (e)) != NULL)
27d020cf 599 {
eb270950 600 struct cgraph_node *caller;
b0d55476 601 class ipa_node_params *caller_parms_info, *callee_pi = NULL;
99b1c316 602 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
603 int i, count = ipa_get_cs_argument_count (args);
604
b0d55476
JH
605 if (count)
606 {
607 if (e->caller->inlined_to)
608 caller = e->caller->inlined_to;
609 else
610 caller = e->caller;
a4a3cdd0
MJ
611 caller_parms_info = ipa_node_params_sum->get (caller);
612 callee_pi = ipa_node_params_sum->get (callee);
b0d55476
JH
613
614 /* Watch for thunks. */
615 if (callee_pi)
616 /* Watch for variadic functions. */
617 count = MIN (count, ipa_get_param_count (callee_pi));
618 }
27d020cf 619
6cf67b62
JH
620 if (callee_pi)
621 for (i = 0; i < count; i++)
622 {
623 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
6cf67b62 624
b0d55476
JH
625 if (ipa_is_param_used_by_indirect_call (callee_pi, i)
626 || ipa_is_param_used_by_ipa_predicates (callee_pi, i))
6cf67b62 627 {
b0d55476
JH
628 /* Determine if we know constant value of the parameter. */
629 tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
630 ipa_get_type (callee_pi, i));
631
632 if (!cst && e->call_stmt
633 && i < (int)gimple_call_num_args (e->call_stmt))
634 {
635 cst = gimple_call_arg (e->call_stmt, i);
636 if (!is_gimple_min_invariant (cst))
637 cst = NULL;
638 }
639 if (cst)
640 {
641 gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
9d5af1db
MJ
642 if (!avals->m_known_vals.length ())
643 avals->m_known_vals.safe_grow_cleared (count, true);
644 avals->m_known_vals[i] = cst;
b0d55476
JH
645 }
646 else if (inline_p && !es->param[i].change_prob)
647 {
9d5af1db
MJ
648 if (!avals->m_known_vals.length ())
649 avals->m_known_vals.safe_grow_cleared (count, true);
650 avals->m_known_vals[i] = error_mark_node;
b0d55476
JH
651 }
652
653 /* If we failed to get simple constant, try value range. */
654 if ((!cst || TREE_CODE (cst) != INTEGER_CST)
2523d721 655 && vrp_will_run_p (caller)
b0d55476
JH
656 && ipa_is_param_used_by_ipa_predicates (callee_pi, i))
657 {
9d5af1db 658 value_range vr
b0d55476
JH
659 = ipa_value_range_from_jfunc (caller_parms_info, e, jf,
660 ipa_get_type (callee_pi,
661 i));
662 if (!vr.undefined_p () && !vr.varying_p ())
663 {
9d5af1db 664 if (!avals->m_known_value_ranges.length ())
4ba9fb0a 665 {
9d5af1db 666 avals->m_known_value_ranges.safe_grow (count, true);
4ba9fb0a 667 for (int i = 0; i < count; ++i)
9d5af1db
MJ
668 new (&avals->m_known_value_ranges[i])
669 value_range ();
4ba9fb0a 670 }
9d5af1db 671 avals->m_known_value_ranges[i] = vr;
b0d55476
JH
672 }
673 }
674
675 /* Determine known aggregate values. */
21e28527 676 if (fre_will_run_p (caller))
b0d55476 677 {
2523d721
JH
678 ipa_agg_value_set agg
679 = ipa_agg_value_set_from_jfunc (caller_parms_info,
680 caller, &jf->agg);
681 if (agg.items.length ())
682 {
9d5af1db
MJ
683 if (!avals->m_known_aggs.length ())
684 avals->m_known_aggs.safe_grow_cleared (count, true);
685 avals->m_known_aggs[i] = agg;
2523d721 686 }
b0d55476 687 }
6cf67b62 688 }
b0d55476
JH
689
690 /* For calls used in polymorphic calls we further determine
691 polymorphic call context. */
9d5af1db 692 if (compute_contexts
b0d55476 693 && ipa_is_param_used_by_polymorphic_call (callee_pi, i))
6cf67b62 694 {
b0d55476
JH
695 ipa_polymorphic_call_context
696 ctx = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
697 if (!ctx.useless_p ())
698 {
9d5af1db
MJ
699 if (!avals->m_known_contexts.length ())
700 avals->m_known_contexts.safe_grow_cleared (count, true);
701 avals->m_known_contexts[i]
b0d55476
JH
702 = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
703 }
704 }
6cf67b62
JH
705 }
706 else
67f3791f 707 gcc_assert (!count || callee->thunk);
27d020cf 708 }
b0d55476 709 else if (e->call_stmt && !e->call_stmt_cannot_inline_p && info->conds)
27d020cf
JH
710 {
711 int i, count = (int)gimple_call_num_args (e->call_stmt);
712
27d020cf
JH
713 for (i = 0; i < count; i++)
714 {
715 tree cst = gimple_call_arg (e->call_stmt, i);
716 if (!is_gimple_min_invariant (cst))
717 cst = NULL;
718 if (cst)
b0d55476 719 {
9d5af1db
MJ
720 if (!avals->m_known_vals.length ())
721 avals->m_known_vals.safe_grow_cleared (count, true);
722 avals->m_known_vals[i] = cst;
b0d55476 723 }
27d020cf
JH
724 }
725 }
726
9d5af1db 727 evaluate_conditions_for_known_args (callee, inline_p, avals, clause_ptr,
27d020cf 728 nonspec_clause_ptr);
27d020cf
JH
729}
730
731
0bceb671 732/* Allocate the function summary. */
27d020cf
JH
733
734static void
0bceb671 735ipa_fn_summary_alloc (void)
27d020cf 736{
0bceb671 737 gcc_checking_assert (!ipa_fn_summaries);
44fca832 738 ipa_size_summaries = new ipa_size_summary_t (symtab);
7237f93e 739 ipa_fn_summaries = ipa_fn_summary_t::create_ggc (symtab);
db30281f 740 ipa_call_summaries = new ipa_call_summary_t (symtab);
27d020cf
JH
741}
742
56f62793 743ipa_call_summary::~ipa_call_summary ()
27d020cf 744{
27d020cf
JH
745 if (predicate)
746 edge_predicate_pool.remove (predicate);
56f62793 747
27d020cf
JH
748 param.release ();
749}
750
56f62793 751ipa_fn_summary::~ipa_fn_summary ()
27d020cf 752{
67ce9099
MJ
753 unsigned len = vec_safe_length (loop_iterations);
754 for (unsigned i = 0; i < len; i++)
755 edge_predicate_pool.remove ((*loop_iterations)[i].predicate);
756 len = vec_safe_length (loop_strides);
757 for (unsigned i = 0; i < len; i++)
758 edge_predicate_pool.remove ((*loop_strides)[i].predicate);
27d020cf 759 vec_free (conds);
366099ff 760 call_size_time_table.release ();
67ce9099
MJ
761 vec_free (loop_iterations);
762 vec_free (loop_strides);
caaa218f 763 builtin_constant_p_parms.release ();
27d020cf
JH
764}
765
27d020cf 766void
56f62793 767ipa_fn_summary_t::remove_callees (cgraph_node *node)
27d020cf 768{
56f62793
ML
769 cgraph_edge *e;
770 for (e = node->callees; e; e = e->next_callee)
771 ipa_call_summaries->remove (e);
772 for (e = node->indirect_calls; e; e = e->next_callee)
773 ipa_call_summaries->remove (e);
27d020cf
JH
774}
775
67ce9099
MJ
776/* Duplicate predicates in loop hint vector, allocating memory for them and
777 remove and deallocate any uninteresting (true or false) ones. Return the
778 result. */
27d020cf 779
67ce9099
MJ
780static vec<ipa_freqcounting_predicate, va_gc> *
781remap_freqcounting_preds_after_dup (vec<ipa_freqcounting_predicate, va_gc> *v,
782 clause_t possible_truths)
27d020cf 783{
67ce9099
MJ
784 if (vec_safe_length (v) == 0)
785 return NULL;
27d020cf 786
67ce9099
MJ
787 vec<ipa_freqcounting_predicate, va_gc> *res = v->copy ();
788 int len = res->length();
789 for (int i = len - 1; i >= 0; i--)
790 {
2d01bef2 791 ipa_predicate new_predicate
67ce9099
MJ
792 = (*res)[i].predicate->remap_after_duplication (possible_truths);
793 /* We do not want to free previous predicate; it is used by node
794 origin. */
795 (*res)[i].predicate = NULL;
796 set_hint_predicate (&(*res)[i].predicate, new_predicate);
797
798 if (!(*res)[i].predicate)
799 res->unordered_remove (i);
800 }
27d020cf 801
67ce9099 802 return res;
27d020cf
JH
803}
804
805
806/* Hook that is called by cgraph.c when a node is duplicated. */
807void
0bceb671 808ipa_fn_summary_t::duplicate (cgraph_node *src,
27d020cf 809 cgraph_node *dst,
366099ff 810 ipa_fn_summary *src_info,
0bceb671 811 ipa_fn_summary *info)
27d020cf 812{
366099ff 813 new (info) ipa_fn_summary (*src_info);
27d020cf
JH
814 /* TODO: as an optimization, we may avoid copying conditions
815 that are known to be false or true. */
816 info->conds = vec_safe_copy (info->conds);
817
ae7a23a3 818 clone_info *cinfo = clone_info::get (dst);
27d020cf
JH
819 /* When there are any replacements in the function body, see if we can figure
820 out that something was optimized out. */
ae7a23a3 821 if (ipa_node_params_sum && cinfo && cinfo->tree_map)
27d020cf 822 {
27d020cf 823 /* Use SRC parm info since it may not be copied yet. */
a4a3cdd0 824 ipa_node_params *parms_info = ipa_node_params_sum->get (src);
9d5af1db 825 ipa_auto_call_arg_values avals;
27d020cf
JH
826 int count = ipa_get_param_count (parms_info);
827 int i, j;
828 clause_t possible_truths;
2d01bef2 829 ipa_predicate true_pred = true;
27d020cf
JH
830 size_time_entry *e;
831 int optimized_out_size = 0;
832 bool inlined_to_p = false;
833 struct cgraph_edge *edge, *next;
834
366099ff 835 info->size_time_table.release ();
9d5af1db 836 avals.m_known_vals.safe_grow_cleared (count, true);
27d020cf
JH
837 for (i = 0; i < count; i++)
838 {
839 struct ipa_replace_map *r;
840
ae7a23a3 841 for (j = 0; vec_safe_iterate (cinfo->tree_map, j, &r); j++)
27d020cf 842 {
ff6686d2 843 if (r->parm_num == i)
27d020cf 844 {
9d5af1db 845 avals.m_known_vals[i] = r->new_tree;
27d020cf
JH
846 break;
847 }
848 }
849 }
850 evaluate_conditions_for_known_args (dst, false,
9d5af1db 851 &avals,
27d020cf
JH
852 &possible_truths,
853 /* We are going to specialize,
854 so ignore nonspec truths. */
855 NULL);
27d020cf
JH
856
857 info->account_size_time (0, 0, true_pred, true_pred);
858
859 /* Remap size_time vectors.
956d615d 860 Simplify the predicate by pruning out alternatives that are known
27d020cf
JH
861 to be false.
862 TODO: as on optimization, we can also eliminate conditions known
863 to be true. */
366099ff 864 for (i = 0; src_info->size_time_table.iterate (i, &e); i++)
27d020cf 865 {
2d01bef2
ML
866 ipa_predicate new_exec_pred;
867 ipa_predicate new_nonconst_pred;
27d020cf
JH
868 new_exec_pred = e->exec_predicate.remap_after_duplication
869 (possible_truths);
870 new_nonconst_pred = e->nonconst_predicate.remap_after_duplication
871 (possible_truths);
872 if (new_exec_pred == false || new_nonconst_pred == false)
873 optimized_out_size += e->size;
874 else
875 info->account_size_time (e->size, e->time, new_exec_pred,
876 new_nonconst_pred);
877 }
878
879 /* Remap edge predicates with the same simplification as above.
880 Also copy constantness arrays. */
881 for (edge = dst->callees; edge; edge = next)
882 {
2d01bef2 883 ipa_predicate new_predicate;
7237f93e 884 class ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf
JH
885 next = edge->next_callee;
886
887 if (!edge->inline_failed)
888 inlined_to_p = true;
889 if (!es->predicate)
890 continue;
891 new_predicate = es->predicate->remap_after_duplication
892 (possible_truths);
893 if (new_predicate == false && *es->predicate != false)
0bceb671 894 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
27d020cf
JH
895 edge_set_predicate (edge, &new_predicate);
896 }
897
956d615d 898 /* Remap indirect edge predicates with the same simplification as above.
27d020cf
JH
899 Also copy constantness arrays. */
900 for (edge = dst->indirect_calls; edge; edge = next)
901 {
2d01bef2 902 ipa_predicate new_predicate;
7237f93e 903 class ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf
JH
904 next = edge->next_callee;
905
906 gcc_checking_assert (edge->inline_failed);
907 if (!es->predicate)
908 continue;
909 new_predicate = es->predicate->remap_after_duplication
910 (possible_truths);
911 if (new_predicate == false && *es->predicate != false)
caaa218f
JH
912 optimized_out_size
913 += es->call_stmt_size * ipa_fn_summary::size_scale;
27d020cf
JH
914 edge_set_predicate (edge, &new_predicate);
915 }
67ce9099
MJ
916 info->loop_iterations
917 = remap_freqcounting_preds_after_dup (info->loop_iterations,
27d020cf 918 possible_truths);
67ce9099
MJ
919 info->loop_strides
920 = remap_freqcounting_preds_after_dup (info->loop_strides,
27d020cf 921 possible_truths);
caaa218f
JH
922 if (info->builtin_constant_p_parms.length())
923 {
924 vec <int, va_heap, vl_ptr> parms = info->builtin_constant_p_parms;
925 int ip;
926 info->builtin_constant_p_parms = vNULL;
927 for (i = 0; parms.iterate (i, &ip); i++)
928 if (!avals.m_known_vals[ip])
929 info->builtin_constant_p_parms.safe_push (ip);
930 }
27d020cf
JH
931
932 /* If inliner or someone after inliner will ever start producing
933 non-trivial clones, we will get trouble with lack of information
934 about updating self sizes, because size vectors already contains
956d615d 935 sizes of the callees. */
27d020cf
JH
936 gcc_assert (!inlined_to_p || !optimized_out_size);
937 }
938 else
939 {
366099ff
JH
940 info->size_time_table = src_info->size_time_table.copy ();
941 info->loop_iterations = vec_safe_copy (src_info->loop_iterations);
67ce9099
MJ
942 info->loop_strides = vec_safe_copy (info->loop_strides);
943
caaa218f
JH
944 info->builtin_constant_p_parms
945 = info->builtin_constant_p_parms.copy ();
946
67ce9099
MJ
947 ipa_freqcounting_predicate *f;
948 for (int i = 0; vec_safe_iterate (info->loop_iterations, i, &f); i++)
27d020cf 949 {
2d01bef2 950 ipa_predicate p = *f->predicate;
67ce9099
MJ
951 f->predicate = NULL;
952 set_hint_predicate (&f->predicate, p);
27d020cf 953 }
67ce9099 954 for (int i = 0; vec_safe_iterate (info->loop_strides, i, &f); i++)
27d020cf 955 {
2d01bef2 956 ipa_predicate p = *f->predicate;
67ce9099
MJ
957 f->predicate = NULL;
958 set_hint_predicate (&f->predicate, p);
27d020cf 959 }
27d020cf 960 }
a62bfab5 961 if (!dst->inlined_to)
0bceb671 962 ipa_update_overall_fn_summary (dst);
27d020cf
JH
963}
964
965
966/* Hook that is called by cgraph.c when a node is duplicated. */
967
968void
969ipa_call_summary_t::duplicate (struct cgraph_edge *src,
970 struct cgraph_edge *dst,
99b1c316
MS
971 class ipa_call_summary *srcinfo,
972 class ipa_call_summary *info)
27d020cf 973{
56f62793 974 new (info) ipa_call_summary (*srcinfo);
27d020cf
JH
975 info->predicate = NULL;
976 edge_set_predicate (dst, srcinfo->predicate);
977 info->param = srcinfo->param.copy ();
978 if (!dst->indirect_unknown_callee && src->indirect_unknown_callee)
979 {
980 info->call_stmt_size -= (eni_size_weights.indirect_call_cost
981 - eni_size_weights.call_cost);
982 info->call_stmt_time -= (eni_time_weights.indirect_call_cost
983 - eni_time_weights.call_cost);
984 }
985}
986
27d020cf
JH
987/* Dump edge summaries associated to NODE and recursively to all clones.
988 Indent by INDENT. */
989
990static void
991dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
99b1c316 992 class ipa_fn_summary *info)
27d020cf
JH
993{
994 struct cgraph_edge *edge;
995 for (edge = node->callees; edge; edge = edge->next_callee)
996 {
99b1c316 997 class ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf
JH
998 struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
999 int i;
1000
1001 fprintf (f,
d597b944
ML
1002 "%*s%s %s\n%*s freq:%4.2f",
1003 indent, "", callee->dump_name (),
27d020cf
JH
1004 !edge->inline_failed
1005 ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
7237f93e
JH
1006 indent, "", edge->sreal_frequency ().to_double ());
1007
b74d8dc4
JH
1008 if (cross_module_call_p (edge))
1009 fprintf (f, " cross module");
1010
7237f93e
JH
1011 if (es)
1012 fprintf (f, " loop depth:%2i size:%2i time: %2i",
1013 es->loop_depth, es->call_stmt_size, es->call_stmt_time);
56f62793
ML
1014
1015 ipa_fn_summary *s = ipa_fn_summaries->get (callee);
f658ad30 1016 ipa_size_summary *ss = ipa_size_summaries->get (callee);
56f62793 1017 if (s != NULL)
f658ad30
JH
1018 fprintf (f, " callee size:%2i stack:%2i",
1019 (int) (ss->size / ipa_fn_summary::size_scale),
56f62793 1020 (int) s->estimated_stack_size);
27d020cf 1021
7237f93e 1022 if (es && es->predicate)
27d020cf
JH
1023 {
1024 fprintf (f, " predicate: ");
1025 es->predicate->dump (f, info->conds);
1026 }
1027 else
1028 fprintf (f, "\n");
7237f93e 1029 if (es && es->param.exists ())
27d020cf
JH
1030 for (i = 0; i < (int) es->param.length (); i++)
1031 {
1032 int prob = es->param[i].change_prob;
1033
1034 if (!prob)
1035 fprintf (f, "%*s op%i is compile time invariant\n",
1036 indent + 2, "", i);
1037 else if (prob != REG_BR_PROB_BASE)
1038 fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i,
1039 prob * 100.0 / REG_BR_PROB_BASE);
b89e4559
JH
1040 if (es->param[i].points_to_local_or_readonly_memory)
1041 fprintf (f, "%*s op%i points to local or readonly memory\n",
1042 indent + 2, "", i);
27d020cf
JH
1043 }
1044 if (!edge->inline_failed)
1045 {
f658ad30
JH
1046 ipa_size_summary *ss = ipa_size_summaries->get (callee);
1047 fprintf (f, "%*sStack frame offset %i, callee self size %i\n",
27d020cf 1048 indent + 2, "",
f658ad30
JH
1049 (int) ipa_get_stack_frame_offset (callee),
1050 (int) ss->estimated_self_stack_size);
27d020cf
JH
1051 dump_ipa_call_summary (f, indent + 2, callee, info);
1052 }
1053 }
1054 for (edge = node->indirect_calls; edge; edge = edge->next_callee)
1055 {
99b1c316 1056 class ipa_call_summary *es = ipa_call_summaries->get (edge);
41f0e819 1057 fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
27d020cf
JH
1058 " time: %2i",
1059 indent, "",
1060 es->loop_depth,
41f0e819
JH
1061 edge->sreal_frequency ().to_double (), es->call_stmt_size,
1062 es->call_stmt_time);
27d020cf
JH
1063 if (es->predicate)
1064 {
1065 fprintf (f, "predicate: ");
1066 es->predicate->dump (f, info->conds);
1067 }
1068 else
1069 fprintf (f, "\n");
1070 }
1071}
1072
1073
1074void
0bceb671 1075ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
27d020cf
JH
1076{
1077 if (node->definition)
1078 {
99b1c316 1079 class ipa_fn_summary *s = ipa_fn_summaries->get (node);
f658ad30 1080 class ipa_size_summary *ss = ipa_size_summaries->get (node);
56f62793 1081 if (s != NULL)
27d020cf 1082 {
56f62793
ML
1083 size_time_entry *e;
1084 int i;
1085 fprintf (f, "IPA function summary for %s", node->dump_name ());
1086 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
1087 fprintf (f, " always_inline");
1088 if (s->inlinable)
1089 fprintf (f, " inlinable");
1090 if (s->fp_expressions)
1091 fprintf (f, " fp_expression");
caaa218f
JH
1092 if (s->builtin_constant_p_parms.length ())
1093 {
1094 fprintf (f, " builtin_constant_p_parms");
1095 for (unsigned int i = 0;
1096 i < s->builtin_constant_p_parms.length (); i++)
1097 fprintf (f, " %i", s->builtin_constant_p_parms[i]);
1098 }
56f62793 1099 fprintf (f, "\n global time: %f\n", s->time.to_double ());
f658ad30
JH
1100 fprintf (f, " self size: %i\n", ss->self_size);
1101 fprintf (f, " global size: %i\n", ss->size);
56f62793
ML
1102 fprintf (f, " min size: %i\n", s->min_size);
1103 fprintf (f, " self stack: %i\n",
f658ad30 1104 (int) ss->estimated_self_stack_size);
56f62793
ML
1105 fprintf (f, " global stack: %i\n", (int) s->estimated_stack_size);
1106 if (s->growth)
1107 fprintf (f, " estimated growth:%i\n", (int) s->growth);
1108 if (s->scc_no)
1109 fprintf (f, " In SCC: %i\n", (int) s->scc_no);
366099ff 1110 for (i = 0; s->size_time_table.iterate (i, &e); i++)
56f62793
ML
1111 {
1112 fprintf (f, " size:%f, time:%f",
1113 (double) e->size / ipa_fn_summary::size_scale,
1114 e->time.to_double ());
1115 if (e->exec_predicate != true)
1116 {
1117 fprintf (f, ", executed if:");
1118 e->exec_predicate.dump (f, s->conds, 0);
1119 }
1120 if (e->exec_predicate != e->nonconst_predicate)
1121 {
1122 fprintf (f, ", nonconst if:");
1123 e->nonconst_predicate.dump (f, s->conds, 0);
1124 }
1125 fprintf (f, "\n");
1126 }
67ce9099
MJ
1127 ipa_freqcounting_predicate *fcp;
1128 bool first_fcp = true;
1129 for (int i = 0; vec_safe_iterate (s->loop_iterations, i, &fcp); i++)
27d020cf 1130 {
67ce9099
MJ
1131 if (first_fcp)
1132 {
1133 fprintf (f, " loop iterations:");
1134 first_fcp = false;
1135 }
1136 fprintf (f, " %3.2f for ", fcp->freq.to_double ());
1137 fcp->predicate->dump (f, s->conds);
27d020cf 1138 }
67ce9099
MJ
1139 first_fcp = true;
1140 for (int i = 0; vec_safe_iterate (s->loop_strides, i, &fcp); i++)
27d020cf 1141 {
67ce9099
MJ
1142 if (first_fcp)
1143 {
1144 fprintf (f, " loop strides:");
1145 first_fcp = false;
1146 }
1147 fprintf (f, " %3.2f for :", fcp->freq.to_double ());
1148 fcp->predicate->dump (f, s->conds);
27d020cf 1149 }
56f62793
ML
1150 fprintf (f, " calls:\n");
1151 dump_ipa_call_summary (f, 4, node, s);
27d020cf 1152 fprintf (f, "\n");
0fc60c18
KL
1153 if (s->target_info)
1154 fprintf (f, " target_info: %x\n", s->target_info);
27d020cf 1155 }
56f62793
ML
1156 else
1157 fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
27d020cf
JH
1158 }
1159}
1160
1161DEBUG_FUNCTION void
0bceb671 1162ipa_debug_fn_summary (struct cgraph_node *node)
27d020cf 1163{
0bceb671 1164 ipa_dump_fn_summary (stderr, node);
27d020cf
JH
1165}
1166
1167void
0bceb671 1168ipa_dump_fn_summaries (FILE *f)
27d020cf
JH
1169{
1170 struct cgraph_node *node;
1171
1172 FOR_EACH_DEFINED_FUNCTION (node)
a62bfab5 1173 if (!node->inlined_to)
0bceb671 1174 ipa_dump_fn_summary (f, node);
27d020cf
JH
1175}
1176
1177/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
1178 boolean variable pointed to by DATA. */
1179
1180static bool
1181mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
1182 void *data)
1183{
1184 bool *b = (bool *) data;
1185 *b = true;
1186 return true;
1187}
1188
1189/* If OP refers to value of function parameter, return the corresponding
1190 parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
1191 PARM_DECL) will be stored to *SIZE_P in that case too. */
1192
1193static tree
c628d1c3 1194unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
86003645 1195 poly_int64 *size_p)
27d020cf
JH
1196{
1197 /* SSA_NAME referring to parm default def? */
1198 if (TREE_CODE (op) == SSA_NAME
1199 && SSA_NAME_IS_DEFAULT_DEF (op)
1200 && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
1201 {
1202 if (size_p)
86003645 1203 *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
27d020cf
JH
1204 return SSA_NAME_VAR (op);
1205 }
1206 /* Non-SSA parm reference? */
6cc886bf
RB
1207 if (TREE_CODE (op) == PARM_DECL
1208 && fbi->aa_walk_budget > 0)
27d020cf
JH
1209 {
1210 bool modified = false;
1211
1212 ao_ref refd;
1213 ao_ref_init (&refd, op);
c628d1c3
MJ
1214 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
1215 mark_modified, &modified, NULL, NULL,
6cc886bf 1216 fbi->aa_walk_budget);
c628d1c3
MJ
1217 if (walked < 0)
1218 {
1219 fbi->aa_walk_budget = 0;
1220 return NULL_TREE;
1221 }
6cc886bf 1222 fbi->aa_walk_budget -= walked;
27d020cf
JH
1223 if (!modified)
1224 {
1225 if (size_p)
86003645 1226 *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
27d020cf
JH
1227 return op;
1228 }
1229 }
1230 return NULL_TREE;
1231}
1232
1233/* If OP refers to value of function parameter, return the corresponding
1234 parameter. Also traverse chains of SSA register assignments. If non-NULL,
1235 the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
1236 stored to *SIZE_P in that case too. */
1237
1238static tree
c628d1c3 1239unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
86003645 1240 poly_int64 *size_p)
27d020cf 1241{
c628d1c3 1242 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
27d020cf
JH
1243 if (res)
1244 return res;
1245
1246 if (TREE_CODE (op) == SSA_NAME
1247 && !SSA_NAME_IS_DEFAULT_DEF (op)
1248 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
c628d1c3 1249 return unmodified_parm (fbi, SSA_NAME_DEF_STMT (op),
27d020cf
JH
1250 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
1251 size_p);
1252 return NULL_TREE;
1253}
1254
1255/* If OP refers to a value of a function parameter or value loaded from an
1256 aggregate passed to a parameter (either by value or reference), return TRUE
1257 and store the number of the parameter to *INDEX_P, the access size into
1258 *SIZE_P, and information whether and how it has been loaded from an
1259 aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
1260 statement in which OP is used or loaded. */
1261
1262static bool
1263unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
1264 gimple *stmt, tree op, int *index_p,
86003645 1265 poly_int64 *size_p,
27d020cf
JH
1266 struct agg_position_info *aggpos)
1267{
c628d1c3 1268 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
27d020cf
JH
1269
1270 gcc_checking_assert (aggpos);
1271 if (res)
1272 {
1273 *index_p = ipa_get_param_decl_index (fbi->info, res);
1274 if (*index_p < 0)
1275 return false;
1276 aggpos->agg_contents = false;
1277 aggpos->by_ref = false;
1278 return true;
1279 }
1280
1281 if (TREE_CODE (op) == SSA_NAME)
1282 {
1283 if (SSA_NAME_IS_DEFAULT_DEF (op)
1284 || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1285 return false;
1286 stmt = SSA_NAME_DEF_STMT (op);
1287 op = gimple_assign_rhs1 (stmt);
1288 if (!REFERENCE_CLASS_P (op))
1289 return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
1290 aggpos);
1291 }
1292
1293 aggpos->agg_contents = true;
1294 return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
1295 stmt, op, index_p, &aggpos->offset,
1296 size_p, &aggpos->by_ref);
1297}
1298
1299/* See if statement might disappear after inlining.
1300 0 - means not eliminated
1301 1 - half of statements goes away
1302 2 - for sure it is eliminated.
1303 We are not terribly sophisticated, basically looking for simple abstraction
1304 penalty wrappers. */
1305
1306static int
c628d1c3 1307eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
27d020cf
JH
1308{
1309 enum gimple_code code = gimple_code (stmt);
1310 enum tree_code rhs_code;
1311
1312 if (!optimize)
1313 return 0;
1314
1315 switch (code)
1316 {
1317 case GIMPLE_RETURN:
1318 return 2;
1319 case GIMPLE_ASSIGN:
1320 if (gimple_num_ops (stmt) != 2)
1321 return 0;
1322
1323 rhs_code = gimple_assign_rhs_code (stmt);
1324
1325 /* Casts of parameters, loads from parameters passed by reference
1326 and stores to return value or parameters are often free after
956d615d 1327 inlining due to SRA and further combining.
27d020cf
JH
1328 Assume that half of statements goes away. */
1329 if (CONVERT_EXPR_CODE_P (rhs_code)
1330 || rhs_code == VIEW_CONVERT_EXPR
1331 || rhs_code == ADDR_EXPR
1332 || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1333 {
1334 tree rhs = gimple_assign_rhs1 (stmt);
1335 tree lhs = gimple_assign_lhs (stmt);
1336 tree inner_rhs = get_base_address (rhs);
1337 tree inner_lhs = get_base_address (lhs);
1338 bool rhs_free = false;
1339 bool lhs_free = false;
1340
1341 if (!inner_rhs)
1342 inner_rhs = rhs;
1343 if (!inner_lhs)
1344 inner_lhs = lhs;
1345
1346 /* Reads of parameter are expected to be free. */
c628d1c3 1347 if (unmodified_parm (fbi, stmt, inner_rhs, NULL))
27d020cf
JH
1348 rhs_free = true;
1349 /* Match expressions of form &this->field. Those will most likely
1350 combine with something upstream after inlining. */
1351 else if (TREE_CODE (inner_rhs) == ADDR_EXPR)
1352 {
1353 tree op = get_base_address (TREE_OPERAND (inner_rhs, 0));
1354 if (TREE_CODE (op) == PARM_DECL)
1355 rhs_free = true;
1356 else if (TREE_CODE (op) == MEM_REF
c628d1c3
MJ
1357 && unmodified_parm (fbi, stmt, TREE_OPERAND (op, 0),
1358 NULL))
27d020cf
JH
1359 rhs_free = true;
1360 }
1361
1362 /* When parameter is not SSA register because its address is taken
1363 and it is just copied into one, the statement will be completely
1364 free after inlining (we will copy propagate backward). */
1365 if (rhs_free && is_gimple_reg (lhs))
1366 return 2;
1367
1368 /* Reads of parameters passed by reference
1369 expected to be free (i.e. optimized out after inlining). */
1370 if (TREE_CODE (inner_rhs) == MEM_REF
c628d1c3 1371 && unmodified_parm (fbi, stmt, TREE_OPERAND (inner_rhs, 0), NULL))
27d020cf
JH
1372 rhs_free = true;
1373
1374 /* Copying parameter passed by reference into gimple register is
1375 probably also going to copy propagate, but we can't be quite
1376 sure. */
1377 if (rhs_free && is_gimple_reg (lhs))
1378 lhs_free = true;
1379
1380 /* Writes to parameters, parameters passed by value and return value
956d615d 1381 (either directly or passed via invisible reference) are free.
27d020cf
JH
1382
1383 TODO: We ought to handle testcase like
1384 struct a {int a,b;};
1385 struct a
956d615d 1386 returnstruct (void)
27d020cf
JH
1387 {
1388 struct a a ={1,2};
1389 return a;
1390 }
1391
1392 This translate into:
1393
956d615d 1394 returnstruct ()
27d020cf
JH
1395 {
1396 int a$b;
1397 int a$a;
1398 struct a a;
1399 struct a D.2739;
1400
1401 <bb 2>:
1402 D.2739.a = 1;
1403 D.2739.b = 2;
1404 return D.2739;
1405
1406 }
1407 For that we either need to copy ipa-split logic detecting writes
1408 to return value. */
1409 if (TREE_CODE (inner_lhs) == PARM_DECL
1410 || TREE_CODE (inner_lhs) == RESULT_DECL
1411 || (TREE_CODE (inner_lhs) == MEM_REF
c628d1c3
MJ
1412 && (unmodified_parm (fbi, stmt, TREE_OPERAND (inner_lhs, 0),
1413 NULL)
27d020cf
JH
1414 || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
1415 && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
1416 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1417 (inner_lhs,
1418 0))) == RESULT_DECL))))
1419 lhs_free = true;
1420 if (lhs_free
1421 && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
1422 rhs_free = true;
1423 if (lhs_free && rhs_free)
1424 return 1;
1425 }
1426 return 0;
1427 default:
1428 return 0;
1429 }
1430}
1431
4307a485
FX
1432/* Analyze EXPR if it represents a series of simple operations performed on
1433 a function parameter and return true if so. FBI, STMT, EXPR, INDEX_P and
1434 AGGPOS have the same meaning like in unmodified_parm_or_parm_agg_item.
1435 Type of the parameter or load from an aggregate via the parameter is
1436 stored in *TYPE_P. Operations on the parameter are recorded to
1437 PARAM_OPS_P if it is not NULL. */
1438
1439static bool
1440decompose_param_expr (struct ipa_func_body_info *fbi,
1441 gimple *stmt, tree expr,
1442 int *index_p, tree *type_p,
1443 struct agg_position_info *aggpos,
1444 expr_eval_ops *param_ops_p = NULL)
1445{
fdfd7f53 1446 int op_limit = opt_for_fn (fbi->node->decl, param_ipa_max_param_expr_ops);
4307a485
FX
1447 int op_count = 0;
1448
1449 if (param_ops_p)
1450 *param_ops_p = NULL;
1451
1452 while (true)
1453 {
1454 expr_eval_op eval_op;
1455 unsigned rhs_count;
1456 unsigned cst_count = 0;
1457
1458 if (unmodified_parm_or_parm_agg_item (fbi, stmt, expr, index_p, NULL,
1459 aggpos))
1460 {
1461 tree type = TREE_TYPE (expr);
1462
1463 if (aggpos->agg_contents)
1464 {
1465 /* Stop if containing bit-field. */
1466 if (TREE_CODE (expr) == BIT_FIELD_REF
1467 || contains_bitfld_component_ref_p (expr))
1468 break;
1469 }
1470
1471 *type_p = type;
1472 return true;
1473 }
1474
1475 if (TREE_CODE (expr) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (expr))
1476 break;
1477
1478 if (!is_gimple_assign (stmt = SSA_NAME_DEF_STMT (expr)))
1479 break;
1480
1481 switch (gimple_assign_rhs_class (stmt))
1482 {
1483 case GIMPLE_SINGLE_RHS:
1484 expr = gimple_assign_rhs1 (stmt);
1485 continue;
1486
1487 case GIMPLE_UNARY_RHS:
1488 rhs_count = 1;
1489 break;
1490
1491 case GIMPLE_BINARY_RHS:
1492 rhs_count = 2;
1493 break;
1494
1495 case GIMPLE_TERNARY_RHS:
1496 rhs_count = 3;
1497 break;
1498
1499 default:
1500 goto fail;
1501 }
1502
1503 /* Stop if expression is too complex. */
1504 if (op_count++ == op_limit)
1505 break;
1506
1507 if (param_ops_p)
1508 {
1509 eval_op.code = gimple_assign_rhs_code (stmt);
1510 eval_op.type = TREE_TYPE (gimple_assign_lhs (stmt));
1511 eval_op.val[0] = NULL_TREE;
1512 eval_op.val[1] = NULL_TREE;
1513 }
1514
1515 expr = NULL_TREE;
1516 for (unsigned i = 0; i < rhs_count; i++)
1517 {
1518 tree op = gimple_op (stmt, i + 1);
1519
1520 gcc_assert (op && !TYPE_P (op));
1521 if (is_gimple_ip_invariant (op))
1522 {
1523 if (++cst_count == rhs_count)
1524 goto fail;
1525
1526 eval_op.val[cst_count - 1] = op;
1527 }
1528 else if (!expr)
1529 {
1530 /* Found a non-constant operand, and record its index in rhs
1531 operands. */
1532 eval_op.index = i;
1533 expr = op;
1534 }
1535 else
1536 {
1537 /* Found more than one non-constant operands. */
1538 goto fail;
1539 }
1540 }
1541
1542 if (param_ops_p)
1543 vec_safe_insert (*param_ops_p, 0, eval_op);
1544 }
1545
1546 /* Failed to decompose, free resource and return. */
1547fail:
1548 if (param_ops_p)
1549 vec_free (*param_ops_p);
1550
1551 return false;
1552}
27d020cf 1553
caaa218f
JH
1554/* Record to SUMMARY that PARM is used by builtin_constant_p. */
1555
1556static void
1557add_builtin_constant_p_parm (class ipa_fn_summary *summary, int parm)
1558{
1559 int ip;
1560
1561 /* Avoid duplicates. */
1562 for (unsigned int i = 0;
1563 summary->builtin_constant_p_parms.iterate (i, &ip); i++)
1564 if (ip == parm)
1565 return;
1566 summary->builtin_constant_p_parms.safe_push (parm);
1567}
1568
27d020cf
JH
1569/* If BB ends by a conditional we can turn into predicates, attach corresponding
1570 predicates to the CFG edges. */
1571
1572static void
1573set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
99b1c316 1574 class ipa_fn_summary *summary,
40a777e8 1575 class ipa_node_params *params_summary,
27d020cf
JH
1576 basic_block bb)
1577{
1578 gimple *last;
4307a485 1579 tree op, op2;
27d020cf 1580 int index;
27d020cf
JH
1581 struct agg_position_info aggpos;
1582 enum tree_code code, inverted_code;
1583 edge e;
1584 edge_iterator ei;
1585 gimple *set_stmt;
4307a485
FX
1586 tree param_type;
1587 expr_eval_ops param_ops;
27d020cf
JH
1588
1589 last = last_stmt (bb);
1590 if (!last || gimple_code (last) != GIMPLE_COND)
1591 return;
1592 if (!is_gimple_ip_invariant (gimple_cond_rhs (last)))
1593 return;
1594 op = gimple_cond_lhs (last);
4307a485
FX
1595
1596 if (decompose_param_expr (fbi, last, op, &index, &param_type, &aggpos,
1597 &param_ops))
27d020cf
JH
1598 {
1599 code = gimple_cond_code (last);
1600 inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
1601
1602 FOR_EACH_EDGE (e, ei, bb->succs)
1603 {
1604 enum tree_code this_code = (e->flags & EDGE_TRUE_VALUE
1605 ? code : inverted_code);
1606 /* invert_tree_comparison will return ERROR_MARK on FP
956d615d 1607 comparisons that are not EQ/NE instead of returning proper
efe12656
FX
1608 unordered one. Be sure it is not confused with NON_CONSTANT.
1609
1610 And if the edge's target is the final block of diamond CFG graph
1611 of this conditional statement, we do not need to compute
1612 predicate for the edge because the final block's predicate must
1613 be at least as that of the first block of the statement. */
1614 if (this_code != ERROR_MARK
1615 && !dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
27d020cf 1616 {
2d01bef2 1617 ipa_predicate p
40a777e8
JH
1618 = add_condition (summary, params_summary, index,
1619 param_type, &aggpos,
4307a485 1620 this_code, gimple_cond_rhs (last), param_ops);
27d020cf 1621 e->aux = edge_predicate_pool.allocate ();
2d01bef2 1622 *(ipa_predicate *) e->aux = p;
27d020cf
JH
1623 }
1624 }
4307a485 1625 vec_free (param_ops);
27d020cf
JH
1626 }
1627
1628 if (TREE_CODE (op) != SSA_NAME)
1629 return;
1630 /* Special case
1631 if (builtin_constant_p (op))
1632 constant_code
1633 else
1634 nonconstant_code.
1635 Here we can predicate nonconstant_code. We can't
1636 really handle constant_code since we have no predicate
1637 for this and also the constant code is not known to be
956d615d 1638 optimized away when inliner doesn't see operand is constant.
27d020cf
JH
1639 Other optimizers might think otherwise. */
1640 if (gimple_cond_code (last) != NE_EXPR
1641 || !integer_zerop (gimple_cond_rhs (last)))
1642 return;
1643 set_stmt = SSA_NAME_DEF_STMT (op);
1644 if (!gimple_call_builtin_p (set_stmt, BUILT_IN_CONSTANT_P)
1645 || gimple_call_num_args (set_stmt) != 1)
1646 return;
1647 op2 = gimple_call_arg (set_stmt, 0);
4307a485 1648 if (!decompose_param_expr (fbi, set_stmt, op2, &index, &param_type, &aggpos))
27d020cf 1649 return;
caaa218f
JH
1650 if (!aggpos.by_ref)
1651 add_builtin_constant_p_parm (summary, index);
27d020cf
JH
1652 FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
1653 {
2d01bef2 1654 ipa_predicate p = add_condition (summary, params_summary, index,
40a777e8 1655 param_type, &aggpos,
2d01bef2 1656 ipa_predicate::is_not_constant, NULL_TREE);
27d020cf 1657 e->aux = edge_predicate_pool.allocate ();
2d01bef2 1658 *(ipa_predicate *) e->aux = p;
27d020cf
JH
1659 }
1660}
1661
1662
1663/* If BB ends by a switch we can turn into predicates, attach corresponding
1664 predicates to the CFG edges. */
1665
1666static void
1667set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
99b1c316 1668 class ipa_fn_summary *summary,
40a777e8 1669 class ipa_node_params *params_summary,
27d020cf
JH
1670 basic_block bb)
1671{
1672 gimple *lastg;
1673 tree op;
1674 int index;
27d020cf
JH
1675 struct agg_position_info aggpos;
1676 edge e;
1677 edge_iterator ei;
1678 size_t n;
1679 size_t case_idx;
4307a485
FX
1680 tree param_type;
1681 expr_eval_ops param_ops;
27d020cf
JH
1682
1683 lastg = last_stmt (bb);
1684 if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH)
1685 return;
1686 gswitch *last = as_a <gswitch *> (lastg);
1687 op = gimple_switch_index (last);
4307a485
FX
1688 if (!decompose_param_expr (fbi, last, op, &index, &param_type, &aggpos,
1689 &param_ops))
27d020cf
JH
1690 return;
1691
351e7c3b
FX
1692 auto_vec<std::pair<tree, tree> > ranges;
1693 tree type = TREE_TYPE (op);
fdfd7f53
ML
1694 int bound_limit = opt_for_fn (fbi->node->decl,
1695 param_ipa_max_switch_predicate_bounds);
351e7c3b 1696 int bound_count = 0;
45f4e2b0
AH
1697 value_range vr;
1698
1699 get_range_query (cfun)->range_of_expr (vr, op);
1700 if (vr.undefined_p ())
1701 vr.set_varying (TREE_TYPE (op));
1702 value_range_kind vr_type = vr.kind ();
1703 wide_int vr_wmin = wi::to_wide (vr.min ());
1704 wide_int vr_wmax = wi::to_wide (vr.max ());
351e7c3b 1705
27d020cf
JH
1706 FOR_EACH_EDGE (e, ei, bb->succs)
1707 {
1708 e->aux = edge_predicate_pool.allocate ();
2d01bef2 1709 *(ipa_predicate *) e->aux = false;
27d020cf 1710 }
351e7c3b 1711
efe12656
FX
1712 e = gimple_switch_edge (cfun, last, 0);
1713 /* Set BOUND_COUNT to maximum count to bypass computing predicate for
1714 default case if its target basic block is in convergence point of all
1715 switch cases, which can be determined by checking whether it
1716 post-dominates the switch statement. */
1717 if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
1718 bound_count = INT_MAX;
1719
27d020cf 1720 n = gimple_switch_num_labels (last);
351e7c3b 1721 for (case_idx = 1; case_idx < n; ++case_idx)
27d020cf
JH
1722 {
1723 tree cl = gimple_switch_label (last, case_idx);
efe12656
FX
1724 tree min = CASE_LOW (cl);
1725 tree max = CASE_HIGH (cl);
2d01bef2 1726 ipa_predicate p;
27d020cf 1727
4307a485
FX
1728 e = gimple_switch_edge (cfun, last, case_idx);
1729
efe12656
FX
1730 /* The case value might not have same type as switch expression,
1731 extend the value based on the expression type. */
1732 if (TREE_TYPE (min) != type)
1733 min = wide_int_to_tree (type, wi::to_wide (min));
27d020cf 1734
351e7c3b 1735 if (!max)
efe12656
FX
1736 max = min;
1737 else if (TREE_TYPE (max) != type)
1738 max = wide_int_to_tree (type, wi::to_wide (max));
1739
1740 /* The case's target basic block is in convergence point of all switch
1741 cases, its predicate should be at least as that of the switch
1742 statement. */
1743 if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
1744 p = true;
1745 else if (min == max)
40a777e8
JH
1746 p = add_condition (summary, params_summary, index, param_type,
1747 &aggpos, EQ_EXPR, min, param_ops);
27d020cf
JH
1748 else
1749 {
2d01bef2 1750 ipa_predicate p1, p2;
40a777e8
JH
1751 p1 = add_condition (summary, params_summary, index, param_type,
1752 &aggpos, GE_EXPR, min, param_ops);
1753 p2 = add_condition (summary, params_summary,index, param_type,
1754 &aggpos, LE_EXPR, max, param_ops);
27d020cf
JH
1755 p = p1 & p2;
1756 }
2d01bef2
ML
1757 *(ipa_predicate *) e->aux
1758 = p.or_with (summary->conds, *(ipa_predicate *) e->aux);
351e7c3b
FX
1759
1760 /* If there are too many disjoint case ranges, predicate for default
1761 case might become too complicated. So add a limit here. */
1762 if (bound_count > bound_limit)
1763 continue;
1764
1765 bool new_range = true;
1766
1767 if (!ranges.is_empty ())
1768 {
1769 wide_int curr_wmin = wi::to_wide (min);
1770 wide_int last_wmax = wi::to_wide (ranges.last ().second);
1771
1772 /* Merge case ranges if they are continuous. */
1773 if (curr_wmin == last_wmax + 1)
1774 new_range = false;
1775 else if (vr_type == VR_ANTI_RANGE)
1776 {
1777 /* If two disjoint case ranges can be connected by anti-range
1778 of switch index, combine them to one range. */
1779 if (wi::lt_p (vr_wmax, curr_wmin - 1, TYPE_SIGN (type)))
1780 vr_type = VR_UNDEFINED;
1781 else if (wi::le_p (vr_wmin, last_wmax + 1, TYPE_SIGN (type)))
1782 new_range = false;
1783 }
1784 }
1785
351e7c3b
FX
1786 /* Create/extend a case range. And we count endpoints of range set,
1787 this number nearly equals to number of conditions that we will create
1788 for predicate of default case. */
1789 if (new_range)
1790 {
1791 bound_count += (min == max) ? 1 : 2;
1792 ranges.safe_push (std::make_pair (min, max));
1793 }
1794 else
1795 {
1796 bound_count += (ranges.last ().first == ranges.last ().second);
1797 ranges.last ().second = max;
1798 }
1799 }
1800
1801 e = gimple_switch_edge (cfun, last, 0);
1802 if (bound_count > bound_limit)
1803 {
2d01bef2 1804 *(ipa_predicate *) e->aux = true;
4307a485 1805 vec_free (param_ops);
351e7c3b 1806 return;
27d020cf 1807 }
351e7c3b 1808
2d01bef2
ML
1809 ipa_predicate p_seg = true;
1810 ipa_predicate p_all = false;
351e7c3b
FX
1811
1812 if (vr_type != VR_RANGE)
1813 {
1814 vr_wmin = wi::to_wide (TYPE_MIN_VALUE (type));
1815 vr_wmax = wi::to_wide (TYPE_MAX_VALUE (type));
1816 }
1817
1818 /* Construct predicate to represent default range set that is negation of
1819 all case ranges. Case range is classified as containing single/non-single
1820 values. Suppose a piece of case ranges in the following.
1821
1822 [D1...D2] [S1] ... [Sn] [D3...D4]
1823
1824 To represent default case's range sets between two non-single value
1825 case ranges (From D2 to D3), we construct predicate as:
1826
1827 D2 < x < D3 && x != S1 && ... && x != Sn
1828 */
1829 for (size_t i = 0; i < ranges.length (); i++)
1830 {
1831 tree min = ranges[i].first;
1832 tree max = ranges[i].second;
1833
1834 if (min == max)
40a777e8
JH
1835 p_seg &= add_condition (summary, params_summary, index,
1836 param_type, &aggpos, NE_EXPR,
4307a485 1837 min, param_ops);
351e7c3b
FX
1838 else
1839 {
1840 /* Do not create sub-predicate for range that is beyond low bound
1841 of switch index. */
1842 if (wi::lt_p (vr_wmin, wi::to_wide (min), TYPE_SIGN (type)))
1843 {
40a777e8
JH
1844 p_seg &= add_condition (summary, params_summary, index,
1845 param_type, &aggpos,
4307a485 1846 LT_EXPR, min, param_ops);
351e7c3b
FX
1847 p_all = p_all.or_with (summary->conds, p_seg);
1848 }
1849
1850 /* Do not create sub-predicate for range that is beyond up bound
1851 of switch index. */
1852 if (wi::le_p (vr_wmax, wi::to_wide (max), TYPE_SIGN (type)))
1853 {
1854 p_seg = false;
1855 break;
1856 }
1857
40a777e8 1858 p_seg = add_condition (summary, params_summary, index,
366099ff 1859 param_type, &aggpos, GT_EXPR,
4307a485 1860 max, param_ops);
351e7c3b
FX
1861 }
1862 }
1863
1864 p_all = p_all.or_with (summary->conds, p_seg);
2d01bef2
ML
1865 *(ipa_predicate *) e->aux
1866 = p_all.or_with (summary->conds, *(ipa_predicate *) e->aux);
4307a485
FX
1867
1868 vec_free (param_ops);
27d020cf
JH
1869}
1870
1871
1872/* For each BB in NODE attach to its AUX pointer predicate under
1873 which it is executable. */
1874
1875static void
1876compute_bb_predicates (struct ipa_func_body_info *fbi,
1877 struct cgraph_node *node,
40a777e8
JH
1878 class ipa_fn_summary *summary,
1879 class ipa_node_params *params_summary)
27d020cf
JH
1880{
1881 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1882 bool done = false;
1883 basic_block bb;
1884
1885 FOR_EACH_BB_FN (bb, my_function)
1886 {
40a777e8
JH
1887 set_cond_stmt_execution_predicate (fbi, summary, params_summary, bb);
1888 set_switch_stmt_execution_predicate (fbi, summary, params_summary, bb);
27d020cf
JH
1889 }
1890
1891 /* Entry block is always executable. */
1892 ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux
1893 = edge_predicate_pool.allocate ();
2d01bef2 1894 *(ipa_predicate *) ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux = true;
27d020cf
JH
1895
1896 /* A simple dataflow propagation of predicates forward in the CFG.
1897 TODO: work in reverse postorder. */
1898 while (!done)
1899 {
1900 done = true;
1901 FOR_EACH_BB_FN (bb, my_function)
1902 {
2d01bef2 1903 ipa_predicate p = false;
27d020cf
JH
1904 edge e;
1905 edge_iterator ei;
1906 FOR_EACH_EDGE (e, ei, bb->preds)
1907 {
1908 if (e->src->aux)
1909 {
2d01bef2
ML
1910 ipa_predicate this_bb_predicate
1911 = *(ipa_predicate *) e->src->aux;
27d020cf 1912 if (e->aux)
2d01bef2 1913 this_bb_predicate &= (*(ipa_predicate *) e->aux);
27d020cf
JH
1914 p = p.or_with (summary->conds, this_bb_predicate);
1915 if (p == true)
1916 break;
1917 }
1918 }
efe12656 1919 if (p != false)
27d020cf 1920 {
efe12656
FX
1921 basic_block pdom_bb;
1922
27d020cf
JH
1923 if (!bb->aux)
1924 {
1925 done = false;
1926 bb->aux = edge_predicate_pool.allocate ();
2d01bef2 1927 *((ipa_predicate *) bb->aux) = p;
27d020cf 1928 }
2d01bef2 1929 else if (p != *(ipa_predicate *) bb->aux)
27d020cf
JH
1930 {
1931 /* This OR operation is needed to ensure monotonous data flow
1932 in the case we hit the limit on number of clauses and the
1933 and/or operations above give approximate answers. */
2d01bef2
ML
1934 p = p.or_with (summary->conds, *(ipa_predicate *)bb->aux);
1935 if (p != *(ipa_predicate *)bb->aux)
27d020cf
JH
1936 {
1937 done = false;
2d01bef2 1938 *((ipa_predicate *)bb->aux) = p;
27d020cf
JH
1939 }
1940 }
efe12656
FX
1941
1942 /* For switch/if statement, we can OR-combine predicates of all
1943 its cases/branches to get predicate for basic block in their
1944 convergence point, but sometimes this will generate very
1945 complicated predicate. Actually, we can get simplified
1946 predicate in another way by using the fact that predicate
1947 for a basic block must also hold true for its post dominators.
1948 To be specific, basic block in convergence point of
1949 conditional statement should include predicate of the
1950 statement. */
1951 pdom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1952 if (pdom_bb == EXIT_BLOCK_PTR_FOR_FN (my_function) || !pdom_bb)
1953 ;
1954 else if (!pdom_bb->aux)
1955 {
1956 done = false;
1957 pdom_bb->aux = edge_predicate_pool.allocate ();
2d01bef2 1958 *((ipa_predicate *)pdom_bb->aux) = p;
efe12656 1959 }
2d01bef2 1960 else if (p != *(ipa_predicate *)pdom_bb->aux)
efe12656 1961 {
2d01bef2
ML
1962 p = p.or_with (summary->conds,
1963 *(ipa_predicate *)pdom_bb->aux);
1964 if (p != *(ipa_predicate *)pdom_bb->aux)
efe12656
FX
1965 {
1966 done = false;
2d01bef2 1967 *((ipa_predicate *)pdom_bb->aux) = p;
efe12656
FX
1968 }
1969 }
27d020cf
JH
1970 }
1971 }
1972 }
1973}
1974
1975
1976/* Return predicate specifying when the STMT might have result that is not
1977 a compile time constant. */
1978
2d01bef2 1979static ipa_predicate
c628d1c3 1980will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
99b1c316 1981 class ipa_fn_summary *summary,
40a777e8 1982 class ipa_node_params *params_summary,
27d020cf 1983 tree expr,
2d01bef2 1984 vec<ipa_predicate> nonconstant_names)
27d020cf
JH
1985{
1986 tree parm;
1987 int index;
27d020cf
JH
1988
1989 while (UNARY_CLASS_P (expr))
1990 expr = TREE_OPERAND (expr, 0);
1991
4307a485 1992 parm = unmodified_parm (fbi, NULL, expr, NULL);
c628d1c3 1993 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
40a777e8 1994 return add_condition (summary, params_summary, index, TREE_TYPE (parm), NULL,
2d01bef2 1995 ipa_predicate::changed, NULL_TREE);
27d020cf
JH
1996 if (is_gimple_min_invariant (expr))
1997 return false;
1998 if (TREE_CODE (expr) == SSA_NAME)
1999 return nonconstant_names[SSA_NAME_VERSION (expr)];
2000 if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
2001 {
2d01bef2 2002 ipa_predicate p1
c628d1c3 2003 = will_be_nonconstant_expr_predicate (fbi, summary,
40a777e8 2004 params_summary,
c628d1c3
MJ
2005 TREE_OPERAND (expr, 0),
2006 nonconstant_names);
27d020cf
JH
2007 if (p1 == true)
2008 return p1;
2009
2d01bef2 2010 ipa_predicate p2
c628d1c3 2011 = will_be_nonconstant_expr_predicate (fbi, summary,
40a777e8 2012 params_summary,
c628d1c3
MJ
2013 TREE_OPERAND (expr, 1),
2014 nonconstant_names);
27d020cf
JH
2015 return p1.or_with (summary->conds, p2);
2016 }
2017 else if (TREE_CODE (expr) == COND_EXPR)
2018 {
2d01bef2 2019 ipa_predicate p1
c628d1c3 2020 = will_be_nonconstant_expr_predicate (fbi, summary,
40a777e8 2021 params_summary,
c628d1c3
MJ
2022 TREE_OPERAND (expr, 0),
2023 nonconstant_names);
27d020cf
JH
2024 if (p1 == true)
2025 return p1;
2026
2d01bef2 2027 ipa_predicate p2
c628d1c3 2028 = will_be_nonconstant_expr_predicate (fbi, summary,
40a777e8 2029 params_summary,
c628d1c3
MJ
2030 TREE_OPERAND (expr, 1),
2031 nonconstant_names);
27d020cf
JH
2032 if (p2 == true)
2033 return p2;
2034 p1 = p1.or_with (summary->conds, p2);
c628d1c3 2035 p2 = will_be_nonconstant_expr_predicate (fbi, summary,
40a777e8 2036 params_summary,
27d020cf
JH
2037 TREE_OPERAND (expr, 2),
2038 nonconstant_names);
2039 return p2.or_with (summary->conds, p1);
2040 }
5126ae0c
KV
2041 else if (TREE_CODE (expr) == CALL_EXPR)
2042 return true;
27d020cf
JH
2043 else
2044 {
2045 debug_tree (expr);
2046 gcc_unreachable ();
2047 }
27d020cf
JH
2048}
2049
2050
2051/* Return predicate specifying when the STMT might have result that is not
2052 a compile time constant. */
2053
2d01bef2 2054static ipa_predicate
27d020cf 2055will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
99b1c316 2056 class ipa_fn_summary *summary,
40a777e8 2057 class ipa_node_params *params_summary,
27d020cf 2058 gimple *stmt,
2d01bef2 2059 vec<ipa_predicate> nonconstant_names)
27d020cf 2060{
2d01bef2 2061 ipa_predicate p = true;
27d020cf
JH
2062 ssa_op_iter iter;
2063 tree use;
4307a485 2064 tree param_type = NULL_TREE;
2d01bef2 2065 ipa_predicate op_non_const;
27d020cf
JH
2066 bool is_load;
2067 int base_index;
27d020cf
JH
2068 struct agg_position_info aggpos;
2069
956d615d 2070 /* What statements might be optimized away
27d020cf
JH
2071 when their arguments are constant. */
2072 if (gimple_code (stmt) != GIMPLE_ASSIGN
2073 && gimple_code (stmt) != GIMPLE_COND
2074 && gimple_code (stmt) != GIMPLE_SWITCH
2075 && (gimple_code (stmt) != GIMPLE_CALL
2076 || !(gimple_call_flags (stmt) & ECF_CONST)))
2077 return p;
2078
2079 /* Stores will stay anyway. */
2080 if (gimple_store_p (stmt))
2081 return p;
2082
2083 is_load = gimple_assign_load_p (stmt);
2084
2085 /* Loads can be optimized when the value is known. */
2086 if (is_load)
2087 {
4307a485
FX
2088 tree op = gimple_assign_rhs1 (stmt);
2089 if (!decompose_param_expr (fbi, stmt, op, &base_index, &param_type,
2090 &aggpos))
27d020cf
JH
2091 return p;
2092 }
2093 else
2094 base_index = -1;
2095
2096 /* See if we understand all operands before we start
2097 adding conditionals. */
2098 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
2099 {
c628d1c3 2100 tree parm = unmodified_parm (fbi, stmt, use, NULL);
27d020cf
JH
2101 /* For arguments we can build a condition. */
2102 if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
2103 continue;
2104 if (TREE_CODE (use) != SSA_NAME)
2105 return p;
2106 /* If we know when operand is constant,
2107 we still can say something useful. */
2108 if (nonconstant_names[SSA_NAME_VERSION (use)] != true)
2109 continue;
2110 return p;
2111 }
2112
2113 if (is_load)
2114 op_non_const =
40a777e8
JH
2115 add_condition (summary, params_summary,
2116 base_index, param_type, &aggpos,
2d01bef2 2117 ipa_predicate::changed, NULL_TREE);
27d020cf
JH
2118 else
2119 op_non_const = false;
2120 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
2121 {
4307a485 2122 tree parm = unmodified_parm (fbi, stmt, use, NULL);
27d020cf
JH
2123 int index;
2124
2125 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
2126 {
2127 if (index != base_index)
40a777e8
JH
2128 p = add_condition (summary, params_summary, index,
2129 TREE_TYPE (parm), NULL,
2d01bef2 2130 ipa_predicate::changed, NULL_TREE);
27d020cf
JH
2131 else
2132 continue;
2133 }
2134 else
2135 p = nonconstant_names[SSA_NAME_VERSION (use)];
2136 op_non_const = p.or_with (summary->conds, op_non_const);
2137 }
2138 if ((gimple_code (stmt) == GIMPLE_ASSIGN || gimple_code (stmt) == GIMPLE_CALL)
2139 && gimple_op (stmt, 0)
2140 && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
2141 nonconstant_names[SSA_NAME_VERSION (gimple_op (stmt, 0))]
2142 = op_non_const;
2143 return op_non_const;
2144}
2145
2146struct record_modified_bb_info
2147{
3b2a6901 2148 tree op;
27d020cf
JH
2149 bitmap bb_set;
2150 gimple *stmt;
2151};
2152
956d615d 2153/* Value is initialized in INIT_BB and used in USE_BB. We want to compute
27d020cf 2154 probability how often it changes between USE_BB.
3b2a6901 2155 INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
27d020cf
JH
2156 is in different loop nest, we can do better.
2157 This is all just estimate. In theory we look for minimal cut separating
2158 INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
2159 anyway. */
2160
2161static basic_block
2162get_minimal_bb (basic_block init_bb, basic_block use_bb)
2163{
99b1c316 2164 class loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
e7a74006 2165 if (l && l->header->count < init_bb->count)
27d020cf
JH
2166 return l->header;
2167 return init_bb;
2168}
2169
2170/* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
2171 set except for info->stmt. */
2172
2173static bool
2174record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
2175{
2176 struct record_modified_bb_info *info =
2177 (struct record_modified_bb_info *) data;
2178 if (SSA_NAME_DEF_STMT (vdef) == info->stmt)
2179 return false;
3b2a6901
JH
2180 if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef)))
2181 return false;
27d020cf
JH
2182 bitmap_set_bit (info->bb_set,
2183 SSA_NAME_IS_DEFAULT_DEF (vdef)
2184 ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index
2185 : get_minimal_bb
2186 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
2187 gimple_bb (info->stmt))->index);
3b2a6901
JH
2188 if (dump_file)
2189 {
2190 fprintf (dump_file, " Param ");
2191 print_generic_expr (dump_file, info->op, TDF_SLIM);
2192 fprintf (dump_file, " changed at bb %i, minimal: %i stmt: ",
2193 gimple_bb (SSA_NAME_DEF_STMT (vdef))->index,
2194 get_minimal_bb
2195 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
2196 gimple_bb (info->stmt))->index);
2197 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (vdef), 0);
2198 }
27d020cf
JH
2199 return false;
2200}
2201
2202/* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
2203 will change since last invocation of STMT.
2204
2205 Value 0 is reserved for compile time invariants.
2206 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
2207 ought to be REG_BR_PROB_BASE / estimated_iters. */
2208
2209static int
c628d1c3 2210param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
27d020cf
JH
2211{
2212 tree op = gimple_call_arg (stmt, i);
2213 basic_block bb = gimple_bb (stmt);
2214
2215 if (TREE_CODE (op) == WITH_SIZE_EXPR)
2216 op = TREE_OPERAND (op, 0);
2217
2218 tree base = get_base_address (op);
2219
2220 /* Global invariants never change. */
2221 if (is_gimple_min_invariant (base))
2222 return 0;
2223
2224 /* We would have to do non-trivial analysis to really work out what
2225 is the probability of value to change (i.e. when init statement
2226 is in a sibling loop of the call).
2227
2228 We do an conservative estimate: when call is executed N times more often
2229 than the statement defining value, we take the frequency 1/N. */
2230 if (TREE_CODE (base) == SSA_NAME)
2231 {
3b2a6901 2232 profile_count init_count;
27d020cf 2233
3b2a6901 2234 if (!bb->count.nonzero_p ())
27d020cf
JH
2235 return REG_BR_PROB_BASE;
2236
2237 if (SSA_NAME_IS_DEFAULT_DEF (base))
3b2a6901 2238 init_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
27d020cf 2239 else
3b2a6901 2240 init_count = get_minimal_bb
27d020cf 2241 (gimple_bb (SSA_NAME_DEF_STMT (base)),
3b2a6901 2242 gimple_bb (stmt))->count;
27d020cf 2243
3b2a6901
JH
2244 if (init_count < bb->count)
2245 return MAX ((init_count.to_sreal_scale (bb->count)
2246 * REG_BR_PROB_BASE).to_int (), 1);
2247 return REG_BR_PROB_BASE;
27d020cf
JH
2248 }
2249 else
2250 {
2251 ao_ref refd;
3b2a6901 2252 profile_count max = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
27d020cf 2253 struct record_modified_bb_info info;
27d020cf
JH
2254 tree init = ctor_for_folding (base);
2255
2256 if (init != error_mark_node)
2257 return 0;
6cc886bf 2258 if (!bb->count.nonzero_p () || fbi->aa_walk_budget == 0)
27d020cf 2259 return REG_BR_PROB_BASE;
3b2a6901
JH
2260 if (dump_file)
2261 {
4307a485 2262 fprintf (dump_file, " Analyzing param change probability of ");
3b2a6901
JH
2263 print_generic_expr (dump_file, op, TDF_SLIM);
2264 fprintf (dump_file, "\n");
2265 }
27d020cf 2266 ao_ref_init (&refd, op);
3b2a6901 2267 info.op = op;
27d020cf
JH
2268 info.stmt = stmt;
2269 info.bb_set = BITMAP_ALLOC (NULL);
c628d1c3
MJ
2270 int walked
2271 = walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
2272 NULL, NULL, fbi->aa_walk_budget);
6cc886bf
RB
2273 if (walked > 0)
2274 fbi->aa_walk_budget -= walked;
c628d1c3 2275 if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
27d020cf 2276 {
6cc886bf
RB
2277 if (walked < 0)
2278 fbi->aa_walk_budget = 0;
3b2a6901 2279 if (dump_file)
c628d1c3
MJ
2280 {
2281 if (walked < 0)
2282 fprintf (dump_file, " Ran out of AA walking budget.\n");
2283 else
2284 fprintf (dump_file, " Set in same BB as used.\n");
2285 }
27d020cf
JH
2286 BITMAP_FREE (info.bb_set);
2287 return REG_BR_PROB_BASE;
2288 }
2289
3b2a6901
JH
2290 bitmap_iterator bi;
2291 unsigned index;
2292 /* Lookup the most frequent update of the value and believe that
2293 it dominates all the other; precise analysis here is difficult. */
27d020cf 2294 EXECUTE_IF_SET_IN_BITMAP (info.bb_set, 0, index, bi)
3b2a6901
JH
2295 max = max.max (BASIC_BLOCK_FOR_FN (cfun, index)->count);
2296 if (dump_file)
2297 {
2298 fprintf (dump_file, " Set with count ");
2299 max.dump (dump_file);
2300 fprintf (dump_file, " and used with count ");
2301 bb->count.dump (dump_file);
2302 fprintf (dump_file, " freq %f\n",
2303 max.to_sreal_scale (bb->count).to_double ());
2304 }
27d020cf
JH
2305
2306 BITMAP_FREE (info.bb_set);
3b2a6901
JH
2307 if (max < bb->count)
2308 return MAX ((max.to_sreal_scale (bb->count)
2309 * REG_BR_PROB_BASE).to_int (), 1);
2310 return REG_BR_PROB_BASE;
27d020cf
JH
2311 }
2312}
2313
2314/* Find whether a basic block BB is the final block of a (half) diamond CFG
2315 sub-graph and if the predicate the condition depends on is known. If so,
2316 return true and store the pointer the predicate in *P. */
2317
2318static bool
c628d1c3 2319phi_result_unknown_predicate (ipa_func_body_info *fbi,
40a777e8
JH
2320 ipa_fn_summary *summary,
2321 class ipa_node_params *params_summary,
2322 basic_block bb,
2d01bef2
ML
2323 ipa_predicate *p,
2324 vec<ipa_predicate> nonconstant_names)
27d020cf
JH
2325{
2326 edge e;
2327 edge_iterator ei;
2328 basic_block first_bb = NULL;
2329 gimple *stmt;
2330
2331 if (single_pred_p (bb))
2332 {
2333 *p = false;
2334 return true;
2335 }
2336
2337 FOR_EACH_EDGE (e, ei, bb->preds)
2338 {
2339 if (single_succ_p (e->src))
2340 {
2341 if (!single_pred_p (e->src))
2342 return false;
2343 if (!first_bb)
2344 first_bb = single_pred (e->src);
2345 else if (single_pred (e->src) != first_bb)
2346 return false;
2347 }
2348 else
2349 {
2350 if (!first_bb)
2351 first_bb = e->src;
2352 else if (e->src != first_bb)
2353 return false;
2354 }
2355 }
2356
2357 if (!first_bb)
2358 return false;
2359
2360 stmt = last_stmt (first_bb);
2361 if (!stmt
2362 || gimple_code (stmt) != GIMPLE_COND
2363 || !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
2364 return false;
2365
40a777e8 2366 *p = will_be_nonconstant_expr_predicate (fbi, summary, params_summary,
27d020cf
JH
2367 gimple_cond_lhs (stmt),
2368 nonconstant_names);
2369 if (*p == true)
2370 return false;
2371 else
2372 return true;
2373}
2374
2375/* Given a PHI statement in a function described by inline properties SUMMARY
2376 and *P being the predicate describing whether the selected PHI argument is
2377 known, store a predicate for the result of the PHI statement into
2378 NONCONSTANT_NAMES, if possible. */
2379
2380static void
99b1c316 2381predicate_for_phi_result (class ipa_fn_summary *summary, gphi *phi,
2d01bef2
ML
2382 ipa_predicate *p,
2383 vec<ipa_predicate> nonconstant_names)
27d020cf
JH
2384{
2385 unsigned i;
2386
2387 for (i = 0; i < gimple_phi_num_args (phi); i++)
2388 {
2389 tree arg = gimple_phi_arg (phi, i)->def;
2390 if (!is_gimple_min_invariant (arg))
2391 {
2392 gcc_assert (TREE_CODE (arg) == SSA_NAME);
2393 *p = p->or_with (summary->conds,
2394 nonconstant_names[SSA_NAME_VERSION (arg)]);
2395 if (*p == true)
2396 return;
2397 }
2398 }
2399
2400 if (dump_file && (dump_flags & TDF_DETAILS))
2401 {
2402 fprintf (dump_file, "\t\tphi predicate: ");
2403 p->dump (dump_file, summary->conds);
2404 }
2405 nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
2406}
2407
27d020cf
JH
2408/* For a typical usage of __builtin_expect (a<b, 1), we
2409 may introduce an extra relation stmt:
2410 With the builtin, we have
2411 t1 = a <= b;
2412 t2 = (long int) t1;
2413 t3 = __builtin_expect (t2, 1);
2414 if (t3 != 0)
2415 goto ...
2416 Without the builtin, we have
2417 if (a<=b)
2418 goto...
2419 This affects the size/time estimation and may have
2420 an impact on the earlier inlining.
2421 Here find this pattern and fix it up later. */
2422
2423static gimple *
2424find_foldable_builtin_expect (basic_block bb)
2425{
2426 gimple_stmt_iterator bsi;
2427
2428 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
2429 {
2430 gimple *stmt = gsi_stmt (bsi);
2431 if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
1e9168b2 2432 || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY)
27d020cf
JH
2433 || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
2434 {
2435 tree var = gimple_call_lhs (stmt);
2436 tree arg = gimple_call_arg (stmt, 0);
2437 use_operand_p use_p;
2438 gimple *use_stmt;
2439 bool match = false;
2440 bool done = false;
2441
2442 if (!var || !arg)
2443 continue;
2444 gcc_assert (TREE_CODE (var) == SSA_NAME);
2445
2446 while (TREE_CODE (arg) == SSA_NAME)
2447 {
2448 gimple *stmt_tmp = SSA_NAME_DEF_STMT (arg);
2449 if (!is_gimple_assign (stmt_tmp))
2450 break;
2451 switch (gimple_assign_rhs_code (stmt_tmp))
2452 {
2453 case LT_EXPR:
2454 case LE_EXPR:
2455 case GT_EXPR:
2456 case GE_EXPR:
2457 case EQ_EXPR:
2458 case NE_EXPR:
2459 match = true;
2460 done = true;
2461 break;
2462 CASE_CONVERT:
2463 break;
2464 default:
2465 done = true;
2466 break;
2467 }
2468 if (done)
2469 break;
2470 arg = gimple_assign_rhs1 (stmt_tmp);
2471 }
2472
2473 if (match && single_imm_use (var, &use_p, &use_stmt)
2474 && gimple_code (use_stmt) == GIMPLE_COND)
2475 return use_stmt;
2476 }
2477 }
2478 return NULL;
2479}
2480
2481/* Return true when the basic blocks contains only clobbers followed by RESX.
2482 Such BBs are kept around to make removal of dead stores possible with
2483 presence of EH and will be optimized out by optimize_clobbers later in the
2484 game.
2485
956d615d 2486 NEED_EH is used to recurse in case the clobber has non-EH predecessors
27d020cf
JH
2487 that can be clobber only, too.. When it is false, the RESX is not necessary
2488 on the end of basic block. */
2489
2490static bool
2491clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
2492{
2493 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2494 edge_iterator ei;
2495 edge e;
2496
2497 if (need_eh)
2498 {
2499 if (gsi_end_p (gsi))
2500 return false;
2501 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
2502 return false;
2503 gsi_prev (&gsi);
2504 }
2505 else if (!single_succ_p (bb))
2506 return false;
2507
2508 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
2509 {
2510 gimple *stmt = gsi_stmt (gsi);
2511 if (is_gimple_debug (stmt))
2512 continue;
2513 if (gimple_clobber_p (stmt))
2514 continue;
2515 if (gimple_code (stmt) == GIMPLE_LABEL)
2516 break;
2517 return false;
2518 }
2519
956d615d 2520 /* See if all predecessors are either throws or clobber only BBs. */
27d020cf
JH
2521 FOR_EACH_EDGE (e, ei, bb->preds)
2522 if (!(e->flags & EDGE_EH)
2523 && !clobber_only_eh_bb_p (e->src, false))
2524 return false;
2525
2526 return true;
2527}
2528
2529/* Return true if STMT compute a floating point expression that may be affected
2530 by -ffast-math and similar flags. */
2531
2532static bool
2533fp_expression_p (gimple *stmt)
2534{
2535 ssa_op_iter i;
2536 tree op;
2537
2538 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
2539 if (FLOAT_TYPE_P (TREE_TYPE (op)))
2540 return true;
2541 return false;
2542}
2543
e977dd5e
JH
2544/* Return true if T references memory location that is local
2545 for the function (that means, dead after return) or read-only. */
2546
2547bool
2548refs_local_or_readonly_memory_p (tree t)
2549{
2550 /* Non-escaping memory is fine. */
2551 t = get_base_address (t);
2552 if ((TREE_CODE (t) == MEM_REF
2553 || TREE_CODE (t) == TARGET_MEM_REF))
2554 return points_to_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
2555
2556 /* Automatic variables are fine. */
2557 if (DECL_P (t)
2558 && auto_var_in_fn_p (t, current_function_decl))
2559 return true;
2560
2561 /* Read-only variables are fine. */
2562 if (DECL_P (t) && TREE_READONLY (t))
2563 return true;
2564
2565 return false;
2566}
2567
2568/* Return true if T is a pointer pointing to memory location that is local
2569 for the function (that means, dead after return) or read-only. */
2570
2571bool
2572points_to_local_or_readonly_memory_p (tree t)
2573{
2574 /* See if memory location is clearly invalid. */
2575 if (integer_zerop (t))
2576 return flag_delete_null_pointer_checks;
2577 if (TREE_CODE (t) == SSA_NAME)
ca84f393
JH
2578 {
2579 /* For IPA passes we can consinder accesses to return slot local
2580 even if it is not local in the sense that memory is dead by
2581 the end of founction.
2582 The outer function will see a store in the call assignment
2583 and thus this will do right thing for all uses of this
2584 function in the current IPA passes (modref, pure/const discovery
2585 and inlining heuristics). */
2586 if (DECL_RESULT (current_function_decl)
2587 && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
2588 && t == ssa_default_def (cfun, DECL_RESULT (current_function_decl)))
2589 return true;
2590 return !ptr_deref_may_alias_global_p (t);
2591 }
e977dd5e
JH
2592 if (TREE_CODE (t) == ADDR_EXPR)
2593 return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
2594 return false;
2595}
2596
2597
0bceb671
JH
2598/* Analyze function body for NODE.
2599 EARLY indicates run from early optimization pipeline. */
27d020cf
JH
2600
2601static void
0bceb671 2602analyze_function_body (struct cgraph_node *node, bool early)
27d020cf 2603{
9340d345 2604 sreal time = opt_for_fn (node->decl, param_uninlined_function_time);
27d020cf 2605 /* Estimate static overhead for function prologue/epilogue and alignment. */
9340d345 2606 int size = opt_for_fn (node->decl, param_uninlined_function_insns);
27d020cf
JH
2607 /* Benefits are scaled by probability of elimination that is in range
2608 <0,2>. */
2609 basic_block bb;
2610 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
b71289b1 2611 sreal freq;
99b1c316 2612 class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
a4a3cdd0
MJ
2613 ipa_node_params *params_summary
2614 = early ? NULL : ipa_node_params_sum->get (node);
2d01bef2 2615 ipa_predicate bb_predicate;
27d020cf 2616 struct ipa_func_body_info fbi;
2d01bef2 2617 vec<ipa_predicate> nonconstant_names = vNULL;
27d020cf
JH
2618 int nblocks, n;
2619 int *order;
27d020cf
JH
2620 gimple *fix_builtin_expect_stmt;
2621
2622 gcc_assert (my_function && my_function->cfg);
2623 gcc_assert (cfun == my_function);
2624
2625 memset(&fbi, 0, sizeof(fbi));
ddfb1317 2626 vec_free (info->conds);
27d020cf 2627 info->conds = NULL;
366099ff
JH
2628 info->size_time_table.release ();
2629 info->call_size_time_table.release ();
27d020cf
JH
2630
2631 /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
2632 so we can produce proper inline hints.
2633
2634 When optimizing and analyzing for early inliner, initialize node params
2635 so we can produce correct BB predicates. */
2636
2637 if (opt_for_fn (node->decl, optimize))
2638 {
2639 calculate_dominance_info (CDI_DOMINATORS);
efe12656 2640 calculate_dominance_info (CDI_POST_DOMINATORS);
27d020cf
JH
2641 if (!early)
2642 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
2643 else
2644 {
2645 ipa_check_create_node_params ();
2646 ipa_initialize_node_params (node);
2647 }
2648
2649 if (ipa_node_params_sum)
2650 {
2651 fbi.node = node;
a4a3cdd0 2652 fbi.info = ipa_node_params_sum->get (node);
27d020cf 2653 fbi.bb_infos = vNULL;
cb3874dc 2654 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
c628d1c3 2655 fbi.param_count = count_formal_params (node->decl);
fdfd7f53 2656 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
c628d1c3 2657
27d020cf 2658 nonconstant_names.safe_grow_cleared
cb3874dc 2659 (SSANAMES (my_function)->length (), true);
27d020cf
JH
2660 }
2661 }
2662
2663 if (dump_file)
2664 fprintf (dump_file, "\nAnalyzing function body size: %s\n",
3629ff8a 2665 node->dump_name ());
27d020cf
JH
2666
2667 /* When we run into maximal number of entries, we assign everything to the
2668 constant truth case. Be sure to have it in list. */
2669 bb_predicate = true;
2670 info->account_size_time (0, 0, bb_predicate, bb_predicate);
2671
2d01bef2 2672 bb_predicate = ipa_predicate::not_inlined ();
9340d345
JH
2673 info->account_size_time (opt_for_fn (node->decl,
2674 param_uninlined_function_insns)
d06f73a3 2675 * ipa_fn_summary::size_scale,
9340d345
JH
2676 opt_for_fn (node->decl,
2677 param_uninlined_function_time),
d06f73a3 2678 bb_predicate,
27d020cf
JH
2679 bb_predicate);
2680
0fc60c18
KL
2681 /* Only look for target information for inlinable functions. */
2682 bool scan_for_target_info =
2683 info->inlinable
2684 && targetm.target_option.need_ipa_fn_target_info (node->decl,
2685 info->target_info);
2686
27d020cf 2687 if (fbi.info)
40a777e8 2688 compute_bb_predicates (&fbi, node, info, params_summary);
67ce9099 2689 const profile_count entry_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
27d020cf
JH
2690 order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
2691 nblocks = pre_and_rev_post_order_compute (NULL, order, false);
2692 for (n = 0; n < nblocks; n++)
2693 {
2694 bb = BASIC_BLOCK_FOR_FN (cfun, order[n]);
67ce9099 2695 freq = bb->count.to_sreal_scale (entry_count);
27d020cf
JH
2696 if (clobber_only_eh_bb_p (bb))
2697 {
2698 if (dump_file && (dump_flags & TDF_DETAILS))
2699 fprintf (dump_file, "\n Ignoring BB %i;"
2700 " it will be optimized away by cleanup_clobbers\n",
2701 bb->index);
2702 continue;
2703 }
2704
2705 /* TODO: Obviously predicates can be propagated down across CFG. */
2706 if (fbi.info)
2707 {
2708 if (bb->aux)
2d01bef2 2709 bb_predicate = *(ipa_predicate *)bb->aux;
27d020cf
JH
2710 else
2711 bb_predicate = false;
2712 }
2713 else
2714 bb_predicate = true;
2715
2716 if (dump_file && (dump_flags & TDF_DETAILS))
2717 {
2718 fprintf (dump_file, "\n BB %i predicate:", bb->index);
2719 bb_predicate.dump (dump_file, info->conds);
2720 }
2721
2722 if (fbi.info && nonconstant_names.exists ())
2723 {
2d01bef2 2724 ipa_predicate phi_predicate;
27d020cf
JH
2725 bool first_phi = true;
2726
2727 for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
2728 gsi_next (&bsi))
2729 {
2730 if (first_phi
40a777e8
JH
2731 && !phi_result_unknown_predicate (&fbi, info,
2732 params_summary,
2733 bb,
27d020cf
JH
2734 &phi_predicate,
2735 nonconstant_names))
2736 break;
2737 first_phi = false;
2738 if (dump_file && (dump_flags & TDF_DETAILS))
2739 {
2740 fprintf (dump_file, " ");
2741 print_gimple_stmt (dump_file, gsi_stmt (bsi), 0);
2742 }
2743 predicate_for_phi_result (info, bsi.phi (), &phi_predicate,
2744 nonconstant_names);
2745 }
2746 }
2747
2748 fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
2749
d3ed5b56
JH
2750 for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb);
2751 !gsi_end_p (bsi); gsi_next_nondebug (&bsi))
27d020cf
JH
2752 {
2753 gimple *stmt = gsi_stmt (bsi);
2754 int this_size = estimate_num_insns (stmt, &eni_size_weights);
2755 int this_time = estimate_num_insns (stmt, &eni_time_weights);
2756 int prob;
2d01bef2 2757 ipa_predicate will_be_nonconstant;
27d020cf
JH
2758
2759 /* This relation stmt should be folded after we remove
956d615d 2760 __builtin_expect call. Adjust the cost here. */
27d020cf
JH
2761 if (stmt == fix_builtin_expect_stmt)
2762 {
2763 this_size--;
2764 this_time--;
2765 }
2766
2767 if (dump_file && (dump_flags & TDF_DETAILS))
2768 {
2769 fprintf (dump_file, " ");
2770 print_gimple_stmt (dump_file, stmt, 0);
2771 fprintf (dump_file, "\t\tfreq:%3.2f size:%3i time:%3i\n",
b71289b1 2772 freq.to_double (), this_size,
27d020cf
JH
2773 this_time);
2774 }
2775
27d020cf
JH
2776 if (is_gimple_call (stmt)
2777 && !gimple_call_internal_p (stmt))
2778 {
2779 struct cgraph_edge *edge = node->get_edge (stmt);
99353fcf 2780 ipa_call_summary *es = ipa_call_summaries->get_create (edge);
27d020cf
JH
2781
2782 /* Special case: results of BUILT_IN_CONSTANT_P will be always
2783 resolved as constant. We however don't want to optimize
2784 out the cgraph edges. */
2785 if (nonconstant_names.exists ()
2786 && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
2787 && gimple_call_lhs (stmt)
2788 && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
2789 {
2d01bef2 2790 ipa_predicate false_p = false;
27d020cf
JH
2791 nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
2792 = false_p;
2793 }
2794 if (ipa_node_params_sum)
2795 {
2796 int count = gimple_call_num_args (stmt);
2797 int i;
2798
2799 if (count)
cb3874dc 2800 es->param.safe_grow_cleared (count, true);
27d020cf
JH
2801 for (i = 0; i < count; i++)
2802 {
c628d1c3 2803 int prob = param_change_prob (&fbi, stmt, i);
27d020cf
JH
2804 gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
2805 es->param[i].change_prob = prob;
b89e4559
JH
2806 es->param[i].points_to_local_or_readonly_memory
2807 = points_to_local_or_readonly_memory_p
2808 (gimple_call_arg (stmt, i));
27d020cf
JH
2809 }
2810 }
7ee164dc
RB
2811 /* We cannot setup VLA parameters during inlining. */
2812 for (unsigned int i = 0; i < gimple_call_num_args (stmt); ++i)
2813 if (TREE_CODE (gimple_call_arg (stmt, i)) == WITH_SIZE_EXPR)
2814 {
2815 edge->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
2816 break;
2817 }
27d020cf
JH
2818 es->call_stmt_size = this_size;
2819 es->call_stmt_time = this_time;
2820 es->loop_depth = bb_loop_depth (bb);
2821 edge_set_predicate (edge, &bb_predicate);
959b8c82
JH
2822 if (edge->speculative)
2823 {
845bb366
JH
2824 cgraph_edge *indirect
2825 = edge->speculative_call_indirect_edge ();
959b8c82 2826 ipa_call_summary *es2
d380e329 2827 = ipa_call_summaries->get_create (indirect);
959b8c82
JH
2828 ipa_call_summaries->duplicate (edge, indirect,
2829 es, es2);
f1ba88b1 2830
845bb366
JH
2831 /* Edge is the first direct call.
2832 create and duplicate call summaries for multiple
f1ba88b1 2833 speculative call targets. */
845bb366
JH
2834 for (cgraph_edge *direct
2835 = edge->next_speculative_call_target ();
2836 direct;
2837 direct = direct->next_speculative_call_target ())
2838 {
2839 ipa_call_summary *es3
2840 = ipa_call_summaries->get_create (direct);
2841 ipa_call_summaries->duplicate (edge, direct,
2842 es, es3);
2843 }
959b8c82 2844 }
27d020cf
JH
2845 }
2846
956d615d 2847 /* TODO: When conditional jump or switch is known to be constant, but
27d020cf
JH
2848 we did not translate it into the predicates, we really can account
2849 just maximum of the possible paths. */
2850 if (fbi.info)
2851 will_be_nonconstant
40a777e8 2852 = will_be_nonconstant_predicate (&fbi, info, params_summary,
27d020cf
JH
2853 stmt, nonconstant_names);
2854 else
2855 will_be_nonconstant = true;
2856 if (this_time || this_size)
2857 {
b71289b1 2858 sreal final_time = (sreal)this_time * freq;
27d020cf 2859
c628d1c3 2860 prob = eliminated_by_inlining_prob (&fbi, stmt);
27d020cf
JH
2861 if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS))
2862 fprintf (dump_file,
2863 "\t\t50%% will be eliminated by inlining\n");
2864 if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
2865 fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
2866
2d01bef2 2867 ipa_predicate p = bb_predicate & will_be_nonconstant;
27d020cf
JH
2868
2869 /* We can ignore statement when we proved it is never going
67914693 2870 to happen, but we cannot do that for call statements
27d020cf
JH
2871 because edges are accounted specially. */
2872
2873 if (*(is_gimple_call (stmt) ? &bb_predicate : &p) != false)
2874 {
b71289b1 2875 time += final_time;
27d020cf
JH
2876 size += this_size;
2877 }
2878
2879 /* We account everything but the calls. Calls have their own
2880 size/time info attached to cgraph edges. This is necessary
2881 in order to make the cost disappear after inlining. */
2882 if (!is_gimple_call (stmt))
2883 {
2884 if (prob)
2885 {
2d01bef2
ML
2886 ipa_predicate ip
2887 = bb_predicate & ipa_predicate::not_inlined ();
27d020cf 2888 info->account_size_time (this_size * prob,
121356b0 2889 (final_time * prob) / 2, ip,
27d020cf
JH
2890 p);
2891 }
2892 if (prob != 2)
2893 info->account_size_time (this_size * (2 - prob),
121356b0 2894 (final_time * (2 - prob) / 2),
27d020cf
JH
2895 bb_predicate,
2896 p);
2897 }
2898
2899 if (!info->fp_expressions && fp_expression_p (stmt))
2900 {
2901 info->fp_expressions = true;
2902 if (dump_file)
2903 fprintf (dump_file, " fp_expression set\n");
2904 }
a20f263b 2905 }
27d020cf 2906
0fc60c18
KL
2907 /* For target specific information, we want to scan all statements
2908 rather than those statements with non-zero weights, to avoid
2909 missing to scan something interesting for target information,
2910 such as: internal function calls. */
2911 if (scan_for_target_info)
2912 scan_for_target_info =
2913 targetm.target_option.update_ipa_fn_target_info
2914 (info->target_info, stmt);
2915
a20f263b
JH
2916 /* Account cost of address calculations in the statements. */
2917 for (unsigned int i = 0; i < gimple_num_ops (stmt); i++)
2918 {
2919 for (tree op = gimple_op (stmt, i);
2920 op && handled_component_p (op);
2921 op = TREE_OPERAND (op, 0))
2922 if ((TREE_CODE (op) == ARRAY_REF
2923 || TREE_CODE (op) == ARRAY_RANGE_REF)
2924 && TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
2925 {
2d01bef2 2926 ipa_predicate p = bb_predicate;
a20f263b
JH
2927 if (fbi.info)
2928 p = p & will_be_nonconstant_expr_predicate
40a777e8
JH
2929 (&fbi, info, params_summary,
2930 TREE_OPERAND (op, 1),
a20f263b
JH
2931 nonconstant_names);
2932 if (p != false)
2933 {
2934 time += freq;
2935 size += 1;
2936 if (dump_file)
2937 fprintf (dump_file,
2938 "\t\tAccounting address calculation.\n");
2939 info->account_size_time (ipa_fn_summary::size_scale,
2940 freq,
2941 bb_predicate,
2942 p);
2943 }
2944 }
27d020cf 2945 }
a20f263b 2946
27d020cf
JH
2947 }
2948 }
27d020cf
JH
2949 free (order);
2950
2951 if (nonconstant_names.exists () && !early)
2952 {
67ce9099 2953 ipa_fn_summary *s = ipa_fn_summaries->get (node);
67ce9099
MJ
2954 unsigned max_loop_predicates = opt_for_fn (node->decl,
2955 param_ipa_max_loop_predicates);
27d020cf
JH
2956
2957 if (dump_file && (dump_flags & TDF_DETAILS))
2958 flow_loops_dump (dump_file, NULL, 0);
2959 scev_initialize ();
e41ba804 2960 for (auto loop : loops_list (cfun, 0))
27d020cf 2961 {
2d01bef2 2962 ipa_predicate loop_iterations = true;
67ce9099 2963 sreal header_freq;
27d020cf
JH
2964 edge ex;
2965 unsigned int j;
99b1c316 2966 class tree_niter_desc niter_desc;
67ce9099
MJ
2967 if (!loop->header->aux)
2968 continue;
27d020cf 2969
67ce9099
MJ
2970 profile_count phdr_count = loop_preheader_edge (loop)->count ();
2971 sreal phdr_freq = phdr_count.to_sreal_scale (entry_count);
2972
2d01bef2 2973 bb_predicate = *(ipa_predicate *)loop->header->aux;
4b9d61f7 2974 auto_vec<edge> exits = get_loop_exit_edges (loop);
27d020cf
JH
2975 FOR_EACH_VEC_ELT (exits, j, ex)
2976 if (number_of_iterations_exit (loop, ex, &niter_desc, false)
2977 && !is_gimple_min_invariant (niter_desc.niter))
2978 {
2d01bef2 2979 ipa_predicate will_be_nonconstant
c628d1c3 2980 = will_be_nonconstant_expr_predicate (&fbi, info,
40a777e8 2981 params_summary,
27d020cf
JH
2982 niter_desc.niter,
2983 nonconstant_names);
2984 if (will_be_nonconstant != true)
2985 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2986 if (will_be_nonconstant != true
2987 && will_be_nonconstant != false)
27d020cf
JH
2988 loop_iterations &= will_be_nonconstant;
2989 }
67ce9099
MJ
2990 add_freqcounting_predicate (&s->loop_iterations, loop_iterations,
2991 phdr_freq, max_loop_predicates);
27d020cf
JH
2992 }
2993
2994 /* To avoid quadratic behavior we analyze stride predicates only
2995 with respect to the containing loop. Thus we simply iterate
2996 over all defs in the outermost loop body. */
9e026da7 2997 for (class loop *loop = loops_for_fn (cfun)->tree_root->inner;
27d020cf
JH
2998 loop != NULL; loop = loop->next)
2999 {
2d01bef2 3000 ipa_predicate loop_stride = true;
27d020cf 3001 basic_block *body = get_loop_body (loop);
67ce9099
MJ
3002 profile_count phdr_count = loop_preheader_edge (loop)->count ();
3003 sreal phdr_freq = phdr_count.to_sreal_scale (entry_count);
27d020cf
JH
3004 for (unsigned i = 0; i < loop->num_nodes; i++)
3005 {
3006 gimple_stmt_iterator gsi;
67ce9099
MJ
3007 if (!body[i]->aux)
3008 continue;
3009
2d01bef2 3010 bb_predicate = *(ipa_predicate *)body[i]->aux;
27d020cf
JH
3011 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
3012 gsi_next (&gsi))
3013 {
3014 gimple *stmt = gsi_stmt (gsi);
3015
3016 if (!is_gimple_assign (stmt))
3017 continue;
3018
3019 tree def = gimple_assign_lhs (stmt);
3020 if (TREE_CODE (def) != SSA_NAME)
3021 continue;
3022
3023 affine_iv iv;
3024 if (!simple_iv (loop_containing_stmt (stmt),
3025 loop_containing_stmt (stmt),
3026 def, &iv, true)
3027 || is_gimple_min_invariant (iv.step))
3028 continue;
3029
2d01bef2 3030 ipa_predicate will_be_nonconstant
40a777e8
JH
3031 = will_be_nonconstant_expr_predicate (&fbi, info,
3032 params_summary,
3033 iv.step,
27d020cf
JH
3034 nonconstant_names);
3035 if (will_be_nonconstant != true)
3036 will_be_nonconstant = bb_predicate & will_be_nonconstant;
3037 if (will_be_nonconstant != true
3038 && will_be_nonconstant != false)
27d020cf
JH
3039 loop_stride = loop_stride & will_be_nonconstant;
3040 }
3041 }
67ce9099
MJ
3042 add_freqcounting_predicate (&s->loop_strides, loop_stride,
3043 phdr_freq, max_loop_predicates);
27d020cf
JH
3044 free (body);
3045 }
27d020cf
JH
3046 scev_finalize ();
3047 }
3048 FOR_ALL_BB_FN (bb, my_function)
3049 {
3050 edge e;
3051 edge_iterator ei;
3052
3053 if (bb->aux)
2d01bef2 3054 edge_predicate_pool.remove ((ipa_predicate *)bb->aux);
27d020cf
JH
3055 bb->aux = NULL;
3056 FOR_EACH_EDGE (e, ei, bb->succs)
3057 {
3058 if (e->aux)
2d01bef2 3059 edge_predicate_pool.remove ((ipa_predicate *)e->aux);
27d020cf
JH
3060 e->aux = NULL;
3061 }
3062 }
56f62793 3063 ipa_fn_summary *s = ipa_fn_summaries->get (node);
f658ad30 3064 ipa_size_summary *ss = ipa_size_summaries->get (node);
cf9b0b5f 3065 s->time = time;
f658ad30 3066 ss->self_size = size;
27d020cf
JH
3067 nonconstant_names.release ();
3068 ipa_release_body_info (&fbi);
3069 if (opt_for_fn (node->decl, optimize))
3070 {
3071 if (!early)
3072 loop_optimizer_finalize ();
3073 else if (!ipa_edge_args_sum)
3074 ipa_free_all_node_params ();
3075 free_dominance_info (CDI_DOMINATORS);
efe12656 3076 free_dominance_info (CDI_POST_DOMINATORS);
27d020cf
JH
3077 }
3078 if (dump_file)
3079 {
3080 fprintf (dump_file, "\n");
0bceb671 3081 ipa_dump_fn_summary (dump_file, node);
27d020cf
JH
3082 }
3083}
3084
3085
0bceb671
JH
3086/* Compute function summary.
3087 EARLY is true when we compute parameters during early opts. */
27d020cf
JH
3088
3089void
0bceb671 3090compute_fn_summary (struct cgraph_node *node, bool early)
27d020cf
JH
3091{
3092 HOST_WIDE_INT self_stack_size;
3093 struct cgraph_edge *e;
27d020cf 3094
a62bfab5 3095 gcc_assert (!node->inlined_to);
27d020cf 3096
0bceb671
JH
3097 if (!ipa_fn_summaries)
3098 ipa_fn_summary_alloc ();
27d020cf 3099
56f62793
ML
3100 /* Create a new ipa_fn_summary. */
3101 ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
3102 ipa_fn_summaries->remove (node);
f658ad30
JH
3103 class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
3104 class ipa_size_summary *size_info = ipa_size_summaries->get_create (node);
27d020cf
JH
3105
3106 /* Estimate the stack size for the function if we're optimizing. */
67f3791f 3107 self_stack_size = optimize && !node->thunk
27d020cf 3108 ? estimated_stack_frame_size (node) : 0;
f658ad30 3109 size_info->estimated_self_stack_size = self_stack_size;
27d020cf 3110 info->estimated_stack_size = self_stack_size;
27d020cf 3111
67f3791f 3112 if (node->thunk)
27d020cf 3113 {
99353fcf 3114 ipa_call_summary *es = ipa_call_summaries->get_create (node->callees);
2d01bef2 3115 ipa_predicate t = true;
27d020cf 3116
87f94429 3117 node->can_change_signature = false;
27d020cf
JH
3118 es->call_stmt_size = eni_size_weights.call_cost;
3119 es->call_stmt_time = eni_time_weights.call_cost;
d06f73a3 3120 info->account_size_time (ipa_fn_summary::size_scale
9340d345
JH
3121 * opt_for_fn (node->decl,
3122 param_uninlined_function_thunk_insns),
3123 opt_for_fn (node->decl,
3124 param_uninlined_function_thunk_time), t, t);
2d01bef2 3125 t = ipa_predicate::not_inlined ();
0bceb671
JH
3126 info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
3127 ipa_update_overall_fn_summary (node);
f658ad30 3128 size_info->self_size = size_info->size;
dbcdd561 3129 if (stdarg_p (TREE_TYPE (node->decl)))
ca04a532
ML
3130 {
3131 info->inlinable = false;
3132 node->callees->inline_failed = CIF_VARIADIC_THUNK;
3133 }
27d020cf
JH
3134 else
3135 info->inlinable = true;
3136 }
3137 else
3138 {
3139 /* Even is_gimple_min_invariant rely on current_function_decl. */
3140 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3141
ac0573de
JH
3142 /* During IPA profile merging we may be called w/o virtual SSA form
3143 built. */
3144 update_ssa (TODO_update_ssa_only_virtuals);
3145
27d020cf
JH
3146 /* Can this function be inlined at all? */
3147 if (!opt_for_fn (node->decl, optimize)
3148 && !lookup_attribute ("always_inline",
3149 DECL_ATTRIBUTES (node->decl)))
3150 info->inlinable = false;
3151 else
3152 info->inlinable = tree_inlinable_function_p (node->decl);
3153
ecdf414b
JH
3154 bool no_signature = false;
3155 /* Type attributes can use parameter indices to describe them.
3156 Special case fn spec since we can safely preserve them in
3157 modref summaries. */
3158 for (tree list = TYPE_ATTRIBUTES (TREE_TYPE (node->decl));
3159 list && !no_signature; list = TREE_CHAIN (list))
2af63f0f
JH
3160 if (!ipa_param_adjustments::type_attribute_allowed_p
3161 (get_attribute_name (list)))
ecdf414b
JH
3162 {
3163 if (dump_file)
3164 {
3165 fprintf (dump_file, "No signature change:"
3166 " function type has unhandled attribute %s.\n",
3167 IDENTIFIER_POINTER (get_attribute_name (list)));
3168 }
3169 no_signature = true;
3170 }
3171 for (tree parm = DECL_ARGUMENTS (node->decl);
3172 parm && !no_signature; parm = DECL_CHAIN (parm))
3173 if (variably_modified_type_p (TREE_TYPE (parm), node->decl))
3174 {
3175 if (dump_file)
3176 {
3177 fprintf (dump_file, "No signature change:"
3178 " has parameter with variably modified type.\n");
3179 }
3180 no_signature = true;
3181 }
3182
3183 /* Likewise for #pragma omp declare simd functions or functions
3184 with simd attribute. */
3185 if (no_signature
3d8fb311
JJ
3186 || lookup_attribute ("omp declare simd",
3187 DECL_ATTRIBUTES (node->decl)))
87f94429 3188 node->can_change_signature = false;
27d020cf
JH
3189 else
3190 {
3191 /* Otherwise, inlinable functions always can change signature. */
3192 if (info->inlinable)
87f94429 3193 node->can_change_signature = true;
27d020cf
JH
3194 else
3195 {
67914693 3196 /* Functions calling builtin_apply cannot change signature. */
27d020cf
JH
3197 for (e = node->callees; e; e = e->next_callee)
3198 {
3199 tree cdecl = e->callee->decl;
3d78e008
ML
3200 if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
3201 || fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
27d020cf
JH
3202 break;
3203 }
87f94429 3204 node->can_change_signature = !e;
27d020cf
JH
3205 }
3206 }
0bceb671 3207 analyze_function_body (node, early);
27d020cf
JH
3208 pop_cfun ();
3209 }
27d020cf
JH
3210
3211 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
f658ad30
JH
3212 size_info->size = size_info->self_size;
3213 info->estimated_stack_size = size_info->estimated_self_stack_size;
27d020cf
JH
3214
3215 /* Code above should compute exactly the same result as
150bde36
JH
3216 ipa_update_overall_fn_summary except for case when speculative
3217 edges are present since these are accounted to size but not
3218 self_size. Do not compare time since different order the roundoff
3219 errors result in slight changes. */
0bceb671 3220 ipa_update_overall_fn_summary (node);
150bde36
JH
3221 if (flag_checking)
3222 {
3223 for (e = node->indirect_calls; e; e = e->next_callee)
3224 if (e->speculative)
3225 break;
3226 gcc_assert (e || size_info->size == size_info->self_size);
3227 }
27d020cf
JH
3228}
3229
3230
3231/* Compute parameters of functions used by inliner using
3232 current_function_decl. */
3233
3234static unsigned int
0bceb671 3235compute_fn_summary_for_current (void)
27d020cf 3236{
0bceb671 3237 compute_fn_summary (cgraph_node::get (current_function_decl), true);
27d020cf
JH
3238 return 0;
3239}
3240
9d5af1db
MJ
3241/* Estimate benefit devirtualizing indirect edge IE and return true if it can
3242 be devirtualized and inlined, provided m_known_vals, m_known_contexts and
3243 m_known_aggs in AVALS. Return false straight away if AVALS is NULL. */
27d020cf
JH
3244
3245static bool
3246estimate_edge_devirt_benefit (struct cgraph_edge *ie,
3247 int *size, int *time,
9d5af1db 3248 ipa_call_arg_values *avals)
27d020cf
JH
3249{
3250 tree target;
3251 struct cgraph_node *callee;
99b1c316 3252 class ipa_fn_summary *isummary;
27d020cf
JH
3253 enum availability avail;
3254 bool speculative;
3255
9d5af1db
MJ
3256 if (!avals
3257 || (!avals->m_known_vals.length() && !avals->m_known_contexts.length ()))
27d020cf
JH
3258 return false;
3259 if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
3260 return false;
3261
9d5af1db 3262 target = ipa_get_indirect_edge_target (ie, avals, &speculative);
27d020cf
JH
3263 if (!target || speculative)
3264 return false;
3265
3266 /* Account for difference in cost between indirect and direct calls. */
3267 *size -= (eni_size_weights.indirect_call_cost - eni_size_weights.call_cost);
3268 *time -= (eni_time_weights.indirect_call_cost - eni_time_weights.call_cost);
3269 gcc_checking_assert (*time >= 0);
3270 gcc_checking_assert (*size >= 0);
3271
3272 callee = cgraph_node::get (target);
3273 if (!callee || !callee->definition)
3274 return false;
3275 callee = callee->function_symbol (&avail);
3276 if (avail < AVAIL_AVAILABLE)
3277 return false;
56f62793 3278 isummary = ipa_fn_summaries->get (callee);
1d546c60
ML
3279 if (isummary == NULL)
3280 return false;
3281
27d020cf
JH
3282 return isummary->inlinable;
3283}
3284
3285/* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
9d5af1db
MJ
3286 handle edge E with probability PROB. Set HINTS accordingly if edge may be
3287 devirtualized. AVALS, if non-NULL, describes the context of the call site
3288 as far as values of parameters are concerened. */
27d020cf
JH
3289
3290static inline void
3291estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
9d5af1db 3292 sreal *time, ipa_call_arg_values *avals,
0bceb671 3293 ipa_hints *hints)
27d020cf 3294{
99b1c316 3295 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
3296 int call_size = es->call_stmt_size;
3297 int call_time = es->call_stmt_time;
3298 int cur_size;
98450d19 3299
83263ef5 3300 if (!e->callee && hints && e->maybe_hot_p ()
9d5af1db 3301 && estimate_edge_devirt_benefit (e, &call_size, &call_time, avals))
27d020cf 3302 *hints |= INLINE_HINT_indirect_call;
0bceb671 3303 cur_size = call_size * ipa_fn_summary::size_scale;
27d020cf
JH
3304 *size += cur_size;
3305 if (min_size)
3306 *min_size += cur_size;
98450d19 3307 if (time)
41f0e819 3308 *time += ((sreal)call_time) * e->sreal_frequency ();
27d020cf
JH
3309}
3310
3311
27d020cf 3312/* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
9d5af1db
MJ
3313 calls in NODE. POSSIBLE_TRUTHS and AVALS describe the context of the call
3314 site.
3315
070e3489
JH
3316 Helper for estimate_calls_size_and_time which does the same but
3317 (in most cases) faster. */
27d020cf
JH
3318
3319static void
070e3489
JH
3320estimate_calls_size_and_time_1 (struct cgraph_node *node, int *size,
3321 int *min_size, sreal *time,
3322 ipa_hints *hints,
3323 clause_t possible_truths,
9d5af1db 3324 ipa_call_arg_values *avals)
27d020cf
JH
3325{
3326 struct cgraph_edge *e;
3327 for (e = node->callees; e; e = e->next_callee)
3328 {
7237f93e
JH
3329 if (!e->inline_failed)
3330 {
3331 gcc_checking_assert (!ipa_call_summaries->get (e));
070e3489 3332 estimate_calls_size_and_time_1 (e->callee, size, min_size, time,
9d5af1db
MJ
3333 hints, possible_truths, avals);
3334
7237f93e
JH
3335 continue;
3336 }
3337 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
3338
3339 /* Do not care about zero sized builtins. */
7237f93e 3340 if (!es->call_stmt_size)
27d020cf
JH
3341 {
3342 gcc_checking_assert (!es->call_stmt_time);
3343 continue;
3344 }
3345 if (!es->predicate
3346 || es->predicate->evaluate (possible_truths))
3347 {
7237f93e 3348 /* Predicates of calls shall not use NOT_CHANGED codes,
956d615d 3349 so we do not need to compute probabilities. */
7237f93e
JH
3350 estimate_edge_size_and_time (e, size,
3351 es->predicate ? NULL : min_size,
9d5af1db 3352 time, avals, hints);
27d020cf
JH
3353 }
3354 }
3355 for (e = node->indirect_calls; e; e = e->next_callee)
3356 {
7237f93e 3357 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
3358 if (!es->predicate
3359 || es->predicate->evaluate (possible_truths))
3360 estimate_edge_size_and_time (e, size,
3361 es->predicate ? NULL : min_size,
9d5af1db 3362 time, avals, hints);
27d020cf
JH
3363 }
3364}
3365
070e3489
JH
3366/* Populate sum->call_size_time_table for edges from NODE. */
3367
3368static void
3369summarize_calls_size_and_time (struct cgraph_node *node,
3370 ipa_fn_summary *sum)
3371{
3372 struct cgraph_edge *e;
3373 for (e = node->callees; e; e = e->next_callee)
3374 {
3375 if (!e->inline_failed)
3376 {
3377 gcc_checking_assert (!ipa_call_summaries->get (e));
3378 summarize_calls_size_and_time (e->callee, sum);
3379 continue;
3380 }
3381 int size = 0;
3382 sreal time = 0;
3383
9d5af1db 3384 estimate_edge_size_and_time (e, &size, NULL, &time, NULL, NULL);
070e3489 3385
2d01bef2 3386 ipa_predicate pred = true;
070e3489
JH
3387 class ipa_call_summary *es = ipa_call_summaries->get (e);
3388
3389 if (es->predicate)
3390 pred = *es->predicate;
3391 sum->account_size_time (size, time, pred, pred, true);
3392 }
3393 for (e = node->indirect_calls; e; e = e->next_callee)
3394 {
3395 int size = 0;
3396 sreal time = 0;
3397
9d5af1db 3398 estimate_edge_size_and_time (e, &size, NULL, &time, NULL, NULL);
2d01bef2 3399 ipa_predicate pred = true;
070e3489
JH
3400 class ipa_call_summary *es = ipa_call_summaries->get (e);
3401
3402 if (es->predicate)
3403 pred = *es->predicate;
3404 sum->account_size_time (size, time, pred, pred, true);
3405 }
3406}
3407
3408/* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
9d5af1db
MJ
3409 calls in NODE. POSSIBLE_TRUTHS and AVALS (the latter if non-NULL) describe
3410 context of the call site. */
070e3489
JH
3411
3412static void
3413estimate_calls_size_and_time (struct cgraph_node *node, int *size,
3414 int *min_size, sreal *time,
3415 ipa_hints *hints,
3416 clause_t possible_truths,
9d5af1db 3417 ipa_call_arg_values *avals)
070e3489
JH
3418{
3419 class ipa_fn_summary *sum = ipa_fn_summaries->get (node);
3420 bool use_table = true;
3421
3422 gcc_assert (node->callees || node->indirect_calls);
3423
3424 /* During early inlining we do not calculate info for very
3425 large functions and thus there is no need for producing
3426 summaries. */
3427 if (!ipa_node_params_sum)
3428 use_table = false;
3429 /* Do not calculate summaries for simple wrappers; it is waste
3430 of memory. */
3431 else if (node->callees && node->indirect_calls
3432 && node->callees->inline_failed && !node->callees->next_callee)
3433 use_table = false;
3434 /* If there is an indirect edge that may be optimized, we need
3435 to go the slow way. */
9d5af1db
MJ
3436 else if (avals && hints
3437 && (avals->m_known_vals.length ()
3438 || avals->m_known_contexts.length ()
3439 || avals->m_known_aggs.length ()))
070e3489 3440 {
a4a3cdd0 3441 ipa_node_params *params_summary = ipa_node_params_sum->get (node);
070e3489
JH
3442 unsigned int nargs = params_summary
3443 ? ipa_get_param_count (params_summary) : 0;
3444
3445 for (unsigned int i = 0; i < nargs && use_table; i++)
3446 {
3447 if (ipa_is_param_used_by_indirect_call (params_summary, i)
9d5af1db
MJ
3448 && (avals->safe_sval_at (i)
3449 || (avals->m_known_aggs.length () > i
3450 && avals->m_known_aggs[i].items.length ())))
070e3489
JH
3451 use_table = false;
3452 else if (ipa_is_param_used_by_polymorphic_call (params_summary, i)
9d5af1db
MJ
3453 && (avals->m_known_contexts.length () > i
3454 && !avals->m_known_contexts[i].useless_p ()))
070e3489
JH
3455 use_table = false;
3456 }
3457 }
3458
3459 /* Fast path is via the call size time table. */
3460 if (use_table)
3461 {
3462 /* Build summary if it is absent. */
366099ff 3463 if (!sum->call_size_time_table.length ())
070e3489 3464 {
2d01bef2 3465 ipa_predicate true_pred = true;
070e3489
JH
3466 sum->account_size_time (0, 0, true_pred, true_pred, true);
3467 summarize_calls_size_and_time (node, sum);
3468 }
3469
3470 int old_size = *size;
3471 sreal old_time = time ? *time : 0;
3472
3473 if (min_size)
366099ff 3474 *min_size += sum->call_size_time_table[0].size;
070e3489
JH
3475
3476 unsigned int i;
3477 size_time_entry *e;
3478
3479 /* Walk the table and account sizes and times. */
366099ff 3480 for (i = 0; sum->call_size_time_table.iterate (i, &e);
070e3489
JH
3481 i++)
3482 if (e->exec_predicate.evaluate (possible_truths))
3483 {
3484 *size += e->size;
3485 if (time)
3486 *time += e->time;
3487 }
3488
3489 /* Be careful and see if both methods agree. */
3490 if ((flag_checking || dump_file)
3491 /* Do not try to sanity check when we know we lost some
3492 precision. */
366099ff 3493 && sum->call_size_time_table.length ()
070e3489
JH
3494 < ipa_fn_summary::max_size_time_table_size)
3495 {
3496 estimate_calls_size_and_time_1 (node, &old_size, NULL, &old_time, NULL,
9d5af1db 3497 possible_truths, avals);
070e3489
JH
3498 gcc_assert (*size == old_size);
3499 if (time && (*time - old_time > 1 || *time - old_time < -1)
3500 && dump_file)
f5b25e15 3501 fprintf (dump_file, "Time mismatch in call summary %f!=%f\n",
070e3489
JH
3502 old_time.to_double (),
3503 time->to_double ());
3504 }
3505 }
3506 /* Slow path by walking all edges. */
3507 else
3508 estimate_calls_size_and_time_1 (node, size, min_size, time, hints,
9d5af1db 3509 possible_truths, avals);
070e3489
JH
3510}
3511
9d5af1db
MJ
3512/* Main constructor for ipa call context. Memory allocation of ARG_VALUES
3513 is owned by the caller. INLINE_PARAM_SUMMARY is also owned by the
3514 caller. */
3515
3516ipa_call_context::ipa_call_context (cgraph_node *node, clause_t possible_truths,
1532500e 3517 clause_t nonspec_possible_truths,
1532500e 3518 vec<inline_param_summary>
9d5af1db
MJ
3519 inline_param_summary,
3520 ipa_auto_call_arg_values *arg_values)
1532500e
JH
3521: m_node (node), m_possible_truths (possible_truths),
3522 m_nonspec_possible_truths (nonspec_possible_truths),
3523 m_inline_param_summary (inline_param_summary),
9d5af1db 3524 m_avals (arg_values)
1532500e
JH
3525{
3526}
3527
40a777e8
JH
3528/* Set THIS to be a duplicate of CTX. Copy all relevant info. */
3529
ac6f2e59 3530void
7d2cb275 3531ipa_cached_call_context::duplicate_from (const ipa_call_context &ctx)
ac6f2e59
JH
3532{
3533 m_node = ctx.m_node;
3534 m_possible_truths = ctx.m_possible_truths;
3535 m_nonspec_possible_truths = ctx.m_nonspec_possible_truths;
a4a3cdd0 3536 ipa_node_params *params_summary = ipa_node_params_sum->get (m_node);
6cf67b62
JH
3537 unsigned int nargs = params_summary
3538 ? ipa_get_param_count (params_summary) : 0;
ac6f2e59 3539
40a777e8
JH
3540 m_inline_param_summary = vNULL;
3541 /* Copy the info only if there is at least one useful entry. */
ac6f2e59 3542 if (ctx.m_inline_param_summary.exists ())
40a777e8
JH
3543 {
3544 unsigned int n = MIN (ctx.m_inline_param_summary.length (), nargs);
3545
3546 for (unsigned int i = 0; i < n; i++)
3547 if (ipa_is_param_used_by_ipa_predicates (params_summary, i)
3548 && !ctx.m_inline_param_summary[i].useless_p ())
3549 {
3550 m_inline_param_summary
3551 = ctx.m_inline_param_summary.copy ();
3552 break;
3553 }
3554 }
9d5af1db
MJ
3555 m_avals.m_known_vals = vNULL;
3556 if (ctx.m_avals.m_known_vals.exists ())
40a777e8 3557 {
9d5af1db 3558 unsigned int n = MIN (ctx.m_avals.m_known_vals.length (), nargs);
40a777e8
JH
3559
3560 for (unsigned int i = 0; i < n; i++)
3561 if (ipa_is_param_used_by_indirect_call (params_summary, i)
9d5af1db 3562 && ctx.m_avals.m_known_vals[i])
40a777e8 3563 {
9d5af1db 3564 m_avals.m_known_vals = ctx.m_avals.m_known_vals.copy ();
40a777e8
JH
3565 break;
3566 }
3567 }
3568
9d5af1db
MJ
3569 m_avals.m_known_contexts = vNULL;
3570 if (ctx.m_avals.m_known_contexts.exists ())
40a777e8 3571 {
9d5af1db 3572 unsigned int n = MIN (ctx.m_avals.m_known_contexts.length (), nargs);
40a777e8
JH
3573
3574 for (unsigned int i = 0; i < n; i++)
3575 if (ipa_is_param_used_by_polymorphic_call (params_summary, i)
9d5af1db 3576 && !ctx.m_avals.m_known_contexts[i].useless_p ())
40a777e8 3577 {
9d5af1db 3578 m_avals.m_known_contexts = ctx.m_avals.m_known_contexts.copy ();
40a777e8
JH
3579 break;
3580 }
3581 }
3582
9d5af1db
MJ
3583 m_avals.m_known_aggs = vNULL;
3584 if (ctx.m_avals.m_known_aggs.exists ())
40a777e8 3585 {
9d5af1db 3586 unsigned int n = MIN (ctx.m_avals.m_known_aggs.length (), nargs);
40a777e8
JH
3587
3588 for (unsigned int i = 0; i < n; i++)
3589 if (ipa_is_param_used_by_indirect_call (params_summary, i)
9d5af1db 3590 && !ctx.m_avals.m_known_aggs[i].is_empty ())
40a777e8 3591 {
9d5af1db
MJ
3592 m_avals.m_known_aggs
3593 = ipa_copy_agg_values (ctx.m_avals.m_known_aggs);
40a777e8
JH
3594 break;
3595 }
3596 }
9d5af1db
MJ
3597
3598 m_avals.m_known_value_ranges = vNULL;
ac6f2e59
JH
3599}
3600
7d2cb275
MJ
3601/* Release memory used by known_vals/contexts/aggs vectors. and
3602 inline_param_summary. */
1532500e
JH
3603
3604void
7d2cb275 3605ipa_cached_call_context::release ()
1532500e 3606{
ac6f2e59
JH
3607 /* See if context is initialized at first place. */
3608 if (!m_node)
3609 return;
7d2cb275
MJ
3610 ipa_release_agg_values (m_avals.m_known_aggs, true);
3611 m_avals.m_known_vals.release ();
3612 m_avals.m_known_contexts.release ();
3613 m_inline_param_summary.release ();
ac6f2e59
JH
3614}
3615
3616/* Return true if CTX describes the same call context as THIS. */
3617
3618bool
3619ipa_call_context::equal_to (const ipa_call_context &ctx)
3620{
3621 if (m_node != ctx.m_node
3622 || m_possible_truths != ctx.m_possible_truths
3623 || m_nonspec_possible_truths != ctx.m_nonspec_possible_truths)
3624 return false;
40a777e8 3625
a4a3cdd0 3626 ipa_node_params *params_summary = ipa_node_params_sum->get (m_node);
6cf67b62
JH
3627 unsigned int nargs = params_summary
3628 ? ipa_get_param_count (params_summary) : 0;
40a777e8
JH
3629
3630 if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ())
ac6f2e59 3631 {
40a777e8
JH
3632 for (unsigned int i = 0; i < nargs; i++)
3633 {
3634 if (!ipa_is_param_used_by_ipa_predicates (params_summary, i))
3635 continue;
3636 if (i >= m_inline_param_summary.length ()
3637 || m_inline_param_summary[i].useless_p ())
3638 {
3639 if (i < ctx.m_inline_param_summary.length ()
3640 && !ctx.m_inline_param_summary[i].useless_p ())
3641 return false;
3642 continue;
3643 }
3644 if (i >= ctx.m_inline_param_summary.length ()
3645 || ctx.m_inline_param_summary[i].useless_p ())
3646 {
3647 if (i < m_inline_param_summary.length ()
3648 && !m_inline_param_summary[i].useless_p ())
3649 return false;
3650 continue;
3651 }
3652 if (!m_inline_param_summary[i].equal_to
3653 (ctx.m_inline_param_summary[i]))
3654 return false;
3655 }
ac6f2e59 3656 }
9d5af1db 3657 if (m_avals.m_known_vals.exists () || ctx.m_avals.m_known_vals.exists ())
ac6f2e59 3658 {
40a777e8 3659 for (unsigned int i = 0; i < nargs; i++)
ac6f2e59 3660 {
40a777e8
JH
3661 if (!ipa_is_param_used_by_indirect_call (params_summary, i))
3662 continue;
9d5af1db 3663 if (i >= m_avals.m_known_vals.length () || !m_avals.m_known_vals[i])
40a777e8 3664 {
9d5af1db
MJ
3665 if (i < ctx.m_avals.m_known_vals.length ()
3666 && ctx.m_avals.m_known_vals[i])
40a777e8
JH
3667 return false;
3668 continue;
3669 }
9d5af1db
MJ
3670 if (i >= ctx.m_avals.m_known_vals.length ()
3671 || !ctx.m_avals.m_known_vals[i])
40a777e8 3672 {
9d5af1db 3673 if (i < m_avals.m_known_vals.length () && m_avals.m_known_vals[i])
40a777e8
JH
3674 return false;
3675 continue;
3676 }
9d5af1db 3677 if (m_avals.m_known_vals[i] != ctx.m_avals.m_known_vals[i])
ac6f2e59
JH
3678 return false;
3679 }
3680 }
9d5af1db
MJ
3681 if (m_avals.m_known_contexts.exists ()
3682 || ctx.m_avals.m_known_contexts.exists ())
ac6f2e59 3683 {
40a777e8
JH
3684 for (unsigned int i = 0; i < nargs; i++)
3685 {
3686 if (!ipa_is_param_used_by_polymorphic_call (params_summary, i))
3687 continue;
9d5af1db
MJ
3688 if (i >= m_avals.m_known_contexts.length ()
3689 || m_avals.m_known_contexts[i].useless_p ())
40a777e8 3690 {
9d5af1db
MJ
3691 if (i < ctx.m_avals.m_known_contexts.length ()
3692 && !ctx.m_avals.m_known_contexts[i].useless_p ())
40a777e8
JH
3693 return false;
3694 continue;
3695 }
9d5af1db
MJ
3696 if (i >= ctx.m_avals.m_known_contexts.length ()
3697 || ctx.m_avals.m_known_contexts[i].useless_p ())
40a777e8 3698 {
9d5af1db
MJ
3699 if (i < m_avals.m_known_contexts.length ()
3700 && !m_avals.m_known_contexts[i].useless_p ())
40a777e8
JH
3701 return false;
3702 continue;
3703 }
9d5af1db
MJ
3704 if (!m_avals.m_known_contexts[i].equal_to
3705 (ctx.m_avals.m_known_contexts[i]))
40a777e8
JH
3706 return false;
3707 }
ac6f2e59 3708 }
9d5af1db 3709 if (m_avals.m_known_aggs.exists () || ctx.m_avals.m_known_aggs.exists ())
ac6f2e59 3710 {
40a777e8
JH
3711 for (unsigned int i = 0; i < nargs; i++)
3712 {
3713 if (!ipa_is_param_used_by_indirect_call (params_summary, i))
3714 continue;
9d5af1db
MJ
3715 if (i >= m_avals.m_known_aggs.length ()
3716 || m_avals.m_known_aggs[i].is_empty ())
40a777e8 3717 {
9d5af1db
MJ
3718 if (i < ctx.m_avals.m_known_aggs.length ()
3719 && !ctx.m_avals.m_known_aggs[i].is_empty ())
40a777e8
JH
3720 return false;
3721 continue;
3722 }
9d5af1db
MJ
3723 if (i >= ctx.m_avals.m_known_aggs.length ()
3724 || ctx.m_avals.m_known_aggs[i].is_empty ())
40a777e8 3725 {
9d5af1db
MJ
3726 if (i < m_avals.m_known_aggs.length ()
3727 && !m_avals.m_known_aggs[i].is_empty ())
40a777e8
JH
3728 return false;
3729 continue;
3730 }
9d5af1db 3731 if (!m_avals.m_known_aggs[i].equal_to (ctx.m_avals.m_known_aggs[i]))
40a777e8
JH
3732 return false;
3733 }
ac6f2e59
JH
3734 }
3735 return true;
1532500e 3736}
27d020cf 3737
1e7fdc02
MJ
3738/* Fill in the selected fields in ESTIMATES with value estimated for call in
3739 this context. Always compute size and min_size. Only compute time and
3740 nonspecialized_time if EST_TIMES is true. Only compute hints if EST_HINTS
3741 is true. */
27d020cf
JH
3742
3743void
1e7fdc02
MJ
3744ipa_call_context::estimate_size_and_time (ipa_call_estimates *estimates,
3745 bool est_times, bool est_hints)
27d020cf 3746{
7237f93e 3747 class ipa_fn_summary *info = ipa_fn_summaries->get (m_node);
27d020cf
JH
3748 size_time_entry *e;
3749 int size = 0;
3750 sreal time = 0;
3751 int min_size = 0;
0bceb671 3752 ipa_hints hints = 0;
67ce9099
MJ
3753 sreal loops_with_known_iterations = 0;
3754 sreal loops_with_known_strides = 0;
27d020cf
JH
3755 int i;
3756
3757 if (dump_file && (dump_flags & TDF_DETAILS))
3758 {
3759 bool found = false;
d597b944
ML
3760 fprintf (dump_file, " Estimating body: %s\n"
3761 " Known to be false: ", m_node->dump_name ());
27d020cf 3762
2d01bef2
ML
3763 for (i = ipa_predicate::not_inlined_condition;
3764 i < (ipa_predicate::first_dynamic_condition
27d020cf 3765 + (int) vec_safe_length (info->conds)); i++)
1532500e 3766 if (!(m_possible_truths & (1 << i)))
27d020cf
JH
3767 {
3768 if (found)
3769 fprintf (dump_file, ", ");
3770 found = true;
3771 dump_condition (dump_file, info->conds, i);
3772 }
3773 }
3774
070e3489
JH
3775 if (m_node->callees || m_node->indirect_calls)
3776 estimate_calls_size_and_time (m_node, &size, &min_size,
1e7fdc02
MJ
3777 est_times ? &time : NULL,
3778 est_hints ? &hints : NULL, m_possible_truths,
9d5af1db 3779 &m_avals);
83263ef5 3780
27d020cf
JH
3781 sreal nonspecialized_time = time;
3782
366099ff
JH
3783 min_size += info->size_time_table[0].size;
3784 for (i = 0; info->size_time_table.iterate (i, &e); i++)
27d020cf 3785 {
1532500e 3786 bool exec = e->exec_predicate.evaluate (m_nonspec_possible_truths);
3494e738
JH
3787
3788 /* Because predicates are conservative, it can happen that nonconst is 1
3789 but exec is 0. */
27d020cf
JH
3790 if (exec)
3791 {
1532500e 3792 bool nonconst = e->nonconst_predicate.evaluate (m_possible_truths);
3494e738 3793
27d020cf
JH
3794 gcc_checking_assert (e->time >= 0);
3795 gcc_checking_assert (time >= 0);
3796
3797 /* We compute specialized size only because size of nonspecialized
3798 copy is context independent.
3799
3800 The difference between nonspecialized execution and specialized is
3801 that nonspecialized is not going to have optimized out computations
3802 known to be constant in a specialized setting. */
3803 if (nonconst)
3804 size += e->size;
1e7fdc02 3805 if (!est_times)
83263ef5 3806 continue;
27d020cf
JH
3807 nonspecialized_time += e->time;
3808 if (!nonconst)
3809 ;
1532500e 3810 else if (!m_inline_param_summary.exists ())
27d020cf
JH
3811 {
3812 if (nonconst)
3813 time += e->time;
3814 }
3815 else
3816 {
3817 int prob = e->nonconst_predicate.probability
1532500e
JH
3818 (info->conds, m_possible_truths,
3819 m_inline_param_summary);
27d020cf
JH
3820 gcc_checking_assert (prob >= 0);
3821 gcc_checking_assert (prob <= REG_BR_PROB_BASE);
fd4656a2
JH
3822 if (prob == REG_BR_PROB_BASE)
3823 time += e->time;
3824 else
3825 time += e->time * prob / REG_BR_PROB_BASE;
27d020cf
JH
3826 }
3827 gcc_checking_assert (time >= 0);
3828 }
3829 }
366099ff
JH
3830 gcc_checking_assert (info->size_time_table[0].exec_predicate == true);
3831 gcc_checking_assert (info->size_time_table[0].nonconst_predicate == true);
e3bd08dd 3832 gcc_checking_assert (min_size >= 0);
27d020cf
JH
3833 gcc_checking_assert (size >= 0);
3834 gcc_checking_assert (time >= 0);
3835 /* nonspecialized_time should be always bigger than specialized time.
3836 Roundoff issues however may get into the way. */
59d27026 3837 gcc_checking_assert ((nonspecialized_time - time * 99 / 100) >= -1);
27d020cf
JH
3838
3839 /* Roundoff issues may make specialized time bigger than nonspecialized
956d615d 3840 time. We do not really want that to happen because some heuristics
27d020cf
JH
3841 may get confused by seeing negative speedups. */
3842 if (time > nonspecialized_time)
3843 time = nonspecialized_time;
3844
1e7fdc02 3845 if (est_hints)
83263ef5 3846 {
83263ef5
JH
3847 if (info->scc_no)
3848 hints |= INLINE_HINT_in_scc;
3849 if (DECL_DECLARED_INLINE_P (m_node->decl))
3850 hints |= INLINE_HINT_declared_inline;
caaa218f
JH
3851 if (info->builtin_constant_p_parms.length ()
3852 && DECL_DECLARED_INLINE_P (m_node->decl))
3853 hints |= INLINE_HINT_builtin_constant_p;
67ce9099
MJ
3854
3855 ipa_freqcounting_predicate *fcp;
3856 for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
3857 if (!fcp->predicate->evaluate (m_possible_truths))
3858 {
3859 hints |= INLINE_HINT_loop_iterations;
3860 loops_with_known_iterations += fcp->freq;
3861 }
3862 estimates->loops_with_known_iterations = loops_with_known_iterations;
3863
3864 for (i = 0; vec_safe_iterate (info->loop_strides, i, &fcp); i++)
3865 if (!fcp->predicate->evaluate (m_possible_truths))
3866 {
3867 hints |= INLINE_HINT_loop_stride;
3868 loops_with_known_strides += fcp->freq;
3869 }
3870 estimates->loops_with_known_strides = loops_with_known_strides;
83263ef5 3871 }
27d020cf 3872
0bceb671
JH
3873 size = RDIV (size, ipa_fn_summary::size_scale);
3874 min_size = RDIV (min_size, ipa_fn_summary::size_scale);
27d020cf
JH
3875
3876 if (dump_file && (dump_flags & TDF_DETAILS))
1e7fdc02 3877 {
67ce9099 3878 fprintf (dump_file, "\n size:%i", (int) size);
1e7fdc02 3879 if (est_times)
67ce9099
MJ
3880 fprintf (dump_file, " time:%f nonspec time:%f",
3881 time.to_double (), nonspecialized_time.to_double ());
3882 if (est_hints)
3883 fprintf (dump_file, " loops with known iterations:%f "
3884 "known strides:%f", loops_with_known_iterations.to_double (),
3885 loops_with_known_strides.to_double ());
3886 fprintf (dump_file, "\n");
1e7fdc02
MJ
3887 }
3888 if (est_times)
3889 {
3890 estimates->time = time;
3891 estimates->nonspecialized_time = nonspecialized_time;
3892 }
3893 estimates->size = size;
3894 estimates->min_size = min_size;
3895 if (est_hints)
3896 estimates->hints = hints;
27d020cf
JH
3897 return;
3898}
3899
3900
3901/* Estimate size and time needed to execute callee of EDGE assuming that
3902 parameters known to be constant at caller of EDGE are propagated.
3903 KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
3904 and types for parameters. */
3905
3906void
3907estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
9d5af1db 3908 ipa_auto_call_arg_values *avals,
1e7fdc02 3909 ipa_call_estimates *estimates)
27d020cf
JH
3910{
3911 clause_t clause, nonspec_clause;
3912
9d5af1db
MJ
3913 evaluate_conditions_for_known_args (node, false, avals, &clause,
3914 &nonspec_clause);
3915 ipa_call_context ctx (node, clause, nonspec_clause, vNULL, avals);
1e7fdc02 3916 ctx.estimate_size_and_time (estimates);
27d020cf
JH
3917}
3918
f658ad30
JH
3919/* Return stack frame offset where frame of NODE is supposed to start inside
3920 of the function it is inlined to.
3921 Return 0 for functions that are not inlined. */
3922
3923HOST_WIDE_INT
3924ipa_get_stack_frame_offset (struct cgraph_node *node)
3925{
3926 HOST_WIDE_INT offset = 0;
a62bfab5 3927 if (!node->inlined_to)
f658ad30
JH
3928 return 0;
3929 node = node->callers->caller;
3930 while (true)
3931 {
3932 offset += ipa_size_summaries->get (node)->estimated_self_stack_size;
a62bfab5 3933 if (!node->inlined_to)
f658ad30
JH
3934 return offset;
3935 node = node->callers->caller;
3936 }
3937}
3938
27d020cf
JH
3939
3940/* Update summary information of inline clones after inlining.
3941 Compute peak stack usage. */
3942
3943static void
3944inline_update_callee_summaries (struct cgraph_node *node, int depth)
3945{
3946 struct cgraph_edge *e;
f658ad30 3947
27d020cf
JH
3948 ipa_propagate_frequency (node);
3949 for (e = node->callees; e; e = e->next_callee)
3950 {
3951 if (!e->inline_failed)
3952 inline_update_callee_summaries (e->callee, depth);
7237f93e
JH
3953 else
3954 ipa_call_summaries->get (e)->loop_depth += depth;
27d020cf
JH
3955 }
3956 for (e = node->indirect_calls; e; e = e->next_callee)
56f62793 3957 ipa_call_summaries->get (e)->loop_depth += depth;
27d020cf
JH
3958}
3959
b89e4559
JH
3960/* Update change_prob and points_to_local_or_readonly_memory of EDGE after
3961 INLINED_EDGE has been inlined.
3962
6cf67b62 3963 When function A is inlined in B and A calls C with parameter that
956d615d 3964 changes with probability PROB1 and C is known to be passthrough
27d020cf
JH
3965 of argument if B that change with probability PROB2, the probability
3966 of change is now PROB1*PROB2. */
3967
3968static void
b89e4559
JH
3969remap_edge_params (struct cgraph_edge *inlined_edge,
3970 struct cgraph_edge *edge)
27d020cf
JH
3971{
3972 if (ipa_node_params_sum)
3973 {
3974 int i;
a4a3cdd0 3975 ipa_edge_args *args = ipa_edge_args_sum->get (edge);
a33c028e
JH
3976 if (!args)
3977 return;
99b1c316
MS
3978 class ipa_call_summary *es = ipa_call_summaries->get (edge);
3979 class ipa_call_summary *inlined_es
56f62793 3980 = ipa_call_summaries->get (inlined_edge);
27d020cf 3981
8c02e054
JH
3982 if (es->param.length () == 0)
3983 return;
3984
27d020cf
JH
3985 for (i = 0; i < ipa_get_cs_argument_count (args); i++)
3986 {
3987 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
3988 if (jfunc->type == IPA_JF_PASS_THROUGH
3989 || jfunc->type == IPA_JF_ANCESTOR)
3990 {
3991 int id = jfunc->type == IPA_JF_PASS_THROUGH
3992 ? ipa_get_jf_pass_through_formal_id (jfunc)
3993 : ipa_get_jf_ancestor_formal_id (jfunc);
3994 if (id < (int) inlined_es->param.length ())
3995 {
3996 int prob1 = es->param[i].change_prob;
3997 int prob2 = inlined_es->param[id].change_prob;
3998 int prob = combine_probabilities (prob1, prob2);
3999
4000 if (prob1 && prob2 && !prob)
4001 prob = 1;
4002
4003 es->param[i].change_prob = prob;
b89e4559
JH
4004
4005 if (inlined_es
4006 ->param[id].points_to_local_or_readonly_memory)
4007 es->param[i].points_to_local_or_readonly_memory = true;
27d020cf 4008 }
b89e4559
JH
4009 if (!es->param[i].points_to_local_or_readonly_memory
4010 && jfunc->type == IPA_JF_CONST
4011 && points_to_local_or_readonly_memory_p
4012 (ipa_get_jf_constant (jfunc)))
4013 es->param[i].points_to_local_or_readonly_memory = true;
27d020cf
JH
4014 }
4015 }
4016 }
4017}
4018
4019/* Update edge summaries of NODE after INLINED_EDGE has been inlined.
4020
4021 Remap predicates of callees of NODE. Rest of arguments match
4022 remap_predicate.
4023
4024 Also update change probabilities. */
4025
4026static void
4027remap_edge_summaries (struct cgraph_edge *inlined_edge,
4028 struct cgraph_node *node,
99b1c316 4029 class ipa_fn_summary *info,
40a777e8 4030 class ipa_node_params *params_summary,
99b1c316 4031 class ipa_fn_summary *callee_info,
00dcc88a
MS
4032 const vec<int> &operand_map,
4033 const vec<HOST_WIDE_INT> &offset_map,
27d020cf 4034 clause_t possible_truths,
2d01bef2 4035 ipa_predicate *toplev_predicate)
27d020cf
JH
4036{
4037 struct cgraph_edge *e, *next;
4038 for (e = node->callees; e; e = next)
4039 {
2d01bef2 4040 ipa_predicate p;
27d020cf
JH
4041 next = e->next_callee;
4042
4043 if (e->inline_failed)
4044 {
6cf67b62 4045 class ipa_call_summary *es = ipa_call_summaries->get (e);
b89e4559 4046 remap_edge_params (inlined_edge, e);
27d020cf
JH
4047
4048 if (es->predicate)
4049 {
4050 p = es->predicate->remap_after_inlining
40a777e8
JH
4051 (info, params_summary,
4052 callee_info, operand_map,
27d020cf
JH
4053 offset_map, possible_truths,
4054 *toplev_predicate);
4055 edge_set_predicate (e, &p);
4056 }
4057 else
4058 edge_set_predicate (e, toplev_predicate);
4059 }
4060 else
40a777e8
JH
4061 remap_edge_summaries (inlined_edge, e->callee, info,
4062 params_summary, callee_info,
27d020cf
JH
4063 operand_map, offset_map, possible_truths,
4064 toplev_predicate);
4065 }
4066 for (e = node->indirect_calls; e; e = next)
4067 {
99b1c316 4068 class ipa_call_summary *es = ipa_call_summaries->get (e);
2d01bef2 4069 ipa_predicate p;
27d020cf
JH
4070 next = e->next_callee;
4071
b89e4559 4072 remap_edge_params (inlined_edge, e);
27d020cf
JH
4073 if (es->predicate)
4074 {
4075 p = es->predicate->remap_after_inlining
40a777e8
JH
4076 (info, params_summary,
4077 callee_info, operand_map, offset_map,
27d020cf
JH
4078 possible_truths, *toplev_predicate);
4079 edge_set_predicate (e, &p);
4080 }
4081 else
4082 edge_set_predicate (e, toplev_predicate);
4083 }
4084}
4085
67ce9099 4086/* Run remap_after_inlining on each predicate in V. */
27d020cf
JH
4087
4088static void
67ce9099
MJ
4089remap_freqcounting_predicate (class ipa_fn_summary *info,
4090 class ipa_node_params *params_summary,
4091 class ipa_fn_summary *callee_info,
4092 vec<ipa_freqcounting_predicate, va_gc> *v,
00dcc88a
MS
4093 const vec<int> &operand_map,
4094 const vec<HOST_WIDE_INT> &offset_map,
67ce9099 4095 clause_t possible_truths,
2d01bef2 4096 ipa_predicate *toplev_predicate)
27d020cf 4097
67ce9099
MJ
4098{
4099 ipa_freqcounting_predicate *fcp;
4100 for (int i = 0; vec_safe_iterate (v, i, &fcp); i++)
27d020cf 4101 {
2d01bef2 4102 ipa_predicate p
67ce9099
MJ
4103 = fcp->predicate->remap_after_inlining (info, params_summary,
4104 callee_info, operand_map,
4105 offset_map, possible_truths,
4106 *toplev_predicate);
4107 if (p != false && p != true)
4108 *fcp->predicate &= p;
27d020cf
JH
4109 }
4110}
4111
4112/* We inlined EDGE. Update summary of the function we inlined into. */
4113
4114void
0bceb671 4115ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
27d020cf 4116{
56f62793 4117 ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
a62bfab5
ML
4118 struct cgraph_node *to = (edge->caller->inlined_to
4119 ? edge->caller->inlined_to : edge->caller);
99b1c316 4120 class ipa_fn_summary *info = ipa_fn_summaries->get (to);
27d020cf
JH
4121 clause_t clause = 0; /* not_inline is known to be false. */
4122 size_time_entry *e;
f658ad30 4123 auto_vec<int, 8> operand_map;
14338468 4124 auto_vec<HOST_WIDE_INT, 8> offset_map;
27d020cf 4125 int i;
2d01bef2 4126 ipa_predicate toplev_predicate;
99b1c316 4127 class ipa_call_summary *es = ipa_call_summaries->get (edge);
a4a3cdd0
MJ
4128 ipa_node_params *params_summary = (ipa_node_params_sum
4129 ? ipa_node_params_sum->get (to) : NULL);
27d020cf
JH
4130
4131 if (es->predicate)
4132 toplev_predicate = *es->predicate;
4133 else
4134 toplev_predicate = true;
4135
4136 info->fp_expressions |= callee_info->fp_expressions;
0fc60c18 4137 info->target_info |= callee_info->target_info;
27d020cf
JH
4138
4139 if (callee_info->conds)
b0d55476 4140 {
9d5af1db
MJ
4141 ipa_auto_call_arg_values avals;
4142 evaluate_properties_for_edge (edge, true, &clause, NULL, &avals, false);
b0d55476 4143 }
27d020cf
JH
4144 if (ipa_node_params_sum && callee_info->conds)
4145 {
a4a3cdd0 4146 ipa_edge_args *args = ipa_edge_args_sum->get (edge);
5a0236f8 4147 int count = args ? ipa_get_cs_argument_count (args) : 0;
27d020cf
JH
4148 int i;
4149
4150 if (count)
4151 {
cb3874dc
ML
4152 operand_map.safe_grow_cleared (count, true);
4153 offset_map.safe_grow_cleared (count, true);
27d020cf
JH
4154 }
4155 for (i = 0; i < count; i++)
4156 {
4157 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
4158 int map = -1;
4159
4160 /* TODO: handle non-NOPs when merging. */
4161 if (jfunc->type == IPA_JF_PASS_THROUGH)
4162 {
4163 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4164 map = ipa_get_jf_pass_through_formal_id (jfunc);
4165 if (!ipa_get_jf_pass_through_agg_preserved (jfunc))
4166 offset_map[i] = -1;
4167 }
4168 else if (jfunc->type == IPA_JF_ANCESTOR)
4169 {
4170 HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc);
4171 if (offset >= 0 && offset < INT_MAX)
4172 {
4173 map = ipa_get_jf_ancestor_formal_id (jfunc);
4174 if (!ipa_get_jf_ancestor_agg_preserved (jfunc))
4175 offset = -1;
4176 offset_map[i] = offset;
4177 }
4178 }
4179 operand_map[i] = map;
40a777e8 4180 gcc_assert (map < ipa_get_param_count (params_summary));
27d020cf 4181 }
caaa218f
JH
4182
4183 int ip;
4184 for (i = 0; callee_info->builtin_constant_p_parms.iterate (i, &ip); i++)
4185 if (ip < count && operand_map[ip] >= 0)
4186 add_builtin_constant_p_parm (info, operand_map[ip]);
27d020cf 4187 }
caaa218f 4188 sreal freq = edge->sreal_frequency ();
366099ff 4189 for (i = 0; callee_info->size_time_table.iterate (i, &e); i++)
27d020cf 4190 {
2d01bef2 4191 ipa_predicate p;
27d020cf 4192 p = e->exec_predicate.remap_after_inlining
40a777e8
JH
4193 (info, params_summary,
4194 callee_info, operand_map,
27d020cf
JH
4195 offset_map, clause,
4196 toplev_predicate);
2d01bef2 4197 ipa_predicate nonconstp;
27d020cf 4198 nonconstp = e->nonconst_predicate.remap_after_inlining
40a777e8
JH
4199 (info, params_summary,
4200 callee_info, operand_map,
27d020cf
JH
4201 offset_map, clause,
4202 toplev_predicate);
4203 if (p != false && nonconstp != false)
4204 {
83263ef5 4205 sreal add_time = ((sreal)e->time * freq);
27d020cf
JH
4206 int prob = e->nonconst_predicate.probability (callee_info->conds,
4207 clause, es->param);
fd4656a2
JH
4208 if (prob != REG_BR_PROB_BASE)
4209 add_time = add_time * prob / REG_BR_PROB_BASE;
27d020cf
JH
4210 if (prob != REG_BR_PROB_BASE
4211 && dump_file && (dump_flags & TDF_DETAILS))
4212 {
4213 fprintf (dump_file, "\t\tScaling time by probability:%f\n",
4214 (double) prob / REG_BR_PROB_BASE);
4215 }
4216 info->account_size_time (e->size, add_time, p, nonconstp);
4217 }
4218 }
40a777e8
JH
4219 remap_edge_summaries (edge, edge->callee, info, params_summary,
4220 callee_info, operand_map,
27d020cf 4221 offset_map, clause, &toplev_predicate);
67ce9099
MJ
4222 remap_freqcounting_predicate (info, params_summary, callee_info,
4223 info->loop_iterations, operand_map,
4224 offset_map, clause, &toplev_predicate);
4225 remap_freqcounting_predicate (info, params_summary, callee_info,
4226 info->loop_strides, operand_map,
4227 offset_map, clause, &toplev_predicate);
27d020cf 4228
f658ad30
JH
4229 HOST_WIDE_INT stack_frame_offset = ipa_get_stack_frame_offset (edge->callee);
4230 HOST_WIDE_INT peak = stack_frame_offset + callee_info->estimated_stack_size;
27d020cf 4231
f658ad30
JH
4232 if (info->estimated_stack_size < peak)
4233 info->estimated_stack_size = peak;
4234
4235 inline_update_callee_summaries (edge->callee, es->loop_depth);
366099ff 4236 if (info->call_size_time_table.length ())
d2bcf46c
JH
4237 {
4238 int edge_size = 0;
4239 sreal edge_time = 0;
4240
9d5af1db 4241 estimate_edge_size_and_time (edge, &edge_size, NULL, &edge_time, NULL, 0);
d2bcf46c
JH
4242 /* Unaccount size and time of the optimized out call. */
4243 info->account_size_time (-edge_size, -edge_time,
4244 es->predicate ? *es->predicate : true,
4245 es->predicate ? *es->predicate : true,
4246 true);
4247 /* Account new calls. */
4248 summarize_calls_size_and_time (edge->callee, info);
4249 }
f658ad30
JH
4250
4251 /* Free summaries that are not maintained for inline clones/edges. */
4252 ipa_call_summaries->remove (edge);
4253 ipa_fn_summaries->remove (edge->callee);
7237f93e 4254 ipa_remove_from_growth_caches (edge);
27d020cf
JH
4255}
4256
f658ad30 4257/* For performance reasons ipa_merge_fn_summary_after_inlining is not updating
d2bcf46c
JH
4258 overall size and time. Recompute it.
4259 If RESET is true also recompute call_time_size_table. */
27d020cf
JH
4260
4261void
d2bcf46c 4262ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset)
27d020cf 4263{
7237f93e
JH
4264 class ipa_fn_summary *info = ipa_fn_summaries->get (node);
4265 class ipa_size_summary *size_info = ipa_size_summaries->get (node);
27d020cf
JH
4266 size_time_entry *e;
4267 int i;
4268
f658ad30 4269 size_info->size = 0;
27d020cf 4270 info->time = 0;
366099ff 4271 for (i = 0; info->size_time_table.iterate (i, &e); i++)
27d020cf 4272 {
f658ad30 4273 size_info->size += e->size;
27d020cf
JH
4274 info->time += e->time;
4275 }
366099ff 4276 info->min_size = info->size_time_table[0].size;
d2bcf46c 4277 if (reset)
366099ff 4278 info->call_size_time_table.release ();
070e3489
JH
4279 if (node->callees || node->indirect_calls)
4280 estimate_calls_size_and_time (node, &size_info->size, &info->min_size,
4281 &info->time, NULL,
2d01bef2 4282 ~(clause_t) (1 << ipa_predicate::false_condition),
9d5af1db 4283 NULL);
e3bd08dd
JH
4284 size_info->size = RDIV (size_info->size, ipa_fn_summary::size_scale);
4285 info->min_size = RDIV (info->min_size, ipa_fn_summary::size_scale);
27d020cf
JH
4286}
4287
4288
4289/* This function performs intraprocedural analysis in NODE that is required to
4290 inline indirect calls. */
4291
4292static void
4293inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
4294{
4295 ipa_analyze_node (node);
4296 if (dump_file && (dump_flags & TDF_DETAILS))
4297 {
4298 ipa_print_node_params (dump_file, node);
4299 ipa_print_node_jump_functions (dump_file, node);
4300 }
4301}
4302
4303
4304/* Note function body size. */
4305
4306void
4307inline_analyze_function (struct cgraph_node *node)
4308{
4309 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4310
4311 if (dump_file)
d597b944 4312 fprintf (dump_file, "\nAnalyzing function: %s\n", node->dump_name ());
67f3791f 4313 if (opt_for_fn (node->decl, optimize) && !node->thunk)
27d020cf 4314 inline_indirect_intraprocedural_analysis (node);
0bceb671 4315 compute_fn_summary (node, false);
27d020cf
JH
4316 if (!optimize)
4317 {
4318 struct cgraph_edge *e;
4319 for (e = node->callees; e; e = e->next_callee)
4320 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
4321 for (e = node->indirect_calls; e; e = e->next_callee)
4322 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
4323 }
4324
4325 pop_cfun ();
4326}
4327
4328
4329/* Called when new function is inserted to callgraph late. */
4330
4331void
0bceb671 4332ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
27d020cf
JH
4333{
4334 inline_analyze_function (node);
4335}
4336
4337/* Note function body size. */
4338
d2db2e6b
JH
4339static void
4340ipa_fn_summary_generate (void)
27d020cf
JH
4341{
4342 struct cgraph_node *node;
4343
4344 FOR_EACH_DEFINED_FUNCTION (node)
4345 if (DECL_STRUCT_FUNCTION (node->decl))
87f94429 4346 node->versionable = tree_versionable_function_p (node->decl);
27d020cf 4347
0bceb671 4348 ipa_fn_summary_alloc ();
27d020cf 4349
0bceb671 4350 ipa_fn_summaries->enable_insertion_hook ();
27d020cf
JH
4351
4352 ipa_register_cgraph_hooks ();
27d020cf
JH
4353
4354 FOR_EACH_DEFINED_FUNCTION (node)
29f1e2b1
JH
4355 if (!node->alias
4356 && (flag_generate_lto || flag_generate_offload|| flag_wpa
4357 || opt_for_fn (node->decl, optimize)))
27d020cf
JH
4358 inline_analyze_function (node);
4359}
4360
4361
4362/* Write inline summary for edge E to OB. */
4363
4364static void
99b1c316 4365read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e,
ddfb1317 4366 bool prevails)
27d020cf 4367{
99b1c316 4368 class ipa_call_summary *es = prevails
ddfb1317 4369 ? ipa_call_summaries->get_create (e) : NULL;
2d01bef2 4370 ipa_predicate p;
27d020cf
JH
4371 int length, i;
4372
ddfb1317
JH
4373 int size = streamer_read_uhwi (ib);
4374 int time = streamer_read_uhwi (ib);
4375 int depth = streamer_read_uhwi (ib);
4376
4377 if (es)
4378 {
4379 es->call_stmt_size = size;
4380 es->call_stmt_time = time;
4381 es->loop_depth = depth;
4382 }
0fab169b
PK
4383
4384 bitpack_d bp = streamer_read_bitpack (ib);
ddfb1317
JH
4385 if (es)
4386 es->is_return_callee_uncaptured = bp_unpack_value (&bp, 1);
4387 else
4388 bp_unpack_value (&bp, 1);
0fab169b 4389
27d020cf 4390 p.stream_in (ib);
ddfb1317
JH
4391 if (es)
4392 edge_set_predicate (e, &p);
27d020cf 4393 length = streamer_read_uhwi (ib);
6cef01c3
JH
4394 if (length && es
4395 && (e->possibly_call_in_translation_unit_p ()
4396 /* Also stream in jump functions to builtins in hope that they
4397 will get fnspecs. */
4398 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
27d020cf 4399 {
cb3874dc 4400 es->param.safe_grow_cleared (length, true);
27d020cf 4401 for (i = 0; i < length; i++)
b89e4559
JH
4402 {
4403 es->param[i].change_prob = streamer_read_uhwi (ib);
4404 es->param[i].points_to_local_or_readonly_memory
4405 = streamer_read_uhwi (ib);
4406 }
27d020cf 4407 }
ddfb1317
JH
4408 else
4409 {
4410 for (i = 0; i < length; i++)
b89e4559
JH
4411 {
4412 streamer_read_uhwi (ib);
4413 streamer_read_uhwi (ib);
4414 }
ddfb1317 4415 }
27d020cf
JH
4416}
4417
4418
4419/* Stream in inline summaries from the section. */
4420
4421static void
4422inline_read_section (struct lto_file_decl_data *file_data, const char *data,
4423 size_t len)
4424{
4425 const struct lto_function_header *header =
4426 (const struct lto_function_header *) data;
4427 const int cfg_offset = sizeof (struct lto_function_header);
4428 const int main_offset = cfg_offset + header->cfg_size;
4429 const int string_offset = main_offset + header->main_size;
99b1c316 4430 class data_in *data_in;
27d020cf
JH
4431 unsigned int i, count2, j;
4432 unsigned int f_count;
4433
4434 lto_input_block ib ((const char *) data + main_offset, header->main_size,
4435 file_data->mode_table);
4436
4437 data_in =
4438 lto_data_in_create (file_data, (const char *) data + string_offset,
4439 header->string_size, vNULL);
4440 f_count = streamer_read_uhwi (&ib);
4441 for (i = 0; i < f_count; i++)
4442 {
4443 unsigned int index;
4444 struct cgraph_node *node;
99b1c316 4445 class ipa_fn_summary *info;
40a777e8 4446 class ipa_node_params *params_summary;
f658ad30 4447 class ipa_size_summary *size_info;
27d020cf
JH
4448 lto_symtab_encoder_t encoder;
4449 struct bitpack_d bp;
4450 struct cgraph_edge *e;
2d01bef2 4451 ipa_predicate p;
27d020cf
JH
4452
4453 index = streamer_read_uhwi (&ib);
4454 encoder = file_data->symtab_node_encoder;
4455 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
4456 index));
ddfb1317 4457 info = node->prevailing_p () ? ipa_fn_summaries->get_create (node) : NULL;
a4a3cdd0
MJ
4458 params_summary = node->prevailing_p ()
4459 ? ipa_node_params_sum->get (node) : NULL;
f658ad30
JH
4460 size_info = node->prevailing_p ()
4461 ? ipa_size_summaries->get_create (node) : NULL;
27d020cf 4462
ddfb1317
JH
4463 int stack_size = streamer_read_uhwi (&ib);
4464 int size = streamer_read_uhwi (&ib);
4465 sreal time = sreal::stream_in (&ib);
4466
4467 if (info)
4468 {
4469 info->estimated_stack_size
f658ad30
JH
4470 = size_info->estimated_self_stack_size = stack_size;
4471 size_info->size = size_info->self_size = size;
ddfb1317
JH
4472 info->time = time;
4473 }
27d020cf
JH
4474
4475 bp = streamer_read_bitpack (&ib);
ddfb1317
JH
4476 if (info)
4477 {
0fc60c18
KL
4478 info->inlinable = bp_unpack_value (&bp, 1);
4479 info->fp_expressions = bp_unpack_value (&bp, 1);
4480 if (!lto_stream_offload_p)
4481 info->target_info = streamer_read_uhwi (&ib);
ddfb1317
JH
4482 }
4483 else
4484 {
0fc60c18
KL
4485 bp_unpack_value (&bp, 1);
4486 bp_unpack_value (&bp, 1);
4487 if (!lto_stream_offload_p)
4488 streamer_read_uhwi (&ib);
ddfb1317 4489 }
27d020cf
JH
4490
4491 count2 = streamer_read_uhwi (&ib);
ddfb1317 4492 gcc_assert (!info || !info->conds);
360386c7
JH
4493 if (info)
4494 vec_safe_reserve_exact (info->conds, count2);
27d020cf
JH
4495 for (j = 0; j < count2; j++)
4496 {
4497 struct condition c;
4307a485 4498 unsigned int k, count3;
27d020cf 4499 c.operand_num = streamer_read_uhwi (&ib);
27d020cf 4500 c.code = (enum tree_code) streamer_read_uhwi (&ib);
4307a485 4501 c.type = stream_read_tree (&ib, data_in);
27d020cf
JH
4502 c.val = stream_read_tree (&ib, data_in);
4503 bp = streamer_read_bitpack (&ib);
4504 c.agg_contents = bp_unpack_value (&bp, 1);
4505 c.by_ref = bp_unpack_value (&bp, 1);
4506 if (c.agg_contents)
4507 c.offset = streamer_read_uhwi (&ib);
4307a485 4508 count3 = streamer_read_uhwi (&ib);
360386c7
JH
4509 c.param_ops = NULL;
4510 if (info)
4511 vec_safe_reserve_exact (c.param_ops, count3);
40a777e8
JH
4512 if (params_summary)
4513 ipa_set_param_used_by_ipa_predicates
4514 (params_summary, c.operand_num, true);
4307a485
FX
4515 for (k = 0; k < count3; k++)
4516 {
4517 struct expr_eval_op op;
4518 enum gimple_rhs_class rhs_class;
4519 op.code = (enum tree_code) streamer_read_uhwi (&ib);
4520 op.type = stream_read_tree (&ib, data_in);
4521 switch (rhs_class = get_gimple_rhs_class (op.code))
4522 {
4523 case GIMPLE_UNARY_RHS:
4524 op.index = 0;
4525 op.val[0] = NULL_TREE;
4526 op.val[1] = NULL_TREE;
4527 break;
4528
4529 case GIMPLE_BINARY_RHS:
4530 case GIMPLE_TERNARY_RHS:
4531 bp = streamer_read_bitpack (&ib);
4532 op.index = bp_unpack_value (&bp, 2);
4533 op.val[0] = stream_read_tree (&ib, data_in);
4534 if (rhs_class == GIMPLE_BINARY_RHS)
4535 op.val[1] = NULL_TREE;
4536 else
4537 op.val[1] = stream_read_tree (&ib, data_in);
4538 break;
4539
4540 default:
4541 fatal_error (UNKNOWN_LOCATION,
4542 "invalid fnsummary in LTO stream");
4543 }
360386c7
JH
4544 if (info)
4545 c.param_ops->quick_push (op);
4307a485 4546 }
ddfb1317 4547 if (info)
360386c7 4548 info->conds->quick_push (c);
27d020cf
JH
4549 }
4550 count2 = streamer_read_uhwi (&ib);
366099ff 4551 gcc_assert (!info || !info->size_time_table.length ());
360386c7 4552 if (info && count2)
366099ff 4553 info->size_time_table.reserve_exact (count2);
27d020cf
JH
4554 for (j = 0; j < count2; j++)
4555 {
99b1c316 4556 class size_time_entry e;
27d020cf
JH
4557
4558 e.size = streamer_read_uhwi (&ib);
4559 e.time = sreal::stream_in (&ib);
4560 e.exec_predicate.stream_in (&ib);
4561 e.nonconst_predicate.stream_in (&ib);
4562
ddfb1317 4563 if (info)
366099ff 4564 info->size_time_table.quick_push (e);
27d020cf
JH
4565 }
4566
67ce9099
MJ
4567 count2 = streamer_read_uhwi (&ib);
4568 for (j = 0; j < count2; j++)
4569 {
4570 p.stream_in (&ib);
4571 sreal fcp_freq = sreal::stream_in (&ib);
4572 if (info)
4573 {
4574 ipa_freqcounting_predicate fcp;
4575 fcp.predicate = NULL;
4576 set_hint_predicate (&fcp.predicate, p);
4577 fcp.freq = fcp_freq;
4578 vec_safe_push (info->loop_iterations, fcp);
4579 }
4580 }
4581 count2 = streamer_read_uhwi (&ib);
4582 for (j = 0; j < count2; j++)
4583 {
4584 p.stream_in (&ib);
4585 sreal fcp_freq = sreal::stream_in (&ib);
4586 if (info)
4587 {
4588 ipa_freqcounting_predicate fcp;
4589 fcp.predicate = NULL;
4590 set_hint_predicate (&fcp.predicate, p);
4591 fcp.freq = fcp_freq;
4592 vec_safe_push (info->loop_strides, fcp);
4593 }
4594 }
caaa218f
JH
4595 count2 = streamer_read_uhwi (&ib);
4596 if (info && count2)
4597 info->builtin_constant_p_parms.reserve_exact (count2);
4598 for (j = 0; j < count2; j++)
4599 {
4600 int parm = streamer_read_uhwi (&ib);
4601 if (info)
4602 info->builtin_constant_p_parms.quick_push (parm);
4603 }
27d020cf 4604 for (e = node->callees; e; e = e->next_callee)
ddfb1317 4605 read_ipa_call_summary (&ib, e, info != NULL);
27d020cf 4606 for (e = node->indirect_calls; e; e = e->next_callee)
ddfb1317 4607 read_ipa_call_summary (&ib, e, info != NULL);
27d020cf
JH
4608 }
4609
0bceb671 4610 lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
27d020cf
JH
4611 len);
4612 lto_data_in_delete (data_in);
4613}
4614
4615
4616/* Read inline summary. Jump functions are shared among ipa-cp
4617 and inliner, so when ipa-cp is active, we don't need to write them
4618 twice. */
4619
d2db2e6b
JH
4620static void
4621ipa_fn_summary_read (void)
27d020cf
JH
4622{
4623 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4624 struct lto_file_decl_data *file_data;
4625 unsigned int j = 0;
4626
568de14d 4627 ipa_prop_read_jump_functions ();
0bceb671 4628 ipa_fn_summary_alloc ();
27d020cf
JH
4629
4630 while ((file_data = file_data_vec[j++]))
4631 {
4632 size_t len;
3c56d8d8
ML
4633 const char *data
4634 = lto_get_summary_section_data (file_data, LTO_section_ipa_fn_summary,
4635 &len);
27d020cf
JH
4636 if (data)
4637 inline_read_section (file_data, data, len);
4638 else
4639 /* Fatal error here. We do not want to support compiling ltrans units
4640 with different version of compiler or different flags than the WPA
4641 unit, so this should never happen. */
4642 fatal_error (input_location,
4643 "ipa inline summary is missing in input file");
4644 }
29f1e2b1 4645 ipa_register_cgraph_hooks ();
27d020cf 4646
0bceb671
JH
4647 gcc_assert (ipa_fn_summaries);
4648 ipa_fn_summaries->enable_insertion_hook ();
27d020cf
JH
4649}
4650
4651
4652/* Write inline summary for edge E to OB. */
4653
4654static void
4655write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
4656{
99b1c316 4657 class ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
4658 int i;
4659
4660 streamer_write_uhwi (ob, es->call_stmt_size);
4661 streamer_write_uhwi (ob, es->call_stmt_time);
4662 streamer_write_uhwi (ob, es->loop_depth);
0fab169b
PK
4663
4664 bitpack_d bp = bitpack_create (ob->main_stream);
4665 bp_pack_value (&bp, es->is_return_callee_uncaptured, 1);
4666 streamer_write_bitpack (&bp);
4667
27d020cf
JH
4668 if (es->predicate)
4669 es->predicate->stream_out (ob);
4670 else
4671 streamer_write_uhwi (ob, 0);
4672 streamer_write_uhwi (ob, es->param.length ());
4673 for (i = 0; i < (int) es->param.length (); i++)
b89e4559
JH
4674 {
4675 streamer_write_uhwi (ob, es->param[i].change_prob);
4676 streamer_write_uhwi (ob, es->param[i].points_to_local_or_readonly_memory);
4677 }
27d020cf
JH
4678}
4679
4680
4681/* Write inline summary for node in SET.
4682 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
4683 active, we don't need to write them twice. */
4684
d2db2e6b
JH
4685static void
4686ipa_fn_summary_write (void)
27d020cf 4687{
0bceb671 4688 struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
16570c12 4689 lto_symtab_encoder_iterator lsei;
27d020cf
JH
4690 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
4691 unsigned int count = 0;
27d020cf 4692
16570c12
JJ
4693 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4694 lsei_next_function_in_partition (&lsei))
27d020cf 4695 {
16570c12
JJ
4696 cgraph_node *cnode = lsei_cgraph_node (lsei);
4697 if (cnode->definition && !cnode->alias)
27d020cf
JH
4698 count++;
4699 }
4700 streamer_write_uhwi (ob, count);
4701
16570c12
JJ
4702 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4703 lsei_next_function_in_partition (&lsei))
27d020cf 4704 {
16570c12
JJ
4705 cgraph_node *cnode = lsei_cgraph_node (lsei);
4706 if (cnode->definition && !cnode->alias)
27d020cf 4707 {
99b1c316 4708 class ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
f658ad30 4709 class ipa_size_summary *size_info = ipa_size_summaries->get (cnode);
27d020cf
JH
4710 struct bitpack_d bp;
4711 struct cgraph_edge *edge;
4712 int i;
4713 size_time_entry *e;
4714 struct condition *c;
4715
4716 streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
f658ad30
JH
4717 streamer_write_hwi (ob, size_info->estimated_self_stack_size);
4718 streamer_write_hwi (ob, size_info->self_size);
27d020cf
JH
4719 info->time.stream_out (ob);
4720 bp = bitpack_create (ob->main_stream);
4721 bp_pack_value (&bp, info->inlinable, 1);
27d020cf
JH
4722 bp_pack_value (&bp, info->fp_expressions, 1);
4723 streamer_write_bitpack (&bp);
0fc60c18
KL
4724 if (!lto_stream_offload_p)
4725 streamer_write_uhwi (ob, info->target_info);
27d020cf
JH
4726 streamer_write_uhwi (ob, vec_safe_length (info->conds));
4727 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
4728 {
4307a485
FX
4729 int j;
4730 struct expr_eval_op *op;
4731
27d020cf 4732 streamer_write_uhwi (ob, c->operand_num);
27d020cf 4733 streamer_write_uhwi (ob, c->code);
4307a485 4734 stream_write_tree (ob, c->type, true);
27d020cf
JH
4735 stream_write_tree (ob, c->val, true);
4736 bp = bitpack_create (ob->main_stream);
4737 bp_pack_value (&bp, c->agg_contents, 1);
4738 bp_pack_value (&bp, c->by_ref, 1);
4739 streamer_write_bitpack (&bp);
4740 if (c->agg_contents)
4741 streamer_write_uhwi (ob, c->offset);
4307a485
FX
4742 streamer_write_uhwi (ob, vec_safe_length (c->param_ops));
4743 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
4744 {
4745 streamer_write_uhwi (ob, op->code);
4746 stream_write_tree (ob, op->type, true);
4747 if (op->val[0])
4748 {
4749 bp = bitpack_create (ob->main_stream);
4750 bp_pack_value (&bp, op->index, 2);
4751 streamer_write_bitpack (&bp);
4752 stream_write_tree (ob, op->val[0], true);
4753 if (op->val[1])
4754 stream_write_tree (ob, op->val[1], true);
4755 }
4756 }
27d020cf 4757 }
366099ff
JH
4758 streamer_write_uhwi (ob, info->size_time_table.length ());
4759 for (i = 0; info->size_time_table.iterate (i, &e); i++)
27d020cf
JH
4760 {
4761 streamer_write_uhwi (ob, e->size);
4762 e->time.stream_out (ob);
4763 e->exec_predicate.stream_out (ob);
4764 e->nonconst_predicate.stream_out (ob);
4765 }
67ce9099
MJ
4766 ipa_freqcounting_predicate *fcp;
4767 streamer_write_uhwi (ob, vec_safe_length (info->loop_iterations));
4768 for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
4769 {
4770 fcp->predicate->stream_out (ob);
4771 fcp->freq.stream_out (ob);
4772 }
4773 streamer_write_uhwi (ob, vec_safe_length (info->loop_strides));
4774 for (i = 0; vec_safe_iterate (info->loop_strides, i, &fcp); i++)
4775 {
4776 fcp->predicate->stream_out (ob);
4777 fcp->freq.stream_out (ob);
4778 }
caaa218f
JH
4779 streamer_write_uhwi (ob, info->builtin_constant_p_parms.length ());
4780 int ip;
4781 for (i = 0; info->builtin_constant_p_parms.iterate (i, &ip);
4782 i++)
4783 streamer_write_uhwi (ob, ip);
27d020cf
JH
4784 for (edge = cnode->callees; edge; edge = edge->next_callee)
4785 write_ipa_call_summary (ob, edge);
4786 for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
4787 write_ipa_call_summary (ob, edge);
4788 }
4789 }
4790 streamer_write_char_stream (ob->main_stream, 0);
4791 produce_asm (ob, NULL);
4792 destroy_output_block (ob);
4793
568de14d 4794 ipa_prop_write_jump_functions ();
27d020cf
JH
4795}
4796
4797
f658ad30 4798/* Release function summary. */
27d020cf
JH
4799
4800void
d2db2e6b 4801ipa_free_fn_summary (void)
27d020cf 4802{
27d020cf
JH
4803 if (!ipa_call_summaries)
4804 return;
ddf628e4 4805 ggc_delete (ipa_fn_summaries);
0bceb671 4806 ipa_fn_summaries = NULL;
27d020cf
JH
4807 delete ipa_call_summaries;
4808 ipa_call_summaries = NULL;
4809 edge_predicate_pool.release ();
f658ad30
JH
4810 /* During IPA this is one of largest datastructures to release. */
4811 if (flag_wpa)
4812 ggc_trim ();
4813}
4814
4815/* Release function summary. */
4816
4817void
4818ipa_free_size_summary (void)
4819{
4820 if (!ipa_size_summaries)
4821 return;
78cd68c0 4822 delete ipa_size_summaries;
f658ad30 4823 ipa_size_summaries = NULL;
27d020cf 4824}
d2db2e6b
JH
4825
4826namespace {
4827
4828const pass_data pass_data_local_fn_summary =
4829{
4830 GIMPLE_PASS, /* type */
4831 "local-fnsummary", /* name */
4832 OPTGROUP_INLINE, /* optinfo_flags */
4833 TV_INLINE_PARAMETERS, /* tv_id */
4834 0, /* properties_required */
4835 0, /* properties_provided */
4836 0, /* properties_destroyed */
4837 0, /* todo_flags_start */
4838 0, /* todo_flags_finish */
4839};
4840
4841class pass_local_fn_summary : public gimple_opt_pass
4842{
4843public:
4844 pass_local_fn_summary (gcc::context *ctxt)
4845 : gimple_opt_pass (pass_data_local_fn_summary, ctxt)
4846 {}
4847
4848 /* opt_pass methods: */
4849 opt_pass * clone () { return new pass_local_fn_summary (m_ctxt); }
4850 virtual unsigned int execute (function *)
4851 {
4852 return compute_fn_summary_for_current ();
4853 }
4854
4855}; // class pass_local_fn_summary
4856
4857} // anon namespace
4858
4859gimple_opt_pass *
4860make_pass_local_fn_summary (gcc::context *ctxt)
4861{
4862 return new pass_local_fn_summary (ctxt);
4863}
4864
4865
4866/* Free inline summary. */
4867
4868namespace {
4869
4870const pass_data pass_data_ipa_free_fn_summary =
4871{
4872 SIMPLE_IPA_PASS, /* type */
4873 "free-fnsummary", /* name */
4874 OPTGROUP_NONE, /* optinfo_flags */
4875 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
4876 0, /* properties_required */
4877 0, /* properties_provided */
4878 0, /* properties_destroyed */
4879 0, /* todo_flags_start */
442db276 4880 0, /* todo_flags_finish */
d2db2e6b
JH
4881};
4882
4883class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
4884{
4885public:
4886 pass_ipa_free_fn_summary (gcc::context *ctxt)
442db276
JJ
4887 : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt),
4888 small_p (false)
d2db2e6b
JH
4889 {}
4890
4891 /* opt_pass methods: */
442db276
JJ
4892 opt_pass *clone () { return new pass_ipa_free_fn_summary (m_ctxt); }
4893 void set_pass_param (unsigned int n, bool param)
4894 {
4895 gcc_assert (n == 0);
4896 small_p = param;
4897 }
f658ad30 4898 virtual bool gate (function *) { return true; }
d2db2e6b
JH
4899 virtual unsigned int execute (function *)
4900 {
4901 ipa_free_fn_summary ();
bc2fcccd
JH
4902 /* Free ipa-prop structures if they are no longer needed. */
4903 ipa_free_all_structures_after_iinln ();
f658ad30
JH
4904 if (!flag_wpa)
4905 ipa_free_size_summary ();
12485662 4906 return 0;
d2db2e6b
JH
4907 }
4908
442db276
JJ
4909private:
4910 bool small_p;
d2db2e6b
JH
4911}; // class pass_ipa_free_fn_summary
4912
4913} // anon namespace
4914
4915simple_ipa_opt_pass *
4916make_pass_ipa_free_fn_summary (gcc::context *ctxt)
4917{
4918 return new pass_ipa_free_fn_summary (ctxt);
4919}
4920
4921namespace {
4922
4923const pass_data pass_data_ipa_fn_summary =
4924{
4925 IPA_PASS, /* type */
4926 "fnsummary", /* name */
4927 OPTGROUP_INLINE, /* optinfo_flags */
66447ef0 4928 TV_IPA_FNSUMMARY, /* tv_id */
d2db2e6b
JH
4929 0, /* properties_required */
4930 0, /* properties_provided */
4931 0, /* properties_destroyed */
4932 0, /* todo_flags_start */
4933 ( TODO_dump_symtab ), /* todo_flags_finish */
4934};
4935
4936class pass_ipa_fn_summary : public ipa_opt_pass_d
4937{
4938public:
4939 pass_ipa_fn_summary (gcc::context *ctxt)
4940 : ipa_opt_pass_d (pass_data_ipa_fn_summary, ctxt,
4941 ipa_fn_summary_generate, /* generate_summary */
4942 ipa_fn_summary_write, /* write_summary */
4943 ipa_fn_summary_read, /* read_summary */
4944 NULL, /* write_optimization_summary */
4945 NULL, /* read_optimization_summary */
4946 NULL, /* stmt_fixup */
4947 0, /* function_transform_todo_flags_start */
4948 NULL, /* function_transform */
4949 NULL) /* variable_transform */
4950 {}
4951
4952 /* opt_pass methods: */
4953 virtual unsigned int execute (function *) { return 0; }
4954
4955}; // class pass_ipa_fn_summary
4956
4957} // anon namespace
4958
4959ipa_opt_pass_d *
4960make_pass_ipa_fn_summary (gcc::context *ctxt)
4961{
4962 return new pass_ipa_fn_summary (ctxt);
4963}
de4381a4
DM
4964
4965/* Reset all state within ipa-fnsummary.c so that we can rerun the compiler
4966 within the same process. For use by toplev::finalize. */
4967
4968void
4969ipa_fnsummary_c_finalize (void)
4970{
4971 ipa_free_fn_summary ();
4972}