PR c++/86342 - -Wdeprecated-copy and system headers.
[official-gcc.git] / gcc / ipa-fnsummary.c
blobc99718a265f3ca034f1b13bb855cd24cd7841925
1 /* Function summary pass.
2 Copyright (C) 2003-2018 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 #include "system.h"
56 #include "coretypes.h"
57 #include "backend.h"
58 #include "tree.h"
59 #include "gimple.h"
60 #include "alloc-pool.h"
61 #include "tree-pass.h"
62 #include "ssa.h"
63 #include "tree-streamer.h"
64 #include "cgraph.h"
65 #include "diagnostic.h"
66 #include "fold-const.h"
67 #include "print-tree.h"
68 #include "tree-inline.h"
69 #include "gimple-pretty-print.h"
70 #include "params.h"
71 #include "cfganal.h"
72 #include "gimple-iterator.h"
73 #include "tree-cfg.h"
74 #include "tree-ssa-loop-niter.h"
75 #include "tree-ssa-loop.h"
76 #include "symbol-summary.h"
77 #include "ipa-prop.h"
78 #include "ipa-fnsummary.h"
79 #include "cfgloop.h"
80 #include "tree-scalar-evolution.h"
81 #include "ipa-utils.h"
82 #include "cfgexpand.h"
83 #include "gimplify.h"
84 #include "stringpool.h"
85 #include "attribs.h"
87 /* Summaries. */
88 function_summary <ipa_fn_summary *> *ipa_fn_summaries;
89 call_summary <ipa_call_summary *> *ipa_call_summaries;
91 /* Edge predicates goes here. */
92 static object_allocator<predicate> edge_predicate_pool ("edge predicates");
95 /* Dump IPA hints. */
96 void
97 ipa_dump_hints (FILE *f, ipa_hints hints)
99 if (!hints)
100 return;
101 fprintf (f, "IPA hints:");
102 if (hints & INLINE_HINT_indirect_call)
104 hints &= ~INLINE_HINT_indirect_call;
105 fprintf (f, " indirect_call");
107 if (hints & INLINE_HINT_loop_iterations)
109 hints &= ~INLINE_HINT_loop_iterations;
110 fprintf (f, " loop_iterations");
112 if (hints & INLINE_HINT_loop_stride)
114 hints &= ~INLINE_HINT_loop_stride;
115 fprintf (f, " loop_stride");
117 if (hints & INLINE_HINT_same_scc)
119 hints &= ~INLINE_HINT_same_scc;
120 fprintf (f, " same_scc");
122 if (hints & INLINE_HINT_in_scc)
124 hints &= ~INLINE_HINT_in_scc;
125 fprintf (f, " in_scc");
127 if (hints & INLINE_HINT_cross_module)
129 hints &= ~INLINE_HINT_cross_module;
130 fprintf (f, " cross_module");
132 if (hints & INLINE_HINT_declared_inline)
134 hints &= ~INLINE_HINT_declared_inline;
135 fprintf (f, " declared_inline");
137 if (hints & INLINE_HINT_array_index)
139 hints &= ~INLINE_HINT_array_index;
140 fprintf (f, " array_index");
142 if (hints & INLINE_HINT_known_hot)
144 hints &= ~INLINE_HINT_known_hot;
145 fprintf (f, " known_hot");
147 gcc_assert (!hints);
151 /* Record SIZE and TIME to SUMMARY.
152 The accounted code will be executed when EXEC_PRED is true.
153 When NONCONST_PRED is false the code will evaulate to constant and
154 will get optimized out in specialized clones of the function. */
156 void
157 ipa_fn_summary::account_size_time (int size, sreal time,
158 const predicate &exec_pred,
159 const predicate &nonconst_pred_in)
161 size_time_entry *e;
162 bool found = false;
163 int i;
164 predicate nonconst_pred;
166 if (exec_pred == false)
167 return;
169 nonconst_pred = nonconst_pred_in & exec_pred;
171 if (nonconst_pred == false)
172 return;
174 /* We need to create initial empty unconitional clause, but otherwie
175 we don't need to account empty times and sizes. */
176 if (!size && time == 0 && size_time_table)
177 return;
179 gcc_assert (time >= 0);
181 for (i = 0; vec_safe_iterate (size_time_table, i, &e); i++)
182 if (e->exec_predicate == exec_pred
183 && e->nonconst_predicate == nonconst_pred)
185 found = true;
186 break;
188 if (i == 256)
190 i = 0;
191 found = true;
192 e = &(*size_time_table)[0];
193 if (dump_file && (dump_flags & TDF_DETAILS))
194 fprintf (dump_file,
195 "\t\tReached limit on number of entries, "
196 "ignoring the predicate.");
198 if (dump_file && (dump_flags & TDF_DETAILS) && (time != 0 || size))
200 fprintf (dump_file,
201 "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
202 ((double) size) / ipa_fn_summary::size_scale,
203 (time.to_double ()), found ? "" : "new ");
204 exec_pred.dump (dump_file, conds, 0);
205 if (exec_pred != nonconst_pred)
207 fprintf (dump_file, " nonconst:");
208 nonconst_pred.dump (dump_file, conds);
210 else
211 fprintf (dump_file, "\n");
213 if (!found)
215 struct size_time_entry new_entry;
216 new_entry.size = size;
217 new_entry.time = time;
218 new_entry.exec_predicate = exec_pred;
219 new_entry.nonconst_predicate = nonconst_pred;
220 vec_safe_push (size_time_table, new_entry);
222 else
224 e->size += size;
225 e->time += time;
229 /* We proved E to be unreachable, redirect it to __bultin_unreachable. */
231 static struct cgraph_edge *
232 redirect_to_unreachable (struct cgraph_edge *e)
234 struct cgraph_node *callee = !e->inline_failed ? e->callee : NULL;
235 struct cgraph_node *target = cgraph_node::get_create
236 (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
238 if (e->speculative)
239 e = e->resolve_speculation (target->decl);
240 else if (!e->callee)
241 e->make_direct (target);
242 else
243 e->redirect_callee (target);
244 struct ipa_call_summary *es = ipa_call_summaries->get (e);
245 e->inline_failed = CIF_UNREACHABLE;
246 e->count = profile_count::zero ();
247 es->call_stmt_size = 0;
248 es->call_stmt_time = 0;
249 if (callee)
250 callee->remove_symbol_and_inline_clones ();
251 return e;
254 /* Set predicate for edge E. */
256 static void
257 edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
259 /* If the edge is determined to be never executed, redirect it
260 to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
261 be optimized out. */
262 if (predicate && *predicate == false
263 /* When handling speculative edges, we need to do the redirection
264 just once. Do it always on the direct edge, so we do not
265 attempt to resolve speculation while duplicating the edge. */
266 && (!e->speculative || e->callee))
267 e = redirect_to_unreachable (e);
269 struct ipa_call_summary *es = ipa_call_summaries->get (e);
270 if (predicate && *predicate != true)
272 if (!es->predicate)
273 es->predicate = edge_predicate_pool.allocate ();
274 *es->predicate = *predicate;
276 else
278 if (es->predicate)
279 edge_predicate_pool.remove (es->predicate);
280 es->predicate = NULL;
284 /* Set predicate for hint *P. */
286 static void
287 set_hint_predicate (predicate **p, predicate new_predicate)
289 if (new_predicate == false || new_predicate == true)
291 if (*p)
292 edge_predicate_pool.remove (*p);
293 *p = NULL;
295 else
297 if (!*p)
298 *p = edge_predicate_pool.allocate ();
299 **p = new_predicate;
304 /* Compute what conditions may or may not hold given invormation about
305 parameters. RET_CLAUSE returns truths that may hold in a specialized copy,
306 whie RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
307 copy when called in a given context. It is a bitmask of conditions. Bit
308 0 means that condition is known to be false, while bit 1 means that condition
309 may or may not be true. These differs - for example NOT_INLINED condition
310 is always false in the second and also builtin_constant_p tests can not use
311 the fact that parameter is indeed a constant.
313 KNOWN_VALS is partial mapping of parameters of NODE to constant values.
314 KNOWN_AGGS is a vector of aggreggate jump functions for each parameter.
315 Return clause of possible truths. When INLINE_P is true, assume that we are
316 inlining.
318 ERROR_MARK means compile time invariant. */
320 static void
321 evaluate_conditions_for_known_args (struct cgraph_node *node,
322 bool inline_p,
323 vec<tree> known_vals,
324 vec<ipa_agg_jump_function_p>
325 known_aggs,
326 clause_t *ret_clause,
327 clause_t *ret_nonspec_clause)
329 clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
330 clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
331 struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
332 int i;
333 struct condition *c;
335 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
337 tree val;
338 tree res;
340 /* We allow call stmt to have fewer arguments than the callee function
341 (especially for K&R style programs). So bound check here (we assume
342 known_aggs vector, if non-NULL, has the same length as
343 known_vals). */
344 gcc_checking_assert (!known_aggs.exists ()
345 || (known_vals.length () == known_aggs.length ()));
346 if (c->operand_num >= (int) known_vals.length ())
348 clause |= 1 << (i + predicate::first_dynamic_condition);
349 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
350 continue;
353 if (c->agg_contents)
355 struct ipa_agg_jump_function *agg;
357 if (c->code == predicate::changed
358 && !c->by_ref
359 && (known_vals[c->operand_num] == error_mark_node))
360 continue;
362 if (known_aggs.exists ())
364 agg = known_aggs[c->operand_num];
365 val = ipa_find_agg_cst_for_param (agg, known_vals[c->operand_num],
366 c->offset, c->by_ref);
368 else
369 val = NULL_TREE;
371 else
373 val = known_vals[c->operand_num];
374 if (val == error_mark_node && c->code != predicate::changed)
375 val = NULL_TREE;
378 if (!val)
380 clause |= 1 << (i + predicate::first_dynamic_condition);
381 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
382 continue;
384 if (c->code == predicate::changed)
386 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
387 continue;
390 if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
392 clause |= 1 << (i + predicate::first_dynamic_condition);
393 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
394 continue;
396 if (c->code == predicate::is_not_constant)
398 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
399 continue;
402 val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val);
403 res = val
404 ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
405 : NULL;
407 if (res && integer_zerop (res))
408 continue;
410 clause |= 1 << (i + predicate::first_dynamic_condition);
411 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
413 *ret_clause = clause;
414 if (ret_nonspec_clause)
415 *ret_nonspec_clause = nonspec_clause;
419 /* Work out what conditions might be true at invocation of E. */
421 void
422 evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p,
423 clause_t *clause_ptr,
424 clause_t *nonspec_clause_ptr,
425 vec<tree> *known_vals_ptr,
426 vec<ipa_polymorphic_call_context>
427 *known_contexts_ptr,
428 vec<ipa_agg_jump_function_p> *known_aggs_ptr)
430 struct cgraph_node *callee = e->callee->ultimate_alias_target ();
431 struct ipa_fn_summary *info = ipa_fn_summaries->get (callee);
432 vec<tree> known_vals = vNULL;
433 vec<ipa_agg_jump_function_p> known_aggs = vNULL;
435 if (clause_ptr)
436 *clause_ptr = inline_p ? 0 : 1 << predicate::not_inlined_condition;
437 if (known_vals_ptr)
438 known_vals_ptr->create (0);
439 if (known_contexts_ptr)
440 known_contexts_ptr->create (0);
442 if (ipa_node_params_sum
443 && !e->call_stmt_cannot_inline_p
444 && ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
446 struct ipa_node_params *caller_parms_info, *callee_pi;
447 struct ipa_edge_args *args = IPA_EDGE_REF (e);
448 struct ipa_call_summary *es = ipa_call_summaries->get (e);
449 int i, count = ipa_get_cs_argument_count (args);
451 if (e->caller->global.inlined_to)
452 caller_parms_info = IPA_NODE_REF (e->caller->global.inlined_to);
453 else
454 caller_parms_info = IPA_NODE_REF (e->caller);
455 callee_pi = IPA_NODE_REF (e->callee);
457 if (count && (info->conds || known_vals_ptr))
458 known_vals.safe_grow_cleared (count);
459 if (count && (info->conds || known_aggs_ptr))
460 known_aggs.safe_grow_cleared (count);
461 if (count && known_contexts_ptr)
462 known_contexts_ptr->safe_grow_cleared (count);
464 for (i = 0; i < count; i++)
466 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
467 tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
468 ipa_get_type (callee_pi, i));
470 if (!cst && e->call_stmt
471 && i < (int)gimple_call_num_args (e->call_stmt))
473 cst = gimple_call_arg (e->call_stmt, i);
474 if (!is_gimple_min_invariant (cst))
475 cst = NULL;
477 if (cst)
479 gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
480 if (known_vals.exists ())
481 known_vals[i] = cst;
483 else if (inline_p && !es->param[i].change_prob)
484 known_vals[i] = error_mark_node;
486 if (known_contexts_ptr)
487 (*known_contexts_ptr)[i]
488 = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
489 /* TODO: When IPA-CP starts propagating and merging aggregate jump
490 functions, use its knowledge of the caller too, just like the
491 scalar case above. */
492 known_aggs[i] = &jf->agg;
495 else if (e->call_stmt && !e->call_stmt_cannot_inline_p
496 && ((clause_ptr && info->conds) || known_vals_ptr))
498 int i, count = (int)gimple_call_num_args (e->call_stmt);
500 if (count && (info->conds || known_vals_ptr))
501 known_vals.safe_grow_cleared (count);
502 for (i = 0; i < count; i++)
504 tree cst = gimple_call_arg (e->call_stmt, i);
505 if (!is_gimple_min_invariant (cst))
506 cst = NULL;
507 if (cst)
508 known_vals[i] = cst;
512 evaluate_conditions_for_known_args (callee, inline_p,
513 known_vals, known_aggs, clause_ptr,
514 nonspec_clause_ptr);
516 if (known_vals_ptr)
517 *known_vals_ptr = known_vals;
518 else
519 known_vals.release ();
521 if (known_aggs_ptr)
522 *known_aggs_ptr = known_aggs;
523 else
524 known_aggs.release ();
528 /* Allocate the function summary. */
530 static void
531 ipa_fn_summary_alloc (void)
533 gcc_checking_assert (!ipa_fn_summaries);
534 ipa_fn_summaries = ipa_fn_summary_t::create_ggc (symtab);
535 ipa_call_summaries = new ipa_call_summary_t (symtab, false);
538 ipa_call_summary::~ipa_call_summary ()
540 if (predicate)
541 edge_predicate_pool.remove (predicate);
543 param.release ();
546 ipa_fn_summary::~ipa_fn_summary ()
548 if (loop_iterations)
549 edge_predicate_pool.remove (loop_iterations);
550 if (loop_stride)
551 edge_predicate_pool.remove (loop_stride);
552 if (array_index)
553 edge_predicate_pool.remove (array_index);
554 vec_free (conds);
555 vec_free (size_time_table);
558 void
559 ipa_fn_summary_t::remove_callees (cgraph_node *node)
561 cgraph_edge *e;
562 for (e = node->callees; e; e = e->next_callee)
563 ipa_call_summaries->remove (e);
564 for (e = node->indirect_calls; e; e = e->next_callee)
565 ipa_call_summaries->remove (e);
568 /* Same as remap_predicate_after_duplication but handle hint predicate *P.
569 Additionally care about allocating new memory slot for updated predicate
570 and set it to NULL when it becomes true or false (and thus uninteresting).
573 static void
574 remap_hint_predicate_after_duplication (predicate **p,
575 clause_t possible_truths)
577 predicate new_predicate;
579 if (!*p)
580 return;
582 new_predicate = (*p)->remap_after_duplication (possible_truths);
583 /* We do not want to free previous predicate; it is used by node origin. */
584 *p = NULL;
585 set_hint_predicate (p, new_predicate);
589 /* Hook that is called by cgraph.c when a node is duplicated. */
590 void
591 ipa_fn_summary_t::duplicate (cgraph_node *src,
592 cgraph_node *dst,
593 ipa_fn_summary *,
594 ipa_fn_summary *info)
596 new (info) ipa_fn_summary (*ipa_fn_summaries->get (src));
597 /* TODO: as an optimization, we may avoid copying conditions
598 that are known to be false or true. */
599 info->conds = vec_safe_copy (info->conds);
601 /* When there are any replacements in the function body, see if we can figure
602 out that something was optimized out. */
603 if (ipa_node_params_sum && dst->clone.tree_map)
605 vec<size_time_entry, va_gc> *entry = info->size_time_table;
606 /* Use SRC parm info since it may not be copied yet. */
607 struct ipa_node_params *parms_info = IPA_NODE_REF (src);
608 vec<tree> known_vals = vNULL;
609 int count = ipa_get_param_count (parms_info);
610 int i, j;
611 clause_t possible_truths;
612 predicate true_pred = true;
613 size_time_entry *e;
614 int optimized_out_size = 0;
615 bool inlined_to_p = false;
616 struct cgraph_edge *edge, *next;
618 info->size_time_table = 0;
619 known_vals.safe_grow_cleared (count);
620 for (i = 0; i < count; i++)
622 struct ipa_replace_map *r;
624 for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++)
626 if (((!r->old_tree && r->parm_num == i)
627 || (r->old_tree && r->old_tree == ipa_get_param (parms_info, i)))
628 && r->replace_p && !r->ref_p)
630 known_vals[i] = r->new_tree;
631 break;
635 evaluate_conditions_for_known_args (dst, false,
636 known_vals,
637 vNULL,
638 &possible_truths,
639 /* We are going to specialize,
640 so ignore nonspec truths. */
641 NULL);
642 known_vals.release ();
644 info->account_size_time (0, 0, true_pred, true_pred);
646 /* Remap size_time vectors.
647 Simplify the predicate by prunning out alternatives that are known
648 to be false.
649 TODO: as on optimization, we can also eliminate conditions known
650 to be true. */
651 for (i = 0; vec_safe_iterate (entry, i, &e); i++)
653 predicate new_exec_pred;
654 predicate new_nonconst_pred;
655 new_exec_pred = e->exec_predicate.remap_after_duplication
656 (possible_truths);
657 new_nonconst_pred = e->nonconst_predicate.remap_after_duplication
658 (possible_truths);
659 if (new_exec_pred == false || new_nonconst_pred == false)
660 optimized_out_size += e->size;
661 else
662 info->account_size_time (e->size, e->time, new_exec_pred,
663 new_nonconst_pred);
666 /* Remap edge predicates with the same simplification as above.
667 Also copy constantness arrays. */
668 for (edge = dst->callees; edge; edge = next)
670 predicate new_predicate;
671 struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
672 next = edge->next_callee;
674 if (!edge->inline_failed)
675 inlined_to_p = true;
676 if (!es->predicate)
677 continue;
678 new_predicate = es->predicate->remap_after_duplication
679 (possible_truths);
680 if (new_predicate == false && *es->predicate != false)
681 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
682 edge_set_predicate (edge, &new_predicate);
685 /* Remap indirect edge predicates with the same simplificaiton as above.
686 Also copy constantness arrays. */
687 for (edge = dst->indirect_calls; edge; edge = next)
689 predicate new_predicate;
690 struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
691 next = edge->next_callee;
693 gcc_checking_assert (edge->inline_failed);
694 if (!es->predicate)
695 continue;
696 new_predicate = es->predicate->remap_after_duplication
697 (possible_truths);
698 if (new_predicate == false && *es->predicate != false)
699 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
700 edge_set_predicate (edge, &new_predicate);
702 remap_hint_predicate_after_duplication (&info->loop_iterations,
703 possible_truths);
704 remap_hint_predicate_after_duplication (&info->loop_stride,
705 possible_truths);
706 remap_hint_predicate_after_duplication (&info->array_index,
707 possible_truths);
709 /* If inliner or someone after inliner will ever start producing
710 non-trivial clones, we will get trouble with lack of information
711 about updating self sizes, because size vectors already contains
712 sizes of the calees. */
713 gcc_assert (!inlined_to_p || !optimized_out_size);
715 else
717 info->size_time_table = vec_safe_copy (info->size_time_table);
718 if (info->loop_iterations)
720 predicate p = *info->loop_iterations;
721 info->loop_iterations = NULL;
722 set_hint_predicate (&info->loop_iterations, p);
724 if (info->loop_stride)
726 predicate p = *info->loop_stride;
727 info->loop_stride = NULL;
728 set_hint_predicate (&info->loop_stride, p);
730 if (info->array_index)
732 predicate p = *info->array_index;
733 info->array_index = NULL;
734 set_hint_predicate (&info->array_index, p);
737 if (!dst->global.inlined_to)
738 ipa_update_overall_fn_summary (dst);
742 /* Hook that is called by cgraph.c when a node is duplicated. */
744 void
745 ipa_call_summary_t::duplicate (struct cgraph_edge *src,
746 struct cgraph_edge *dst,
747 struct ipa_call_summary *srcinfo,
748 struct ipa_call_summary *info)
750 new (info) ipa_call_summary (*srcinfo);
751 info->predicate = NULL;
752 edge_set_predicate (dst, srcinfo->predicate);
753 info->param = srcinfo->param.copy ();
754 if (!dst->indirect_unknown_callee && src->indirect_unknown_callee)
756 info->call_stmt_size -= (eni_size_weights.indirect_call_cost
757 - eni_size_weights.call_cost);
758 info->call_stmt_time -= (eni_time_weights.indirect_call_cost
759 - eni_time_weights.call_cost);
763 /* Dump edge summaries associated to NODE and recursively to all clones.
764 Indent by INDENT. */
766 static void
767 dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
768 struct ipa_fn_summary *info)
770 struct cgraph_edge *edge;
771 for (edge = node->callees; edge; edge = edge->next_callee)
773 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
774 struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
775 int i;
777 fprintf (f,
778 "%*s%s/%i %s\n%*s loop depth:%2i freq:%4.2f size:%2i time: %2i",
779 indent, "", callee->name (), callee->order,
780 !edge->inline_failed
781 ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
782 indent, "", es->loop_depth, edge->sreal_frequency ().to_double (),
783 es->call_stmt_size, es->call_stmt_time);
785 ipa_fn_summary *s = ipa_fn_summaries->get (callee);
786 if (s != NULL)
787 fprintf (f, "callee size:%2i stack:%2i",
788 (int) (s->size / ipa_fn_summary::size_scale),
789 (int) s->estimated_stack_size);
791 if (es->predicate)
793 fprintf (f, " predicate: ");
794 es->predicate->dump (f, info->conds);
796 else
797 fprintf (f, "\n");
798 if (es->param.exists ())
799 for (i = 0; i < (int) es->param.length (); i++)
801 int prob = es->param[i].change_prob;
803 if (!prob)
804 fprintf (f, "%*s op%i is compile time invariant\n",
805 indent + 2, "", i);
806 else if (prob != REG_BR_PROB_BASE)
807 fprintf (f, "%*s op%i change %f%% of time\n", indent + 2, "", i,
808 prob * 100.0 / REG_BR_PROB_BASE);
810 if (!edge->inline_failed)
812 ipa_fn_summary *s = ipa_fn_summaries->get (callee);
813 fprintf (f, "%*sStack frame offset %i, callee self size %i,"
814 " callee size %i\n",
815 indent + 2, "",
816 (int) s->stack_frame_offset,
817 (int) s->estimated_self_stack_size,
818 (int) s->estimated_stack_size);
819 dump_ipa_call_summary (f, indent + 2, callee, info);
822 for (edge = node->indirect_calls; edge; edge = edge->next_callee)
824 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
825 fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
826 " time: %2i",
827 indent, "",
828 es->loop_depth,
829 edge->sreal_frequency ().to_double (), es->call_stmt_size,
830 es->call_stmt_time);
831 if (es->predicate)
833 fprintf (f, "predicate: ");
834 es->predicate->dump (f, info->conds);
836 else
837 fprintf (f, "\n");
842 void
843 ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
845 if (node->definition)
847 struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
848 if (s != NULL)
850 size_time_entry *e;
851 int i;
852 fprintf (f, "IPA function summary for %s", node->dump_name ());
853 if (DECL_DISREGARD_INLINE_LIMITS (node->decl))
854 fprintf (f, " always_inline");
855 if (s->inlinable)
856 fprintf (f, " inlinable");
857 if (s->fp_expressions)
858 fprintf (f, " fp_expression");
859 fprintf (f, "\n global time: %f\n", s->time.to_double ());
860 fprintf (f, " self size: %i\n", s->self_size);
861 fprintf (f, " global size: %i\n", s->size);
862 fprintf (f, " min size: %i\n", s->min_size);
863 fprintf (f, " self stack: %i\n",
864 (int) s->estimated_self_stack_size);
865 fprintf (f, " global stack: %i\n", (int) s->estimated_stack_size);
866 if (s->growth)
867 fprintf (f, " estimated growth:%i\n", (int) s->growth);
868 if (s->scc_no)
869 fprintf (f, " In SCC: %i\n", (int) s->scc_no);
870 for (i = 0; vec_safe_iterate (s->size_time_table, i, &e); i++)
872 fprintf (f, " size:%f, time:%f",
873 (double) e->size / ipa_fn_summary::size_scale,
874 e->time.to_double ());
875 if (e->exec_predicate != true)
877 fprintf (f, ", executed if:");
878 e->exec_predicate.dump (f, s->conds, 0);
880 if (e->exec_predicate != e->nonconst_predicate)
882 fprintf (f, ", nonconst if:");
883 e->nonconst_predicate.dump (f, s->conds, 0);
885 fprintf (f, "\n");
887 if (s->loop_iterations)
889 fprintf (f, " loop iterations:");
890 s->loop_iterations->dump (f, s->conds);
892 if (s->loop_stride)
894 fprintf (f, " loop stride:");
895 s->loop_stride->dump (f, s->conds);
897 if (s->array_index)
899 fprintf (f, " array index:");
900 s->array_index->dump (f, s->conds);
902 fprintf (f, " calls:\n");
903 dump_ipa_call_summary (f, 4, node, s);
904 fprintf (f, "\n");
906 else
907 fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
911 DEBUG_FUNCTION void
912 ipa_debug_fn_summary (struct cgraph_node *node)
914 ipa_dump_fn_summary (stderr, node);
917 void
918 ipa_dump_fn_summaries (FILE *f)
920 struct cgraph_node *node;
922 FOR_EACH_DEFINED_FUNCTION (node)
923 if (!node->global.inlined_to)
924 ipa_dump_fn_summary (f, node);
927 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
928 boolean variable pointed to by DATA. */
930 static bool
931 mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
932 void *data)
934 bool *b = (bool *) data;
935 *b = true;
936 return true;
939 /* If OP refers to value of function parameter, return the corresponding
940 parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
941 PARM_DECL) will be stored to *SIZE_P in that case too. */
943 static tree
944 unmodified_parm_1 (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
946 /* SSA_NAME referring to parm default def? */
947 if (TREE_CODE (op) == SSA_NAME
948 && SSA_NAME_IS_DEFAULT_DEF (op)
949 && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
951 if (size_p)
952 *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
953 return SSA_NAME_VAR (op);
955 /* Non-SSA parm reference? */
956 if (TREE_CODE (op) == PARM_DECL)
958 bool modified = false;
960 ao_ref refd;
961 ao_ref_init (&refd, op);
962 walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
963 NULL);
964 if (!modified)
966 if (size_p)
967 *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
968 return op;
971 return NULL_TREE;
974 /* If OP refers to value of function parameter, return the corresponding
975 parameter. Also traverse chains of SSA register assignments. If non-NULL,
976 the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
977 stored to *SIZE_P in that case too. */
979 static tree
980 unmodified_parm (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
982 tree res = unmodified_parm_1 (stmt, op, size_p);
983 if (res)
984 return res;
986 if (TREE_CODE (op) == SSA_NAME
987 && !SSA_NAME_IS_DEFAULT_DEF (op)
988 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
989 return unmodified_parm (SSA_NAME_DEF_STMT (op),
990 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
991 size_p);
992 return NULL_TREE;
995 /* If OP refers to a value of a function parameter or value loaded from an
996 aggregate passed to a parameter (either by value or reference), return TRUE
997 and store the number of the parameter to *INDEX_P, the access size into
998 *SIZE_P, and information whether and how it has been loaded from an
999 aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
1000 statement in which OP is used or loaded. */
1002 static bool
1003 unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
1004 gimple *stmt, tree op, int *index_p,
1005 HOST_WIDE_INT *size_p,
1006 struct agg_position_info *aggpos)
1008 tree res = unmodified_parm_1 (stmt, op, size_p);
1010 gcc_checking_assert (aggpos);
1011 if (res)
1013 *index_p = ipa_get_param_decl_index (fbi->info, res);
1014 if (*index_p < 0)
1015 return false;
1016 aggpos->agg_contents = false;
1017 aggpos->by_ref = false;
1018 return true;
1021 if (TREE_CODE (op) == SSA_NAME)
1023 if (SSA_NAME_IS_DEFAULT_DEF (op)
1024 || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1025 return false;
1026 stmt = SSA_NAME_DEF_STMT (op);
1027 op = gimple_assign_rhs1 (stmt);
1028 if (!REFERENCE_CLASS_P (op))
1029 return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
1030 aggpos);
1033 aggpos->agg_contents = true;
1034 return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
1035 stmt, op, index_p, &aggpos->offset,
1036 size_p, &aggpos->by_ref);
1039 /* See if statement might disappear after inlining.
1040 0 - means not eliminated
1041 1 - half of statements goes away
1042 2 - for sure it is eliminated.
1043 We are not terribly sophisticated, basically looking for simple abstraction
1044 penalty wrappers. */
1046 static int
1047 eliminated_by_inlining_prob (gimple *stmt)
1049 enum gimple_code code = gimple_code (stmt);
1050 enum tree_code rhs_code;
1052 if (!optimize)
1053 return 0;
1055 switch (code)
1057 case GIMPLE_RETURN:
1058 return 2;
1059 case GIMPLE_ASSIGN:
1060 if (gimple_num_ops (stmt) != 2)
1061 return 0;
1063 rhs_code = gimple_assign_rhs_code (stmt);
1065 /* Casts of parameters, loads from parameters passed by reference
1066 and stores to return value or parameters are often free after
1067 inlining dua to SRA and further combining.
1068 Assume that half of statements goes away. */
1069 if (CONVERT_EXPR_CODE_P (rhs_code)
1070 || rhs_code == VIEW_CONVERT_EXPR
1071 || rhs_code == ADDR_EXPR
1072 || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1074 tree rhs = gimple_assign_rhs1 (stmt);
1075 tree lhs = gimple_assign_lhs (stmt);
1076 tree inner_rhs = get_base_address (rhs);
1077 tree inner_lhs = get_base_address (lhs);
1078 bool rhs_free = false;
1079 bool lhs_free = false;
1081 if (!inner_rhs)
1082 inner_rhs = rhs;
1083 if (!inner_lhs)
1084 inner_lhs = lhs;
1086 /* Reads of parameter are expected to be free. */
1087 if (unmodified_parm (stmt, inner_rhs, NULL))
1088 rhs_free = true;
1089 /* Match expressions of form &this->field. Those will most likely
1090 combine with something upstream after inlining. */
1091 else if (TREE_CODE (inner_rhs) == ADDR_EXPR)
1093 tree op = get_base_address (TREE_OPERAND (inner_rhs, 0));
1094 if (TREE_CODE (op) == PARM_DECL)
1095 rhs_free = true;
1096 else if (TREE_CODE (op) == MEM_REF
1097 && unmodified_parm (stmt, TREE_OPERAND (op, 0), NULL))
1098 rhs_free = true;
1101 /* When parameter is not SSA register because its address is taken
1102 and it is just copied into one, the statement will be completely
1103 free after inlining (we will copy propagate backward). */
1104 if (rhs_free && is_gimple_reg (lhs))
1105 return 2;
1107 /* Reads of parameters passed by reference
1108 expected to be free (i.e. optimized out after inlining). */
1109 if (TREE_CODE (inner_rhs) == MEM_REF
1110 && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0), NULL))
1111 rhs_free = true;
1113 /* Copying parameter passed by reference into gimple register is
1114 probably also going to copy propagate, but we can't be quite
1115 sure. */
1116 if (rhs_free && is_gimple_reg (lhs))
1117 lhs_free = true;
1119 /* Writes to parameters, parameters passed by value and return value
1120 (either dirrectly or passed via invisible reference) are free.
1122 TODO: We ought to handle testcase like
1123 struct a {int a,b;};
1124 struct a
1125 retrurnsturct (void)
1127 struct a a ={1,2};
1128 return a;
1131 This translate into:
1133 retrurnsturct ()
1135 int a$b;
1136 int a$a;
1137 struct a a;
1138 struct a D.2739;
1140 <bb 2>:
1141 D.2739.a = 1;
1142 D.2739.b = 2;
1143 return D.2739;
1146 For that we either need to copy ipa-split logic detecting writes
1147 to return value. */
1148 if (TREE_CODE (inner_lhs) == PARM_DECL
1149 || TREE_CODE (inner_lhs) == RESULT_DECL
1150 || (TREE_CODE (inner_lhs) == MEM_REF
1151 && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0), NULL)
1152 || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
1153 && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
1154 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1155 (inner_lhs,
1156 0))) == RESULT_DECL))))
1157 lhs_free = true;
1158 if (lhs_free
1159 && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
1160 rhs_free = true;
1161 if (lhs_free && rhs_free)
1162 return 1;
1164 return 0;
1165 default:
1166 return 0;
1171 /* If BB ends by a conditional we can turn into predicates, attach corresponding
1172 predicates to the CFG edges. */
1174 static void
1175 set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1176 struct ipa_fn_summary *summary,
1177 basic_block bb)
1179 gimple *last;
1180 tree op;
1181 int index;
1182 HOST_WIDE_INT size;
1183 struct agg_position_info aggpos;
1184 enum tree_code code, inverted_code;
1185 edge e;
1186 edge_iterator ei;
1187 gimple *set_stmt;
1188 tree op2;
1190 last = last_stmt (bb);
1191 if (!last || gimple_code (last) != GIMPLE_COND)
1192 return;
1193 if (!is_gimple_ip_invariant (gimple_cond_rhs (last)))
1194 return;
1195 op = gimple_cond_lhs (last);
1196 /* TODO: handle conditionals like
1197 var = op0 < 4;
1198 if (var != 0). */
1199 if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1201 code = gimple_cond_code (last);
1202 inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
1204 FOR_EACH_EDGE (e, ei, bb->succs)
1206 enum tree_code this_code = (e->flags & EDGE_TRUE_VALUE
1207 ? code : inverted_code);
1208 /* invert_tree_comparison will return ERROR_MARK on FP
1209 comparsions that are not EQ/NE instead of returning proper
1210 unordered one. Be sure it is not confused with NON_CONSTANT. */
1211 if (this_code != ERROR_MARK)
1213 predicate p
1214 = add_condition (summary, index, size, &aggpos, this_code,
1215 unshare_expr_without_location
1216 (gimple_cond_rhs (last)));
1217 e->aux = edge_predicate_pool.allocate ();
1218 *(predicate *) e->aux = p;
1223 if (TREE_CODE (op) != SSA_NAME)
1224 return;
1225 /* Special case
1226 if (builtin_constant_p (op))
1227 constant_code
1228 else
1229 nonconstant_code.
1230 Here we can predicate nonconstant_code. We can't
1231 really handle constant_code since we have no predicate
1232 for this and also the constant code is not known to be
1233 optimized away when inliner doen't see operand is constant.
1234 Other optimizers might think otherwise. */
1235 if (gimple_cond_code (last) != NE_EXPR
1236 || !integer_zerop (gimple_cond_rhs (last)))
1237 return;
1238 set_stmt = SSA_NAME_DEF_STMT (op);
1239 if (!gimple_call_builtin_p (set_stmt, BUILT_IN_CONSTANT_P)
1240 || gimple_call_num_args (set_stmt) != 1)
1241 return;
1242 op2 = gimple_call_arg (set_stmt, 0);
1243 if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size,
1244 &aggpos))
1245 return;
1246 FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
1248 predicate p = add_condition (summary, index, size, &aggpos,
1249 predicate::is_not_constant, NULL_TREE);
1250 e->aux = edge_predicate_pool.allocate ();
1251 *(predicate *) e->aux = p;
1256 /* If BB ends by a switch we can turn into predicates, attach corresponding
1257 predicates to the CFG edges. */
1259 static void
1260 set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
1261 struct ipa_fn_summary *summary,
1262 basic_block bb)
1264 gimple *lastg;
1265 tree op;
1266 int index;
1267 HOST_WIDE_INT size;
1268 struct agg_position_info aggpos;
1269 edge e;
1270 edge_iterator ei;
1271 size_t n;
1272 size_t case_idx;
1274 lastg = last_stmt (bb);
1275 if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH)
1276 return;
1277 gswitch *last = as_a <gswitch *> (lastg);
1278 op = gimple_switch_index (last);
1279 if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1280 return;
1282 FOR_EACH_EDGE (e, ei, bb->succs)
1284 e->aux = edge_predicate_pool.allocate ();
1285 *(predicate *) e->aux = false;
1287 n = gimple_switch_num_labels (last);
1288 for (case_idx = 0; case_idx < n; ++case_idx)
1290 tree cl = gimple_switch_label (last, case_idx);
1291 tree min, max;
1292 predicate p;
1294 e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
1295 min = CASE_LOW (cl);
1296 max = CASE_HIGH (cl);
1298 /* For default we might want to construct predicate that none
1299 of cases is met, but it is bit hard to do not having negations
1300 of conditionals handy. */
1301 if (!min && !max)
1302 p = true;
1303 else if (!max)
1304 p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
1305 unshare_expr_without_location (min));
1306 else
1308 predicate p1, p2;
1309 p1 = add_condition (summary, index, size, &aggpos, GE_EXPR,
1310 unshare_expr_without_location (min));
1311 p2 = add_condition (summary, index, size, &aggpos, LE_EXPR,
1312 unshare_expr_without_location (max));
1313 p = p1 & p2;
1315 *(struct predicate *) e->aux
1316 = p.or_with (summary->conds, *(struct predicate *) e->aux);
1321 /* For each BB in NODE attach to its AUX pointer predicate under
1322 which it is executable. */
1324 static void
1325 compute_bb_predicates (struct ipa_func_body_info *fbi,
1326 struct cgraph_node *node,
1327 struct ipa_fn_summary *summary)
1329 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1330 bool done = false;
1331 basic_block bb;
1333 FOR_EACH_BB_FN (bb, my_function)
1335 set_cond_stmt_execution_predicate (fbi, summary, bb);
1336 set_switch_stmt_execution_predicate (fbi, summary, bb);
1339 /* Entry block is always executable. */
1340 ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux
1341 = edge_predicate_pool.allocate ();
1342 *(predicate *) ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux = true;
1344 /* A simple dataflow propagation of predicates forward in the CFG.
1345 TODO: work in reverse postorder. */
1346 while (!done)
1348 done = true;
1349 FOR_EACH_BB_FN (bb, my_function)
1351 predicate p = false;
1352 edge e;
1353 edge_iterator ei;
1354 FOR_EACH_EDGE (e, ei, bb->preds)
1356 if (e->src->aux)
1358 predicate this_bb_predicate
1359 = *(predicate *) e->src->aux;
1360 if (e->aux)
1361 this_bb_predicate &= (*(struct predicate *) e->aux);
1362 p = p.or_with (summary->conds, this_bb_predicate);
1363 if (p == true)
1364 break;
1367 if (p == false)
1368 gcc_checking_assert (!bb->aux);
1369 else
1371 if (!bb->aux)
1373 done = false;
1374 bb->aux = edge_predicate_pool.allocate ();
1375 *((predicate *) bb->aux) = p;
1377 else if (p != *(predicate *) bb->aux)
1379 /* This OR operation is needed to ensure monotonous data flow
1380 in the case we hit the limit on number of clauses and the
1381 and/or operations above give approximate answers. */
1382 p = p.or_with (summary->conds, *(predicate *)bb->aux);
1383 if (p != *(predicate *) bb->aux)
1385 done = false;
1386 *((predicate *) bb->aux) = p;
1395 /* Return predicate specifying when the STMT might have result that is not
1396 a compile time constant. */
1398 static predicate
1399 will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
1400 struct ipa_fn_summary *summary,
1401 tree expr,
1402 vec<predicate> nonconstant_names)
1404 tree parm;
1405 int index;
1406 HOST_WIDE_INT size;
1408 while (UNARY_CLASS_P (expr))
1409 expr = TREE_OPERAND (expr, 0);
1411 parm = unmodified_parm (NULL, expr, &size);
1412 if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
1413 return add_condition (summary, index, size, NULL, predicate::changed,
1414 NULL_TREE);
1415 if (is_gimple_min_invariant (expr))
1416 return false;
1417 if (TREE_CODE (expr) == SSA_NAME)
1418 return nonconstant_names[SSA_NAME_VERSION (expr)];
1419 if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
1421 predicate p1 = will_be_nonconstant_expr_predicate
1422 (info, summary, TREE_OPERAND (expr, 0),
1423 nonconstant_names);
1424 if (p1 == true)
1425 return p1;
1427 predicate p2;
1428 p2 = will_be_nonconstant_expr_predicate (info, summary,
1429 TREE_OPERAND (expr, 1),
1430 nonconstant_names);
1431 return p1.or_with (summary->conds, p2);
1433 else if (TREE_CODE (expr) == COND_EXPR)
1435 predicate p1 = will_be_nonconstant_expr_predicate
1436 (info, summary, TREE_OPERAND (expr, 0),
1437 nonconstant_names);
1438 if (p1 == true)
1439 return p1;
1441 predicate p2;
1442 p2 = will_be_nonconstant_expr_predicate (info, summary,
1443 TREE_OPERAND (expr, 1),
1444 nonconstant_names);
1445 if (p2 == true)
1446 return p2;
1447 p1 = p1.or_with (summary->conds, p2);
1448 p2 = will_be_nonconstant_expr_predicate (info, summary,
1449 TREE_OPERAND (expr, 2),
1450 nonconstant_names);
1451 return p2.or_with (summary->conds, p1);
1453 else if (TREE_CODE (expr) == CALL_EXPR)
1454 return true;
1455 else
1457 debug_tree (expr);
1458 gcc_unreachable ();
1460 return false;
1464 /* Return predicate specifying when the STMT might have result that is not
1465 a compile time constant. */
1467 static predicate
1468 will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
1469 struct ipa_fn_summary *summary,
1470 gimple *stmt,
1471 vec<predicate> nonconstant_names)
1473 predicate p = true;
1474 ssa_op_iter iter;
1475 tree use;
1476 predicate op_non_const;
1477 bool is_load;
1478 int base_index;
1479 HOST_WIDE_INT size;
1480 struct agg_position_info aggpos;
1482 /* What statments might be optimized away
1483 when their arguments are constant. */
1484 if (gimple_code (stmt) != GIMPLE_ASSIGN
1485 && gimple_code (stmt) != GIMPLE_COND
1486 && gimple_code (stmt) != GIMPLE_SWITCH
1487 && (gimple_code (stmt) != GIMPLE_CALL
1488 || !(gimple_call_flags (stmt) & ECF_CONST)))
1489 return p;
1491 /* Stores will stay anyway. */
1492 if (gimple_store_p (stmt))
1493 return p;
1495 is_load = gimple_assign_load_p (stmt);
1497 /* Loads can be optimized when the value is known. */
1498 if (is_load)
1500 tree op;
1501 gcc_assert (gimple_assign_single_p (stmt));
1502 op = gimple_assign_rhs1 (stmt);
1503 if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size,
1504 &aggpos))
1505 return p;
1507 else
1508 base_index = -1;
1510 /* See if we understand all operands before we start
1511 adding conditionals. */
1512 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1514 tree parm = unmodified_parm (stmt, use, NULL);
1515 /* For arguments we can build a condition. */
1516 if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
1517 continue;
1518 if (TREE_CODE (use) != SSA_NAME)
1519 return p;
1520 /* If we know when operand is constant,
1521 we still can say something useful. */
1522 if (nonconstant_names[SSA_NAME_VERSION (use)] != true)
1523 continue;
1524 return p;
1527 if (is_load)
1528 op_non_const =
1529 add_condition (summary, base_index, size, &aggpos, predicate::changed,
1530 NULL);
1531 else
1532 op_non_const = false;
1533 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1535 HOST_WIDE_INT size;
1536 tree parm = unmodified_parm (stmt, use, &size);
1537 int index;
1539 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
1541 if (index != base_index)
1542 p = add_condition (summary, index, size, NULL, predicate::changed,
1543 NULL_TREE);
1544 else
1545 continue;
1547 else
1548 p = nonconstant_names[SSA_NAME_VERSION (use)];
1549 op_non_const = p.or_with (summary->conds, op_non_const);
1551 if ((gimple_code (stmt) == GIMPLE_ASSIGN || gimple_code (stmt) == GIMPLE_CALL)
1552 && gimple_op (stmt, 0)
1553 && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
1554 nonconstant_names[SSA_NAME_VERSION (gimple_op (stmt, 0))]
1555 = op_non_const;
1556 return op_non_const;
1559 struct record_modified_bb_info
1561 tree op;
1562 bitmap bb_set;
1563 gimple *stmt;
1566 /* Value is initialized in INIT_BB and used in USE_BB. We want to copute
1567 probability how often it changes between USE_BB.
1568 INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
1569 is in different loop nest, we can do better.
1570 This is all just estimate. In theory we look for minimal cut separating
1571 INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
1572 anyway. */
1574 static basic_block
1575 get_minimal_bb (basic_block init_bb, basic_block use_bb)
1577 struct loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
1578 if (l && l->header->count < init_bb->count)
1579 return l->header;
1580 return init_bb;
1583 /* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
1584 set except for info->stmt. */
1586 static bool
1587 record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1589 struct record_modified_bb_info *info =
1590 (struct record_modified_bb_info *) data;
1591 if (SSA_NAME_DEF_STMT (vdef) == info->stmt)
1592 return false;
1593 if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef)))
1594 return false;
1595 bitmap_set_bit (info->bb_set,
1596 SSA_NAME_IS_DEFAULT_DEF (vdef)
1597 ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index
1598 : get_minimal_bb
1599 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1600 gimple_bb (info->stmt))->index);
1601 if (dump_file)
1603 fprintf (dump_file, " Param ");
1604 print_generic_expr (dump_file, info->op, TDF_SLIM);
1605 fprintf (dump_file, " changed at bb %i, minimal: %i stmt: ",
1606 gimple_bb (SSA_NAME_DEF_STMT (vdef))->index,
1607 get_minimal_bb
1608 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1609 gimple_bb (info->stmt))->index);
1610 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (vdef), 0);
1612 return false;
1615 /* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
1616 will change since last invocation of STMT.
1618 Value 0 is reserved for compile time invariants.
1619 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
1620 ought to be REG_BR_PROB_BASE / estimated_iters. */
1622 static int
1623 param_change_prob (gimple *stmt, int i)
1625 tree op = gimple_call_arg (stmt, i);
1626 basic_block bb = gimple_bb (stmt);
1628 if (TREE_CODE (op) == WITH_SIZE_EXPR)
1629 op = TREE_OPERAND (op, 0);
1631 tree base = get_base_address (op);
1633 /* Global invariants never change. */
1634 if (is_gimple_min_invariant (base))
1635 return 0;
1637 /* We would have to do non-trivial analysis to really work out what
1638 is the probability of value to change (i.e. when init statement
1639 is in a sibling loop of the call).
1641 We do an conservative estimate: when call is executed N times more often
1642 than the statement defining value, we take the frequency 1/N. */
1643 if (TREE_CODE (base) == SSA_NAME)
1645 profile_count init_count;
1647 if (!bb->count.nonzero_p ())
1648 return REG_BR_PROB_BASE;
1650 if (SSA_NAME_IS_DEFAULT_DEF (base))
1651 init_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
1652 else
1653 init_count = get_minimal_bb
1654 (gimple_bb (SSA_NAME_DEF_STMT (base)),
1655 gimple_bb (stmt))->count;
1657 if (init_count < bb->count)
1658 return MAX ((init_count.to_sreal_scale (bb->count)
1659 * REG_BR_PROB_BASE).to_int (), 1);
1660 return REG_BR_PROB_BASE;
1662 else
1664 ao_ref refd;
1665 profile_count max = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
1666 struct record_modified_bb_info info;
1667 tree init = ctor_for_folding (base);
1669 if (init != error_mark_node)
1670 return 0;
1671 if (!bb->count.nonzero_p ())
1672 return REG_BR_PROB_BASE;
1673 if (dump_file)
1675 fprintf (dump_file, " Analyzing param change probablity of ");
1676 print_generic_expr (dump_file, op, TDF_SLIM);
1677 fprintf (dump_file, "\n");
1679 ao_ref_init (&refd, op);
1680 info.op = op;
1681 info.stmt = stmt;
1682 info.bb_set = BITMAP_ALLOC (NULL);
1683 walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
1684 NULL);
1685 if (bitmap_bit_p (info.bb_set, bb->index))
1687 if (dump_file)
1688 fprintf (dump_file, " Set in same BB as used.\n");
1689 BITMAP_FREE (info.bb_set);
1690 return REG_BR_PROB_BASE;
1693 bitmap_iterator bi;
1694 unsigned index;
1695 /* Lookup the most frequent update of the value and believe that
1696 it dominates all the other; precise analysis here is difficult. */
1697 EXECUTE_IF_SET_IN_BITMAP (info.bb_set, 0, index, bi)
1698 max = max.max (BASIC_BLOCK_FOR_FN (cfun, index)->count);
1699 if (dump_file)
1701 fprintf (dump_file, " Set with count ");
1702 max.dump (dump_file);
1703 fprintf (dump_file, " and used with count ");
1704 bb->count.dump (dump_file);
1705 fprintf (dump_file, " freq %f\n",
1706 max.to_sreal_scale (bb->count).to_double ());
1709 BITMAP_FREE (info.bb_set);
1710 if (max < bb->count)
1711 return MAX ((max.to_sreal_scale (bb->count)
1712 * REG_BR_PROB_BASE).to_int (), 1);
1713 return REG_BR_PROB_BASE;
1717 /* Find whether a basic block BB is the final block of a (half) diamond CFG
1718 sub-graph and if the predicate the condition depends on is known. If so,
1719 return true and store the pointer the predicate in *P. */
1721 static bool
1722 phi_result_unknown_predicate (struct ipa_node_params *info,
1723 ipa_fn_summary *summary, basic_block bb,
1724 predicate *p,
1725 vec<predicate> nonconstant_names)
1727 edge e;
1728 edge_iterator ei;
1729 basic_block first_bb = NULL;
1730 gimple *stmt;
1732 if (single_pred_p (bb))
1734 *p = false;
1735 return true;
1738 FOR_EACH_EDGE (e, ei, bb->preds)
1740 if (single_succ_p (e->src))
1742 if (!single_pred_p (e->src))
1743 return false;
1744 if (!first_bb)
1745 first_bb = single_pred (e->src);
1746 else if (single_pred (e->src) != first_bb)
1747 return false;
1749 else
1751 if (!first_bb)
1752 first_bb = e->src;
1753 else if (e->src != first_bb)
1754 return false;
1758 if (!first_bb)
1759 return false;
1761 stmt = last_stmt (first_bb);
1762 if (!stmt
1763 || gimple_code (stmt) != GIMPLE_COND
1764 || !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
1765 return false;
1767 *p = will_be_nonconstant_expr_predicate (info, summary,
1768 gimple_cond_lhs (stmt),
1769 nonconstant_names);
1770 if (*p == true)
1771 return false;
1772 else
1773 return true;
1776 /* Given a PHI statement in a function described by inline properties SUMMARY
1777 and *P being the predicate describing whether the selected PHI argument is
1778 known, store a predicate for the result of the PHI statement into
1779 NONCONSTANT_NAMES, if possible. */
1781 static void
1782 predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
1783 predicate *p,
1784 vec<predicate> nonconstant_names)
1786 unsigned i;
1788 for (i = 0; i < gimple_phi_num_args (phi); i++)
1790 tree arg = gimple_phi_arg (phi, i)->def;
1791 if (!is_gimple_min_invariant (arg))
1793 gcc_assert (TREE_CODE (arg) == SSA_NAME);
1794 *p = p->or_with (summary->conds,
1795 nonconstant_names[SSA_NAME_VERSION (arg)]);
1796 if (*p == true)
1797 return;
1801 if (dump_file && (dump_flags & TDF_DETAILS))
1803 fprintf (dump_file, "\t\tphi predicate: ");
1804 p->dump (dump_file, summary->conds);
1806 nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
1809 /* Return predicate specifying when array index in access OP becomes non-constant. */
1811 static predicate
1812 array_index_predicate (ipa_fn_summary *info,
1813 vec< predicate> nonconstant_names, tree op)
1815 predicate p = false;
1816 while (handled_component_p (op))
1818 if (TREE_CODE (op) == ARRAY_REF || TREE_CODE (op) == ARRAY_RANGE_REF)
1820 if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
1821 p = p.or_with (info->conds,
1822 nonconstant_names[SSA_NAME_VERSION
1823 (TREE_OPERAND (op, 1))]);
1825 op = TREE_OPERAND (op, 0);
1827 return p;
1830 /* For a typical usage of __builtin_expect (a<b, 1), we
1831 may introduce an extra relation stmt:
1832 With the builtin, we have
1833 t1 = a <= b;
1834 t2 = (long int) t1;
1835 t3 = __builtin_expect (t2, 1);
1836 if (t3 != 0)
1837 goto ...
1838 Without the builtin, we have
1839 if (a<=b)
1840 goto...
1841 This affects the size/time estimation and may have
1842 an impact on the earlier inlining.
1843 Here find this pattern and fix it up later. */
1845 static gimple *
1846 find_foldable_builtin_expect (basic_block bb)
1848 gimple_stmt_iterator bsi;
1850 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
1852 gimple *stmt = gsi_stmt (bsi);
1853 if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
1854 || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
1856 tree var = gimple_call_lhs (stmt);
1857 tree arg = gimple_call_arg (stmt, 0);
1858 use_operand_p use_p;
1859 gimple *use_stmt;
1860 bool match = false;
1861 bool done = false;
1863 if (!var || !arg)
1864 continue;
1865 gcc_assert (TREE_CODE (var) == SSA_NAME);
1867 while (TREE_CODE (arg) == SSA_NAME)
1869 gimple *stmt_tmp = SSA_NAME_DEF_STMT (arg);
1870 if (!is_gimple_assign (stmt_tmp))
1871 break;
1872 switch (gimple_assign_rhs_code (stmt_tmp))
1874 case LT_EXPR:
1875 case LE_EXPR:
1876 case GT_EXPR:
1877 case GE_EXPR:
1878 case EQ_EXPR:
1879 case NE_EXPR:
1880 match = true;
1881 done = true;
1882 break;
1883 CASE_CONVERT:
1884 break;
1885 default:
1886 done = true;
1887 break;
1889 if (done)
1890 break;
1891 arg = gimple_assign_rhs1 (stmt_tmp);
1894 if (match && single_imm_use (var, &use_p, &use_stmt)
1895 && gimple_code (use_stmt) == GIMPLE_COND)
1896 return use_stmt;
1899 return NULL;
1902 /* Return true when the basic blocks contains only clobbers followed by RESX.
1903 Such BBs are kept around to make removal of dead stores possible with
1904 presence of EH and will be optimized out by optimize_clobbers later in the
1905 game.
1907 NEED_EH is used to recurse in case the clobber has non-EH predecestors
1908 that can be clobber only, too.. When it is false, the RESX is not necessary
1909 on the end of basic block. */
1911 static bool
1912 clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
1914 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1915 edge_iterator ei;
1916 edge e;
1918 if (need_eh)
1920 if (gsi_end_p (gsi))
1921 return false;
1922 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
1923 return false;
1924 gsi_prev (&gsi);
1926 else if (!single_succ_p (bb))
1927 return false;
1929 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
1931 gimple *stmt = gsi_stmt (gsi);
1932 if (is_gimple_debug (stmt))
1933 continue;
1934 if (gimple_clobber_p (stmt))
1935 continue;
1936 if (gimple_code (stmt) == GIMPLE_LABEL)
1937 break;
1938 return false;
1941 /* See if all predecestors are either throws or clobber only BBs. */
1942 FOR_EACH_EDGE (e, ei, bb->preds)
1943 if (!(e->flags & EDGE_EH)
1944 && !clobber_only_eh_bb_p (e->src, false))
1945 return false;
1947 return true;
1950 /* Return true if STMT compute a floating point expression that may be affected
1951 by -ffast-math and similar flags. */
1953 static bool
1954 fp_expression_p (gimple *stmt)
1956 ssa_op_iter i;
1957 tree op;
1959 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
1960 if (FLOAT_TYPE_P (TREE_TYPE (op)))
1961 return true;
1962 return false;
1965 /* Analyze function body for NODE.
1966 EARLY indicates run from early optimization pipeline. */
1968 static void
1969 analyze_function_body (struct cgraph_node *node, bool early)
1971 sreal time = 0;
1972 /* Estimate static overhead for function prologue/epilogue and alignment. */
1973 int size = 2;
1974 /* Benefits are scaled by probability of elimination that is in range
1975 <0,2>. */
1976 basic_block bb;
1977 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1978 sreal freq;
1979 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
1980 predicate bb_predicate;
1981 struct ipa_func_body_info fbi;
1982 vec<predicate> nonconstant_names = vNULL;
1983 int nblocks, n;
1984 int *order;
1985 predicate array_index = true;
1986 gimple *fix_builtin_expect_stmt;
1988 gcc_assert (my_function && my_function->cfg);
1989 gcc_assert (cfun == my_function);
1991 memset(&fbi, 0, sizeof(fbi));
1992 info->conds = NULL;
1993 info->size_time_table = NULL;
1995 /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
1996 so we can produce proper inline hints.
1998 When optimizing and analyzing for early inliner, initialize node params
1999 so we can produce correct BB predicates. */
2001 if (opt_for_fn (node->decl, optimize))
2003 calculate_dominance_info (CDI_DOMINATORS);
2004 if (!early)
2005 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
2006 else
2008 ipa_check_create_node_params ();
2009 ipa_initialize_node_params (node);
2012 if (ipa_node_params_sum)
2014 fbi.node = node;
2015 fbi.info = IPA_NODE_REF (node);
2016 fbi.bb_infos = vNULL;
2017 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
2018 fbi.param_count = count_formal_params(node->decl);
2019 nonconstant_names.safe_grow_cleared
2020 (SSANAMES (my_function)->length ());
2024 if (dump_file)
2025 fprintf (dump_file, "\nAnalyzing function body size: %s\n",
2026 node->name ());
2028 /* When we run into maximal number of entries, we assign everything to the
2029 constant truth case. Be sure to have it in list. */
2030 bb_predicate = true;
2031 info->account_size_time (0, 0, bb_predicate, bb_predicate);
2033 bb_predicate = predicate::not_inlined ();
2034 info->account_size_time (2 * ipa_fn_summary::size_scale, 0, bb_predicate,
2035 bb_predicate);
2037 if (fbi.info)
2038 compute_bb_predicates (&fbi, node, info);
2039 order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
2040 nblocks = pre_and_rev_post_order_compute (NULL, order, false);
2041 for (n = 0; n < nblocks; n++)
2043 bb = BASIC_BLOCK_FOR_FN (cfun, order[n]);
2044 freq = bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count);
2045 if (clobber_only_eh_bb_p (bb))
2047 if (dump_file && (dump_flags & TDF_DETAILS))
2048 fprintf (dump_file, "\n Ignoring BB %i;"
2049 " it will be optimized away by cleanup_clobbers\n",
2050 bb->index);
2051 continue;
2054 /* TODO: Obviously predicates can be propagated down across CFG. */
2055 if (fbi.info)
2057 if (bb->aux)
2058 bb_predicate = *(predicate *) bb->aux;
2059 else
2060 bb_predicate = false;
2062 else
2063 bb_predicate = true;
2065 if (dump_file && (dump_flags & TDF_DETAILS))
2067 fprintf (dump_file, "\n BB %i predicate:", bb->index);
2068 bb_predicate.dump (dump_file, info->conds);
2071 if (fbi.info && nonconstant_names.exists ())
2073 predicate phi_predicate;
2074 bool first_phi = true;
2076 for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
2077 gsi_next (&bsi))
2079 if (first_phi
2080 && !phi_result_unknown_predicate (fbi.info, info, bb,
2081 &phi_predicate,
2082 nonconstant_names))
2083 break;
2084 first_phi = false;
2085 if (dump_file && (dump_flags & TDF_DETAILS))
2087 fprintf (dump_file, " ");
2088 print_gimple_stmt (dump_file, gsi_stmt (bsi), 0);
2090 predicate_for_phi_result (info, bsi.phi (), &phi_predicate,
2091 nonconstant_names);
2095 fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
2097 for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
2098 gsi_next (&bsi))
2100 gimple *stmt = gsi_stmt (bsi);
2101 int this_size = estimate_num_insns (stmt, &eni_size_weights);
2102 int this_time = estimate_num_insns (stmt, &eni_time_weights);
2103 int prob;
2104 predicate will_be_nonconstant;
2106 /* This relation stmt should be folded after we remove
2107 buildin_expect call. Adjust the cost here. */
2108 if (stmt == fix_builtin_expect_stmt)
2110 this_size--;
2111 this_time--;
2114 if (dump_file && (dump_flags & TDF_DETAILS))
2116 fprintf (dump_file, " ");
2117 print_gimple_stmt (dump_file, stmt, 0);
2118 fprintf (dump_file, "\t\tfreq:%3.2f size:%3i time:%3i\n",
2119 freq.to_double (), this_size,
2120 this_time);
2123 if (gimple_assign_load_p (stmt) && nonconstant_names.exists ())
2125 predicate this_array_index;
2126 this_array_index =
2127 array_index_predicate (info, nonconstant_names,
2128 gimple_assign_rhs1 (stmt));
2129 if (this_array_index != false)
2130 array_index &= this_array_index;
2132 if (gimple_store_p (stmt) && nonconstant_names.exists ())
2134 predicate this_array_index;
2135 this_array_index =
2136 array_index_predicate (info, nonconstant_names,
2137 gimple_get_lhs (stmt));
2138 if (this_array_index != false)
2139 array_index &= this_array_index;
2143 if (is_gimple_call (stmt)
2144 && !gimple_call_internal_p (stmt))
2146 struct cgraph_edge *edge = node->get_edge (stmt);
2147 ipa_call_summary *es = ipa_call_summaries->get_create (edge);
2149 /* Special case: results of BUILT_IN_CONSTANT_P will be always
2150 resolved as constant. We however don't want to optimize
2151 out the cgraph edges. */
2152 if (nonconstant_names.exists ()
2153 && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
2154 && gimple_call_lhs (stmt)
2155 && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
2157 predicate false_p = false;
2158 nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
2159 = false_p;
2161 if (ipa_node_params_sum)
2163 int count = gimple_call_num_args (stmt);
2164 int i;
2166 if (count)
2167 es->param.safe_grow_cleared (count);
2168 for (i = 0; i < count; i++)
2170 int prob = param_change_prob (stmt, i);
2171 gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
2172 es->param[i].change_prob = prob;
2176 es->call_stmt_size = this_size;
2177 es->call_stmt_time = this_time;
2178 es->loop_depth = bb_loop_depth (bb);
2179 edge_set_predicate (edge, &bb_predicate);
2182 /* TODO: When conditional jump or swithc is known to be constant, but
2183 we did not translate it into the predicates, we really can account
2184 just maximum of the possible paths. */
2185 if (fbi.info)
2186 will_be_nonconstant
2187 = will_be_nonconstant_predicate (&fbi, info,
2188 stmt, nonconstant_names);
2189 else
2190 will_be_nonconstant = true;
2191 if (this_time || this_size)
2193 sreal final_time = (sreal)this_time * freq;
2195 prob = eliminated_by_inlining_prob (stmt);
2196 if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS))
2197 fprintf (dump_file,
2198 "\t\t50%% will be eliminated by inlining\n");
2199 if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
2200 fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
2202 struct predicate p = bb_predicate & will_be_nonconstant;
2204 /* We can ignore statement when we proved it is never going
2205 to happen, but we can not do that for call statements
2206 because edges are accounted specially. */
2208 if (*(is_gimple_call (stmt) ? &bb_predicate : &p) != false)
2210 time += final_time;
2211 size += this_size;
2214 /* We account everything but the calls. Calls have their own
2215 size/time info attached to cgraph edges. This is necessary
2216 in order to make the cost disappear after inlining. */
2217 if (!is_gimple_call (stmt))
2219 if (prob)
2221 predicate ip = bb_predicate & predicate::not_inlined ();
2222 info->account_size_time (this_size * prob,
2223 (this_time * prob) / 2, ip,
2226 if (prob != 2)
2227 info->account_size_time (this_size * (2 - prob),
2228 (this_time * (2 - prob) / 2),
2229 bb_predicate,
2233 if (!info->fp_expressions && fp_expression_p (stmt))
2235 info->fp_expressions = true;
2236 if (dump_file)
2237 fprintf (dump_file, " fp_expression set\n");
2240 gcc_assert (time >= 0);
2241 gcc_assert (size >= 0);
2245 set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index,
2246 array_index);
2247 free (order);
2249 if (nonconstant_names.exists () && !early)
2251 struct loop *loop;
2252 predicate loop_iterations = true;
2253 predicate loop_stride = true;
2255 if (dump_file && (dump_flags & TDF_DETAILS))
2256 flow_loops_dump (dump_file, NULL, 0);
2257 scev_initialize ();
2258 FOR_EACH_LOOP (loop, 0)
2260 vec<edge> exits;
2261 edge ex;
2262 unsigned int j;
2263 struct tree_niter_desc niter_desc;
2264 bb_predicate = *(predicate *) loop->header->aux;
2266 exits = get_loop_exit_edges (loop);
2267 FOR_EACH_VEC_ELT (exits, j, ex)
2268 if (number_of_iterations_exit (loop, ex, &niter_desc, false)
2269 && !is_gimple_min_invariant (niter_desc.niter))
2271 predicate will_be_nonconstant
2272 = will_be_nonconstant_expr_predicate (fbi.info, info,
2273 niter_desc.niter,
2274 nonconstant_names);
2275 if (will_be_nonconstant != true)
2276 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2277 if (will_be_nonconstant != true
2278 && will_be_nonconstant != false)
2279 /* This is slightly inprecise. We may want to represent each
2280 loop with independent predicate. */
2281 loop_iterations &= will_be_nonconstant;
2283 exits.release ();
2286 /* To avoid quadratic behavior we analyze stride predicates only
2287 with respect to the containing loop. Thus we simply iterate
2288 over all defs in the outermost loop body. */
2289 for (loop = loops_for_fn (cfun)->tree_root->inner;
2290 loop != NULL; loop = loop->next)
2292 basic_block *body = get_loop_body (loop);
2293 for (unsigned i = 0; i < loop->num_nodes; i++)
2295 gimple_stmt_iterator gsi;
2296 bb_predicate = *(predicate *) body[i]->aux;
2297 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
2298 gsi_next (&gsi))
2300 gimple *stmt = gsi_stmt (gsi);
2302 if (!is_gimple_assign (stmt))
2303 continue;
2305 tree def = gimple_assign_lhs (stmt);
2306 if (TREE_CODE (def) != SSA_NAME)
2307 continue;
2309 affine_iv iv;
2310 if (!simple_iv (loop_containing_stmt (stmt),
2311 loop_containing_stmt (stmt),
2312 def, &iv, true)
2313 || is_gimple_min_invariant (iv.step))
2314 continue;
2316 predicate will_be_nonconstant
2317 = will_be_nonconstant_expr_predicate (fbi.info, info,
2318 iv.step,
2319 nonconstant_names);
2320 if (will_be_nonconstant != true)
2321 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2322 if (will_be_nonconstant != true
2323 && will_be_nonconstant != false)
2324 /* This is slightly inprecise. We may want to represent
2325 each loop with independent predicate. */
2326 loop_stride = loop_stride & will_be_nonconstant;
2329 free (body);
2331 ipa_fn_summary *s = ipa_fn_summaries->get (node);
2332 set_hint_predicate (&s->loop_iterations, loop_iterations);
2333 set_hint_predicate (&s->loop_stride, loop_stride);
2334 scev_finalize ();
2336 FOR_ALL_BB_FN (bb, my_function)
2338 edge e;
2339 edge_iterator ei;
2341 if (bb->aux)
2342 edge_predicate_pool.remove ((predicate *)bb->aux);
2343 bb->aux = NULL;
2344 FOR_EACH_EDGE (e, ei, bb->succs)
2346 if (e->aux)
2347 edge_predicate_pool.remove ((predicate *) e->aux);
2348 e->aux = NULL;
2351 ipa_fn_summary *s = ipa_fn_summaries->get (node);
2352 s->time = time;
2353 s->self_size = size;
2354 nonconstant_names.release ();
2355 ipa_release_body_info (&fbi);
2356 if (opt_for_fn (node->decl, optimize))
2358 if (!early)
2359 loop_optimizer_finalize ();
2360 else if (!ipa_edge_args_sum)
2361 ipa_free_all_node_params ();
2362 free_dominance_info (CDI_DOMINATORS);
2364 if (dump_file)
2366 fprintf (dump_file, "\n");
2367 ipa_dump_fn_summary (dump_file, node);
2372 /* Compute function summary.
2373 EARLY is true when we compute parameters during early opts. */
2375 void
2376 compute_fn_summary (struct cgraph_node *node, bool early)
2378 HOST_WIDE_INT self_stack_size;
2379 struct cgraph_edge *e;
2380 struct ipa_fn_summary *info;
2382 gcc_assert (!node->global.inlined_to);
2384 if (!ipa_fn_summaries)
2385 ipa_fn_summary_alloc ();
2387 /* Create a new ipa_fn_summary. */
2388 ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
2389 ipa_fn_summaries->remove (node);
2390 info = ipa_fn_summaries->get_create (node);
2392 /* Estimate the stack size for the function if we're optimizing. */
2393 self_stack_size = optimize && !node->thunk.thunk_p
2394 ? estimated_stack_frame_size (node) : 0;
2395 info->estimated_self_stack_size = self_stack_size;
2396 info->estimated_stack_size = self_stack_size;
2397 info->stack_frame_offset = 0;
2399 if (node->thunk.thunk_p)
2401 ipa_call_summary *es = ipa_call_summaries->get_create (node->callees);
2402 predicate t = true;
2404 node->local.can_change_signature = false;
2405 es->call_stmt_size = eni_size_weights.call_cost;
2406 es->call_stmt_time = eni_time_weights.call_cost;
2407 info->account_size_time (ipa_fn_summary::size_scale * 2, 2, t, t);
2408 t = predicate::not_inlined ();
2409 info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
2410 ipa_update_overall_fn_summary (node);
2411 info->self_size = info->size;
2412 /* We can not inline instrumentation clones. */
2413 if (node->thunk.add_pointer_bounds_args)
2415 info->inlinable = false;
2416 node->callees->inline_failed = CIF_CHKP;
2418 else if (stdarg_p (TREE_TYPE (node->decl)))
2420 info->inlinable = false;
2421 node->callees->inline_failed = CIF_VARIADIC_THUNK;
2423 else
2424 info->inlinable = true;
2426 else
2428 /* Even is_gimple_min_invariant rely on current_function_decl. */
2429 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2431 /* Can this function be inlined at all? */
2432 if (!opt_for_fn (node->decl, optimize)
2433 && !lookup_attribute ("always_inline",
2434 DECL_ATTRIBUTES (node->decl)))
2435 info->inlinable = false;
2436 else
2437 info->inlinable = tree_inlinable_function_p (node->decl);
2439 /* Type attributes can use parameter indices to describe them. */
2440 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))
2441 /* Likewise for #pragma omp declare simd functions or functions
2442 with simd attribute. */
2443 || lookup_attribute ("omp declare simd",
2444 DECL_ATTRIBUTES (node->decl)))
2445 node->local.can_change_signature = false;
2446 else
2448 /* Otherwise, inlinable functions always can change signature. */
2449 if (info->inlinable)
2450 node->local.can_change_signature = true;
2451 else
2453 /* Functions calling builtin_apply can not change signature. */
2454 for (e = node->callees; e; e = e->next_callee)
2456 tree cdecl = e->callee->decl;
2457 if (DECL_BUILT_IN (cdecl)
2458 && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
2459 && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
2460 || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
2461 break;
2463 node->local.can_change_signature = !e;
2466 /* Functions called by instrumentation thunk can't change signature
2467 because instrumentation thunk modification is not supported. */
2468 if (node->local.can_change_signature)
2469 for (e = node->callers; e; e = e->next_caller)
2470 if (e->caller->thunk.thunk_p
2471 && e->caller->thunk.add_pointer_bounds_args)
2473 node->local.can_change_signature = false;
2474 break;
2476 analyze_function_body (node, early);
2477 pop_cfun ();
2479 for (e = node->callees; e; e = e->next_callee)
2480 if (e->callee->comdat_local_p ())
2481 break;
2482 node->calls_comdat_local = (e != NULL);
2484 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
2485 info->size = info->self_size;
2486 info->stack_frame_offset = 0;
2487 info->estimated_stack_size = info->estimated_self_stack_size;
2489 /* Code above should compute exactly the same result as
2490 ipa_update_overall_fn_summary but because computation happens in
2491 different order the roundoff errors result in slight changes. */
2492 ipa_update_overall_fn_summary (node);
2493 gcc_assert (info->size == info->self_size);
2497 /* Compute parameters of functions used by inliner using
2498 current_function_decl. */
2500 static unsigned int
2501 compute_fn_summary_for_current (void)
2503 compute_fn_summary (cgraph_node::get (current_function_decl), true);
2504 return 0;
2507 /* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS,
2508 KNOWN_CONTEXTS and KNOWN_AGGS. */
2510 static bool
2511 estimate_edge_devirt_benefit (struct cgraph_edge *ie,
2512 int *size, int *time,
2513 vec<tree> known_vals,
2514 vec<ipa_polymorphic_call_context> known_contexts,
2515 vec<ipa_agg_jump_function_p> known_aggs)
2517 tree target;
2518 struct cgraph_node *callee;
2519 struct ipa_fn_summary *isummary;
2520 enum availability avail;
2521 bool speculative;
2523 if (!known_vals.exists () && !known_contexts.exists ())
2524 return false;
2525 if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
2526 return false;
2528 target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts,
2529 known_aggs, &speculative);
2530 if (!target || speculative)
2531 return false;
2533 /* Account for difference in cost between indirect and direct calls. */
2534 *size -= (eni_size_weights.indirect_call_cost - eni_size_weights.call_cost);
2535 *time -= (eni_time_weights.indirect_call_cost - eni_time_weights.call_cost);
2536 gcc_checking_assert (*time >= 0);
2537 gcc_checking_assert (*size >= 0);
2539 callee = cgraph_node::get (target);
2540 if (!callee || !callee->definition)
2541 return false;
2542 callee = callee->function_symbol (&avail);
2543 if (avail < AVAIL_AVAILABLE)
2544 return false;
2545 isummary = ipa_fn_summaries->get (callee);
2546 return isummary->inlinable;
2549 /* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
2550 handle edge E with probability PROB.
2551 Set HINTS if edge may be devirtualized.
2552 KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS describe context of the call
2553 site. */
2555 static inline void
2556 estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
2557 sreal *time,
2558 int prob,
2559 vec<tree> known_vals,
2560 vec<ipa_polymorphic_call_context> known_contexts,
2561 vec<ipa_agg_jump_function_p> known_aggs,
2562 ipa_hints *hints)
2564 struct ipa_call_summary *es = ipa_call_summaries->get (e);
2565 int call_size = es->call_stmt_size;
2566 int call_time = es->call_stmt_time;
2567 int cur_size;
2568 if (!e->callee
2569 && estimate_edge_devirt_benefit (e, &call_size, &call_time,
2570 known_vals, known_contexts, known_aggs)
2571 && hints && e->maybe_hot_p ())
2572 *hints |= INLINE_HINT_indirect_call;
2573 cur_size = call_size * ipa_fn_summary::size_scale;
2574 *size += cur_size;
2575 if (min_size)
2576 *min_size += cur_size;
2577 if (prob == REG_BR_PROB_BASE)
2578 *time += ((sreal)call_time) * e->sreal_frequency ();
2579 else
2580 *time += ((sreal)call_time * prob) * e->sreal_frequency ();
2585 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
2586 calls in NODE. POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2587 describe context of the call site. */
2589 static void
2590 estimate_calls_size_and_time (struct cgraph_node *node, int *size,
2591 int *min_size, sreal *time,
2592 ipa_hints *hints,
2593 clause_t possible_truths,
2594 vec<tree> known_vals,
2595 vec<ipa_polymorphic_call_context> known_contexts,
2596 vec<ipa_agg_jump_function_p> known_aggs)
2598 struct cgraph_edge *e;
2599 for (e = node->callees; e; e = e->next_callee)
2601 struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
2603 /* Do not care about zero sized builtins. */
2604 if (e->inline_failed && !es->call_stmt_size)
2606 gcc_checking_assert (!es->call_stmt_time);
2607 continue;
2609 if (!es->predicate
2610 || es->predicate->evaluate (possible_truths))
2612 if (e->inline_failed)
2614 /* Predicates of calls shall not use NOT_CHANGED codes,
2615 sowe do not need to compute probabilities. */
2616 estimate_edge_size_and_time (e, size,
2617 es->predicate ? NULL : min_size,
2618 time, REG_BR_PROB_BASE,
2619 known_vals, known_contexts,
2620 known_aggs, hints);
2622 else
2623 estimate_calls_size_and_time (e->callee, size, min_size, time,
2624 hints,
2625 possible_truths,
2626 known_vals, known_contexts,
2627 known_aggs);
2630 for (e = node->indirect_calls; e; e = e->next_callee)
2632 struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
2633 if (!es->predicate
2634 || es->predicate->evaluate (possible_truths))
2635 estimate_edge_size_and_time (e, size,
2636 es->predicate ? NULL : min_size,
2637 time, REG_BR_PROB_BASE,
2638 known_vals, known_contexts, known_aggs,
2639 hints);
2644 /* Estimate size and time needed to execute NODE assuming
2645 POSSIBLE_TRUTHS clause, and KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2646 information about NODE's arguments. If non-NULL use also probability
2647 information present in INLINE_PARAM_SUMMARY vector.
2648 Additionally detemine hints determined by the context. Finally compute
2649 minimal size needed for the call that is independent on the call context and
2650 can be used for fast estimates. Return the values in RET_SIZE,
2651 RET_MIN_SIZE, RET_TIME and RET_HINTS. */
2653 void
2654 estimate_node_size_and_time (struct cgraph_node *node,
2655 clause_t possible_truths,
2656 clause_t nonspec_possible_truths,
2657 vec<tree> known_vals,
2658 vec<ipa_polymorphic_call_context> known_contexts,
2659 vec<ipa_agg_jump_function_p> known_aggs,
2660 int *ret_size, int *ret_min_size,
2661 sreal *ret_time,
2662 sreal *ret_nonspecialized_time,
2663 ipa_hints *ret_hints,
2664 vec<inline_param_summary>
2665 inline_param_summary)
2667 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
2668 size_time_entry *e;
2669 int size = 0;
2670 sreal time = 0;
2671 int min_size = 0;
2672 ipa_hints hints = 0;
2673 int i;
2675 if (dump_file && (dump_flags & TDF_DETAILS))
2677 bool found = false;
2678 fprintf (dump_file, " Estimating body: %s/%i\n"
2679 " Known to be false: ", node->name (),
2680 node->order);
2682 for (i = predicate::not_inlined_condition;
2683 i < (predicate::first_dynamic_condition
2684 + (int) vec_safe_length (info->conds)); i++)
2685 if (!(possible_truths & (1 << i)))
2687 if (found)
2688 fprintf (dump_file, ", ");
2689 found = true;
2690 dump_condition (dump_file, info->conds, i);
2694 estimate_calls_size_and_time (node, &size, &min_size, &time, &hints, possible_truths,
2695 known_vals, known_contexts, known_aggs);
2696 sreal nonspecialized_time = time;
2698 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
2700 bool exec = e->exec_predicate.evaluate (nonspec_possible_truths);
2702 /* Because predicates are conservative, it can happen that nonconst is 1
2703 but exec is 0. */
2704 if (exec)
2706 bool nonconst = e->nonconst_predicate.evaluate (possible_truths);
2708 gcc_checking_assert (e->time >= 0);
2709 gcc_checking_assert (time >= 0);
2711 /* We compute specialized size only because size of nonspecialized
2712 copy is context independent.
2714 The difference between nonspecialized execution and specialized is
2715 that nonspecialized is not going to have optimized out computations
2716 known to be constant in a specialized setting. */
2717 if (nonconst)
2718 size += e->size;
2719 nonspecialized_time += e->time;
2720 if (!nonconst)
2722 else if (!inline_param_summary.exists ())
2724 if (nonconst)
2725 time += e->time;
2727 else
2729 int prob = e->nonconst_predicate.probability
2730 (info->conds, possible_truths,
2731 inline_param_summary);
2732 gcc_checking_assert (prob >= 0);
2733 gcc_checking_assert (prob <= REG_BR_PROB_BASE);
2734 time += e->time * prob / REG_BR_PROB_BASE;
2736 gcc_checking_assert (time >= 0);
2739 gcc_checking_assert ((*info->size_time_table)[0].exec_predicate == true);
2740 gcc_checking_assert ((*info->size_time_table)[0].nonconst_predicate == true);
2741 min_size = (*info->size_time_table)[0].size;
2742 gcc_checking_assert (size >= 0);
2743 gcc_checking_assert (time >= 0);
2744 /* nonspecialized_time should be always bigger than specialized time.
2745 Roundoff issues however may get into the way. */
2746 gcc_checking_assert ((nonspecialized_time - time * 0.99) >= -1);
2748 /* Roundoff issues may make specialized time bigger than nonspecialized
2749 time. We do not really want that to happen because some heurstics
2750 may get confused by seeing negative speedups. */
2751 if (time > nonspecialized_time)
2752 time = nonspecialized_time;
2754 if (info->loop_iterations
2755 && !info->loop_iterations->evaluate (possible_truths))
2756 hints |= INLINE_HINT_loop_iterations;
2757 if (info->loop_stride
2758 && !info->loop_stride->evaluate (possible_truths))
2759 hints |= INLINE_HINT_loop_stride;
2760 if (info->array_index
2761 && !info->array_index->evaluate (possible_truths))
2762 hints |= INLINE_HINT_array_index;
2763 if (info->scc_no)
2764 hints |= INLINE_HINT_in_scc;
2765 if (DECL_DECLARED_INLINE_P (node->decl))
2766 hints |= INLINE_HINT_declared_inline;
2768 size = RDIV (size, ipa_fn_summary::size_scale);
2769 min_size = RDIV (min_size, ipa_fn_summary::size_scale);
2771 if (dump_file && (dump_flags & TDF_DETAILS))
2772 fprintf (dump_file, "\n size:%i time:%f nonspec time:%f\n", (int) size,
2773 time.to_double (), nonspecialized_time.to_double ());
2774 if (ret_time)
2775 *ret_time = time;
2776 if (ret_nonspecialized_time)
2777 *ret_nonspecialized_time = nonspecialized_time;
2778 if (ret_size)
2779 *ret_size = size;
2780 if (ret_min_size)
2781 *ret_min_size = min_size;
2782 if (ret_hints)
2783 *ret_hints = hints;
2784 return;
2788 /* Estimate size and time needed to execute callee of EDGE assuming that
2789 parameters known to be constant at caller of EDGE are propagated.
2790 KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
2791 and types for parameters. */
2793 void
2794 estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
2795 vec<tree> known_vals,
2796 vec<ipa_polymorphic_call_context>
2797 known_contexts,
2798 vec<ipa_agg_jump_function_p> known_aggs,
2799 int *ret_size, sreal *ret_time,
2800 sreal *ret_nonspec_time,
2801 ipa_hints *hints)
2803 clause_t clause, nonspec_clause;
2805 evaluate_conditions_for_known_args (node, false, known_vals, known_aggs,
2806 &clause, &nonspec_clause);
2807 estimate_node_size_and_time (node, clause, nonspec_clause,
2808 known_vals, known_contexts,
2809 known_aggs, ret_size, NULL, ret_time,
2810 ret_nonspec_time, hints, vNULL);
2814 /* Update summary information of inline clones after inlining.
2815 Compute peak stack usage. */
2817 static void
2818 inline_update_callee_summaries (struct cgraph_node *node, int depth)
2820 struct cgraph_edge *e;
2821 ipa_fn_summary *callee_info = ipa_fn_summaries->get (node);
2822 ipa_fn_summary *caller_info = ipa_fn_summaries->get (node->callers->caller);
2823 HOST_WIDE_INT peak;
2825 callee_info->stack_frame_offset
2826 = caller_info->stack_frame_offset
2827 + caller_info->estimated_self_stack_size;
2828 peak = callee_info->stack_frame_offset
2829 + callee_info->estimated_self_stack_size;
2831 ipa_fn_summary *s = ipa_fn_summaries->get (node->global.inlined_to);
2832 if (s->estimated_stack_size < peak)
2833 s->estimated_stack_size = peak;
2834 ipa_propagate_frequency (node);
2835 for (e = node->callees; e; e = e->next_callee)
2837 if (!e->inline_failed)
2838 inline_update_callee_summaries (e->callee, depth);
2839 ipa_call_summaries->get (e)->loop_depth += depth;
2841 for (e = node->indirect_calls; e; e = e->next_callee)
2842 ipa_call_summaries->get (e)->loop_depth += depth;
2845 /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
2846 When functoin A is inlined in B and A calls C with parameter that
2847 changes with probability PROB1 and C is known to be passthroug
2848 of argument if B that change with probability PROB2, the probability
2849 of change is now PROB1*PROB2. */
2851 static void
2852 remap_edge_change_prob (struct cgraph_edge *inlined_edge,
2853 struct cgraph_edge *edge)
2855 if (ipa_node_params_sum)
2857 int i;
2858 struct ipa_edge_args *args = IPA_EDGE_REF (edge);
2859 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
2860 struct ipa_call_summary *inlined_es
2861 = ipa_call_summaries->get (inlined_edge);
2863 for (i = 0; i < ipa_get_cs_argument_count (args); i++)
2865 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
2866 if (jfunc->type == IPA_JF_PASS_THROUGH
2867 || jfunc->type == IPA_JF_ANCESTOR)
2869 int id = jfunc->type == IPA_JF_PASS_THROUGH
2870 ? ipa_get_jf_pass_through_formal_id (jfunc)
2871 : ipa_get_jf_ancestor_formal_id (jfunc);
2872 if (id < (int) inlined_es->param.length ())
2874 int prob1 = es->param[i].change_prob;
2875 int prob2 = inlined_es->param[id].change_prob;
2876 int prob = combine_probabilities (prob1, prob2);
2878 if (prob1 && prob2 && !prob)
2879 prob = 1;
2881 es->param[i].change_prob = prob;
2888 /* Update edge summaries of NODE after INLINED_EDGE has been inlined.
2890 Remap predicates of callees of NODE. Rest of arguments match
2891 remap_predicate.
2893 Also update change probabilities. */
2895 static void
2896 remap_edge_summaries (struct cgraph_edge *inlined_edge,
2897 struct cgraph_node *node,
2898 struct ipa_fn_summary *info,
2899 struct ipa_fn_summary *callee_info,
2900 vec<int> operand_map,
2901 vec<int> offset_map,
2902 clause_t possible_truths,
2903 predicate *toplev_predicate)
2905 struct cgraph_edge *e, *next;
2906 for (e = node->callees; e; e = next)
2908 struct ipa_call_summary *es = ipa_call_summaries->get (e);
2909 predicate p;
2910 next = e->next_callee;
2912 if (e->inline_failed)
2914 remap_edge_change_prob (inlined_edge, e);
2916 if (es->predicate)
2918 p = es->predicate->remap_after_inlining
2919 (info, callee_info, operand_map,
2920 offset_map, possible_truths,
2921 *toplev_predicate);
2922 edge_set_predicate (e, &p);
2924 else
2925 edge_set_predicate (e, toplev_predicate);
2927 else
2928 remap_edge_summaries (inlined_edge, e->callee, info, callee_info,
2929 operand_map, offset_map, possible_truths,
2930 toplev_predicate);
2932 for (e = node->indirect_calls; e; e = next)
2934 struct ipa_call_summary *es = ipa_call_summaries->get (e);
2935 predicate p;
2936 next = e->next_callee;
2938 remap_edge_change_prob (inlined_edge, e);
2939 if (es->predicate)
2941 p = es->predicate->remap_after_inlining
2942 (info, callee_info, operand_map, offset_map,
2943 possible_truths, *toplev_predicate);
2944 edge_set_predicate (e, &p);
2946 else
2947 edge_set_predicate (e, toplev_predicate);
2951 /* Same as remap_predicate, but set result into hint *HINT. */
2953 static void
2954 remap_hint_predicate (struct ipa_fn_summary *info,
2955 struct ipa_fn_summary *callee_info,
2956 predicate **hint,
2957 vec<int> operand_map,
2958 vec<int> offset_map,
2959 clause_t possible_truths,
2960 predicate *toplev_predicate)
2962 predicate p;
2964 if (!*hint)
2965 return;
2966 p = (*hint)->remap_after_inlining
2967 (info, callee_info,
2968 operand_map, offset_map,
2969 possible_truths, *toplev_predicate);
2970 if (p != false && p != true)
2972 if (!*hint)
2973 set_hint_predicate (hint, p);
2974 else
2975 **hint &= p;
2979 /* We inlined EDGE. Update summary of the function we inlined into. */
2981 void
2982 ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
2984 ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
2985 struct cgraph_node *to = (edge->caller->global.inlined_to
2986 ? edge->caller->global.inlined_to : edge->caller);
2987 struct ipa_fn_summary *info = ipa_fn_summaries->get (to);
2988 clause_t clause = 0; /* not_inline is known to be false. */
2989 size_time_entry *e;
2990 vec<int> operand_map = vNULL;
2991 vec<int> offset_map = vNULL;
2992 int i;
2993 predicate toplev_predicate;
2994 predicate true_p = true;
2995 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
2997 if (es->predicate)
2998 toplev_predicate = *es->predicate;
2999 else
3000 toplev_predicate = true;
3002 info->fp_expressions |= callee_info->fp_expressions;
3004 if (callee_info->conds)
3005 evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL, NULL);
3006 if (ipa_node_params_sum && callee_info->conds)
3008 struct ipa_edge_args *args = IPA_EDGE_REF (edge);
3009 int count = ipa_get_cs_argument_count (args);
3010 int i;
3012 if (count)
3014 operand_map.safe_grow_cleared (count);
3015 offset_map.safe_grow_cleared (count);
3017 for (i = 0; i < count; i++)
3019 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
3020 int map = -1;
3022 /* TODO: handle non-NOPs when merging. */
3023 if (jfunc->type == IPA_JF_PASS_THROUGH)
3025 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3026 map = ipa_get_jf_pass_through_formal_id (jfunc);
3027 if (!ipa_get_jf_pass_through_agg_preserved (jfunc))
3028 offset_map[i] = -1;
3030 else if (jfunc->type == IPA_JF_ANCESTOR)
3032 HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc);
3033 if (offset >= 0 && offset < INT_MAX)
3035 map = ipa_get_jf_ancestor_formal_id (jfunc);
3036 if (!ipa_get_jf_ancestor_agg_preserved (jfunc))
3037 offset = -1;
3038 offset_map[i] = offset;
3041 operand_map[i] = map;
3042 gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to)));
3045 for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
3047 predicate p;
3048 p = e->exec_predicate.remap_after_inlining
3049 (info, callee_info, operand_map,
3050 offset_map, clause,
3051 toplev_predicate);
3052 predicate nonconstp;
3053 nonconstp = e->nonconst_predicate.remap_after_inlining
3054 (info, callee_info, operand_map,
3055 offset_map, clause,
3056 toplev_predicate);
3057 if (p != false && nonconstp != false)
3059 sreal add_time = ((sreal)e->time * edge->sreal_frequency ());
3060 int prob = e->nonconst_predicate.probability (callee_info->conds,
3061 clause, es->param);
3062 add_time = add_time * prob / REG_BR_PROB_BASE;
3063 if (prob != REG_BR_PROB_BASE
3064 && dump_file && (dump_flags & TDF_DETAILS))
3066 fprintf (dump_file, "\t\tScaling time by probability:%f\n",
3067 (double) prob / REG_BR_PROB_BASE);
3069 info->account_size_time (e->size, add_time, p, nonconstp);
3072 remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
3073 offset_map, clause, &toplev_predicate);
3074 remap_hint_predicate (info, callee_info,
3075 &callee_info->loop_iterations,
3076 operand_map, offset_map, clause, &toplev_predicate);
3077 remap_hint_predicate (info, callee_info,
3078 &callee_info->loop_stride,
3079 operand_map, offset_map, clause, &toplev_predicate);
3080 remap_hint_predicate (info, callee_info,
3081 &callee_info->array_index,
3082 operand_map, offset_map, clause, &toplev_predicate);
3084 ipa_call_summary *s = ipa_call_summaries->get (edge);
3085 inline_update_callee_summaries (edge->callee, s->loop_depth);
3087 /* We do not maintain predicates of inlined edges, free it. */
3088 edge_set_predicate (edge, &true_p);
3089 /* Similarly remove param summaries. */
3090 es->param.release ();
3091 operand_map.release ();
3092 offset_map.release ();
3095 /* For performance reasons ipa_merge_fn_summary_after_inlining is not updating overall size
3096 and time. Recompute it. */
3098 void
3099 ipa_update_overall_fn_summary (struct cgraph_node *node)
3101 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
3102 size_time_entry *e;
3103 int i;
3105 info->size = 0;
3106 info->time = 0;
3107 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3109 info->size += e->size;
3110 info->time += e->time;
3112 estimate_calls_size_and_time (node, &info->size, &info->min_size,
3113 &info->time, NULL,
3114 ~(clause_t) (1 << predicate::false_condition),
3115 vNULL, vNULL, vNULL);
3116 info->size = (info->size + ipa_fn_summary::size_scale / 2) / ipa_fn_summary::size_scale;
3120 /* This function performs intraprocedural analysis in NODE that is required to
3121 inline indirect calls. */
3123 static void
3124 inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
3126 ipa_analyze_node (node);
3127 if (dump_file && (dump_flags & TDF_DETAILS))
3129 ipa_print_node_params (dump_file, node);
3130 ipa_print_node_jump_functions (dump_file, node);
3135 /* Note function body size. */
3137 void
3138 inline_analyze_function (struct cgraph_node *node)
3140 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3142 if (dump_file)
3143 fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
3144 node->name (), node->order);
3145 if (opt_for_fn (node->decl, optimize) && !node->thunk.thunk_p)
3146 inline_indirect_intraprocedural_analysis (node);
3147 compute_fn_summary (node, false);
3148 if (!optimize)
3150 struct cgraph_edge *e;
3151 for (e = node->callees; e; e = e->next_callee)
3152 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3153 for (e = node->indirect_calls; e; e = e->next_callee)
3154 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3157 pop_cfun ();
3161 /* Called when new function is inserted to callgraph late. */
3163 void
3164 ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
3166 inline_analyze_function (node);
3169 /* Note function body size. */
3171 static void
3172 ipa_fn_summary_generate (void)
3174 struct cgraph_node *node;
3176 FOR_EACH_DEFINED_FUNCTION (node)
3177 if (DECL_STRUCT_FUNCTION (node->decl))
3178 node->local.versionable = tree_versionable_function_p (node->decl);
3180 ipa_fn_summary_alloc ();
3182 ipa_fn_summaries->enable_insertion_hook ();
3184 ipa_register_cgraph_hooks ();
3186 FOR_EACH_DEFINED_FUNCTION (node)
3187 if (!node->alias
3188 && (flag_generate_lto || flag_generate_offload|| flag_wpa
3189 || opt_for_fn (node->decl, optimize)))
3190 inline_analyze_function (node);
3194 /* Write inline summary for edge E to OB. */
3196 static void
3197 read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e)
3199 struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
3200 predicate p;
3201 int length, i;
3203 es->call_stmt_size = streamer_read_uhwi (ib);
3204 es->call_stmt_time = streamer_read_uhwi (ib);
3205 es->loop_depth = streamer_read_uhwi (ib);
3207 bitpack_d bp = streamer_read_bitpack (ib);
3208 es->is_return_callee_uncaptured = bp_unpack_value (&bp, 1);
3210 p.stream_in (ib);
3211 edge_set_predicate (e, &p);
3212 length = streamer_read_uhwi (ib);
3213 if (length)
3215 es->param.safe_grow_cleared (length);
3216 for (i = 0; i < length; i++)
3217 es->param[i].change_prob = streamer_read_uhwi (ib);
3222 /* Stream in inline summaries from the section. */
3224 static void
3225 inline_read_section (struct lto_file_decl_data *file_data, const char *data,
3226 size_t len)
3228 const struct lto_function_header *header =
3229 (const struct lto_function_header *) data;
3230 const int cfg_offset = sizeof (struct lto_function_header);
3231 const int main_offset = cfg_offset + header->cfg_size;
3232 const int string_offset = main_offset + header->main_size;
3233 struct data_in *data_in;
3234 unsigned int i, count2, j;
3235 unsigned int f_count;
3237 lto_input_block ib ((const char *) data + main_offset, header->main_size,
3238 file_data->mode_table);
3240 data_in =
3241 lto_data_in_create (file_data, (const char *) data + string_offset,
3242 header->string_size, vNULL);
3243 f_count = streamer_read_uhwi (&ib);
3244 for (i = 0; i < f_count; i++)
3246 unsigned int index;
3247 struct cgraph_node *node;
3248 struct ipa_fn_summary *info;
3249 lto_symtab_encoder_t encoder;
3250 struct bitpack_d bp;
3251 struct cgraph_edge *e;
3252 predicate p;
3254 index = streamer_read_uhwi (&ib);
3255 encoder = file_data->symtab_node_encoder;
3256 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
3257 index));
3258 info = ipa_fn_summaries->get_create (node);
3260 info->estimated_stack_size
3261 = info->estimated_self_stack_size = streamer_read_uhwi (&ib);
3262 info->size = info->self_size = streamer_read_uhwi (&ib);
3263 info->time = sreal::stream_in (&ib);
3265 bp = streamer_read_bitpack (&ib);
3266 info->inlinable = bp_unpack_value (&bp, 1);
3267 info->fp_expressions = bp_unpack_value (&bp, 1);
3269 count2 = streamer_read_uhwi (&ib);
3270 gcc_assert (!info->conds);
3271 for (j = 0; j < count2; j++)
3273 struct condition c;
3274 c.operand_num = streamer_read_uhwi (&ib);
3275 c.size = streamer_read_uhwi (&ib);
3276 c.code = (enum tree_code) streamer_read_uhwi (&ib);
3277 c.val = stream_read_tree (&ib, data_in);
3278 bp = streamer_read_bitpack (&ib);
3279 c.agg_contents = bp_unpack_value (&bp, 1);
3280 c.by_ref = bp_unpack_value (&bp, 1);
3281 if (c.agg_contents)
3282 c.offset = streamer_read_uhwi (&ib);
3283 vec_safe_push (info->conds, c);
3285 count2 = streamer_read_uhwi (&ib);
3286 gcc_assert (!info->size_time_table);
3287 for (j = 0; j < count2; j++)
3289 struct size_time_entry e;
3291 e.size = streamer_read_uhwi (&ib);
3292 e.time = sreal::stream_in (&ib);
3293 e.exec_predicate.stream_in (&ib);
3294 e.nonconst_predicate.stream_in (&ib);
3296 vec_safe_push (info->size_time_table, e);
3299 p.stream_in (&ib);
3300 set_hint_predicate (&info->loop_iterations, p);
3301 p.stream_in (&ib);
3302 set_hint_predicate (&info->loop_stride, p);
3303 p.stream_in (&ib);
3304 set_hint_predicate (&info->array_index, p);
3305 for (e = node->callees; e; e = e->next_callee)
3306 read_ipa_call_summary (&ib, e);
3307 for (e = node->indirect_calls; e; e = e->next_callee)
3308 read_ipa_call_summary (&ib, e);
3311 lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
3312 len);
3313 lto_data_in_delete (data_in);
3317 /* Read inline summary. Jump functions are shared among ipa-cp
3318 and inliner, so when ipa-cp is active, we don't need to write them
3319 twice. */
3321 static void
3322 ipa_fn_summary_read (void)
3324 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
3325 struct lto_file_decl_data *file_data;
3326 unsigned int j = 0;
3328 ipa_fn_summary_alloc ();
3330 while ((file_data = file_data_vec[j++]))
3332 size_t len;
3333 const char *data = lto_get_section_data (file_data,
3334 LTO_section_ipa_fn_summary,
3335 NULL, &len);
3336 if (data)
3337 inline_read_section (file_data, data, len);
3338 else
3339 /* Fatal error here. We do not want to support compiling ltrans units
3340 with different version of compiler or different flags than the WPA
3341 unit, so this should never happen. */
3342 fatal_error (input_location,
3343 "ipa inline summary is missing in input file");
3345 ipa_register_cgraph_hooks ();
3346 if (!flag_ipa_cp)
3347 ipa_prop_read_jump_functions ();
3349 gcc_assert (ipa_fn_summaries);
3350 ipa_fn_summaries->enable_insertion_hook ();
3354 /* Write inline summary for edge E to OB. */
3356 static void
3357 write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
3359 struct ipa_call_summary *es = ipa_call_summaries->get (e);
3360 int i;
3362 streamer_write_uhwi (ob, es->call_stmt_size);
3363 streamer_write_uhwi (ob, es->call_stmt_time);
3364 streamer_write_uhwi (ob, es->loop_depth);
3366 bitpack_d bp = bitpack_create (ob->main_stream);
3367 bp_pack_value (&bp, es->is_return_callee_uncaptured, 1);
3368 streamer_write_bitpack (&bp);
3370 if (es->predicate)
3371 es->predicate->stream_out (ob);
3372 else
3373 streamer_write_uhwi (ob, 0);
3374 streamer_write_uhwi (ob, es->param.length ());
3375 for (i = 0; i < (int) es->param.length (); i++)
3376 streamer_write_uhwi (ob, es->param[i].change_prob);
3380 /* Write inline summary for node in SET.
3381 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
3382 active, we don't need to write them twice. */
3384 static void
3385 ipa_fn_summary_write (void)
3387 struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
3388 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
3389 unsigned int count = 0;
3390 int i;
3392 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3394 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3395 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3396 if (cnode && cnode->definition && !cnode->alias)
3397 count++;
3399 streamer_write_uhwi (ob, count);
3401 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3403 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3404 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3405 if (cnode && cnode->definition && !cnode->alias)
3407 struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
3408 struct bitpack_d bp;
3409 struct cgraph_edge *edge;
3410 int i;
3411 size_time_entry *e;
3412 struct condition *c;
3414 streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
3415 streamer_write_hwi (ob, info->estimated_self_stack_size);
3416 streamer_write_hwi (ob, info->self_size);
3417 info->time.stream_out (ob);
3418 bp = bitpack_create (ob->main_stream);
3419 bp_pack_value (&bp, info->inlinable, 1);
3420 bp_pack_value (&bp, false, 1);
3421 bp_pack_value (&bp, info->fp_expressions, 1);
3422 streamer_write_bitpack (&bp);
3423 streamer_write_uhwi (ob, vec_safe_length (info->conds));
3424 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
3426 streamer_write_uhwi (ob, c->operand_num);
3427 streamer_write_uhwi (ob, c->size);
3428 streamer_write_uhwi (ob, c->code);
3429 stream_write_tree (ob, c->val, true);
3430 bp = bitpack_create (ob->main_stream);
3431 bp_pack_value (&bp, c->agg_contents, 1);
3432 bp_pack_value (&bp, c->by_ref, 1);
3433 streamer_write_bitpack (&bp);
3434 if (c->agg_contents)
3435 streamer_write_uhwi (ob, c->offset);
3437 streamer_write_uhwi (ob, vec_safe_length (info->size_time_table));
3438 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3440 streamer_write_uhwi (ob, e->size);
3441 e->time.stream_out (ob);
3442 e->exec_predicate.stream_out (ob);
3443 e->nonconst_predicate.stream_out (ob);
3445 if (info->loop_iterations)
3446 info->loop_iterations->stream_out (ob);
3447 else
3448 streamer_write_uhwi (ob, 0);
3449 if (info->loop_stride)
3450 info->loop_stride->stream_out (ob);
3451 else
3452 streamer_write_uhwi (ob, 0);
3453 if (info->array_index)
3454 info->array_index->stream_out (ob);
3455 else
3456 streamer_write_uhwi (ob, 0);
3457 for (edge = cnode->callees; edge; edge = edge->next_callee)
3458 write_ipa_call_summary (ob, edge);
3459 for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
3460 write_ipa_call_summary (ob, edge);
3463 streamer_write_char_stream (ob->main_stream, 0);
3464 produce_asm (ob, NULL);
3465 destroy_output_block (ob);
3467 if (!flag_ipa_cp)
3468 ipa_prop_write_jump_functions ();
3472 /* Release inline summary. */
3474 void
3475 ipa_free_fn_summary (void)
3477 struct cgraph_node *node;
3478 if (!ipa_call_summaries)
3479 return;
3480 FOR_EACH_DEFINED_FUNCTION (node)
3481 if (!node->alias)
3482 ipa_fn_summaries->remove (node);
3483 ipa_fn_summaries->release ();
3484 ipa_fn_summaries = NULL;
3485 ipa_call_summaries->release ();
3486 delete ipa_call_summaries;
3487 ipa_call_summaries = NULL;
3488 edge_predicate_pool.release ();
3491 namespace {
3493 const pass_data pass_data_local_fn_summary =
3495 GIMPLE_PASS, /* type */
3496 "local-fnsummary", /* name */
3497 OPTGROUP_INLINE, /* optinfo_flags */
3498 TV_INLINE_PARAMETERS, /* tv_id */
3499 0, /* properties_required */
3500 0, /* properties_provided */
3501 0, /* properties_destroyed */
3502 0, /* todo_flags_start */
3503 0, /* todo_flags_finish */
3506 class pass_local_fn_summary : public gimple_opt_pass
3508 public:
3509 pass_local_fn_summary (gcc::context *ctxt)
3510 : gimple_opt_pass (pass_data_local_fn_summary, ctxt)
3513 /* opt_pass methods: */
3514 opt_pass * clone () { return new pass_local_fn_summary (m_ctxt); }
3515 virtual unsigned int execute (function *)
3517 return compute_fn_summary_for_current ();
3520 }; // class pass_local_fn_summary
3522 } // anon namespace
3524 gimple_opt_pass *
3525 make_pass_local_fn_summary (gcc::context *ctxt)
3527 return new pass_local_fn_summary (ctxt);
3531 /* Free inline summary. */
3533 namespace {
3535 const pass_data pass_data_ipa_free_fn_summary =
3537 SIMPLE_IPA_PASS, /* type */
3538 "free-fnsummary", /* name */
3539 OPTGROUP_NONE, /* optinfo_flags */
3540 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
3541 0, /* properties_required */
3542 0, /* properties_provided */
3543 0, /* properties_destroyed */
3544 0, /* todo_flags_start */
3545 0, /* todo_flags_finish */
3548 class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
3550 public:
3551 pass_ipa_free_fn_summary (gcc::context *ctxt)
3552 : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt),
3553 small_p (false)
3556 /* opt_pass methods: */
3557 opt_pass *clone () { return new pass_ipa_free_fn_summary (m_ctxt); }
3558 void set_pass_param (unsigned int n, bool param)
3560 gcc_assert (n == 0);
3561 small_p = param;
3563 virtual bool gate (function *) { return small_p || !flag_wpa; }
3564 virtual unsigned int execute (function *)
3566 ipa_free_fn_summary ();
3567 /* Early optimizations may make function unreachable. We can not
3568 remove unreachable functions as part of the early opts pass because
3569 TODOs are run before subpasses. Do it here. */
3570 return small_p ? TODO_remove_functions | TODO_dump_symtab : 0;
3573 private:
3574 bool small_p;
3575 }; // class pass_ipa_free_fn_summary
3577 } // anon namespace
3579 simple_ipa_opt_pass *
3580 make_pass_ipa_free_fn_summary (gcc::context *ctxt)
3582 return new pass_ipa_free_fn_summary (ctxt);
3585 namespace {
3587 const pass_data pass_data_ipa_fn_summary =
3589 IPA_PASS, /* type */
3590 "fnsummary", /* name */
3591 OPTGROUP_INLINE, /* optinfo_flags */
3592 TV_IPA_FNSUMMARY, /* tv_id */
3593 0, /* properties_required */
3594 0, /* properties_provided */
3595 0, /* properties_destroyed */
3596 0, /* todo_flags_start */
3597 ( TODO_dump_symtab ), /* todo_flags_finish */
3600 class pass_ipa_fn_summary : public ipa_opt_pass_d
3602 public:
3603 pass_ipa_fn_summary (gcc::context *ctxt)
3604 : ipa_opt_pass_d (pass_data_ipa_fn_summary, ctxt,
3605 ipa_fn_summary_generate, /* generate_summary */
3606 ipa_fn_summary_write, /* write_summary */
3607 ipa_fn_summary_read, /* read_summary */
3608 NULL, /* write_optimization_summary */
3609 NULL, /* read_optimization_summary */
3610 NULL, /* stmt_fixup */
3611 0, /* function_transform_todo_flags_start */
3612 NULL, /* function_transform */
3613 NULL) /* variable_transform */
3616 /* opt_pass methods: */
3617 virtual unsigned int execute (function *) { return 0; }
3619 }; // class pass_ipa_fn_summary
3621 } // anon namespace
3623 ipa_opt_pass_d *
3624 make_pass_ipa_fn_summary (gcc::context *ctxt)
3626 return new pass_ipa_fn_summary (ctxt);
3629 /* Reset all state within ipa-fnsummary.c so that we can rerun the compiler
3630 within the same process. For use by toplev::finalize. */
3632 void
3633 ipa_fnsummary_c_finalize (void)
3635 ipa_free_fn_summary ();