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