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