d: Add test for PR d/108167 to the testsuite [PR108167]
[official-gcc.git] / gcc / ipa-fnsummary.cc
blob63bd525b4c56eb1725732b966dab919c9278b8e5
1 /* Function summary pass.
2 Copyright (C) 2003-2023 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* Analysis of function bodies used by inter-procedural passes
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
30 ipa_fn_summary data structures store above information locally (i.e.
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).
35 We provide access to the ipa_fn_summary data structure and
36 basic logic updating the parameters when inlining is performed.
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.
46 estimate_edge_size_and_time can be used to query
47 function size/time in the given context. ipa_merge_fn_summary_after_inlining merges
48 properties of caller and callee after inlining.
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. */
54 #include "config.h"
55 #define INCLUDE_VECTOR
56 #include "system.h"
57 #include "coretypes.h"
58 #include "backend.h"
59 #include "target.h"
60 #include "tree.h"
61 #include "gimple.h"
62 #include "alloc-pool.h"
63 #include "tree-pass.h"
64 #include "ssa.h"
65 #include "tree-streamer.h"
66 #include "cgraph.h"
67 #include "diagnostic.h"
68 #include "fold-const.h"
69 #include "print-tree.h"
70 #include "tree-inline.h"
71 #include "gimple-pretty-print.h"
72 #include "cfganal.h"
73 #include "gimple-iterator.h"
74 #include "tree-cfg.h"
75 #include "tree-ssa-loop-niter.h"
76 #include "tree-ssa-loop.h"
77 #include "symbol-summary.h"
78 #include "ipa-prop.h"
79 #include "ipa-fnsummary.h"
80 #include "cfgloop.h"
81 #include "tree-scalar-evolution.h"
82 #include "ipa-utils.h"
83 #include "cfgexpand.h"
84 #include "gimplify.h"
85 #include "stringpool.h"
86 #include "attribs.h"
87 #include "tree-into-ssa.h"
88 #include "symtab-clones.h"
89 #include "gimple-range.h"
90 #include "tree-dfa.h"
92 /* Summaries. */
93 fast_function_summary <ipa_fn_summary *, va_gc> *ipa_fn_summaries;
94 fast_function_summary <ipa_size_summary *, va_heap> *ipa_size_summaries;
95 fast_call_summary <ipa_call_summary *, va_heap> *ipa_call_summaries;
97 /* Edge predicates goes here. */
98 static object_allocator<ipa_predicate> edge_predicate_pool ("edge predicates");
101 /* Dump IPA hints. */
102 void
103 ipa_dump_hints (FILE *f, ipa_hints hints)
105 if (!hints)
106 return;
107 fprintf (f, "IPA hints:");
108 if (hints & INLINE_HINT_indirect_call)
110 hints &= ~INLINE_HINT_indirect_call;
111 fprintf (f, " indirect_call");
113 if (hints & INLINE_HINT_loop_iterations)
115 hints &= ~INLINE_HINT_loop_iterations;
116 fprintf (f, " loop_iterations");
118 if (hints & INLINE_HINT_loop_stride)
120 hints &= ~INLINE_HINT_loop_stride;
121 fprintf (f, " loop_stride");
123 if (hints & INLINE_HINT_same_scc)
125 hints &= ~INLINE_HINT_same_scc;
126 fprintf (f, " same_scc");
128 if (hints & INLINE_HINT_in_scc)
130 hints &= ~INLINE_HINT_in_scc;
131 fprintf (f, " in_scc");
133 if (hints & INLINE_HINT_cross_module)
135 hints &= ~INLINE_HINT_cross_module;
136 fprintf (f, " cross_module");
138 if (hints & INLINE_HINT_declared_inline)
140 hints &= ~INLINE_HINT_declared_inline;
141 fprintf (f, " declared_inline");
143 if (hints & INLINE_HINT_known_hot)
145 hints &= ~INLINE_HINT_known_hot;
146 fprintf (f, " known_hot");
148 if (hints & INLINE_HINT_builtin_constant_p)
150 hints &= ~INLINE_HINT_builtin_constant_p;
151 fprintf (f, " builtin_constant_p");
153 gcc_assert (!hints);
157 /* Record SIZE and TIME to SUMMARY.
158 The accounted code will be executed when EXEC_PRED is true.
159 When NONCONST_PRED is false the code will evaluate to constant and
160 will get optimized out in specialized clones of the function.
161 If CALL is true account to call_size_time_table rather than
162 size_time_table. */
164 void
165 ipa_fn_summary::account_size_time (int size, sreal time,
166 const ipa_predicate &exec_pred,
167 const ipa_predicate &nonconst_pred_in,
168 bool call)
170 size_time_entry *e;
171 bool found = false;
172 int i;
173 ipa_predicate nonconst_pred;
174 vec<size_time_entry> *table = call ? &call_size_time_table : &size_time_table;
176 if (exec_pred == false)
177 return;
179 nonconst_pred = nonconst_pred_in & exec_pred;
181 if (nonconst_pred == false)
182 return;
184 /* We need to create initial empty unconditional clause, but otherwise
185 we don't need to account empty times and sizes. */
186 if (!size && time == 0 && table->length ())
187 return;
189 /* Only for calls we are unaccounting what we previously recorded. */
190 gcc_checking_assert (time >= 0 || call);
192 for (i = 0; table->iterate (i, &e); i++)
193 if (e->exec_predicate == exec_pred
194 && e->nonconst_predicate == nonconst_pred)
196 found = true;
197 break;
199 if (i == max_size_time_table_size)
201 i = 0;
202 found = true;
203 e = &(*table)[0];
204 if (dump_file && (dump_flags & TDF_DETAILS))
205 fprintf (dump_file,
206 "\t\tReached limit on number of entries, "
207 "ignoring the predicate.");
209 if (dump_file && (dump_flags & TDF_DETAILS) && (time != 0 || size))
211 fprintf (dump_file,
212 "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
213 ((double) size) / ipa_fn_summary::size_scale,
214 (time.to_double ()), found ? "" : "new ");
215 exec_pred.dump (dump_file, conds, 0);
216 if (exec_pred != nonconst_pred)
218 fprintf (dump_file, " nonconst:");
219 nonconst_pred.dump (dump_file, conds);
221 else
222 fprintf (dump_file, "\n");
224 if (!found)
226 class size_time_entry new_entry;
227 new_entry.size = size;
228 new_entry.time = time;
229 new_entry.exec_predicate = exec_pred;
230 new_entry.nonconst_predicate = nonconst_pred;
231 if (call)
232 call_size_time_table.safe_push (new_entry);
233 else
234 size_time_table.safe_push (new_entry);
236 else
238 e->size += size;
239 e->time += time;
240 /* FIXME: PR bootstrap/92653 gcc_checking_assert (e->time >= -1); */
241 /* Tolerate small roundoff issues. */
242 if (e->time < 0)
243 e->time = 0;
247 /* We proved E to be unreachable, redirect it to __builtin_unreachable. */
249 static struct cgraph_edge *
250 redirect_to_unreachable (struct cgraph_edge *e)
252 struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
253 struct cgraph_node *target
254 = cgraph_node::get_create (builtin_decl_unreachable ());
256 if (e->speculative)
257 e = cgraph_edge::resolve_speculation (e, target->decl);
258 else if (!e->callee)
259 e = cgraph_edge::make_direct (e, target);
260 else
261 e->redirect_callee (target);
262 class ipa_call_summary *es = ipa_call_summaries->get (e);
263 e->inline_failed = CIF_UNREACHABLE;
264 e->count = profile_count::zero ();
265 es->call_stmt_size = 0;
266 es->call_stmt_time = 0;
267 if (callee)
268 callee->remove_symbol_and_inline_clones ();
269 return e;
272 /* Set predicate for edge E. */
274 static void
275 edge_set_predicate (struct cgraph_edge *e, ipa_predicate *predicate)
277 /* If the edge is determined to be never executed, redirect it
278 to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
279 be optimized out. */
280 if (predicate && *predicate == false
281 /* When handling speculative edges, we need to do the redirection
282 just once. Do it always on the direct edge, so we do not
283 attempt to resolve speculation while duplicating the edge. */
284 && (!e->speculative || e->callee))
285 e = redirect_to_unreachable (e);
287 class ipa_call_summary *es = ipa_call_summaries->get (e);
288 if (predicate && *predicate != true)
290 if (!es->predicate)
291 es->predicate = edge_predicate_pool.allocate ();
292 *es->predicate = *predicate;
294 else
296 if (es->predicate)
297 edge_predicate_pool.remove (es->predicate);
298 es->predicate = NULL;
302 /* Set predicate for hint *P. */
304 static void
305 set_hint_predicate (ipa_predicate **p, ipa_predicate new_predicate)
307 if (new_predicate == false || new_predicate == true)
309 if (*p)
310 edge_predicate_pool.remove (*p);
311 *p = NULL;
313 else
315 if (!*p)
316 *p = edge_predicate_pool.allocate ();
317 **p = new_predicate;
321 /* Find if NEW_PREDICATE is already in V and if so, increment its freq.
322 Otherwise add a new item to the vector with this predicate and frerq equal
323 to add_freq, unless the number of predicates would exceed MAX_NUM_PREDICATES
324 in which case the function does nothing. */
326 static void
327 add_freqcounting_predicate (vec<ipa_freqcounting_predicate, va_gc> **v,
328 const ipa_predicate &new_predicate, sreal add_freq,
329 unsigned max_num_predicates)
331 if (new_predicate == false || new_predicate == true)
332 return;
333 ipa_freqcounting_predicate *f;
334 for (int i = 0; vec_safe_iterate (*v, i, &f); i++)
335 if (new_predicate == f->predicate)
337 f->freq += add_freq;
338 return;
340 if (vec_safe_length (*v) >= max_num_predicates)
341 /* Too many different predicates to account for. */
342 return;
344 ipa_freqcounting_predicate fcp;
345 fcp.predicate = NULL;
346 set_hint_predicate (&fcp.predicate, new_predicate);
347 fcp.freq = add_freq;
348 vec_safe_push (*v, fcp);
349 return;
352 /* Compute what conditions may or may not hold given information about
353 parameters. RET_CLAUSE returns truths that may hold in a specialized copy,
354 while RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
355 copy when called in a given context. It is a bitmask of conditions. Bit
356 0 means that condition is known to be false, while bit 1 means that condition
357 may or may not be true. These differs - for example NOT_INLINED condition
358 is always false in the second and also builtin_constant_p tests cannot use
359 the fact that parameter is indeed a constant.
361 When INLINE_P is true, assume that we are inlining. AVAL contains known
362 information about argument values. The function does not modify its content
363 and so AVALs could also be of type ipa_call_arg_values but so far all
364 callers work with the auto version and so we avoid the conversion for
365 convenience.
367 ERROR_MARK value of an argument means compile time invariant. */
369 static void
370 evaluate_conditions_for_known_args (struct cgraph_node *node,
371 bool inline_p,
372 ipa_auto_call_arg_values *avals,
373 clause_t *ret_clause,
374 clause_t *ret_nonspec_clause)
376 clause_t clause = inline_p ? 0 : 1 << ipa_predicate::not_inlined_condition;
377 clause_t nonspec_clause = 1 << ipa_predicate::not_inlined_condition;
378 class ipa_fn_summary *info = ipa_fn_summaries->get (node);
379 int i;
380 struct condition *c;
382 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
384 tree val = NULL;
385 tree res;
386 int j;
387 struct expr_eval_op *op;
389 if (c->agg_contents)
391 if (c->code == ipa_predicate::changed
392 && !c->by_ref
393 && (avals->safe_sval_at(c->operand_num) == error_mark_node))
394 continue;
396 if (tree sval = avals->safe_sval_at (c->operand_num))
397 val = ipa_find_agg_cst_from_init (sval, c->offset, c->by_ref);
398 if (!val)
400 ipa_argagg_value_list avs (avals);
401 val = avs.get_value (c->operand_num, c->offset / BITS_PER_UNIT,
402 c->by_ref);
405 else
407 val = avals->safe_sval_at (c->operand_num);
408 if (val && val == error_mark_node
409 && c->code != ipa_predicate::changed)
410 val = NULL_TREE;
413 if (!val
414 && (c->code == ipa_predicate::changed
415 || c->code == ipa_predicate::is_not_constant))
417 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
418 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
419 continue;
421 if (c->code == ipa_predicate::changed)
423 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
424 continue;
427 if (c->code == ipa_predicate::is_not_constant)
429 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
430 continue;
433 if (val && TYPE_SIZE (c->type) == TYPE_SIZE (TREE_TYPE (val)))
435 if (c->type != TREE_TYPE (val))
436 val = fold_unary (VIEW_CONVERT_EXPR, c->type, val);
437 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
439 if (!val)
440 break;
441 if (!op->val[0])
442 val = fold_unary (op->code, op->type, val);
443 else if (!op->val[1])
444 val = fold_binary (op->code, op->type,
445 op->index ? op->val[0] : val,
446 op->index ? val : op->val[0]);
447 else if (op->index == 0)
448 val = fold_ternary (op->code, op->type,
449 val, op->val[0], op->val[1]);
450 else if (op->index == 1)
451 val = fold_ternary (op->code, op->type,
452 op->val[0], val, op->val[1]);
453 else if (op->index == 2)
454 val = fold_ternary (op->code, op->type,
455 op->val[0], op->val[1], val);
456 else
457 val = NULL_TREE;
460 res = val
461 ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
462 : NULL;
464 if (res && integer_zerop (res))
465 continue;
466 if (res && integer_onep (res))
468 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
469 nonspec_clause
470 |= 1 << (i + ipa_predicate::first_dynamic_condition);
471 continue;
474 if (c->operand_num < (int) avals->m_known_value_ranges.length ()
475 && !c->agg_contents
476 && (!val || TREE_CODE (val) != INTEGER_CST))
478 value_range vr = avals->m_known_value_ranges[c->operand_num];
479 if (!vr.undefined_p ()
480 && !vr.varying_p ()
481 && (TYPE_SIZE (c->type) == TYPE_SIZE (vr.type ())))
483 if (!useless_type_conversion_p (c->type, vr.type ()))
485 value_range res;
486 range_fold_unary_expr (&res, NOP_EXPR,
487 c->type, &vr, vr.type ());
488 vr = res;
490 tree type = c->type;
492 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
494 if (vr.varying_p () || vr.undefined_p ())
495 break;
497 value_range res;
498 if (!op->val[0])
499 range_fold_unary_expr (&res, op->code, op->type, &vr, type);
500 else if (!op->val[1])
502 value_range op0 (op->val[0], op->val[0]);
503 range_fold_binary_expr (&res, op->code, op->type,
504 op->index ? &op0 : &vr,
505 op->index ? &vr : &op0);
507 else
508 res.set_varying (op->type);
509 type = op->type;
510 vr = res;
512 if (!vr.varying_p () && !vr.undefined_p ())
514 value_range res;
515 value_range val_vr (c->val, c->val);
516 range_fold_binary_expr (&res, c->code, boolean_type_node,
517 &vr,
518 &val_vr);
519 if (res.zero_p ())
520 continue;
525 clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
526 nonspec_clause |= 1 << (i + ipa_predicate::first_dynamic_condition);
528 *ret_clause = clause;
529 if (ret_nonspec_clause)
530 *ret_nonspec_clause = nonspec_clause;
533 /* Return true if VRP will be exectued on the function.
534 We do not want to anticipate optimizations that will not happen.
536 FIXME: This can be confused with -fdisable and debug counters and thus
537 it should not be used for correctness (only to make heuristics work).
538 This means that inliner should do its own optimizations of expressions
539 that it predicts to be constant so wrong code can not be triggered by
540 builtin_constant_p. */
542 static bool
543 vrp_will_run_p (struct cgraph_node *node)
545 return (opt_for_fn (node->decl, optimize)
546 && !opt_for_fn (node->decl, optimize_debug)
547 && opt_for_fn (node->decl, flag_tree_vrp));
550 /* Similarly about FRE. */
552 static bool
553 fre_will_run_p (struct cgraph_node *node)
555 return (opt_for_fn (node->decl, optimize)
556 && !opt_for_fn (node->decl, optimize_debug)
557 && opt_for_fn (node->decl, flag_tree_fre));
560 /* Work out what conditions might be true at invocation of E.
561 Compute costs for inlined edge if INLINE_P is true.
563 Return in CLAUSE_PTR the evaluated conditions and in NONSPEC_CLAUSE_PTR
564 (if non-NULL) conditions evaluated for nonspecialized clone called
565 in a given context.
567 Vectors in AVALS will be populated with useful known information about
568 argument values - information not known to have any uses will be omitted -
569 except for m_known_contexts which will only be calculated if
570 COMPUTE_CONTEXTS is true. */
572 void
573 evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
574 clause_t *clause_ptr,
575 clause_t *nonspec_clause_ptr,
576 ipa_auto_call_arg_values *avals,
577 bool compute_contexts)
579 struct cgraph_node *callee = e->callee->ultimate_alias_target ();
580 class ipa_fn_summary *info = ipa_fn_summaries->get (callee);
581 class ipa_edge_args *args;
583 if (clause_ptr)
584 *clause_ptr = inline_p ? 0 : 1 << ipa_predicate::not_inlined_condition;
586 if (ipa_node_params_sum
587 && !e->call_stmt_cannot_inline_p
588 && (info->conds || compute_contexts)
589 && (args = ipa_edge_args_sum->get (e)) != NULL)
591 struct cgraph_node *caller;
592 class ipa_node_params *caller_parms_info, *callee_pi = NULL;
593 class ipa_call_summary *es = ipa_call_summaries->get (e);
594 int i, count = ipa_get_cs_argument_count (args);
596 if (count)
598 if (e->caller->inlined_to)
599 caller = e->caller->inlined_to;
600 else
601 caller = e->caller;
602 caller_parms_info = ipa_node_params_sum->get (caller);
603 callee_pi = ipa_node_params_sum->get (callee);
605 /* Watch for thunks. */
606 if (callee_pi)
607 /* Watch for variadic functions. */
608 count = MIN (count, ipa_get_param_count (callee_pi));
611 if (callee_pi)
612 for (i = 0; i < count; i++)
614 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
616 if (ipa_is_param_used_by_indirect_call (callee_pi, i)
617 || ipa_is_param_used_by_ipa_predicates (callee_pi, i))
619 /* Determine if we know constant value of the parameter. */
620 tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
621 ipa_get_type (callee_pi, i));
623 if (!cst && e->call_stmt
624 && i < (int)gimple_call_num_args (e->call_stmt))
626 cst = gimple_call_arg (e->call_stmt, i);
627 if (!is_gimple_min_invariant (cst))
628 cst = NULL;
630 if (cst)
632 gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
633 if (!avals->m_known_vals.length ())
634 avals->m_known_vals.safe_grow_cleared (count, true);
635 avals->m_known_vals[i] = cst;
637 else if (inline_p && !es->param[i].change_prob)
639 if (!avals->m_known_vals.length ())
640 avals->m_known_vals.safe_grow_cleared (count, true);
641 avals->m_known_vals[i] = error_mark_node;
644 /* If we failed to get simple constant, try value range. */
645 if ((!cst || TREE_CODE (cst) != INTEGER_CST)
646 && vrp_will_run_p (caller)
647 && ipa_is_param_used_by_ipa_predicates (callee_pi, i))
649 value_range vr
650 = ipa_value_range_from_jfunc (caller_parms_info, e, jf,
651 ipa_get_type (callee_pi,
652 i));
653 if (!vr.undefined_p () && !vr.varying_p ())
655 if (!avals->m_known_value_ranges.length ())
657 avals->m_known_value_ranges.safe_grow (count, true);
658 for (int i = 0; i < count; ++i)
659 new (&avals->m_known_value_ranges[i])
660 value_range ();
662 avals->m_known_value_ranges[i] = vr;
666 /* Determine known aggregate values. */
667 if (fre_will_run_p (caller))
668 ipa_push_agg_values_from_jfunc (caller_parms_info,
669 caller, &jf->agg, i,
670 &avals->m_known_aggs);
673 /* For calls used in polymorphic calls we further determine
674 polymorphic call context. */
675 if (compute_contexts
676 && ipa_is_param_used_by_polymorphic_call (callee_pi, i))
678 ipa_polymorphic_call_context
679 ctx = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
680 if (!ctx.useless_p ())
682 if (!avals->m_known_contexts.length ())
683 avals->m_known_contexts.safe_grow_cleared (count, true);
684 avals->m_known_contexts[i]
685 = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
689 else
690 gcc_assert (!count || callee->thunk);
692 else if (e->call_stmt && !e->call_stmt_cannot_inline_p && info->conds)
694 int i, count = (int)gimple_call_num_args (e->call_stmt);
696 for (i = 0; i < count; i++)
698 tree cst = gimple_call_arg (e->call_stmt, i);
699 if (!is_gimple_min_invariant (cst))
700 cst = NULL;
701 if (cst)
703 if (!avals->m_known_vals.length ())
704 avals->m_known_vals.safe_grow_cleared (count, true);
705 avals->m_known_vals[i] = cst;
710 evaluate_conditions_for_known_args (callee, inline_p, avals, clause_ptr,
711 nonspec_clause_ptr);
715 /* Allocate the function summary. */
717 static void
718 ipa_fn_summary_alloc (void)
720 gcc_checking_assert (!ipa_fn_summaries);
721 ipa_size_summaries = new ipa_size_summary_t (symtab);
722 ipa_fn_summaries = ipa_fn_summary_t::create_ggc (symtab);
723 ipa_call_summaries = new ipa_call_summary_t (symtab);
726 ipa_call_summary::~ipa_call_summary ()
728 if (predicate)
729 edge_predicate_pool.remove (predicate);
731 param.release ();
734 ipa_fn_summary::~ipa_fn_summary ()
736 unsigned len = vec_safe_length (loop_iterations);
737 for (unsigned i = 0; i < len; i++)
738 edge_predicate_pool.remove ((*loop_iterations)[i].predicate);
739 len = vec_safe_length (loop_strides);
740 for (unsigned i = 0; i < len; i++)
741 edge_predicate_pool.remove ((*loop_strides)[i].predicate);
742 vec_free (conds);
743 call_size_time_table.release ();
744 vec_free (loop_iterations);
745 vec_free (loop_strides);
746 builtin_constant_p_parms.release ();
749 void
750 ipa_fn_summary_t::remove_callees (cgraph_node *node)
752 cgraph_edge *e;
753 for (e = node->callees; e; e = e->next_callee)
754 ipa_call_summaries->remove (e);
755 for (e = node->indirect_calls; e; e = e->next_callee)
756 ipa_call_summaries->remove (e);
759 /* Duplicate predicates in loop hint vector, allocating memory for them and
760 remove and deallocate any uninteresting (true or false) ones. Return the
761 result. */
763 static vec<ipa_freqcounting_predicate, va_gc> *
764 remap_freqcounting_preds_after_dup (vec<ipa_freqcounting_predicate, va_gc> *v,
765 clause_t possible_truths)
767 if (vec_safe_length (v) == 0)
768 return NULL;
770 vec<ipa_freqcounting_predicate, va_gc> *res = v->copy ();
771 int len = res->length();
772 for (int i = len - 1; i >= 0; i--)
774 ipa_predicate new_predicate
775 = (*res)[i].predicate->remap_after_duplication (possible_truths);
776 /* We do not want to free previous predicate; it is used by node
777 origin. */
778 (*res)[i].predicate = NULL;
779 set_hint_predicate (&(*res)[i].predicate, new_predicate);
781 if (!(*res)[i].predicate)
782 res->unordered_remove (i);
785 return res;
789 /* Hook that is called by cgraph.cc when a node is duplicated. */
790 void
791 ipa_fn_summary_t::duplicate (cgraph_node *src,
792 cgraph_node *dst,
793 ipa_fn_summary *src_info,
794 ipa_fn_summary *info)
796 new (info) ipa_fn_summary (*src_info);
797 /* TODO: as an optimization, we may avoid copying conditions
798 that are known to be false or true. */
799 info->conds = vec_safe_copy (info->conds);
801 clone_info *cinfo = clone_info::get (dst);
802 /* When there are any replacements in the function body, see if we can figure
803 out that something was optimized out. */
804 if (ipa_node_params_sum && cinfo && cinfo->tree_map)
806 /* Use SRC parm info since it may not be copied yet. */
807 ipa_node_params *parms_info = ipa_node_params_sum->get (src);
808 ipa_auto_call_arg_values avals;
809 int count = ipa_get_param_count (parms_info);
810 int i, j;
811 clause_t possible_truths;
812 ipa_predicate true_pred = true;
813 size_time_entry *e;
814 int optimized_out_size = 0;
815 bool inlined_to_p = false;
816 struct cgraph_edge *edge, *next;
818 info->size_time_table.release ();
819 avals.m_known_vals.safe_grow_cleared (count, true);
820 for (i = 0; i < count; i++)
822 struct ipa_replace_map *r;
824 for (j = 0; vec_safe_iterate (cinfo->tree_map, j, &r); j++)
826 if (r->parm_num == i)
828 avals.m_known_vals[i] = r->new_tree;
829 break;
833 evaluate_conditions_for_known_args (dst, false,
834 &avals,
835 &possible_truths,
836 /* We are going to specialize,
837 so ignore nonspec truths. */
838 NULL);
840 info->account_size_time (0, 0, true_pred, true_pred);
842 /* Remap size_time vectors.
843 Simplify the predicate by pruning out alternatives that are known
844 to be false.
845 TODO: as on optimization, we can also eliminate conditions known
846 to be true. */
847 for (i = 0; src_info->size_time_table.iterate (i, &e); i++)
849 ipa_predicate new_exec_pred;
850 ipa_predicate new_nonconst_pred;
851 new_exec_pred = e->exec_predicate.remap_after_duplication
852 (possible_truths);
853 new_nonconst_pred = e->nonconst_predicate.remap_after_duplication
854 (possible_truths);
855 if (new_exec_pred == false || new_nonconst_pred == false)
856 optimized_out_size += e->size;
857 else
858 info->account_size_time (e->size, e->time, new_exec_pred,
859 new_nonconst_pred);
862 /* Remap edge predicates with the same simplification as above.
863 Also copy constantness arrays. */
864 for (edge = dst->callees; edge; edge = next)
866 ipa_predicate new_predicate;
867 class ipa_call_summary *es = ipa_call_summaries->get (edge);
868 next = edge->next_callee;
870 if (!edge->inline_failed)
871 inlined_to_p = true;
872 if (!es->predicate)
873 continue;
874 new_predicate = es->predicate->remap_after_duplication
875 (possible_truths);
876 if (new_predicate == false && *es->predicate != false)
877 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
878 edge_set_predicate (edge, &new_predicate);
881 /* Remap indirect edge predicates with the same simplification as above.
882 Also copy constantness arrays. */
883 for (edge = dst->indirect_calls; edge; edge = next)
885 ipa_predicate new_predicate;
886 class ipa_call_summary *es = ipa_call_summaries->get (edge);
887 next = edge->next_callee;
889 gcc_checking_assert (edge->inline_failed);
890 if (!es->predicate)
891 continue;
892 new_predicate = es->predicate->remap_after_duplication
893 (possible_truths);
894 if (new_predicate == false && *es->predicate != false)
895 optimized_out_size
896 += es->call_stmt_size * ipa_fn_summary::size_scale;
897 edge_set_predicate (edge, &new_predicate);
899 info->loop_iterations
900 = remap_freqcounting_preds_after_dup (info->loop_iterations,
901 possible_truths);
902 info->loop_strides
903 = remap_freqcounting_preds_after_dup (info->loop_strides,
904 possible_truths);
905 if (info->builtin_constant_p_parms.length())
907 vec <int, va_heap, vl_ptr> parms = info->builtin_constant_p_parms;
908 int ip;
909 info->builtin_constant_p_parms = vNULL;
910 for (i = 0; parms.iterate (i, &ip); i++)
911 if (!avals.m_known_vals[ip])
912 info->builtin_constant_p_parms.safe_push (ip);
915 /* If inliner or someone after inliner will ever start producing
916 non-trivial clones, we will get trouble with lack of information
917 about updating self sizes, because size vectors already contains
918 sizes of the callees. */
919 gcc_assert (!inlined_to_p || !optimized_out_size);
921 else
923 info->size_time_table = src_info->size_time_table.copy ();
924 info->loop_iterations = vec_safe_copy (src_info->loop_iterations);
925 info->loop_strides = vec_safe_copy (info->loop_strides);
927 info->builtin_constant_p_parms
928 = info->builtin_constant_p_parms.copy ();
930 ipa_freqcounting_predicate *f;
931 for (int i = 0; vec_safe_iterate (info->loop_iterations, i, &f); i++)
933 ipa_predicate p = *f->predicate;
934 f->predicate = NULL;
935 set_hint_predicate (&f->predicate, p);
937 for (int i = 0; vec_safe_iterate (info->loop_strides, i, &f); i++)
939 ipa_predicate p = *f->predicate;
940 f->predicate = NULL;
941 set_hint_predicate (&f->predicate, p);
944 if (!dst->inlined_to)
945 ipa_update_overall_fn_summary (dst);
949 /* Hook that is called by cgraph.cc when a node is duplicated. */
951 void
952 ipa_call_summary_t::duplicate (struct cgraph_edge *src,
953 struct cgraph_edge *dst,
954 class ipa_call_summary *srcinfo,
955 class ipa_call_summary *info)
957 new (info) ipa_call_summary (*srcinfo);
958 info->predicate = NULL;
959 edge_set_predicate (dst, srcinfo->predicate);
960 info->param = srcinfo->param.copy ();
961 if (!dst->indirect_unknown_callee && src->indirect_unknown_callee)
963 info->call_stmt_size -= (eni_size_weights.indirect_call_cost
964 - eni_size_weights.call_cost);
965 info->call_stmt_time -= (eni_time_weights.indirect_call_cost
966 - eni_time_weights.call_cost);
970 /* Dump edge summaries associated to NODE and recursively to all clones.
971 Indent by INDENT. */
973 static void
974 dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
975 class ipa_fn_summary *info)
977 struct cgraph_edge *edge;
978 for (edge = node->callees; edge; edge = edge->next_callee)
980 class ipa_call_summary *es = ipa_call_summaries->get (edge);
981 struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
982 int i;
984 fprintf (f,
985 "%*s%s %s\n%*s freq:%4.2f",
986 indent, "", callee->dump_name (),
987 !edge->inline_failed
988 ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
989 indent, "", edge->sreal_frequency ().to_double ());
991 if (cross_module_call_p (edge))
992 fprintf (f, " cross module");
994 if (es)
995 fprintf (f, " loop depth:%2i size:%2i time: %2i",
996 es->loop_depth, es->call_stmt_size, es->call_stmt_time);
998 ipa_fn_summary *s = ipa_fn_summaries->get (callee);
999 ipa_size_summary *ss = ipa_size_summaries->get (callee);
1000 if (s != NULL)
1001 fprintf (f, " callee size:%2i stack:%2i",
1002 (int) (ss->size / ipa_fn_summary::size_scale),
1003 (int) s->estimated_stack_size);
1005 if (es && es->predicate)
1007 fprintf (f, " predicate: ");
1008 es->predicate->dump (f, info->conds);
1010 else
1011 fprintf (f, "\n");
1012 if (es && es->param.exists ())
1013 for (i = 0; i < (int) es->param.length (); i++)
1015 int prob = es->param[i].change_prob;
1017 if (!prob)
1018 fprintf (f, "%*s op%i is compile time invariant\n",
1019 indent + 2, "", i);
1020 else if (prob != REG_BR_PROB_BASE)
1021 fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i,
1022 prob * 100.0 / REG_BR_PROB_BASE);
1023 if (es->param[i].points_to_local_or_readonly_memory)
1024 fprintf (f, "%*s op%i points to local or readonly memory\n",
1025 indent + 2, "", i);
1027 if (!edge->inline_failed)
1029 ipa_size_summary *ss = ipa_size_summaries->get (callee);
1030 fprintf (f, "%*sStack frame offset %i, callee self size %i\n",
1031 indent + 2, "",
1032 (int) ipa_get_stack_frame_offset (callee),
1033 (int) ss->estimated_self_stack_size);
1034 dump_ipa_call_summary (f, indent + 2, callee, info);
1037 for (edge = node->indirect_calls; edge; edge = edge->next_callee)
1039 class ipa_call_summary *es = ipa_call_summaries->get (edge);
1040 fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
1041 " time: %2i",
1042 indent, "",
1043 es->loop_depth,
1044 edge->sreal_frequency ().to_double (), es->call_stmt_size,
1045 es->call_stmt_time);
1046 if (es->predicate)
1048 fprintf (f, "predicate: ");
1049 es->predicate->dump (f, info->conds);
1051 else
1052 fprintf (f, "\n");
1057 void
1058 ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
1060 if (node->definition)
1062 class ipa_fn_summary *s = ipa_fn_summaries->get (node);
1063 class ipa_size_summary *ss = ipa_size_summaries->get (node);
1064 if (s != NULL)
1066 size_time_entry *e;
1067 int i;
1068 fprintf (f, "IPA function summary for %s", node->dump_name ());
1069 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
1070 fprintf (f, " always_inline");
1071 if (s->inlinable)
1072 fprintf (f, " inlinable");
1073 if (s->fp_expressions)
1074 fprintf (f, " fp_expression");
1075 if (s->builtin_constant_p_parms.length ())
1077 fprintf (f, " builtin_constant_p_parms");
1078 for (unsigned int i = 0;
1079 i < s->builtin_constant_p_parms.length (); i++)
1080 fprintf (f, " %i", s->builtin_constant_p_parms[i]);
1082 fprintf (f, "\n global time: %f\n", s->time.to_double ());
1083 fprintf (f, " self size: %i\n", ss->self_size);
1084 fprintf (f, " global size: %i\n", ss->size);
1085 fprintf (f, " min size: %i\n", s->min_size);
1086 fprintf (f, " self stack: %i\n",
1087 (int) ss->estimated_self_stack_size);
1088 fprintf (f, " global stack: %i\n", (int) s->estimated_stack_size);
1089 if (s->growth)
1090 fprintf (f, " estimated growth:%i\n", (int) s->growth);
1091 if (s->scc_no)
1092 fprintf (f, " In SCC: %i\n", (int) s->scc_no);
1093 for (i = 0; s->size_time_table.iterate (i, &e); i++)
1095 fprintf (f, " size:%f, time:%f",
1096 (double) e->size / ipa_fn_summary::size_scale,
1097 e->time.to_double ());
1098 if (e->exec_predicate != true)
1100 fprintf (f, ", executed if:");
1101 e->exec_predicate.dump (f, s->conds, 0);
1103 if (e->exec_predicate != e->nonconst_predicate)
1105 fprintf (f, ", nonconst if:");
1106 e->nonconst_predicate.dump (f, s->conds, 0);
1108 fprintf (f, "\n");
1110 ipa_freqcounting_predicate *fcp;
1111 bool first_fcp = true;
1112 for (int i = 0; vec_safe_iterate (s->loop_iterations, i, &fcp); i++)
1114 if (first_fcp)
1116 fprintf (f, " loop iterations:");
1117 first_fcp = false;
1119 fprintf (f, " %3.2f for ", fcp->freq.to_double ());
1120 fcp->predicate->dump (f, s->conds);
1122 first_fcp = true;
1123 for (int i = 0; vec_safe_iterate (s->loop_strides, i, &fcp); i++)
1125 if (first_fcp)
1127 fprintf (f, " loop strides:");
1128 first_fcp = false;
1130 fprintf (f, " %3.2f for :", fcp->freq.to_double ());
1131 fcp->predicate->dump (f, s->conds);
1133 fprintf (f, " calls:\n");
1134 dump_ipa_call_summary (f, 4, node, s);
1135 fprintf (f, "\n");
1136 if (s->target_info)
1137 fprintf (f, " target_info: %x\n", s->target_info);
1139 else
1140 fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
1144 DEBUG_FUNCTION void
1145 ipa_debug_fn_summary (struct cgraph_node *node)
1147 ipa_dump_fn_summary (stderr, node);
1150 void
1151 ipa_dump_fn_summaries (FILE *f)
1153 struct cgraph_node *node;
1155 FOR_EACH_DEFINED_FUNCTION (node)
1156 if (!node->inlined_to)
1157 ipa_dump_fn_summary (f, node);
1160 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
1161 boolean variable pointed to by DATA. */
1163 static bool
1164 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
1165 void *data)
1167 bool *b = (bool *) data;
1168 *b = true;
1169 return true;
1172 /* If OP refers to value of function parameter, return the corresponding
1173 parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
1174 PARM_DECL) will be stored to *SIZE_P in that case too. */
1176 static tree
1177 unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
1178 poly_int64 *size_p)
1180 /* SSA_NAME referring to parm default def? */
1181 if (TREE_CODE (op) == SSA_NAME
1182 && SSA_NAME_IS_DEFAULT_DEF (op)
1183 && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
1185 if (size_p)
1186 *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
1187 return SSA_NAME_VAR (op);
1189 /* Non-SSA parm reference? */
1190 if (TREE_CODE (op) == PARM_DECL
1191 && fbi->aa_walk_budget > 0)
1193 bool modified = false;
1195 ao_ref refd;
1196 ao_ref_init (&refd, op);
1197 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
1198 mark_modified, &modified, NULL, NULL,
1199 fbi->aa_walk_budget);
1200 if (walked < 0)
1202 fbi->aa_walk_budget = 0;
1203 return NULL_TREE;
1205 fbi->aa_walk_budget -= walked;
1206 if (!modified)
1208 if (size_p)
1209 *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
1210 return op;
1213 return NULL_TREE;
1216 /* If OP refers to value of function parameter, return the corresponding
1217 parameter. Also traverse chains of SSA register assignments. If non-NULL,
1218 the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
1219 stored to *SIZE_P in that case too. */
1221 static tree
1222 unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
1223 poly_int64 *size_p)
1225 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
1226 if (res)
1227 return res;
1229 if (TREE_CODE (op) == SSA_NAME
1230 && !SSA_NAME_IS_DEFAULT_DEF (op)
1231 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1232 return unmodified_parm (fbi, SSA_NAME_DEF_STMT (op),
1233 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
1234 size_p);
1235 return NULL_TREE;
1238 /* If OP refers to a value of a function parameter or value loaded from an
1239 aggregate passed to a parameter (either by value or reference), return TRUE
1240 and store the number of the parameter to *INDEX_P, the access size into
1241 *SIZE_P, and information whether and how it has been loaded from an
1242 aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
1243 statement in which OP is used or loaded. */
1245 static bool
1246 unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
1247 gimple *stmt, tree op, int *index_p,
1248 poly_int64 *size_p,
1249 struct agg_position_info *aggpos)
1251 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
1253 gcc_checking_assert (aggpos);
1254 if (res)
1256 *index_p = ipa_get_param_decl_index (fbi->info, res);
1257 if (*index_p < 0)
1258 return false;
1259 aggpos->agg_contents = false;
1260 aggpos->by_ref = false;
1261 return true;
1264 if (TREE_CODE (op) == SSA_NAME)
1266 if (SSA_NAME_IS_DEFAULT_DEF (op)
1267 || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1268 return false;
1269 stmt = SSA_NAME_DEF_STMT (op);
1270 op = gimple_assign_rhs1 (stmt);
1271 if (!REFERENCE_CLASS_P (op))
1272 return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
1273 aggpos);
1276 aggpos->agg_contents = true;
1277 return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
1278 stmt, op, index_p, &aggpos->offset,
1279 size_p, &aggpos->by_ref);
1282 /* See if statement might disappear after inlining.
1283 0 - means not eliminated
1284 1 - half of statements goes away
1285 2 - for sure it is eliminated.
1286 We are not terribly sophisticated, basically looking for simple abstraction
1287 penalty wrappers. */
1289 static int
1290 eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
1292 enum gimple_code code = gimple_code (stmt);
1293 enum tree_code rhs_code;
1295 if (!optimize)
1296 return 0;
1298 switch (code)
1300 case GIMPLE_RETURN:
1301 return 2;
1302 case GIMPLE_ASSIGN:
1303 if (gimple_num_ops (stmt) != 2)
1304 return 0;
1306 rhs_code = gimple_assign_rhs_code (stmt);
1308 /* Casts of parameters, loads from parameters passed by reference
1309 and stores to return value or parameters are often free after
1310 inlining due to SRA and further combining.
1311 Assume that half of statements goes away. */
1312 if (CONVERT_EXPR_CODE_P (rhs_code)
1313 || rhs_code == VIEW_CONVERT_EXPR
1314 || rhs_code == ADDR_EXPR
1315 || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1317 tree rhs = gimple_assign_rhs1 (stmt);
1318 tree lhs = gimple_assign_lhs (stmt);
1319 tree inner_rhs = get_base_address (rhs);
1320 tree inner_lhs = get_base_address (lhs);
1321 bool rhs_free = false;
1322 bool lhs_free = false;
1324 if (!inner_rhs)
1325 inner_rhs = rhs;
1326 if (!inner_lhs)
1327 inner_lhs = lhs;
1329 /* Reads of parameter are expected to be free. */
1330 if (unmodified_parm (fbi, stmt, inner_rhs, NULL))
1331 rhs_free = true;
1332 /* Match expressions of form &this->field. Those will most likely
1333 combine with something upstream after inlining. */
1334 else if (TREE_CODE (inner_rhs) == ADDR_EXPR)
1336 tree op = get_base_address (TREE_OPERAND (inner_rhs, 0));
1337 if (TREE_CODE (op) == PARM_DECL)
1338 rhs_free = true;
1339 else if (TREE_CODE (op) == MEM_REF
1340 && unmodified_parm (fbi, stmt, TREE_OPERAND (op, 0),
1341 NULL))
1342 rhs_free = true;
1345 /* When parameter is not SSA register because its address is taken
1346 and it is just copied into one, the statement will be completely
1347 free after inlining (we will copy propagate backward). */
1348 if (rhs_free && is_gimple_reg (lhs))
1349 return 2;
1351 /* Reads of parameters passed by reference
1352 expected to be free (i.e. optimized out after inlining). */
1353 if (TREE_CODE (inner_rhs) == MEM_REF
1354 && unmodified_parm (fbi, stmt, TREE_OPERAND (inner_rhs, 0), NULL))
1355 rhs_free = true;
1357 /* Copying parameter passed by reference into gimple register is
1358 probably also going to copy propagate, but we can't be quite
1359 sure. */
1360 if (rhs_free && is_gimple_reg (lhs))
1361 lhs_free = true;
1363 /* Writes to parameters, parameters passed by value and return value
1364 (either directly or passed via invisible reference) are free.
1366 TODO: We ought to handle testcase like
1367 struct a {int a,b;};
1368 struct a
1369 returnstruct (void)
1371 struct a a ={1,2};
1372 return a;
1375 This translate into:
1377 returnstruct ()
1379 int a$b;
1380 int a$a;
1381 struct a a;
1382 struct a D.2739;
1384 <bb 2>:
1385 D.2739.a = 1;
1386 D.2739.b = 2;
1387 return D.2739;
1390 For that we either need to copy ipa-split logic detecting writes
1391 to return value. */
1392 if (TREE_CODE (inner_lhs) == PARM_DECL
1393 || TREE_CODE (inner_lhs) == RESULT_DECL
1394 || (TREE_CODE (inner_lhs) == MEM_REF
1395 && (unmodified_parm (fbi, stmt, TREE_OPERAND (inner_lhs, 0),
1396 NULL)
1397 || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
1398 && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
1399 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1400 (inner_lhs,
1401 0))) == RESULT_DECL))))
1402 lhs_free = true;
1403 if (lhs_free
1404 && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
1405 rhs_free = true;
1406 if (lhs_free && rhs_free)
1407 return 1;
1409 return 0;
1410 default:
1411 return 0;
1415 /* Analyze EXPR if it represents a series of simple operations performed on
1416 a function parameter and return true if so. FBI, STMT, EXPR, INDEX_P and
1417 AGGPOS have the same meaning like in unmodified_parm_or_parm_agg_item.
1418 Type of the parameter or load from an aggregate via the parameter is
1419 stored in *TYPE_P. Operations on the parameter are recorded to
1420 PARAM_OPS_P if it is not NULL. */
1422 static bool
1423 decompose_param_expr (struct ipa_func_body_info *fbi,
1424 gimple *stmt, tree expr,
1425 int *index_p, tree *type_p,
1426 struct agg_position_info *aggpos,
1427 expr_eval_ops *param_ops_p = NULL)
1429 int op_limit = opt_for_fn (fbi->node->decl, param_ipa_max_param_expr_ops);
1430 int op_count = 0;
1432 if (param_ops_p)
1433 *param_ops_p = NULL;
1435 while (true)
1437 expr_eval_op eval_op;
1438 unsigned rhs_count;
1439 unsigned cst_count = 0;
1441 if (unmodified_parm_or_parm_agg_item (fbi, stmt, expr, index_p, NULL,
1442 aggpos))
1444 tree type = TREE_TYPE (expr);
1446 if (aggpos->agg_contents)
1448 /* Stop if containing bit-field. */
1449 if (TREE_CODE (expr) == BIT_FIELD_REF
1450 || contains_bitfld_component_ref_p (expr))
1451 break;
1454 *type_p = type;
1455 return true;
1458 if (TREE_CODE (expr) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (expr))
1459 break;
1461 if (!is_gimple_assign (stmt = SSA_NAME_DEF_STMT (expr)))
1462 break;
1464 switch (gimple_assign_rhs_class (stmt))
1466 case GIMPLE_SINGLE_RHS:
1467 expr = gimple_assign_rhs1 (stmt);
1468 continue;
1470 case GIMPLE_UNARY_RHS:
1471 rhs_count = 1;
1472 break;
1474 case GIMPLE_BINARY_RHS:
1475 rhs_count = 2;
1476 break;
1478 case GIMPLE_TERNARY_RHS:
1479 rhs_count = 3;
1480 break;
1482 default:
1483 goto fail;
1486 /* Stop if expression is too complex. */
1487 if (op_count++ == op_limit)
1488 break;
1490 if (param_ops_p)
1492 eval_op.code = gimple_assign_rhs_code (stmt);
1493 eval_op.type = TREE_TYPE (gimple_assign_lhs (stmt));
1494 eval_op.val[0] = NULL_TREE;
1495 eval_op.val[1] = NULL_TREE;
1498 expr = NULL_TREE;
1499 for (unsigned i = 0; i < rhs_count; i++)
1501 tree op = gimple_op (stmt, i + 1);
1503 gcc_assert (op && !TYPE_P (op));
1504 if (is_gimple_ip_invariant (op))
1506 if (++cst_count == rhs_count)
1507 goto fail;
1509 eval_op.val[cst_count - 1] = op;
1511 else if (!expr)
1513 /* Found a non-constant operand, and record its index in rhs
1514 operands. */
1515 eval_op.index = i;
1516 expr = op;
1518 else
1520 /* Found more than one non-constant operands. */
1521 goto fail;
1525 if (param_ops_p)
1526 vec_safe_insert (*param_ops_p, 0, eval_op);
1529 /* Failed to decompose, free resource and return. */
1530 fail:
1531 if (param_ops_p)
1532 vec_free (*param_ops_p);
1534 return false;
1537 /* Record to SUMMARY that PARM is used by builtin_constant_p. */
1539 static void
1540 add_builtin_constant_p_parm (class ipa_fn_summary *summary, int parm)
1542 int ip;
1544 /* Avoid duplicates. */
1545 for (unsigned int i = 0;
1546 summary->builtin_constant_p_parms.iterate (i, &ip); i++)
1547 if (ip == parm)
1548 return;
1549 summary->builtin_constant_p_parms.safe_push (parm);
1552 /* If BB ends by a conditional we can turn into predicates, attach corresponding
1553 predicates to the CFG edges. */
1555 static void
1556 set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1557 class ipa_fn_summary *summary,
1558 class ipa_node_params *params_summary,
1559 basic_block bb)
1561 gimple *last;
1562 tree op, op2;
1563 int index;
1564 struct agg_position_info aggpos;
1565 enum tree_code code, inverted_code;
1566 edge e;
1567 edge_iterator ei;
1568 gimple *set_stmt;
1569 tree param_type;
1570 expr_eval_ops param_ops;
1572 last = last_stmt (bb);
1573 if (!last || gimple_code (last) != GIMPLE_COND)
1574 return;
1575 if (!is_gimple_ip_invariant (gimple_cond_rhs (last)))
1576 return;
1577 op = gimple_cond_lhs (last);
1579 if (decompose_param_expr (fbi, last, op, &index, &param_type, &aggpos,
1580 &param_ops))
1582 code = gimple_cond_code (last);
1583 inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
1585 FOR_EACH_EDGE (e, ei, bb->succs)
1587 enum tree_code this_code = (e->flags & EDGE_TRUE_VALUE
1588 ? code : inverted_code);
1589 /* invert_tree_comparison will return ERROR_MARK on FP
1590 comparisons that are not EQ/NE instead of returning proper
1591 unordered one. Be sure it is not confused with NON_CONSTANT.
1593 And if the edge's target is the final block of diamond CFG graph
1594 of this conditional statement, we do not need to compute
1595 predicate for the edge because the final block's predicate must
1596 be at least as that of the first block of the statement. */
1597 if (this_code != ERROR_MARK
1598 && !dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
1600 ipa_predicate p
1601 = add_condition (summary, params_summary, index,
1602 param_type, &aggpos,
1603 this_code, gimple_cond_rhs (last), param_ops);
1604 e->aux = edge_predicate_pool.allocate ();
1605 *(ipa_predicate *) e->aux = p;
1608 vec_free (param_ops);
1611 if (TREE_CODE (op) != SSA_NAME)
1612 return;
1613 /* Special case
1614 if (builtin_constant_p (op))
1615 constant_code
1616 else
1617 nonconstant_code.
1618 Here we can predicate nonconstant_code. We can't
1619 really handle constant_code since we have no predicate
1620 for this and also the constant code is not known to be
1621 optimized away when inliner doesn't see operand is constant.
1622 Other optimizers might think otherwise. */
1623 if (gimple_cond_code (last) != NE_EXPR
1624 || !integer_zerop (gimple_cond_rhs (last)))
1625 return;
1626 set_stmt = SSA_NAME_DEF_STMT (op);
1627 if (!gimple_call_builtin_p (set_stmt, BUILT_IN_CONSTANT_P)
1628 || gimple_call_num_args (set_stmt) != 1)
1629 return;
1630 op2 = gimple_call_arg (set_stmt, 0);
1631 if (!decompose_param_expr (fbi, set_stmt, op2, &index, &param_type, &aggpos))
1632 return;
1633 if (!aggpos.by_ref)
1634 add_builtin_constant_p_parm (summary, index);
1635 FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
1637 ipa_predicate p = add_condition (summary, params_summary, index,
1638 param_type, &aggpos,
1639 ipa_predicate::is_not_constant, NULL_TREE);
1640 e->aux = edge_predicate_pool.allocate ();
1641 *(ipa_predicate *) e->aux = p;
1646 /* If BB ends by a switch we can turn into predicates, attach corresponding
1647 predicates to the CFG edges. */
1649 static void
1650 set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1651 class ipa_fn_summary *summary,
1652 class ipa_node_params *params_summary,
1653 basic_block bb)
1655 gimple *lastg;
1656 tree op;
1657 int index;
1658 struct agg_position_info aggpos;
1659 edge e;
1660 edge_iterator ei;
1661 size_t n;
1662 size_t case_idx;
1663 tree param_type;
1664 expr_eval_ops param_ops;
1666 lastg = last_stmt (bb);
1667 if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH)
1668 return;
1669 gswitch *last = as_a <gswitch *> (lastg);
1670 op = gimple_switch_index (last);
1671 if (!decompose_param_expr (fbi, last, op, &index, &param_type, &aggpos,
1672 &param_ops))
1673 return;
1675 auto_vec<std::pair<tree, tree> > ranges;
1676 tree type = TREE_TYPE (op);
1677 int bound_limit = opt_for_fn (fbi->node->decl,
1678 param_ipa_max_switch_predicate_bounds);
1679 int bound_count = 0;
1680 value_range vr;
1682 get_range_query (cfun)->range_of_expr (vr, op);
1683 if (vr.undefined_p ())
1684 vr.set_varying (TREE_TYPE (op));
1685 value_range_kind vr_type = vr.kind ();
1686 wide_int vr_wmin = wi::to_wide (vr.min ());
1687 wide_int vr_wmax = wi::to_wide (vr.max ());
1689 FOR_EACH_EDGE (e, ei, bb->succs)
1691 e->aux = edge_predicate_pool.allocate ();
1692 *(ipa_predicate *) e->aux = false;
1695 e = gimple_switch_edge (cfun, last, 0);
1696 /* Set BOUND_COUNT to maximum count to bypass computing predicate for
1697 default case if its target basic block is in convergence point of all
1698 switch cases, which can be determined by checking whether it
1699 post-dominates the switch statement. */
1700 if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
1701 bound_count = INT_MAX;
1703 n = gimple_switch_num_labels (last);
1704 for (case_idx = 1; case_idx < n; ++case_idx)
1706 tree cl = gimple_switch_label (last, case_idx);
1707 tree min = CASE_LOW (cl);
1708 tree max = CASE_HIGH (cl);
1709 ipa_predicate p;
1711 e = gimple_switch_edge (cfun, last, case_idx);
1713 /* The case value might not have same type as switch expression,
1714 extend the value based on the expression type. */
1715 if (TREE_TYPE (min) != type)
1716 min = wide_int_to_tree (type, wi::to_wide (min));
1718 if (!max)
1719 max = min;
1720 else if (TREE_TYPE (max) != type)
1721 max = wide_int_to_tree (type, wi::to_wide (max));
1723 /* The case's target basic block is in convergence point of all switch
1724 cases, its predicate should be at least as that of the switch
1725 statement. */
1726 if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
1727 p = true;
1728 else if (min == max)
1729 p = add_condition (summary, params_summary, index, param_type,
1730 &aggpos, EQ_EXPR, min, param_ops);
1731 else
1733 ipa_predicate p1, p2;
1734 p1 = add_condition (summary, params_summary, index, param_type,
1735 &aggpos, GE_EXPR, min, param_ops);
1736 p2 = add_condition (summary, params_summary,index, param_type,
1737 &aggpos, LE_EXPR, max, param_ops);
1738 p = p1 & p2;
1740 *(ipa_predicate *) e->aux
1741 = p.or_with (summary->conds, *(ipa_predicate *) e->aux);
1743 /* If there are too many disjoint case ranges, predicate for default
1744 case might become too complicated. So add a limit here. */
1745 if (bound_count > bound_limit)
1746 continue;
1748 bool new_range = true;
1750 if (!ranges.is_empty ())
1752 wide_int curr_wmin = wi::to_wide (min);
1753 wide_int last_wmax = wi::to_wide (ranges.last ().second);
1755 /* Merge case ranges if they are continuous. */
1756 if (curr_wmin == last_wmax + 1)
1757 new_range = false;
1758 else if (vr_type == VR_ANTI_RANGE)
1760 /* If two disjoint case ranges can be connected by anti-range
1761 of switch index, combine them to one range. */
1762 if (wi::lt_p (vr_wmax, curr_wmin - 1, TYPE_SIGN (type)))
1763 vr_type = VR_UNDEFINED;
1764 else if (wi::le_p (vr_wmin, last_wmax + 1, TYPE_SIGN (type)))
1765 new_range = false;
1769 /* Create/extend a case range. And we count endpoints of range set,
1770 this number nearly equals to number of conditions that we will create
1771 for predicate of default case. */
1772 if (new_range)
1774 bound_count += (min == max) ? 1 : 2;
1775 ranges.safe_push (std::make_pair (min, max));
1777 else
1779 bound_count += (ranges.last ().first == ranges.last ().second);
1780 ranges.last ().second = max;
1784 e = gimple_switch_edge (cfun, last, 0);
1785 if (bound_count > bound_limit)
1787 *(ipa_predicate *) e->aux = true;
1788 vec_free (param_ops);
1789 return;
1792 ipa_predicate p_seg = true;
1793 ipa_predicate p_all = false;
1795 if (vr_type != VR_RANGE)
1797 vr_wmin = wi::to_wide (TYPE_MIN_VALUE (type));
1798 vr_wmax = wi::to_wide (TYPE_MAX_VALUE (type));
1801 /* Construct predicate to represent default range set that is negation of
1802 all case ranges. Case range is classified as containing single/non-single
1803 values. Suppose a piece of case ranges in the following.
1805 [D1...D2] [S1] ... [Sn] [D3...D4]
1807 To represent default case's range sets between two non-single value
1808 case ranges (From D2 to D3), we construct predicate as:
1810 D2 < x < D3 && x != S1 && ... && x != Sn
1812 for (size_t i = 0; i < ranges.length (); i++)
1814 tree min = ranges[i].first;
1815 tree max = ranges[i].second;
1817 if (min == max)
1818 p_seg &= add_condition (summary, params_summary, index,
1819 param_type, &aggpos, NE_EXPR,
1820 min, param_ops);
1821 else
1823 /* Do not create sub-predicate for range that is beyond low bound
1824 of switch index. */
1825 if (wi::lt_p (vr_wmin, wi::to_wide (min), TYPE_SIGN (type)))
1827 p_seg &= add_condition (summary, params_summary, index,
1828 param_type, &aggpos,
1829 LT_EXPR, min, param_ops);
1830 p_all = p_all.or_with (summary->conds, p_seg);
1833 /* Do not create sub-predicate for range that is beyond up bound
1834 of switch index. */
1835 if (wi::le_p (vr_wmax, wi::to_wide (max), TYPE_SIGN (type)))
1837 p_seg = false;
1838 break;
1841 p_seg = add_condition (summary, params_summary, index,
1842 param_type, &aggpos, GT_EXPR,
1843 max, param_ops);
1847 p_all = p_all.or_with (summary->conds, p_seg);
1848 *(ipa_predicate *) e->aux
1849 = p_all.or_with (summary->conds, *(ipa_predicate *) e->aux);
1851 vec_free (param_ops);
1855 /* For each BB in NODE attach to its AUX pointer predicate under
1856 which it is executable. */
1858 static void
1859 compute_bb_predicates (struct ipa_func_body_info *fbi,
1860 struct cgraph_node *node,
1861 class ipa_fn_summary *summary,
1862 class ipa_node_params *params_summary)
1864 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1865 bool done = false;
1866 basic_block bb;
1868 FOR_EACH_BB_FN (bb, my_function)
1870 set_cond_stmt_execution_predicate (fbi, summary, params_summary, bb);
1871 set_switch_stmt_execution_predicate (fbi, summary, params_summary, bb);
1874 /* Entry block is always executable. */
1875 ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux
1876 = edge_predicate_pool.allocate ();
1877 *(ipa_predicate *) ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux = true;
1879 /* A simple dataflow propagation of predicates forward in the CFG.
1880 TODO: work in reverse postorder. */
1881 while (!done)
1883 done = true;
1884 FOR_EACH_BB_FN (bb, my_function)
1886 ipa_predicate p = false;
1887 edge e;
1888 edge_iterator ei;
1889 FOR_EACH_EDGE (e, ei, bb->preds)
1891 if (e->src->aux)
1893 ipa_predicate this_bb_predicate
1894 = *(ipa_predicate *) e->src->aux;
1895 if (e->aux)
1896 this_bb_predicate &= (*(ipa_predicate *) e->aux);
1897 p = p.or_with (summary->conds, this_bb_predicate);
1898 if (p == true)
1899 break;
1902 if (p != false)
1904 basic_block pdom_bb;
1906 if (!bb->aux)
1908 done = false;
1909 bb->aux = edge_predicate_pool.allocate ();
1910 *((ipa_predicate *) bb->aux) = p;
1912 else if (p != *(ipa_predicate *) bb->aux)
1914 /* This OR operation is needed to ensure monotonous data flow
1915 in the case we hit the limit on number of clauses and the
1916 and/or operations above give approximate answers. */
1917 p = p.or_with (summary->conds, *(ipa_predicate *)bb->aux);
1918 if (p != *(ipa_predicate *)bb->aux)
1920 done = false;
1921 *((ipa_predicate *)bb->aux) = p;
1925 /* For switch/if statement, we can OR-combine predicates of all
1926 its cases/branches to get predicate for basic block in their
1927 convergence point, but sometimes this will generate very
1928 complicated predicate. Actually, we can get simplified
1929 predicate in another way by using the fact that predicate
1930 for a basic block must also hold true for its post dominators.
1931 To be specific, basic block in convergence point of
1932 conditional statement should include predicate of the
1933 statement. */
1934 pdom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
1935 if (pdom_bb == EXIT_BLOCK_PTR_FOR_FN (my_function) || !pdom_bb)
1937 else if (!pdom_bb->aux)
1939 done = false;
1940 pdom_bb->aux = edge_predicate_pool.allocate ();
1941 *((ipa_predicate *)pdom_bb->aux) = p;
1943 else if (p != *(ipa_predicate *)pdom_bb->aux)
1945 p = p.or_with (summary->conds,
1946 *(ipa_predicate *)pdom_bb->aux);
1947 if (p != *(ipa_predicate *)pdom_bb->aux)
1949 done = false;
1950 *((ipa_predicate *)pdom_bb->aux) = p;
1959 /* Return predicate specifying when the STMT might have result that is not
1960 a compile time constant. */
1962 static ipa_predicate
1963 will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
1964 class ipa_fn_summary *summary,
1965 class ipa_node_params *params_summary,
1966 tree expr,
1967 vec<ipa_predicate> nonconstant_names)
1969 tree parm;
1970 int index;
1972 while (UNARY_CLASS_P (expr))
1973 expr = TREE_OPERAND (expr, 0);
1975 parm = unmodified_parm (fbi, NULL, expr, NULL);
1976 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
1977 return add_condition (summary, params_summary, index, TREE_TYPE (parm), NULL,
1978 ipa_predicate::changed, NULL_TREE);
1979 if (is_gimple_min_invariant (expr))
1980 return false;
1981 if (TREE_CODE (expr) == SSA_NAME)
1982 return nonconstant_names[SSA_NAME_VERSION (expr)];
1983 if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
1985 ipa_predicate p1
1986 = will_be_nonconstant_expr_predicate (fbi, summary,
1987 params_summary,
1988 TREE_OPERAND (expr, 0),
1989 nonconstant_names);
1990 if (p1 == true)
1991 return p1;
1993 ipa_predicate p2
1994 = will_be_nonconstant_expr_predicate (fbi, summary,
1995 params_summary,
1996 TREE_OPERAND (expr, 1),
1997 nonconstant_names);
1998 return p1.or_with (summary->conds, p2);
2000 else if (TREE_CODE (expr) == COND_EXPR)
2002 ipa_predicate p1
2003 = will_be_nonconstant_expr_predicate (fbi, summary,
2004 params_summary,
2005 TREE_OPERAND (expr, 0),
2006 nonconstant_names);
2007 if (p1 == true)
2008 return p1;
2010 ipa_predicate p2
2011 = will_be_nonconstant_expr_predicate (fbi, summary,
2012 params_summary,
2013 TREE_OPERAND (expr, 1),
2014 nonconstant_names);
2015 if (p2 == true)
2016 return p2;
2017 p1 = p1.or_with (summary->conds, p2);
2018 p2 = will_be_nonconstant_expr_predicate (fbi, summary,
2019 params_summary,
2020 TREE_OPERAND (expr, 2),
2021 nonconstant_names);
2022 return p2.or_with (summary->conds, p1);
2024 else if (TREE_CODE (expr) == CALL_EXPR)
2025 return true;
2026 else
2028 debug_tree (expr);
2029 gcc_unreachable ();
2034 /* Return predicate specifying when the STMT might have result that is not
2035 a compile time constant. */
2037 static ipa_predicate
2038 will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
2039 class ipa_fn_summary *summary,
2040 class ipa_node_params *params_summary,
2041 gimple *stmt,
2042 vec<ipa_predicate> nonconstant_names)
2044 ipa_predicate p = true;
2045 ssa_op_iter iter;
2046 tree use;
2047 tree param_type = NULL_TREE;
2048 ipa_predicate op_non_const;
2049 bool is_load;
2050 int base_index;
2051 struct agg_position_info aggpos;
2053 /* What statements might be optimized away
2054 when their arguments are constant. */
2055 if (gimple_code (stmt) != GIMPLE_ASSIGN
2056 && gimple_code (stmt) != GIMPLE_COND
2057 && gimple_code (stmt) != GIMPLE_SWITCH
2058 && (gimple_code (stmt) != GIMPLE_CALL
2059 || !(gimple_call_flags (stmt) & ECF_CONST)))
2060 return p;
2062 /* Stores will stay anyway. */
2063 if (gimple_store_p (stmt))
2064 return p;
2066 is_load = gimple_assign_load_p (stmt);
2068 /* Loads can be optimized when the value is known. */
2069 if (is_load)
2071 tree op = gimple_assign_rhs1 (stmt);
2072 if (!decompose_param_expr (fbi, stmt, op, &base_index, &param_type,
2073 &aggpos))
2074 return p;
2076 else
2077 base_index = -1;
2079 /* See if we understand all operands before we start
2080 adding conditionals. */
2081 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
2083 tree parm = unmodified_parm (fbi, stmt, use, NULL);
2084 /* For arguments we can build a condition. */
2085 if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
2086 continue;
2087 if (TREE_CODE (use) != SSA_NAME)
2088 return p;
2089 /* If we know when operand is constant,
2090 we still can say something useful. */
2091 if (nonconstant_names[SSA_NAME_VERSION (use)] != true)
2092 continue;
2093 return p;
2096 if (is_load)
2097 op_non_const =
2098 add_condition (summary, params_summary,
2099 base_index, param_type, &aggpos,
2100 ipa_predicate::changed, NULL_TREE);
2101 else
2102 op_non_const = false;
2103 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
2105 tree parm = unmodified_parm (fbi, stmt, use, NULL);
2106 int index;
2108 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
2110 if (index != base_index)
2111 p = add_condition (summary, params_summary, index,
2112 TREE_TYPE (parm), NULL,
2113 ipa_predicate::changed, NULL_TREE);
2114 else
2115 continue;
2117 else
2118 p = nonconstant_names[SSA_NAME_VERSION (use)];
2119 op_non_const = p.or_with (summary->conds, op_non_const);
2121 if ((gimple_code (stmt) == GIMPLE_ASSIGN || gimple_code (stmt) == GIMPLE_CALL)
2122 && gimple_op (stmt, 0)
2123 && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
2124 nonconstant_names[SSA_NAME_VERSION (gimple_op (stmt, 0))]
2125 = op_non_const;
2126 return op_non_const;
2129 struct record_modified_bb_info
2131 tree op;
2132 bitmap bb_set;
2133 gimple *stmt;
2136 /* Value is initialized in INIT_BB and used in USE_BB. We want to compute
2137 probability how often it changes between USE_BB.
2138 INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
2139 is in different loop nest, we can do better.
2140 This is all just estimate. In theory we look for minimal cut separating
2141 INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
2142 anyway. */
2144 static basic_block
2145 get_minimal_bb (basic_block init_bb, basic_block use_bb)
2147 class loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
2148 if (l && l->header->count < init_bb->count)
2149 return l->header;
2150 return init_bb;
2153 /* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
2154 set except for info->stmt. */
2156 static bool
2157 record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
2159 struct record_modified_bb_info *info =
2160 (struct record_modified_bb_info *) data;
2161 if (SSA_NAME_DEF_STMT (vdef) == info->stmt)
2162 return false;
2163 if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef)))
2164 return false;
2165 bitmap_set_bit (info->bb_set,
2166 SSA_NAME_IS_DEFAULT_DEF (vdef)
2167 ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index
2168 : get_minimal_bb
2169 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
2170 gimple_bb (info->stmt))->index);
2171 if (dump_file)
2173 fprintf (dump_file, " Param ");
2174 print_generic_expr (dump_file, info->op, TDF_SLIM);
2175 fprintf (dump_file, " changed at bb %i, minimal: %i stmt: ",
2176 gimple_bb (SSA_NAME_DEF_STMT (vdef))->index,
2177 get_minimal_bb
2178 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
2179 gimple_bb (info->stmt))->index);
2180 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (vdef), 0);
2182 return false;
2185 /* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
2186 will change since last invocation of STMT.
2188 Value 0 is reserved for compile time invariants.
2189 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
2190 ought to be REG_BR_PROB_BASE / estimated_iters. */
2192 static int
2193 param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
2195 tree op = gimple_call_arg (stmt, i);
2196 basic_block bb = gimple_bb (stmt);
2198 if (TREE_CODE (op) == WITH_SIZE_EXPR)
2199 op = TREE_OPERAND (op, 0);
2201 tree base = get_base_address (op);
2203 /* Global invariants never change. */
2204 if (is_gimple_min_invariant (base))
2205 return 0;
2207 /* We would have to do non-trivial analysis to really work out what
2208 is the probability of value to change (i.e. when init statement
2209 is in a sibling loop of the call).
2211 We do an conservative estimate: when call is executed N times more often
2212 than the statement defining value, we take the frequency 1/N. */
2213 if (TREE_CODE (base) == SSA_NAME)
2215 profile_count init_count;
2217 if (!bb->count.nonzero_p ())
2218 return REG_BR_PROB_BASE;
2220 if (SSA_NAME_IS_DEFAULT_DEF (base))
2221 init_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
2222 else
2223 init_count = get_minimal_bb
2224 (gimple_bb (SSA_NAME_DEF_STMT (base)),
2225 gimple_bb (stmt))->count;
2227 if (init_count < bb->count)
2228 return MAX ((init_count.to_sreal_scale (bb->count)
2229 * REG_BR_PROB_BASE).to_int (), 1);
2230 return REG_BR_PROB_BASE;
2232 else
2234 ao_ref refd;
2235 profile_count max = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
2236 struct record_modified_bb_info info;
2237 tree init = ctor_for_folding (base);
2239 if (init != error_mark_node)
2240 return 0;
2241 if (!bb->count.nonzero_p () || fbi->aa_walk_budget == 0)
2242 return REG_BR_PROB_BASE;
2243 if (dump_file)
2245 fprintf (dump_file, " Analyzing param change probability of ");
2246 print_generic_expr (dump_file, op, TDF_SLIM);
2247 fprintf (dump_file, "\n");
2249 ao_ref_init (&refd, op);
2250 info.op = op;
2251 info.stmt = stmt;
2252 info.bb_set = BITMAP_ALLOC (NULL);
2253 int walked
2254 = walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
2255 NULL, NULL, fbi->aa_walk_budget);
2256 if (walked > 0)
2257 fbi->aa_walk_budget -= walked;
2258 if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
2260 if (walked < 0)
2261 fbi->aa_walk_budget = 0;
2262 if (dump_file)
2264 if (walked < 0)
2265 fprintf (dump_file, " Ran out of AA walking budget.\n");
2266 else
2267 fprintf (dump_file, " Set in same BB as used.\n");
2269 BITMAP_FREE (info.bb_set);
2270 return REG_BR_PROB_BASE;
2273 bitmap_iterator bi;
2274 unsigned index;
2275 /* Lookup the most frequent update of the value and believe that
2276 it dominates all the other; precise analysis here is difficult. */
2277 EXECUTE_IF_SET_IN_BITMAP (info.bb_set, 0, index, bi)
2278 max = max.max (BASIC_BLOCK_FOR_FN (cfun, index)->count);
2279 if (dump_file)
2281 fprintf (dump_file, " Set with count ");
2282 max.dump (dump_file);
2283 fprintf (dump_file, " and used with count ");
2284 bb->count.dump (dump_file);
2285 fprintf (dump_file, " freq %f\n",
2286 max.to_sreal_scale (bb->count).to_double ());
2289 BITMAP_FREE (info.bb_set);
2290 if (max < bb->count)
2291 return MAX ((max.to_sreal_scale (bb->count)
2292 * REG_BR_PROB_BASE).to_int (), 1);
2293 return REG_BR_PROB_BASE;
2297 /* Find whether a basic block BB is the final block of a (half) diamond CFG
2298 sub-graph and if the predicate the condition depends on is known. If so,
2299 return true and store the pointer the predicate in *P. */
2301 static bool
2302 phi_result_unknown_predicate (ipa_func_body_info *fbi,
2303 ipa_fn_summary *summary,
2304 class ipa_node_params *params_summary,
2305 basic_block bb,
2306 ipa_predicate *p,
2307 vec<ipa_predicate> nonconstant_names)
2309 edge e;
2310 edge_iterator ei;
2311 basic_block first_bb = NULL;
2312 gimple *stmt;
2314 if (single_pred_p (bb))
2316 *p = false;
2317 return true;
2320 FOR_EACH_EDGE (e, ei, bb->preds)
2322 if (single_succ_p (e->src))
2324 if (!single_pred_p (e->src))
2325 return false;
2326 if (!first_bb)
2327 first_bb = single_pred (e->src);
2328 else if (single_pred (e->src) != first_bb)
2329 return false;
2331 else
2333 if (!first_bb)
2334 first_bb = e->src;
2335 else if (e->src != first_bb)
2336 return false;
2340 if (!first_bb)
2341 return false;
2343 stmt = last_stmt (first_bb);
2344 if (!stmt
2345 || gimple_code (stmt) != GIMPLE_COND
2346 || !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
2347 return false;
2349 *p = will_be_nonconstant_expr_predicate (fbi, summary, params_summary,
2350 gimple_cond_lhs (stmt),
2351 nonconstant_names);
2352 if (*p == true)
2353 return false;
2354 else
2355 return true;
2358 /* Given a PHI statement in a function described by inline properties SUMMARY
2359 and *P being the predicate describing whether the selected PHI argument is
2360 known, store a predicate for the result of the PHI statement into
2361 NONCONSTANT_NAMES, if possible. */
2363 static void
2364 predicate_for_phi_result (class ipa_fn_summary *summary, gphi *phi,
2365 ipa_predicate *p,
2366 vec<ipa_predicate> nonconstant_names)
2368 unsigned i;
2370 for (i = 0; i < gimple_phi_num_args (phi); i++)
2372 tree arg = gimple_phi_arg (phi, i)->def;
2373 if (!is_gimple_min_invariant (arg))
2375 gcc_assert (TREE_CODE (arg) == SSA_NAME);
2376 *p = p->or_with (summary->conds,
2377 nonconstant_names[SSA_NAME_VERSION (arg)]);
2378 if (*p == true)
2379 return;
2383 if (dump_file && (dump_flags & TDF_DETAILS))
2385 fprintf (dump_file, "\t\tphi predicate: ");
2386 p->dump (dump_file, summary->conds);
2388 nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
2391 /* For a typical usage of __builtin_expect (a<b, 1), we
2392 may introduce an extra relation stmt:
2393 With the builtin, we have
2394 t1 = a <= b;
2395 t2 = (long int) t1;
2396 t3 = __builtin_expect (t2, 1);
2397 if (t3 != 0)
2398 goto ...
2399 Without the builtin, we have
2400 if (a<=b)
2401 goto...
2402 This affects the size/time estimation and may have
2403 an impact on the earlier inlining.
2404 Here find this pattern and fix it up later. */
2406 static gimple *
2407 find_foldable_builtin_expect (basic_block bb)
2409 gimple_stmt_iterator bsi;
2411 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
2413 gimple *stmt = gsi_stmt (bsi);
2414 if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
2415 || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY)
2416 || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
2418 tree var = gimple_call_lhs (stmt);
2419 tree arg = gimple_call_arg (stmt, 0);
2420 use_operand_p use_p;
2421 gimple *use_stmt;
2422 bool match = false;
2423 bool done = false;
2425 if (!var || !arg)
2426 continue;
2427 gcc_assert (TREE_CODE (var) == SSA_NAME);
2429 while (TREE_CODE (arg) == SSA_NAME)
2431 gimple *stmt_tmp = SSA_NAME_DEF_STMT (arg);
2432 if (!is_gimple_assign (stmt_tmp))
2433 break;
2434 switch (gimple_assign_rhs_code (stmt_tmp))
2436 case LT_EXPR:
2437 case LE_EXPR:
2438 case GT_EXPR:
2439 case GE_EXPR:
2440 case EQ_EXPR:
2441 case NE_EXPR:
2442 match = true;
2443 done = true;
2444 break;
2445 CASE_CONVERT:
2446 break;
2447 default:
2448 done = true;
2449 break;
2451 if (done)
2452 break;
2453 arg = gimple_assign_rhs1 (stmt_tmp);
2456 if (match && single_imm_use (var, &use_p, &use_stmt)
2457 && gimple_code (use_stmt) == GIMPLE_COND)
2458 return use_stmt;
2461 return NULL;
2464 /* Return true when the basic blocks contains only clobbers followed by RESX.
2465 Such BBs are kept around to make removal of dead stores possible with
2466 presence of EH and will be optimized out by optimize_clobbers later in the
2467 game.
2469 NEED_EH is used to recurse in case the clobber has non-EH predecessors
2470 that can be clobber only, too.. When it is false, the RESX is not necessary
2471 on the end of basic block. */
2473 static bool
2474 clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
2476 gimple_stmt_iterator gsi = gsi_last_bb (bb);
2477 edge_iterator ei;
2478 edge e;
2480 if (need_eh)
2482 if (gsi_end_p (gsi))
2483 return false;
2484 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
2485 return false;
2486 gsi_prev (&gsi);
2488 else if (!single_succ_p (bb))
2489 return false;
2491 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
2493 gimple *stmt = gsi_stmt (gsi);
2494 if (is_gimple_debug (stmt))
2495 continue;
2496 if (gimple_clobber_p (stmt))
2497 continue;
2498 if (gimple_code (stmt) == GIMPLE_LABEL)
2499 break;
2500 return false;
2503 /* See if all predecessors are either throws or clobber only BBs. */
2504 FOR_EACH_EDGE (e, ei, bb->preds)
2505 if (!(e->flags & EDGE_EH)
2506 && !clobber_only_eh_bb_p (e->src, false))
2507 return false;
2509 return true;
2512 /* Return true if STMT compute a floating point expression that may be affected
2513 by -ffast-math and similar flags. */
2515 static bool
2516 fp_expression_p (gimple *stmt)
2518 ssa_op_iter i;
2519 tree op;
2521 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
2522 if (FLOAT_TYPE_P (TREE_TYPE (op)))
2523 return true;
2524 return false;
2527 /* Return true if T references memory location that is local
2528 for the function (that means, dead after return) or read-only. */
2530 bool
2531 refs_local_or_readonly_memory_p (tree t)
2533 /* Non-escaping memory is fine. */
2534 t = get_base_address (t);
2535 if ((TREE_CODE (t) == MEM_REF
2536 || TREE_CODE (t) == TARGET_MEM_REF))
2537 return points_to_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
2539 /* Automatic variables are fine. */
2540 if (DECL_P (t)
2541 && auto_var_in_fn_p (t, current_function_decl))
2542 return true;
2544 /* Read-only variables are fine. */
2545 if (DECL_P (t) && TREE_READONLY (t))
2546 return true;
2548 return false;
2551 /* Return true if T is a pointer pointing to memory location that is local
2552 for the function (that means, dead after return) or read-only. */
2554 bool
2555 points_to_local_or_readonly_memory_p (tree t)
2557 /* See if memory location is clearly invalid. */
2558 if (integer_zerop (t))
2559 return flag_delete_null_pointer_checks;
2560 if (TREE_CODE (t) == SSA_NAME)
2562 /* For IPA passes we can consinder accesses to return slot local
2563 even if it is not local in the sense that memory is dead by
2564 the end of founction.
2565 The outer function will see a store in the call assignment
2566 and thus this will do right thing for all uses of this
2567 function in the current IPA passes (modref, pure/const discovery
2568 and inlining heuristics). */
2569 if (DECL_RESULT (current_function_decl)
2570 && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))
2571 && t == ssa_default_def (cfun, DECL_RESULT (current_function_decl)))
2572 return true;
2573 return !ptr_deref_may_alias_global_p (t, false);
2575 if (TREE_CODE (t) == ADDR_EXPR)
2576 return refs_local_or_readonly_memory_p (TREE_OPERAND (t, 0));
2577 return false;
2581 /* Analyze function body for NODE.
2582 EARLY indicates run from early optimization pipeline. */
2584 static void
2585 analyze_function_body (struct cgraph_node *node, bool early)
2587 sreal time = opt_for_fn (node->decl, param_uninlined_function_time);
2588 /* Estimate static overhead for function prologue/epilogue and alignment. */
2589 int size = opt_for_fn (node->decl, param_uninlined_function_insns);
2590 /* Benefits are scaled by probability of elimination that is in range
2591 <0,2>. */
2592 basic_block bb;
2593 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
2594 sreal freq;
2595 class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
2596 ipa_node_params *params_summary
2597 = early ? NULL : ipa_node_params_sum->get (node);
2598 ipa_predicate bb_predicate;
2599 struct ipa_func_body_info fbi;
2600 vec<ipa_predicate> nonconstant_names = vNULL;
2601 int nblocks, n;
2602 int *order;
2603 gimple *fix_builtin_expect_stmt;
2605 gcc_assert (my_function && my_function->cfg);
2606 gcc_assert (cfun == my_function);
2608 memset(&fbi, 0, sizeof(fbi));
2609 vec_free (info->conds);
2610 info->conds = NULL;
2611 info->size_time_table.release ();
2612 info->call_size_time_table.release ();
2614 /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
2615 so we can produce proper inline hints.
2617 When optimizing and analyzing for early inliner, initialize node params
2618 so we can produce correct BB predicates. */
2620 if (opt_for_fn (node->decl, optimize))
2622 calculate_dominance_info (CDI_DOMINATORS);
2623 calculate_dominance_info (CDI_POST_DOMINATORS);
2624 if (!early)
2625 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
2626 else
2628 ipa_check_create_node_params ();
2629 ipa_initialize_node_params (node);
2632 if (ipa_node_params_sum)
2634 fbi.node = node;
2635 fbi.info = ipa_node_params_sum->get (node);
2636 fbi.bb_infos = vNULL;
2637 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
2638 fbi.param_count = count_formal_params (node->decl);
2639 fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
2641 nonconstant_names.safe_grow_cleared
2642 (SSANAMES (my_function)->length (), true);
2646 if (dump_file)
2647 fprintf (dump_file, "\nAnalyzing function body size: %s\n",
2648 node->dump_name ());
2650 /* When we run into maximal number of entries, we assign everything to the
2651 constant truth case. Be sure to have it in list. */
2652 bb_predicate = true;
2653 info->account_size_time (0, 0, bb_predicate, bb_predicate);
2655 bb_predicate = ipa_predicate::not_inlined ();
2656 info->account_size_time (opt_for_fn (node->decl,
2657 param_uninlined_function_insns)
2658 * ipa_fn_summary::size_scale,
2659 opt_for_fn (node->decl,
2660 param_uninlined_function_time),
2661 bb_predicate,
2662 bb_predicate);
2664 /* Only look for target information for inlinable functions. */
2665 bool scan_for_target_info =
2666 info->inlinable
2667 && targetm.target_option.need_ipa_fn_target_info (node->decl,
2668 info->target_info);
2670 if (fbi.info)
2671 compute_bb_predicates (&fbi, node, info, params_summary);
2672 const profile_count entry_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
2673 order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
2674 nblocks = pre_and_rev_post_order_compute (NULL, order, false);
2675 for (n = 0; n < nblocks; n++)
2677 bb = BASIC_BLOCK_FOR_FN (cfun, order[n]);
2678 freq = bb->count.to_sreal_scale (entry_count);
2679 if (clobber_only_eh_bb_p (bb))
2681 if (dump_file && (dump_flags & TDF_DETAILS))
2682 fprintf (dump_file, "\n Ignoring BB %i;"
2683 " it will be optimized away by cleanup_clobbers\n",
2684 bb->index);
2685 continue;
2688 /* TODO: Obviously predicates can be propagated down across CFG. */
2689 if (fbi.info)
2691 if (bb->aux)
2692 bb_predicate = *(ipa_predicate *)bb->aux;
2693 else
2694 bb_predicate = false;
2696 else
2697 bb_predicate = true;
2699 if (dump_file && (dump_flags & TDF_DETAILS))
2701 fprintf (dump_file, "\n BB %i predicate:", bb->index);
2702 bb_predicate.dump (dump_file, info->conds);
2705 if (fbi.info && nonconstant_names.exists ())
2707 ipa_predicate phi_predicate;
2708 bool first_phi = true;
2710 for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
2711 gsi_next (&bsi))
2713 if (first_phi
2714 && !phi_result_unknown_predicate (&fbi, info,
2715 params_summary,
2717 &phi_predicate,
2718 nonconstant_names))
2719 break;
2720 first_phi = false;
2721 if (dump_file && (dump_flags & TDF_DETAILS))
2723 fprintf (dump_file, " ");
2724 print_gimple_stmt (dump_file, gsi_stmt (bsi), 0);
2726 predicate_for_phi_result (info, bsi.phi (), &phi_predicate,
2727 nonconstant_names);
2731 fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
2733 for (gimple_stmt_iterator bsi = gsi_start_nondebug_bb (bb);
2734 !gsi_end_p (bsi); gsi_next_nondebug (&bsi))
2736 gimple *stmt = gsi_stmt (bsi);
2737 int this_size = estimate_num_insns (stmt, &eni_size_weights);
2738 int this_time = estimate_num_insns (stmt, &eni_time_weights);
2739 int prob;
2740 ipa_predicate will_be_nonconstant;
2742 /* This relation stmt should be folded after we remove
2743 __builtin_expect call. Adjust the cost here. */
2744 if (stmt == fix_builtin_expect_stmt)
2746 this_size--;
2747 this_time--;
2750 if (dump_file && (dump_flags & TDF_DETAILS))
2752 fprintf (dump_file, " ");
2753 print_gimple_stmt (dump_file, stmt, 0);
2754 fprintf (dump_file, "\t\tfreq:%3.2f size:%3i time:%3i\n",
2755 freq.to_double (), this_size,
2756 this_time);
2759 if (is_gimple_call (stmt)
2760 && !gimple_call_internal_p (stmt))
2762 struct cgraph_edge *edge = node->get_edge (stmt);
2763 ipa_call_summary *es = ipa_call_summaries->get_create (edge);
2765 /* Special case: results of BUILT_IN_CONSTANT_P will be always
2766 resolved as constant. We however don't want to optimize
2767 out the cgraph edges. */
2768 if (nonconstant_names.exists ()
2769 && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
2770 && gimple_call_lhs (stmt)
2771 && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
2773 ipa_predicate false_p = false;
2774 nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
2775 = false_p;
2777 if (ipa_node_params_sum)
2779 int count = gimple_call_num_args (stmt);
2780 int i;
2782 if (count)
2783 es->param.safe_grow_cleared (count, true);
2784 for (i = 0; i < count; i++)
2786 int prob = param_change_prob (&fbi, stmt, i);
2787 gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
2788 es->param[i].change_prob = prob;
2789 es->param[i].points_to_local_or_readonly_memory
2790 = points_to_local_or_readonly_memory_p
2791 (gimple_call_arg (stmt, i));
2794 /* We cannot setup VLA parameters during inlining. */
2795 for (unsigned int i = 0; i < gimple_call_num_args (stmt); ++i)
2796 if (TREE_CODE (gimple_call_arg (stmt, i)) == WITH_SIZE_EXPR)
2798 edge->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
2799 break;
2801 es->call_stmt_size = this_size;
2802 es->call_stmt_time = this_time;
2803 es->loop_depth = bb_loop_depth (bb);
2804 edge_set_predicate (edge, &bb_predicate);
2805 if (edge->speculative)
2807 cgraph_edge *indirect
2808 = edge->speculative_call_indirect_edge ();
2809 ipa_call_summary *es2
2810 = ipa_call_summaries->get_create (indirect);
2811 ipa_call_summaries->duplicate (edge, indirect,
2812 es, es2);
2814 /* Edge is the first direct call.
2815 create and duplicate call summaries for multiple
2816 speculative call targets. */
2817 for (cgraph_edge *direct
2818 = edge->next_speculative_call_target ();
2819 direct;
2820 direct = direct->next_speculative_call_target ())
2822 ipa_call_summary *es3
2823 = ipa_call_summaries->get_create (direct);
2824 ipa_call_summaries->duplicate (edge, direct,
2825 es, es3);
2830 /* TODO: When conditional jump or switch is known to be constant, but
2831 we did not translate it into the predicates, we really can account
2832 just maximum of the possible paths. */
2833 if (fbi.info)
2834 will_be_nonconstant
2835 = will_be_nonconstant_predicate (&fbi, info, params_summary,
2836 stmt, nonconstant_names);
2837 else
2838 will_be_nonconstant = true;
2839 if (this_time || this_size)
2841 sreal final_time = (sreal)this_time * freq;
2843 prob = eliminated_by_inlining_prob (&fbi, stmt);
2844 if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS))
2845 fprintf (dump_file,
2846 "\t\t50%% will be eliminated by inlining\n");
2847 if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
2848 fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
2850 ipa_predicate p = bb_predicate & will_be_nonconstant;
2852 /* We can ignore statement when we proved it is never going
2853 to happen, but we cannot do that for call statements
2854 because edges are accounted specially. */
2856 if (*(is_gimple_call (stmt) ? &bb_predicate : &p) != false)
2858 time += final_time;
2859 size += this_size;
2862 /* We account everything but the calls. Calls have their own
2863 size/time info attached to cgraph edges. This is necessary
2864 in order to make the cost disappear after inlining. */
2865 if (!is_gimple_call (stmt))
2867 if (prob)
2869 ipa_predicate ip
2870 = bb_predicate & ipa_predicate::not_inlined ();
2871 info->account_size_time (this_size * prob,
2872 (final_time * prob) / 2, ip,
2875 if (prob != 2)
2876 info->account_size_time (this_size * (2 - prob),
2877 (final_time * (2 - prob) / 2),
2878 bb_predicate,
2882 if (!info->fp_expressions && fp_expression_p (stmt))
2884 info->fp_expressions = true;
2885 if (dump_file)
2886 fprintf (dump_file, " fp_expression set\n");
2890 /* For target specific information, we want to scan all statements
2891 rather than those statements with non-zero weights, to avoid
2892 missing to scan something interesting for target information,
2893 such as: internal function calls. */
2894 if (scan_for_target_info)
2895 scan_for_target_info =
2896 targetm.target_option.update_ipa_fn_target_info
2897 (info->target_info, stmt);
2899 /* Account cost of address calculations in the statements. */
2900 for (unsigned int i = 0; i < gimple_num_ops (stmt); i++)
2902 for (tree op = gimple_op (stmt, i);
2903 op && handled_component_p (op);
2904 op = TREE_OPERAND (op, 0))
2905 if ((TREE_CODE (op) == ARRAY_REF
2906 || TREE_CODE (op) == ARRAY_RANGE_REF)
2907 && TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
2909 ipa_predicate p = bb_predicate;
2910 if (fbi.info)
2911 p = p & will_be_nonconstant_expr_predicate
2912 (&fbi, info, params_summary,
2913 TREE_OPERAND (op, 1),
2914 nonconstant_names);
2915 if (p != false)
2917 time += freq;
2918 size += 1;
2919 if (dump_file)
2920 fprintf (dump_file,
2921 "\t\tAccounting address calculation.\n");
2922 info->account_size_time (ipa_fn_summary::size_scale,
2923 freq,
2924 bb_predicate,
2932 free (order);
2934 if (nonconstant_names.exists () && !early)
2936 ipa_fn_summary *s = ipa_fn_summaries->get (node);
2937 unsigned max_loop_predicates = opt_for_fn (node->decl,
2938 param_ipa_max_loop_predicates);
2940 if (dump_file && (dump_flags & TDF_DETAILS))
2941 flow_loops_dump (dump_file, NULL, 0);
2942 scev_initialize ();
2943 for (auto loop : loops_list (cfun, 0))
2945 ipa_predicate loop_iterations = true;
2946 sreal header_freq;
2947 edge ex;
2948 unsigned int j;
2949 class tree_niter_desc niter_desc;
2950 if (!loop->header->aux)
2951 continue;
2953 profile_count phdr_count = loop_preheader_edge (loop)->count ();
2954 sreal phdr_freq = phdr_count.to_sreal_scale (entry_count);
2956 bb_predicate = *(ipa_predicate *)loop->header->aux;
2957 auto_vec<edge> exits = get_loop_exit_edges (loop);
2958 FOR_EACH_VEC_ELT (exits, j, ex)
2959 if (number_of_iterations_exit (loop, ex, &niter_desc, false)
2960 && !is_gimple_min_invariant (niter_desc.niter))
2962 ipa_predicate will_be_nonconstant
2963 = will_be_nonconstant_expr_predicate (&fbi, info,
2964 params_summary,
2965 niter_desc.niter,
2966 nonconstant_names);
2967 if (will_be_nonconstant != true)
2968 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2969 if (will_be_nonconstant != true
2970 && will_be_nonconstant != false)
2971 loop_iterations &= will_be_nonconstant;
2973 add_freqcounting_predicate (&s->loop_iterations, loop_iterations,
2974 phdr_freq, max_loop_predicates);
2977 /* To avoid quadratic behavior we analyze stride predicates only
2978 with respect to the containing loop. Thus we simply iterate
2979 over all defs in the outermost loop body. */
2980 for (class loop *loop = loops_for_fn (cfun)->tree_root->inner;
2981 loop != NULL; loop = loop->next)
2983 ipa_predicate loop_stride = true;
2984 basic_block *body = get_loop_body (loop);
2985 profile_count phdr_count = loop_preheader_edge (loop)->count ();
2986 sreal phdr_freq = phdr_count.to_sreal_scale (entry_count);
2987 for (unsigned i = 0; i < loop->num_nodes; i++)
2989 gimple_stmt_iterator gsi;
2990 if (!body[i]->aux)
2991 continue;
2993 bb_predicate = *(ipa_predicate *)body[i]->aux;
2994 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
2995 gsi_next (&gsi))
2997 gimple *stmt = gsi_stmt (gsi);
2999 if (!is_gimple_assign (stmt))
3000 continue;
3002 tree def = gimple_assign_lhs (stmt);
3003 if (TREE_CODE (def) != SSA_NAME)
3004 continue;
3006 affine_iv iv;
3007 if (!simple_iv (loop_containing_stmt (stmt),
3008 loop_containing_stmt (stmt),
3009 def, &iv, true)
3010 || is_gimple_min_invariant (iv.step))
3011 continue;
3013 ipa_predicate will_be_nonconstant
3014 = will_be_nonconstant_expr_predicate (&fbi, info,
3015 params_summary,
3016 iv.step,
3017 nonconstant_names);
3018 if (will_be_nonconstant != true)
3019 will_be_nonconstant = bb_predicate & will_be_nonconstant;
3020 if (will_be_nonconstant != true
3021 && will_be_nonconstant != false)
3022 loop_stride = loop_stride & will_be_nonconstant;
3025 add_freqcounting_predicate (&s->loop_strides, loop_stride,
3026 phdr_freq, max_loop_predicates);
3027 free (body);
3029 scev_finalize ();
3031 FOR_ALL_BB_FN (bb, my_function)
3033 edge e;
3034 edge_iterator ei;
3036 if (bb->aux)
3037 edge_predicate_pool.remove ((ipa_predicate *)bb->aux);
3038 bb->aux = NULL;
3039 FOR_EACH_EDGE (e, ei, bb->succs)
3041 if (e->aux)
3042 edge_predicate_pool.remove ((ipa_predicate *)e->aux);
3043 e->aux = NULL;
3046 ipa_fn_summary *s = ipa_fn_summaries->get (node);
3047 ipa_size_summary *ss = ipa_size_summaries->get (node);
3048 s->time = time;
3049 ss->self_size = size;
3050 nonconstant_names.release ();
3051 ipa_release_body_info (&fbi);
3052 if (opt_for_fn (node->decl, optimize))
3054 if (!early)
3055 loop_optimizer_finalize ();
3056 else if (!ipa_edge_args_sum)
3057 ipa_free_all_node_params ();
3058 free_dominance_info (CDI_DOMINATORS);
3059 free_dominance_info (CDI_POST_DOMINATORS);
3061 if (dump_file)
3063 fprintf (dump_file, "\n");
3064 ipa_dump_fn_summary (dump_file, node);
3069 /* Compute function summary.
3070 EARLY is true when we compute parameters during early opts. */
3072 void
3073 compute_fn_summary (struct cgraph_node *node, bool early)
3075 HOST_WIDE_INT self_stack_size;
3076 struct cgraph_edge *e;
3078 gcc_assert (!node->inlined_to);
3080 if (!ipa_fn_summaries)
3081 ipa_fn_summary_alloc ();
3083 /* Create a new ipa_fn_summary. */
3084 ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
3085 ipa_fn_summaries->remove (node);
3086 class ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
3087 class ipa_size_summary *size_info = ipa_size_summaries->get_create (node);
3089 /* Estimate the stack size for the function if we're optimizing. */
3090 self_stack_size = optimize && !node->thunk
3091 ? estimated_stack_frame_size (node) : 0;
3092 size_info->estimated_self_stack_size = self_stack_size;
3093 info->estimated_stack_size = self_stack_size;
3095 if (node->thunk)
3097 ipa_call_summary *es = ipa_call_summaries->get_create (node->callees);
3098 ipa_predicate t = true;
3100 node->can_change_signature = false;
3101 es->call_stmt_size = eni_size_weights.call_cost;
3102 es->call_stmt_time = eni_time_weights.call_cost;
3103 info->account_size_time (ipa_fn_summary::size_scale
3104 * opt_for_fn (node->decl,
3105 param_uninlined_function_thunk_insns),
3106 opt_for_fn (node->decl,
3107 param_uninlined_function_thunk_time), t, t);
3108 t = ipa_predicate::not_inlined ();
3109 info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
3110 ipa_update_overall_fn_summary (node);
3111 size_info->self_size = size_info->size;
3112 if (stdarg_p (TREE_TYPE (node->decl)))
3114 info->inlinable = false;
3115 node->callees->inline_failed = CIF_VARIADIC_THUNK;
3117 else
3118 info->inlinable = true;
3120 else
3122 /* Even is_gimple_min_invariant rely on current_function_decl. */
3123 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3125 /* During IPA profile merging we may be called w/o virtual SSA form
3126 built. */
3127 update_ssa (TODO_update_ssa_only_virtuals);
3129 /* Can this function be inlined at all? */
3130 if (!opt_for_fn (node->decl, optimize)
3131 && !lookup_attribute ("always_inline",
3132 DECL_ATTRIBUTES (node->decl)))
3133 info->inlinable = false;
3134 else
3135 info->inlinable = tree_inlinable_function_p (node->decl);
3137 bool no_signature = false;
3138 /* Type attributes can use parameter indices to describe them.
3139 Special case fn spec since we can safely preserve them in
3140 modref summaries. */
3141 for (tree list = TYPE_ATTRIBUTES (TREE_TYPE (node->decl));
3142 list && !no_signature; list = TREE_CHAIN (list))
3143 if (!ipa_param_adjustments::type_attribute_allowed_p
3144 (get_attribute_name (list)))
3146 if (dump_file)
3148 fprintf (dump_file, "No signature change:"
3149 " function type has unhandled attribute %s.\n",
3150 IDENTIFIER_POINTER (get_attribute_name (list)));
3152 no_signature = true;
3154 for (tree parm = DECL_ARGUMENTS (node->decl);
3155 parm && !no_signature; parm = DECL_CHAIN (parm))
3156 if (variably_modified_type_p (TREE_TYPE (parm), node->decl))
3158 if (dump_file)
3160 fprintf (dump_file, "No signature change:"
3161 " has parameter with variably modified type.\n");
3163 no_signature = true;
3166 /* Likewise for #pragma omp declare simd functions or functions
3167 with simd attribute. */
3168 if (no_signature
3169 || lookup_attribute ("omp declare simd",
3170 DECL_ATTRIBUTES (node->decl)))
3171 node->can_change_signature = false;
3172 else
3174 /* Otherwise, inlinable functions always can change signature. */
3175 if (info->inlinable)
3176 node->can_change_signature = true;
3177 else
3179 /* Functions calling builtin_apply cannot change signature. */
3180 for (e = node->callees; e; e = e->next_callee)
3182 tree cdecl = e->callee->decl;
3183 if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
3184 || fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
3185 break;
3187 node->can_change_signature = !e;
3190 analyze_function_body (node, early);
3191 pop_cfun ();
3194 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
3195 size_info->size = size_info->self_size;
3196 info->estimated_stack_size = size_info->estimated_self_stack_size;
3198 /* Code above should compute exactly the same result as
3199 ipa_update_overall_fn_summary except for case when speculative
3200 edges are present since these are accounted to size but not
3201 self_size. Do not compare time since different order the roundoff
3202 errors result in slight changes. */
3203 ipa_update_overall_fn_summary (node);
3204 if (flag_checking)
3206 for (e = node->indirect_calls; e; e = e->next_callee)
3207 if (e->speculative)
3208 break;
3209 gcc_assert (e || size_info->size == size_info->self_size);
3214 /* Compute parameters of functions used by inliner using
3215 current_function_decl. */
3217 static unsigned int
3218 compute_fn_summary_for_current (void)
3220 compute_fn_summary (cgraph_node::get (current_function_decl), true);
3221 return 0;
3224 /* Estimate benefit devirtualizing indirect edge IE and return true if it can
3225 be devirtualized and inlined, provided m_known_vals, m_known_contexts and
3226 m_known_aggs in AVALS. Return false straight away if AVALS is NULL. */
3228 static bool
3229 estimate_edge_devirt_benefit (struct cgraph_edge *ie,
3230 int *size, int *time,
3231 ipa_call_arg_values *avals)
3233 tree target;
3234 struct cgraph_node *callee;
3235 class ipa_fn_summary *isummary;
3236 enum availability avail;
3237 bool speculative;
3239 if (!avals
3240 || (!avals->m_known_vals.length() && !avals->m_known_contexts.length ()))
3241 return false;
3242 if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
3243 return false;
3245 target = ipa_get_indirect_edge_target (ie, avals, &speculative);
3246 if (!target || speculative)
3247 return false;
3249 /* Account for difference in cost between indirect and direct calls. */
3250 *size -= (eni_size_weights.indirect_call_cost - eni_size_weights.call_cost);
3251 *time -= (eni_time_weights.indirect_call_cost - eni_time_weights.call_cost);
3252 gcc_checking_assert (*time >= 0);
3253 gcc_checking_assert (*size >= 0);
3255 callee = cgraph_node::get (target);
3256 if (!callee || !callee->definition)
3257 return false;
3258 callee = callee->function_symbol (&avail);
3259 if (avail < AVAIL_AVAILABLE)
3260 return false;
3261 isummary = ipa_fn_summaries->get (callee);
3262 if (isummary == NULL)
3263 return false;
3265 return isummary->inlinable;
3268 /* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
3269 handle edge E with probability PROB. Set HINTS accordingly if edge may be
3270 devirtualized. AVALS, if non-NULL, describes the context of the call site
3271 as far as values of parameters are concerened. */
3273 static inline void
3274 estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
3275 sreal *time, ipa_call_arg_values *avals,
3276 ipa_hints *hints)
3278 class ipa_call_summary *es = ipa_call_summaries->get (e);
3279 int call_size = es->call_stmt_size;
3280 int call_time = es->call_stmt_time;
3281 int cur_size;
3283 if (!e->callee && hints && e->maybe_hot_p ()
3284 && estimate_edge_devirt_benefit (e, &call_size, &call_time, avals))
3285 *hints |= INLINE_HINT_indirect_call;
3286 cur_size = call_size * ipa_fn_summary::size_scale;
3287 *size += cur_size;
3288 if (min_size)
3289 *min_size += cur_size;
3290 if (time)
3291 *time += ((sreal)call_time) * e->sreal_frequency ();
3295 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
3296 calls in NODE. POSSIBLE_TRUTHS and AVALS describe the context of the call
3297 site.
3299 Helper for estimate_calls_size_and_time which does the same but
3300 (in most cases) faster. */
3302 static void
3303 estimate_calls_size_and_time_1 (struct cgraph_node *node, int *size,
3304 int *min_size, sreal *time,
3305 ipa_hints *hints,
3306 clause_t possible_truths,
3307 ipa_call_arg_values *avals)
3309 struct cgraph_edge *e;
3310 for (e = node->callees; e; e = e->next_callee)
3312 if (!e->inline_failed)
3314 gcc_checking_assert (!ipa_call_summaries->get (e));
3315 estimate_calls_size_and_time_1 (e->callee, size, min_size, time,
3316 hints, possible_truths, avals);
3318 continue;
3320 class ipa_call_summary *es = ipa_call_summaries->get (e);
3322 /* Do not care about zero sized builtins. */
3323 if (!es->call_stmt_size)
3325 gcc_checking_assert (!es->call_stmt_time);
3326 continue;
3328 if (!es->predicate
3329 || es->predicate->evaluate (possible_truths))
3331 /* Predicates of calls shall not use NOT_CHANGED codes,
3332 so we do not need to compute probabilities. */
3333 estimate_edge_size_and_time (e, size,
3334 es->predicate ? NULL : min_size,
3335 time, avals, hints);
3338 for (e = node->indirect_calls; e; e = e->next_callee)
3340 class ipa_call_summary *es = ipa_call_summaries->get (e);
3341 if (!es->predicate
3342 || es->predicate->evaluate (possible_truths))
3343 estimate_edge_size_and_time (e, size,
3344 es->predicate ? NULL : min_size,
3345 time, avals, hints);
3349 /* Populate sum->call_size_time_table for edges from NODE. */
3351 static void
3352 summarize_calls_size_and_time (struct cgraph_node *node,
3353 ipa_fn_summary *sum)
3355 struct cgraph_edge *e;
3356 for (e = node->callees; e; e = e->next_callee)
3358 if (!e->inline_failed)
3360 gcc_checking_assert (!ipa_call_summaries->get (e));
3361 summarize_calls_size_and_time (e->callee, sum);
3362 continue;
3364 int size = 0;
3365 sreal time = 0;
3367 estimate_edge_size_and_time (e, &size, NULL, &time, NULL, NULL);
3369 ipa_predicate pred = true;
3370 class ipa_call_summary *es = ipa_call_summaries->get (e);
3372 if (es->predicate)
3373 pred = *es->predicate;
3374 sum->account_size_time (size, time, pred, pred, true);
3376 for (e = node->indirect_calls; e; e = e->next_callee)
3378 int size = 0;
3379 sreal time = 0;
3381 estimate_edge_size_and_time (e, &size, NULL, &time, NULL, NULL);
3382 ipa_predicate pred = true;
3383 class ipa_call_summary *es = ipa_call_summaries->get (e);
3385 if (es->predicate)
3386 pred = *es->predicate;
3387 sum->account_size_time (size, time, pred, pred, true);
3391 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
3392 calls in NODE. POSSIBLE_TRUTHS and AVALS (the latter if non-NULL) describe
3393 context of the call site. */
3395 static void
3396 estimate_calls_size_and_time (struct cgraph_node *node, int *size,
3397 int *min_size, sreal *time,
3398 ipa_hints *hints,
3399 clause_t possible_truths,
3400 ipa_call_arg_values *avals)
3402 class ipa_fn_summary *sum = ipa_fn_summaries->get (node);
3403 bool use_table = true;
3405 gcc_assert (node->callees || node->indirect_calls);
3407 /* During early inlining we do not calculate info for very
3408 large functions and thus there is no need for producing
3409 summaries. */
3410 if (!ipa_node_params_sum)
3411 use_table = false;
3412 /* Do not calculate summaries for simple wrappers; it is waste
3413 of memory. */
3414 else if (node->callees && node->indirect_calls
3415 && node->callees->inline_failed && !node->callees->next_callee)
3416 use_table = false;
3417 /* If there is an indirect edge that may be optimized, we need
3418 to go the slow way. */
3419 else if (avals && hints
3420 && (avals->m_known_vals.length ()
3421 || avals->m_known_contexts.length ()
3422 || avals->m_known_aggs.length ()))
3424 ipa_node_params *params_summary = ipa_node_params_sum->get (node);
3425 unsigned int nargs = params_summary
3426 ? ipa_get_param_count (params_summary) : 0;
3428 for (unsigned int i = 0; i < nargs && use_table; i++)
3430 if (ipa_is_param_used_by_indirect_call (params_summary, i)
3431 && (avals->safe_sval_at (i)
3432 || (ipa_argagg_value_list (avals).value_for_index_p (i))))
3433 use_table = false;
3434 else if (ipa_is_param_used_by_polymorphic_call (params_summary, i)
3435 && (avals->m_known_contexts.length () > i
3436 && !avals->m_known_contexts[i].useless_p ()))
3437 use_table = false;
3441 /* Fast path is via the call size time table. */
3442 if (use_table)
3444 /* Build summary if it is absent. */
3445 if (!sum->call_size_time_table.length ())
3447 ipa_predicate true_pred = true;
3448 sum->account_size_time (0, 0, true_pred, true_pred, true);
3449 summarize_calls_size_and_time (node, sum);
3452 int old_size = *size;
3453 sreal old_time = time ? *time : 0;
3455 if (min_size)
3456 *min_size += sum->call_size_time_table[0].size;
3458 unsigned int i;
3459 size_time_entry *e;
3461 /* Walk the table and account sizes and times. */
3462 for (i = 0; sum->call_size_time_table.iterate (i, &e);
3463 i++)
3464 if (e->exec_predicate.evaluate (possible_truths))
3466 *size += e->size;
3467 if (time)
3468 *time += e->time;
3471 /* Be careful and see if both methods agree. */
3472 if ((flag_checking || dump_file)
3473 /* Do not try to sanity check when we know we lost some
3474 precision. */
3475 && sum->call_size_time_table.length ()
3476 < ipa_fn_summary::max_size_time_table_size)
3478 estimate_calls_size_and_time_1 (node, &old_size, NULL, &old_time, NULL,
3479 possible_truths, avals);
3480 gcc_assert (*size == old_size);
3481 if (time && (*time - old_time > 1 || *time - old_time < -1)
3482 && dump_file)
3483 fprintf (dump_file, "Time mismatch in call summary %f!=%f\n",
3484 old_time.to_double (),
3485 time->to_double ());
3488 /* Slow path by walking all edges. */
3489 else
3490 estimate_calls_size_and_time_1 (node, size, min_size, time, hints,
3491 possible_truths, avals);
3494 /* Main constructor for ipa call context. Memory allocation of ARG_VALUES
3495 is owned by the caller. INLINE_PARAM_SUMMARY is also owned by the
3496 caller. */
3498 ipa_call_context::ipa_call_context (cgraph_node *node, clause_t possible_truths,
3499 clause_t nonspec_possible_truths,
3500 vec<inline_param_summary>
3501 inline_param_summary,
3502 ipa_auto_call_arg_values *arg_values)
3503 : m_node (node), m_possible_truths (possible_truths),
3504 m_nonspec_possible_truths (nonspec_possible_truths),
3505 m_inline_param_summary (inline_param_summary),
3506 m_avals (arg_values)
3510 /* Set THIS to be a duplicate of CTX. Copy all relevant info. */
3512 void
3513 ipa_cached_call_context::duplicate_from (const ipa_call_context &ctx)
3515 m_node = ctx.m_node;
3516 m_possible_truths = ctx.m_possible_truths;
3517 m_nonspec_possible_truths = ctx.m_nonspec_possible_truths;
3518 ipa_node_params *params_summary = ipa_node_params_sum->get (m_node);
3519 unsigned int nargs = params_summary
3520 ? ipa_get_param_count (params_summary) : 0;
3522 m_inline_param_summary = vNULL;
3523 /* Copy the info only if there is at least one useful entry. */
3524 if (ctx.m_inline_param_summary.exists ())
3526 unsigned int n = MIN (ctx.m_inline_param_summary.length (), nargs);
3528 for (unsigned int i = 0; i < n; i++)
3529 if (ipa_is_param_used_by_ipa_predicates (params_summary, i)
3530 && !ctx.m_inline_param_summary[i].useless_p ())
3532 m_inline_param_summary
3533 = ctx.m_inline_param_summary.copy ();
3534 break;
3537 m_avals.m_known_vals = vNULL;
3538 if (ctx.m_avals.m_known_vals.exists ())
3540 unsigned int n = MIN (ctx.m_avals.m_known_vals.length (), nargs);
3542 for (unsigned int i = 0; i < n; i++)
3543 if (ipa_is_param_used_by_indirect_call (params_summary, i)
3544 && ctx.m_avals.m_known_vals[i])
3546 m_avals.m_known_vals = ctx.m_avals.m_known_vals.copy ();
3547 break;
3551 m_avals.m_known_contexts = vNULL;
3552 if (ctx.m_avals.m_known_contexts.exists ())
3554 unsigned int n = MIN (ctx.m_avals.m_known_contexts.length (), nargs);
3556 for (unsigned int i = 0; i < n; i++)
3557 if (ipa_is_param_used_by_polymorphic_call (params_summary, i)
3558 && !ctx.m_avals.m_known_contexts[i].useless_p ())
3560 m_avals.m_known_contexts = ctx.m_avals.m_known_contexts.copy ();
3561 break;
3565 m_avals.m_known_aggs = vNULL;
3566 if (ctx.m_avals.m_known_aggs.exists ())
3568 const ipa_argagg_value_list avl (&ctx.m_avals);
3569 for (unsigned int i = 0; i < nargs; i++)
3570 if (ipa_is_param_used_by_indirect_call (params_summary, i)
3571 && avl.value_for_index_p (i))
3573 m_avals.m_known_aggs = ctx.m_avals.m_known_aggs.copy ();
3574 break;
3578 m_avals.m_known_value_ranges = vNULL;
3581 /* Release memory used by known_vals/contexts/aggs vectors. and
3582 inline_param_summary. */
3584 void
3585 ipa_cached_call_context::release ()
3587 /* See if context is initialized at first place. */
3588 if (!m_node)
3589 return;
3590 m_avals.m_known_aggs.release ();
3591 m_avals.m_known_vals.release ();
3592 m_avals.m_known_contexts.release ();
3593 m_inline_param_summary.release ();
3596 /* Return true if CTX describes the same call context as THIS. */
3598 bool
3599 ipa_call_context::equal_to (const ipa_call_context &ctx)
3601 if (m_node != ctx.m_node
3602 || m_possible_truths != ctx.m_possible_truths
3603 || m_nonspec_possible_truths != ctx.m_nonspec_possible_truths)
3604 return false;
3606 ipa_node_params *params_summary = ipa_node_params_sum->get (m_node);
3607 unsigned int nargs = params_summary
3608 ? ipa_get_param_count (params_summary) : 0;
3610 if (m_inline_param_summary.exists () || ctx.m_inline_param_summary.exists ())
3612 for (unsigned int i = 0; i < nargs; i++)
3614 if (!ipa_is_param_used_by_ipa_predicates (params_summary, i))
3615 continue;
3616 if (i >= m_inline_param_summary.length ()
3617 || m_inline_param_summary[i].useless_p ())
3619 if (i < ctx.m_inline_param_summary.length ()
3620 && !ctx.m_inline_param_summary[i].useless_p ())
3621 return false;
3622 continue;
3624 if (i >= ctx.m_inline_param_summary.length ()
3625 || ctx.m_inline_param_summary[i].useless_p ())
3627 if (i < m_inline_param_summary.length ()
3628 && !m_inline_param_summary[i].useless_p ())
3629 return false;
3630 continue;
3632 if (!m_inline_param_summary[i].equal_to
3633 (ctx.m_inline_param_summary[i]))
3634 return false;
3637 if (m_avals.m_known_vals.exists () || ctx.m_avals.m_known_vals.exists ())
3639 for (unsigned int i = 0; i < nargs; i++)
3641 if (!ipa_is_param_used_by_indirect_call (params_summary, i))
3642 continue;
3643 if (i >= m_avals.m_known_vals.length () || !m_avals.m_known_vals[i])
3645 if (i < ctx.m_avals.m_known_vals.length ()
3646 && ctx.m_avals.m_known_vals[i])
3647 return false;
3648 continue;
3650 if (i >= ctx.m_avals.m_known_vals.length ()
3651 || !ctx.m_avals.m_known_vals[i])
3653 if (i < m_avals.m_known_vals.length () && m_avals.m_known_vals[i])
3654 return false;
3655 continue;
3657 if (m_avals.m_known_vals[i] != ctx.m_avals.m_known_vals[i])
3658 return false;
3661 if (m_avals.m_known_contexts.exists ()
3662 || ctx.m_avals.m_known_contexts.exists ())
3664 for (unsigned int i = 0; i < nargs; i++)
3666 if (!ipa_is_param_used_by_polymorphic_call (params_summary, i))
3667 continue;
3668 if (i >= m_avals.m_known_contexts.length ()
3669 || m_avals.m_known_contexts[i].useless_p ())
3671 if (i < ctx.m_avals.m_known_contexts.length ()
3672 && !ctx.m_avals.m_known_contexts[i].useless_p ())
3673 return false;
3674 continue;
3676 if (i >= ctx.m_avals.m_known_contexts.length ()
3677 || ctx.m_avals.m_known_contexts[i].useless_p ())
3679 if (i < m_avals.m_known_contexts.length ()
3680 && !m_avals.m_known_contexts[i].useless_p ())
3681 return false;
3682 continue;
3684 if (!m_avals.m_known_contexts[i].equal_to
3685 (ctx.m_avals.m_known_contexts[i]))
3686 return false;
3689 if (m_avals.m_known_aggs.exists () || ctx.m_avals.m_known_aggs.exists ())
3691 unsigned i = 0, j = 0;
3692 while (i < m_avals.m_known_aggs.length ()
3693 || j < ctx.m_avals.m_known_aggs.length ())
3695 if (i >= m_avals.m_known_aggs.length ())
3697 int idx2 = ctx.m_avals.m_known_aggs[j].index;
3698 if (ipa_is_param_used_by_indirect_call (params_summary, idx2))
3699 return false;
3700 j++;
3701 continue;
3703 if (j >= ctx.m_avals.m_known_aggs.length ())
3705 int idx1 = m_avals.m_known_aggs[i].index;
3706 if (ipa_is_param_used_by_indirect_call (params_summary, idx1))
3707 return false;
3708 i++;
3709 continue;
3712 int idx1 = m_avals.m_known_aggs[i].index;
3713 int idx2 = ctx.m_avals.m_known_aggs[j].index;
3714 if (idx1 < idx2)
3716 if (ipa_is_param_used_by_indirect_call (params_summary, idx1))
3717 return false;
3718 i++;
3719 continue;
3721 if (idx1 > idx2)
3723 if (ipa_is_param_used_by_indirect_call (params_summary, idx2))
3724 return false;
3725 j++;
3726 continue;
3728 if (!ipa_is_param_used_by_indirect_call (params_summary, idx1))
3730 i++;
3731 j++;
3732 continue;
3735 if ((m_avals.m_known_aggs[i].unit_offset
3736 != ctx.m_avals.m_known_aggs[j].unit_offset)
3737 || (m_avals.m_known_aggs[i].by_ref
3738 != ctx.m_avals.m_known_aggs[j].by_ref)
3739 || !operand_equal_p (m_avals.m_known_aggs[i].value,
3740 ctx.m_avals.m_known_aggs[j].value))
3741 return false;
3742 i++;
3743 j++;
3746 return true;
3749 /* Fill in the selected fields in ESTIMATES with value estimated for call in
3750 this context. Always compute size and min_size. Only compute time and
3751 nonspecialized_time if EST_TIMES is true. Only compute hints if EST_HINTS
3752 is true. */
3754 void
3755 ipa_call_context::estimate_size_and_time (ipa_call_estimates *estimates,
3756 bool est_times, bool est_hints)
3758 class ipa_fn_summary *info = ipa_fn_summaries->get (m_node);
3759 size_time_entry *e;
3760 int size = 0;
3761 sreal time = 0;
3762 int min_size = 0;
3763 ipa_hints hints = 0;
3764 sreal loops_with_known_iterations = 0;
3765 sreal loops_with_known_strides = 0;
3766 int i;
3768 if (dump_file && (dump_flags & TDF_DETAILS))
3770 bool found = false;
3771 fprintf (dump_file, " Estimating body: %s\n"
3772 " Known to be false: ", m_node->dump_name ());
3774 for (i = ipa_predicate::not_inlined_condition;
3775 i < (ipa_predicate::first_dynamic_condition
3776 + (int) vec_safe_length (info->conds)); i++)
3777 if (!(m_possible_truths & (1 << i)))
3779 if (found)
3780 fprintf (dump_file, ", ");
3781 found = true;
3782 dump_condition (dump_file, info->conds, i);
3786 if (m_node->callees || m_node->indirect_calls)
3787 estimate_calls_size_and_time (m_node, &size, &min_size,
3788 est_times ? &time : NULL,
3789 est_hints ? &hints : NULL, m_possible_truths,
3790 &m_avals);
3792 sreal nonspecialized_time = time;
3794 min_size += info->size_time_table[0].size;
3795 for (i = 0; info->size_time_table.iterate (i, &e); i++)
3797 bool exec = e->exec_predicate.evaluate (m_nonspec_possible_truths);
3799 /* Because predicates are conservative, it can happen that nonconst is 1
3800 but exec is 0. */
3801 if (exec)
3803 bool nonconst = e->nonconst_predicate.evaluate (m_possible_truths);
3805 gcc_checking_assert (e->time >= 0);
3806 gcc_checking_assert (time >= 0);
3808 /* We compute specialized size only because size of nonspecialized
3809 copy is context independent.
3811 The difference between nonspecialized execution and specialized is
3812 that nonspecialized is not going to have optimized out computations
3813 known to be constant in a specialized setting. */
3814 if (nonconst)
3815 size += e->size;
3816 if (!est_times)
3817 continue;
3818 nonspecialized_time += e->time;
3819 if (!nonconst)
3821 else if (!m_inline_param_summary.exists ())
3823 if (nonconst)
3824 time += e->time;
3826 else
3828 int prob = e->nonconst_predicate.probability
3829 (info->conds, m_possible_truths,
3830 m_inline_param_summary);
3831 gcc_checking_assert (prob >= 0);
3832 gcc_checking_assert (prob <= REG_BR_PROB_BASE);
3833 if (prob == REG_BR_PROB_BASE)
3834 time += e->time;
3835 else
3836 time += e->time * prob / REG_BR_PROB_BASE;
3838 gcc_checking_assert (time >= 0);
3841 gcc_checking_assert (info->size_time_table[0].exec_predicate == true);
3842 gcc_checking_assert (info->size_time_table[0].nonconst_predicate == true);
3843 gcc_checking_assert (min_size >= 0);
3844 gcc_checking_assert (size >= 0);
3845 gcc_checking_assert (time >= 0);
3846 /* nonspecialized_time should be always bigger than specialized time.
3847 Roundoff issues however may get into the way. */
3848 gcc_checking_assert ((nonspecialized_time - time * 99 / 100) >= -1);
3850 /* Roundoff issues may make specialized time bigger than nonspecialized
3851 time. We do not really want that to happen because some heuristics
3852 may get confused by seeing negative speedups. */
3853 if (time > nonspecialized_time)
3854 time = nonspecialized_time;
3856 if (est_hints)
3858 if (info->scc_no)
3859 hints |= INLINE_HINT_in_scc;
3860 if (DECL_DECLARED_INLINE_P (m_node->decl))
3861 hints |= INLINE_HINT_declared_inline;
3862 if (info->builtin_constant_p_parms.length ()
3863 && DECL_DECLARED_INLINE_P (m_node->decl))
3864 hints |= INLINE_HINT_builtin_constant_p;
3866 ipa_freqcounting_predicate *fcp;
3867 for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
3868 if (!fcp->predicate->evaluate (m_possible_truths))
3870 hints |= INLINE_HINT_loop_iterations;
3871 loops_with_known_iterations += fcp->freq;
3873 estimates->loops_with_known_iterations = loops_with_known_iterations;
3875 for (i = 0; vec_safe_iterate (info->loop_strides, i, &fcp); i++)
3876 if (!fcp->predicate->evaluate (m_possible_truths))
3878 hints |= INLINE_HINT_loop_stride;
3879 loops_with_known_strides += fcp->freq;
3881 estimates->loops_with_known_strides = loops_with_known_strides;
3884 size = RDIV (size, ipa_fn_summary::size_scale);
3885 min_size = RDIV (min_size, ipa_fn_summary::size_scale);
3887 if (dump_file && (dump_flags & TDF_DETAILS))
3889 fprintf (dump_file, "\n size:%i", (int) size);
3890 if (est_times)
3891 fprintf (dump_file, " time:%f nonspec time:%f",
3892 time.to_double (), nonspecialized_time.to_double ());
3893 if (est_hints)
3894 fprintf (dump_file, " loops with known iterations:%f "
3895 "known strides:%f", loops_with_known_iterations.to_double (),
3896 loops_with_known_strides.to_double ());
3897 fprintf (dump_file, "\n");
3899 if (est_times)
3901 estimates->time = time;
3902 estimates->nonspecialized_time = nonspecialized_time;
3904 estimates->size = size;
3905 estimates->min_size = min_size;
3906 if (est_hints)
3907 estimates->hints = hints;
3908 return;
3912 /* Estimate size and time needed to execute callee of EDGE assuming that
3913 parameters known to be constant at caller of EDGE are propagated.
3914 KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
3915 and types for parameters. */
3917 void
3918 estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
3919 ipa_auto_call_arg_values *avals,
3920 ipa_call_estimates *estimates)
3922 clause_t clause, nonspec_clause;
3924 evaluate_conditions_for_known_args (node, false, avals, &clause,
3925 &nonspec_clause);
3926 ipa_call_context ctx (node, clause, nonspec_clause, vNULL, avals);
3927 ctx.estimate_size_and_time (estimates);
3930 /* Return stack frame offset where frame of NODE is supposed to start inside
3931 of the function it is inlined to.
3932 Return 0 for functions that are not inlined. */
3934 HOST_WIDE_INT
3935 ipa_get_stack_frame_offset (struct cgraph_node *node)
3937 HOST_WIDE_INT offset = 0;
3938 if (!node->inlined_to)
3939 return 0;
3940 node = node->callers->caller;
3941 while (true)
3943 offset += ipa_size_summaries->get (node)->estimated_self_stack_size;
3944 if (!node->inlined_to)
3945 return offset;
3946 node = node->callers->caller;
3951 /* Update summary information of inline clones after inlining.
3952 Compute peak stack usage. */
3954 static void
3955 inline_update_callee_summaries (struct cgraph_node *node, int depth)
3957 struct cgraph_edge *e;
3959 ipa_propagate_frequency (node);
3960 for (e = node->callees; e; e = e->next_callee)
3962 if (!e->inline_failed)
3963 inline_update_callee_summaries (e->callee, depth);
3964 else
3965 ipa_call_summaries->get (e)->loop_depth += depth;
3967 for (e = node->indirect_calls; e; e = e->next_callee)
3968 ipa_call_summaries->get (e)->loop_depth += depth;
3971 /* Update change_prob and points_to_local_or_readonly_memory of EDGE after
3972 INLINED_EDGE has been inlined.
3974 When function A is inlined in B and A calls C with parameter that
3975 changes with probability PROB1 and C is known to be passthrough
3976 of argument if B that change with probability PROB2, the probability
3977 of change is now PROB1*PROB2. */
3979 static void
3980 remap_edge_params (struct cgraph_edge *inlined_edge,
3981 struct cgraph_edge *edge)
3983 if (ipa_node_params_sum)
3985 int i;
3986 ipa_edge_args *args = ipa_edge_args_sum->get (edge);
3987 if (!args)
3988 return;
3989 class ipa_call_summary *es = ipa_call_summaries->get (edge);
3990 class ipa_call_summary *inlined_es
3991 = ipa_call_summaries->get (inlined_edge);
3993 if (es->param.length () == 0)
3994 return;
3996 for (i = 0; i < ipa_get_cs_argument_count (args); i++)
3998 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
3999 if (jfunc->type == IPA_JF_PASS_THROUGH
4000 || jfunc->type == IPA_JF_ANCESTOR)
4002 int id = jfunc->type == IPA_JF_PASS_THROUGH
4003 ? ipa_get_jf_pass_through_formal_id (jfunc)
4004 : ipa_get_jf_ancestor_formal_id (jfunc);
4005 if (id < (int) inlined_es->param.length ())
4007 int prob1 = es->param[i].change_prob;
4008 int prob2 = inlined_es->param[id].change_prob;
4009 int prob = combine_probabilities (prob1, prob2);
4011 if (prob1 && prob2 && !prob)
4012 prob = 1;
4014 es->param[i].change_prob = prob;
4016 if (inlined_es
4017 ->param[id].points_to_local_or_readonly_memory)
4018 es->param[i].points_to_local_or_readonly_memory = true;
4020 if (!es->param[i].points_to_local_or_readonly_memory
4021 && jfunc->type == IPA_JF_CONST
4022 && points_to_local_or_readonly_memory_p
4023 (ipa_get_jf_constant (jfunc)))
4024 es->param[i].points_to_local_or_readonly_memory = true;
4030 /* Update edge summaries of NODE after INLINED_EDGE has been inlined.
4032 Remap predicates of callees of NODE. Rest of arguments match
4033 remap_predicate.
4035 Also update change probabilities. */
4037 static void
4038 remap_edge_summaries (struct cgraph_edge *inlined_edge,
4039 struct cgraph_node *node,
4040 class ipa_fn_summary *info,
4041 class ipa_node_params *params_summary,
4042 class ipa_fn_summary *callee_info,
4043 const vec<int> &operand_map,
4044 const vec<HOST_WIDE_INT> &offset_map,
4045 clause_t possible_truths,
4046 ipa_predicate *toplev_predicate)
4048 struct cgraph_edge *e, *next;
4049 for (e = node->callees; e; e = next)
4051 ipa_predicate p;
4052 next = e->next_callee;
4054 if (e->inline_failed)
4056 class ipa_call_summary *es = ipa_call_summaries->get (e);
4057 remap_edge_params (inlined_edge, e);
4059 if (es->predicate)
4061 p = es->predicate->remap_after_inlining
4062 (info, params_summary,
4063 callee_info, operand_map,
4064 offset_map, possible_truths,
4065 *toplev_predicate);
4066 edge_set_predicate (e, &p);
4068 else
4069 edge_set_predicate (e, toplev_predicate);
4071 else
4072 remap_edge_summaries (inlined_edge, e->callee, info,
4073 params_summary, callee_info,
4074 operand_map, offset_map, possible_truths,
4075 toplev_predicate);
4077 for (e = node->indirect_calls; e; e = next)
4079 class ipa_call_summary *es = ipa_call_summaries->get (e);
4080 ipa_predicate p;
4081 next = e->next_callee;
4083 remap_edge_params (inlined_edge, e);
4084 if (es->predicate)
4086 p = es->predicate->remap_after_inlining
4087 (info, params_summary,
4088 callee_info, operand_map, offset_map,
4089 possible_truths, *toplev_predicate);
4090 edge_set_predicate (e, &p);
4092 else
4093 edge_set_predicate (e, toplev_predicate);
4097 /* Run remap_after_inlining on each predicate in V. */
4099 static void
4100 remap_freqcounting_predicate (class ipa_fn_summary *info,
4101 class ipa_node_params *params_summary,
4102 class ipa_fn_summary *callee_info,
4103 vec<ipa_freqcounting_predicate, va_gc> *v,
4104 const vec<int> &operand_map,
4105 const vec<HOST_WIDE_INT> &offset_map,
4106 clause_t possible_truths,
4107 ipa_predicate *toplev_predicate)
4110 ipa_freqcounting_predicate *fcp;
4111 for (int i = 0; vec_safe_iterate (v, i, &fcp); i++)
4113 ipa_predicate p
4114 = fcp->predicate->remap_after_inlining (info, params_summary,
4115 callee_info, operand_map,
4116 offset_map, possible_truths,
4117 *toplev_predicate);
4118 if (p != false && p != true)
4119 *fcp->predicate &= p;
4123 /* We inlined EDGE. Update summary of the function we inlined into. */
4125 void
4126 ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
4128 ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
4129 struct cgraph_node *to = (edge->caller->inlined_to
4130 ? edge->caller->inlined_to : edge->caller);
4131 class ipa_fn_summary *info = ipa_fn_summaries->get (to);
4132 clause_t clause = 0; /* not_inline is known to be false. */
4133 size_time_entry *e;
4134 auto_vec<int, 8> operand_map;
4135 auto_vec<HOST_WIDE_INT, 8> offset_map;
4136 int i;
4137 ipa_predicate toplev_predicate;
4138 class ipa_call_summary *es = ipa_call_summaries->get (edge);
4139 ipa_node_params *params_summary = (ipa_node_params_sum
4140 ? ipa_node_params_sum->get (to) : NULL);
4142 if (es->predicate)
4143 toplev_predicate = *es->predicate;
4144 else
4145 toplev_predicate = true;
4147 info->fp_expressions |= callee_info->fp_expressions;
4148 info->target_info |= callee_info->target_info;
4150 if (callee_info->conds)
4152 ipa_auto_call_arg_values avals;
4153 evaluate_properties_for_edge (edge, true, &clause, NULL, &avals, false);
4155 if (ipa_node_params_sum && callee_info->conds)
4157 ipa_edge_args *args = ipa_edge_args_sum->get (edge);
4158 int count = args ? ipa_get_cs_argument_count (args) : 0;
4159 int i;
4161 if (count)
4163 operand_map.safe_grow_cleared (count, true);
4164 offset_map.safe_grow_cleared (count, true);
4166 for (i = 0; i < count; i++)
4168 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
4169 int map = -1;
4171 /* TODO: handle non-NOPs when merging. */
4172 if (jfunc->type == IPA_JF_PASS_THROUGH)
4174 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4175 map = ipa_get_jf_pass_through_formal_id (jfunc);
4176 if (!ipa_get_jf_pass_through_agg_preserved (jfunc))
4177 offset_map[i] = -1;
4179 else if (jfunc->type == IPA_JF_ANCESTOR)
4181 HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc);
4182 if (offset >= 0 && offset < INT_MAX)
4184 map = ipa_get_jf_ancestor_formal_id (jfunc);
4185 if (!ipa_get_jf_ancestor_agg_preserved (jfunc))
4186 offset = -1;
4187 offset_map[i] = offset;
4190 operand_map[i] = map;
4191 gcc_assert (map < ipa_get_param_count (params_summary));
4194 int ip;
4195 for (i = 0; callee_info->builtin_constant_p_parms.iterate (i, &ip); i++)
4196 if (ip < count && operand_map[ip] >= 0)
4197 add_builtin_constant_p_parm (info, operand_map[ip]);
4199 sreal freq = edge->sreal_frequency ();
4200 for (i = 0; callee_info->size_time_table.iterate (i, &e); i++)
4202 ipa_predicate p;
4203 p = e->exec_predicate.remap_after_inlining
4204 (info, params_summary,
4205 callee_info, operand_map,
4206 offset_map, clause,
4207 toplev_predicate);
4208 ipa_predicate nonconstp;
4209 nonconstp = e->nonconst_predicate.remap_after_inlining
4210 (info, params_summary,
4211 callee_info, operand_map,
4212 offset_map, clause,
4213 toplev_predicate);
4214 if (p != false && nonconstp != false)
4216 sreal add_time = ((sreal)e->time * freq);
4217 int prob = e->nonconst_predicate.probability (callee_info->conds,
4218 clause, es->param);
4219 if (prob != REG_BR_PROB_BASE)
4220 add_time = add_time * prob / REG_BR_PROB_BASE;
4221 if (prob != REG_BR_PROB_BASE
4222 && dump_file && (dump_flags & TDF_DETAILS))
4224 fprintf (dump_file, "\t\tScaling time by probability:%f\n",
4225 (double) prob / REG_BR_PROB_BASE);
4227 info->account_size_time (e->size, add_time, p, nonconstp);
4230 remap_edge_summaries (edge, edge->callee, info, params_summary,
4231 callee_info, operand_map,
4232 offset_map, clause, &toplev_predicate);
4233 remap_freqcounting_predicate (info, params_summary, callee_info,
4234 info->loop_iterations, operand_map,
4235 offset_map, clause, &toplev_predicate);
4236 remap_freqcounting_predicate (info, params_summary, callee_info,
4237 info->loop_strides, operand_map,
4238 offset_map, clause, &toplev_predicate);
4240 HOST_WIDE_INT stack_frame_offset = ipa_get_stack_frame_offset (edge->callee);
4241 HOST_WIDE_INT peak = stack_frame_offset + callee_info->estimated_stack_size;
4243 if (info->estimated_stack_size < peak)
4244 info->estimated_stack_size = peak;
4246 inline_update_callee_summaries (edge->callee, es->loop_depth);
4247 if (info->call_size_time_table.length ())
4249 int edge_size = 0;
4250 sreal edge_time = 0;
4252 estimate_edge_size_and_time (edge, &edge_size, NULL, &edge_time, NULL, 0);
4253 /* Unaccount size and time of the optimized out call. */
4254 info->account_size_time (-edge_size, -edge_time,
4255 es->predicate ? *es->predicate : true,
4256 es->predicate ? *es->predicate : true,
4257 true);
4258 /* Account new calls. */
4259 summarize_calls_size_and_time (edge->callee, info);
4262 /* Free summaries that are not maintained for inline clones/edges. */
4263 ipa_call_summaries->remove (edge);
4264 ipa_fn_summaries->remove (edge->callee);
4265 ipa_remove_from_growth_caches (edge);
4268 /* For performance reasons ipa_merge_fn_summary_after_inlining is not updating
4269 overall size and time. Recompute it.
4270 If RESET is true also recompute call_time_size_table. */
4272 void
4273 ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset)
4275 class ipa_fn_summary *info = ipa_fn_summaries->get (node);
4276 class ipa_size_summary *size_info = ipa_size_summaries->get (node);
4277 size_time_entry *e;
4278 int i;
4280 size_info->size = 0;
4281 info->time = 0;
4282 for (i = 0; info->size_time_table.iterate (i, &e); i++)
4284 size_info->size += e->size;
4285 info->time += e->time;
4287 info->min_size = info->size_time_table[0].size;
4288 if (reset)
4289 info->call_size_time_table.release ();
4290 if (node->callees || node->indirect_calls)
4291 estimate_calls_size_and_time (node, &size_info->size, &info->min_size,
4292 &info->time, NULL,
4293 ~(clause_t) (1 << ipa_predicate::false_condition),
4294 NULL);
4295 size_info->size = RDIV (size_info->size, ipa_fn_summary::size_scale);
4296 info->min_size = RDIV (info->min_size, ipa_fn_summary::size_scale);
4300 /* This function performs intraprocedural analysis in NODE that is required to
4301 inline indirect calls. */
4303 static void
4304 inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
4306 ipa_analyze_node (node);
4307 if (dump_file && (dump_flags & TDF_DETAILS))
4309 ipa_print_node_params (dump_file, node);
4310 ipa_print_node_jump_functions (dump_file, node);
4315 /* Note function body size. */
4317 void
4318 inline_analyze_function (struct cgraph_node *node)
4320 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
4322 if (dump_file)
4323 fprintf (dump_file, "\nAnalyzing function: %s\n", node->dump_name ());
4324 if (opt_for_fn (node->decl, optimize) && !node->thunk)
4325 inline_indirect_intraprocedural_analysis (node);
4326 compute_fn_summary (node, false);
4327 if (!optimize)
4329 struct cgraph_edge *e;
4330 for (e = node->callees; e; e = e->next_callee)
4331 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
4332 for (e = node->indirect_calls; e; e = e->next_callee)
4333 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
4336 pop_cfun ();
4340 /* Called when new function is inserted to callgraph late. */
4342 void
4343 ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
4345 inline_analyze_function (node);
4348 /* Note function body size. */
4350 static void
4351 ipa_fn_summary_generate (void)
4353 struct cgraph_node *node;
4355 FOR_EACH_DEFINED_FUNCTION (node)
4356 if (DECL_STRUCT_FUNCTION (node->decl))
4357 node->versionable = tree_versionable_function_p (node->decl);
4359 ipa_fn_summary_alloc ();
4361 ipa_fn_summaries->enable_insertion_hook ();
4363 ipa_register_cgraph_hooks ();
4365 FOR_EACH_DEFINED_FUNCTION (node)
4366 if (!node->alias
4367 && (flag_generate_lto || flag_generate_offload|| flag_wpa
4368 || opt_for_fn (node->decl, optimize)))
4369 inline_analyze_function (node);
4373 /* Write inline summary for edge E to OB. */
4375 static void
4376 read_ipa_call_summary (class lto_input_block *ib, struct cgraph_edge *e,
4377 bool prevails)
4379 class ipa_call_summary *es = prevails
4380 ? ipa_call_summaries->get_create (e) : NULL;
4381 ipa_predicate p;
4382 int length, i;
4384 int size = streamer_read_uhwi (ib);
4385 int time = streamer_read_uhwi (ib);
4386 int depth = streamer_read_uhwi (ib);
4388 if (es)
4390 es->call_stmt_size = size;
4391 es->call_stmt_time = time;
4392 es->loop_depth = depth;
4395 bitpack_d bp = streamer_read_bitpack (ib);
4396 if (es)
4397 es->is_return_callee_uncaptured = bp_unpack_value (&bp, 1);
4398 else
4399 bp_unpack_value (&bp, 1);
4401 p.stream_in (ib);
4402 if (es)
4403 edge_set_predicate (e, &p);
4404 length = streamer_read_uhwi (ib);
4405 if (length && es
4406 && (e->possibly_call_in_translation_unit_p ()
4407 /* Also stream in jump functions to builtins in hope that they
4408 will get fnspecs. */
4409 || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
4411 es->param.safe_grow_cleared (length, true);
4412 for (i = 0; i < length; i++)
4414 es->param[i].change_prob = streamer_read_uhwi (ib);
4415 es->param[i].points_to_local_or_readonly_memory
4416 = streamer_read_uhwi (ib);
4419 else
4421 for (i = 0; i < length; i++)
4423 streamer_read_uhwi (ib);
4424 streamer_read_uhwi (ib);
4430 /* Stream in inline summaries from the section. */
4432 static void
4433 inline_read_section (struct lto_file_decl_data *file_data, const char *data,
4434 size_t len)
4436 const struct lto_function_header *header =
4437 (const struct lto_function_header *) data;
4438 const int cfg_offset = sizeof (struct lto_function_header);
4439 const int main_offset = cfg_offset + header->cfg_size;
4440 const int string_offset = main_offset + header->main_size;
4441 class data_in *data_in;
4442 unsigned int i, count2, j;
4443 unsigned int f_count;
4445 lto_input_block ib ((const char *) data + main_offset, header->main_size,
4446 file_data->mode_table);
4448 data_in =
4449 lto_data_in_create (file_data, (const char *) data + string_offset,
4450 header->string_size, vNULL);
4451 f_count = streamer_read_uhwi (&ib);
4452 for (i = 0; i < f_count; i++)
4454 unsigned int index;
4455 struct cgraph_node *node;
4456 class ipa_fn_summary *info;
4457 class ipa_node_params *params_summary;
4458 class ipa_size_summary *size_info;
4459 lto_symtab_encoder_t encoder;
4460 struct bitpack_d bp;
4461 struct cgraph_edge *e;
4462 ipa_predicate p;
4464 index = streamer_read_uhwi (&ib);
4465 encoder = file_data->symtab_node_encoder;
4466 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
4467 index));
4468 info = node->prevailing_p () ? ipa_fn_summaries->get_create (node) : NULL;
4469 params_summary = node->prevailing_p ()
4470 ? ipa_node_params_sum->get (node) : NULL;
4471 size_info = node->prevailing_p ()
4472 ? ipa_size_summaries->get_create (node) : NULL;
4474 int stack_size = streamer_read_uhwi (&ib);
4475 int size = streamer_read_uhwi (&ib);
4476 sreal time = sreal::stream_in (&ib);
4478 if (info)
4480 info->estimated_stack_size
4481 = size_info->estimated_self_stack_size = stack_size;
4482 size_info->size = size_info->self_size = size;
4483 info->time = time;
4486 bp = streamer_read_bitpack (&ib);
4487 if (info)
4489 info->inlinable = bp_unpack_value (&bp, 1);
4490 info->fp_expressions = bp_unpack_value (&bp, 1);
4491 if (!lto_stream_offload_p)
4492 info->target_info = streamer_read_uhwi (&ib);
4494 else
4496 bp_unpack_value (&bp, 1);
4497 bp_unpack_value (&bp, 1);
4498 if (!lto_stream_offload_p)
4499 streamer_read_uhwi (&ib);
4502 count2 = streamer_read_uhwi (&ib);
4503 gcc_assert (!info || !info->conds);
4504 if (info)
4505 vec_safe_reserve_exact (info->conds, count2);
4506 for (j = 0; j < count2; j++)
4508 struct condition c;
4509 unsigned int k, count3;
4510 c.operand_num = streamer_read_uhwi (&ib);
4511 c.code = (enum tree_code) streamer_read_uhwi (&ib);
4512 c.type = stream_read_tree (&ib, data_in);
4513 c.val = stream_read_tree (&ib, data_in);
4514 bp = streamer_read_bitpack (&ib);
4515 c.agg_contents = bp_unpack_value (&bp, 1);
4516 c.by_ref = bp_unpack_value (&bp, 1);
4517 if (c.agg_contents)
4518 c.offset = streamer_read_uhwi (&ib);
4519 count3 = streamer_read_uhwi (&ib);
4520 c.param_ops = NULL;
4521 if (info)
4522 vec_safe_reserve_exact (c.param_ops, count3);
4523 if (params_summary)
4524 ipa_set_param_used_by_ipa_predicates
4525 (params_summary, c.operand_num, true);
4526 for (k = 0; k < count3; k++)
4528 struct expr_eval_op op;
4529 enum gimple_rhs_class rhs_class;
4530 op.code = (enum tree_code) streamer_read_uhwi (&ib);
4531 op.type = stream_read_tree (&ib, data_in);
4532 switch (rhs_class = get_gimple_rhs_class (op.code))
4534 case GIMPLE_UNARY_RHS:
4535 op.index = 0;
4536 op.val[0] = NULL_TREE;
4537 op.val[1] = NULL_TREE;
4538 break;
4540 case GIMPLE_BINARY_RHS:
4541 case GIMPLE_TERNARY_RHS:
4542 bp = streamer_read_bitpack (&ib);
4543 op.index = bp_unpack_value (&bp, 2);
4544 op.val[0] = stream_read_tree (&ib, data_in);
4545 if (rhs_class == GIMPLE_BINARY_RHS)
4546 op.val[1] = NULL_TREE;
4547 else
4548 op.val[1] = stream_read_tree (&ib, data_in);
4549 break;
4551 default:
4552 fatal_error (UNKNOWN_LOCATION,
4553 "invalid fnsummary in LTO stream");
4555 if (info)
4556 c.param_ops->quick_push (op);
4558 if (info)
4559 info->conds->quick_push (c);
4561 count2 = streamer_read_uhwi (&ib);
4562 gcc_assert (!info || !info->size_time_table.length ());
4563 if (info && count2)
4564 info->size_time_table.reserve_exact (count2);
4565 for (j = 0; j < count2; j++)
4567 class size_time_entry e;
4569 e.size = streamer_read_uhwi (&ib);
4570 e.time = sreal::stream_in (&ib);
4571 e.exec_predicate.stream_in (&ib);
4572 e.nonconst_predicate.stream_in (&ib);
4574 if (info)
4575 info->size_time_table.quick_push (e);
4578 count2 = streamer_read_uhwi (&ib);
4579 for (j = 0; j < count2; j++)
4581 p.stream_in (&ib);
4582 sreal fcp_freq = sreal::stream_in (&ib);
4583 if (info)
4585 ipa_freqcounting_predicate fcp;
4586 fcp.predicate = NULL;
4587 set_hint_predicate (&fcp.predicate, p);
4588 fcp.freq = fcp_freq;
4589 vec_safe_push (info->loop_iterations, fcp);
4592 count2 = streamer_read_uhwi (&ib);
4593 for (j = 0; j < count2; j++)
4595 p.stream_in (&ib);
4596 sreal fcp_freq = sreal::stream_in (&ib);
4597 if (info)
4599 ipa_freqcounting_predicate fcp;
4600 fcp.predicate = NULL;
4601 set_hint_predicate (&fcp.predicate, p);
4602 fcp.freq = fcp_freq;
4603 vec_safe_push (info->loop_strides, fcp);
4606 count2 = streamer_read_uhwi (&ib);
4607 if (info && count2)
4608 info->builtin_constant_p_parms.reserve_exact (count2);
4609 for (j = 0; j < count2; j++)
4611 int parm = streamer_read_uhwi (&ib);
4612 if (info)
4613 info->builtin_constant_p_parms.quick_push (parm);
4615 for (e = node->callees; e; e = e->next_callee)
4616 read_ipa_call_summary (&ib, e, info != NULL);
4617 for (e = node->indirect_calls; e; e = e->next_callee)
4618 read_ipa_call_summary (&ib, e, info != NULL);
4621 lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
4622 len);
4623 lto_data_in_delete (data_in);
4627 /* Read inline summary. Jump functions are shared among ipa-cp
4628 and inliner, so when ipa-cp is active, we don't need to write them
4629 twice. */
4631 static void
4632 ipa_fn_summary_read (void)
4634 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
4635 struct lto_file_decl_data *file_data;
4636 unsigned int j = 0;
4638 ipa_prop_read_jump_functions ();
4639 ipa_fn_summary_alloc ();
4641 while ((file_data = file_data_vec[j++]))
4643 size_t len;
4644 const char *data
4645 = lto_get_summary_section_data (file_data, LTO_section_ipa_fn_summary,
4646 &len);
4647 if (data)
4648 inline_read_section (file_data, data, len);
4649 else
4650 /* Fatal error here. We do not want to support compiling ltrans units
4651 with different version of compiler or different flags than the WPA
4652 unit, so this should never happen. */
4653 fatal_error (input_location,
4654 "ipa inline summary is missing in input file");
4656 ipa_register_cgraph_hooks ();
4658 gcc_assert (ipa_fn_summaries);
4659 ipa_fn_summaries->enable_insertion_hook ();
4663 /* Write inline summary for edge E to OB. */
4665 static void
4666 write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
4668 class ipa_call_summary *es = ipa_call_summaries->get (e);
4669 int i;
4671 streamer_write_uhwi (ob, es->call_stmt_size);
4672 streamer_write_uhwi (ob, es->call_stmt_time);
4673 streamer_write_uhwi (ob, es->loop_depth);
4675 bitpack_d bp = bitpack_create (ob->main_stream);
4676 bp_pack_value (&bp, es->is_return_callee_uncaptured, 1);
4677 streamer_write_bitpack (&bp);
4679 if (es->predicate)
4680 es->predicate->stream_out (ob);
4681 else
4682 streamer_write_uhwi (ob, 0);
4683 streamer_write_uhwi (ob, es->param.length ());
4684 for (i = 0; i < (int) es->param.length (); i++)
4686 streamer_write_uhwi (ob, es->param[i].change_prob);
4687 streamer_write_uhwi (ob, es->param[i].points_to_local_or_readonly_memory);
4692 /* Write inline summary for node in SET.
4693 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
4694 active, we don't need to write them twice. */
4696 static void
4697 ipa_fn_summary_write (void)
4699 struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
4700 lto_symtab_encoder_iterator lsei;
4701 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
4702 unsigned int count = 0;
4704 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4705 lsei_next_function_in_partition (&lsei))
4707 cgraph_node *cnode = lsei_cgraph_node (lsei);
4708 if (cnode->definition && !cnode->alias)
4709 count++;
4711 streamer_write_uhwi (ob, count);
4713 for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
4714 lsei_next_function_in_partition (&lsei))
4716 cgraph_node *cnode = lsei_cgraph_node (lsei);
4717 if (cnode->definition && !cnode->alias)
4719 class ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
4720 class ipa_size_summary *size_info = ipa_size_summaries->get (cnode);
4721 struct bitpack_d bp;
4722 struct cgraph_edge *edge;
4723 int i;
4724 size_time_entry *e;
4725 struct condition *c;
4727 streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
4728 streamer_write_hwi (ob, size_info->estimated_self_stack_size);
4729 streamer_write_hwi (ob, size_info->self_size);
4730 info->time.stream_out (ob);
4731 bp = bitpack_create (ob->main_stream);
4732 bp_pack_value (&bp, info->inlinable, 1);
4733 bp_pack_value (&bp, info->fp_expressions, 1);
4734 streamer_write_bitpack (&bp);
4735 if (!lto_stream_offload_p)
4736 streamer_write_uhwi (ob, info->target_info);
4737 streamer_write_uhwi (ob, vec_safe_length (info->conds));
4738 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
4740 int j;
4741 struct expr_eval_op *op;
4743 streamer_write_uhwi (ob, c->operand_num);
4744 streamer_write_uhwi (ob, c->code);
4745 stream_write_tree (ob, c->type, true);
4746 stream_write_tree (ob, c->val, true);
4747 bp = bitpack_create (ob->main_stream);
4748 bp_pack_value (&bp, c->agg_contents, 1);
4749 bp_pack_value (&bp, c->by_ref, 1);
4750 streamer_write_bitpack (&bp);
4751 if (c->agg_contents)
4752 streamer_write_uhwi (ob, c->offset);
4753 streamer_write_uhwi (ob, vec_safe_length (c->param_ops));
4754 for (j = 0; vec_safe_iterate (c->param_ops, j, &op); j++)
4756 streamer_write_uhwi (ob, op->code);
4757 stream_write_tree (ob, op->type, true);
4758 if (op->val[0])
4760 bp = bitpack_create (ob->main_stream);
4761 bp_pack_value (&bp, op->index, 2);
4762 streamer_write_bitpack (&bp);
4763 stream_write_tree (ob, op->val[0], true);
4764 if (op->val[1])
4765 stream_write_tree (ob, op->val[1], true);
4769 streamer_write_uhwi (ob, info->size_time_table.length ());
4770 for (i = 0; info->size_time_table.iterate (i, &e); i++)
4772 streamer_write_uhwi (ob, e->size);
4773 e->time.stream_out (ob);
4774 e->exec_predicate.stream_out (ob);
4775 e->nonconst_predicate.stream_out (ob);
4777 ipa_freqcounting_predicate *fcp;
4778 streamer_write_uhwi (ob, vec_safe_length (info->loop_iterations));
4779 for (i = 0; vec_safe_iterate (info->loop_iterations, i, &fcp); i++)
4781 fcp->predicate->stream_out (ob);
4782 fcp->freq.stream_out (ob);
4784 streamer_write_uhwi (ob, vec_safe_length (info->loop_strides));
4785 for (i = 0; vec_safe_iterate (info->loop_strides, i, &fcp); i++)
4787 fcp->predicate->stream_out (ob);
4788 fcp->freq.stream_out (ob);
4790 streamer_write_uhwi (ob, info->builtin_constant_p_parms.length ());
4791 int ip;
4792 for (i = 0; info->builtin_constant_p_parms.iterate (i, &ip);
4793 i++)
4794 streamer_write_uhwi (ob, ip);
4795 for (edge = cnode->callees; edge; edge = edge->next_callee)
4796 write_ipa_call_summary (ob, edge);
4797 for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
4798 write_ipa_call_summary (ob, edge);
4801 streamer_write_char_stream (ob->main_stream, 0);
4802 produce_asm (ob, NULL);
4803 destroy_output_block (ob);
4805 ipa_prop_write_jump_functions ();
4809 /* Release function summary. */
4811 void
4812 ipa_free_fn_summary (void)
4814 if (!ipa_call_summaries)
4815 return;
4816 ggc_delete (ipa_fn_summaries);
4817 ipa_fn_summaries = NULL;
4818 delete ipa_call_summaries;
4819 ipa_call_summaries = NULL;
4820 edge_predicate_pool.release ();
4821 /* During IPA this is one of largest datastructures to release. */
4822 if (flag_wpa)
4823 ggc_trim ();
4826 /* Release function summary. */
4828 void
4829 ipa_free_size_summary (void)
4831 if (!ipa_size_summaries)
4832 return;
4833 delete ipa_size_summaries;
4834 ipa_size_summaries = NULL;
4837 namespace {
4839 const pass_data pass_data_local_fn_summary =
4841 GIMPLE_PASS, /* type */
4842 "local-fnsummary", /* name */
4843 OPTGROUP_INLINE, /* optinfo_flags */
4844 TV_INLINE_PARAMETERS, /* tv_id */
4845 0, /* properties_required */
4846 0, /* properties_provided */
4847 0, /* properties_destroyed */
4848 0, /* todo_flags_start */
4849 0, /* todo_flags_finish */
4852 class pass_local_fn_summary : public gimple_opt_pass
4854 public:
4855 pass_local_fn_summary (gcc::context *ctxt)
4856 : gimple_opt_pass (pass_data_local_fn_summary, ctxt)
4859 /* opt_pass methods: */
4860 opt_pass * clone () final override
4862 return new pass_local_fn_summary (m_ctxt);
4864 unsigned int execute (function *) final override
4866 return compute_fn_summary_for_current ();
4869 }; // class pass_local_fn_summary
4871 } // anon namespace
4873 gimple_opt_pass *
4874 make_pass_local_fn_summary (gcc::context *ctxt)
4876 return new pass_local_fn_summary (ctxt);
4880 /* Free inline summary. */
4882 namespace {
4884 const pass_data pass_data_ipa_free_fn_summary =
4886 SIMPLE_IPA_PASS, /* type */
4887 "free-fnsummary", /* name */
4888 OPTGROUP_NONE, /* optinfo_flags */
4889 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
4890 0, /* properties_required */
4891 0, /* properties_provided */
4892 0, /* properties_destroyed */
4893 0, /* todo_flags_start */
4894 0, /* todo_flags_finish */
4897 class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
4899 public:
4900 pass_ipa_free_fn_summary (gcc::context *ctxt)
4901 : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt),
4902 small_p (false)
4905 /* opt_pass methods: */
4906 opt_pass *clone () final override
4908 return new pass_ipa_free_fn_summary (m_ctxt);
4910 void set_pass_param (unsigned int n, bool param) final override
4912 gcc_assert (n == 0);
4913 small_p = param;
4915 bool gate (function *) final override { return true; }
4916 unsigned int execute (function *) final override
4918 ipa_free_fn_summary ();
4919 /* Free ipa-prop structures if they are no longer needed. */
4920 ipa_free_all_structures_after_iinln ();
4921 if (!flag_wpa)
4922 ipa_free_size_summary ();
4923 return 0;
4926 private:
4927 bool small_p;
4928 }; // class pass_ipa_free_fn_summary
4930 } // anon namespace
4932 simple_ipa_opt_pass *
4933 make_pass_ipa_free_fn_summary (gcc::context *ctxt)
4935 return new pass_ipa_free_fn_summary (ctxt);
4938 namespace {
4940 const pass_data pass_data_ipa_fn_summary =
4942 IPA_PASS, /* type */
4943 "fnsummary", /* name */
4944 OPTGROUP_INLINE, /* optinfo_flags */
4945 TV_IPA_FNSUMMARY, /* tv_id */
4946 0, /* properties_required */
4947 0, /* properties_provided */
4948 0, /* properties_destroyed */
4949 0, /* todo_flags_start */
4950 ( TODO_dump_symtab ), /* todo_flags_finish */
4953 class pass_ipa_fn_summary : public ipa_opt_pass_d
4955 public:
4956 pass_ipa_fn_summary (gcc::context *ctxt)
4957 : ipa_opt_pass_d (pass_data_ipa_fn_summary, ctxt,
4958 ipa_fn_summary_generate, /* generate_summary */
4959 ipa_fn_summary_write, /* write_summary */
4960 ipa_fn_summary_read, /* read_summary */
4961 NULL, /* write_optimization_summary */
4962 NULL, /* read_optimization_summary */
4963 NULL, /* stmt_fixup */
4964 0, /* function_transform_todo_flags_start */
4965 NULL, /* function_transform */
4966 NULL) /* variable_transform */
4969 /* opt_pass methods: */
4970 unsigned int execute (function *) final override { return 0; }
4972 }; // class pass_ipa_fn_summary
4974 } // anon namespace
4976 ipa_opt_pass_d *
4977 make_pass_ipa_fn_summary (gcc::context *ctxt)
4979 return new pass_ipa_fn_summary (ctxt);
4982 /* Reset all state within ipa-fnsummary.cc so that we can rerun the compiler
4983 within the same process. For use by toplev::finalize. */
4985 void
4986 ipa_fnsummary_cc_finalize (void)
4988 ipa_free_fn_summary ();