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