]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-fnsummary.c
[multiple changes]
[thirdparty/gcc.git] / gcc / ipa-fnsummary.c
CommitLineData
27d020cf 1/* Function summary pass.
a5544970 2 Copyright (C) 2003-2019 Free Software Foundation, Inc.
27d020cf
JH
3 Contributed by Jan Hubicka
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21/* Analysis of function bodies used by inter-procedural passes
22
23 We estimate for each function
24 - function body size and size after specializing into given context
25 - average function execution time in a given context
26 - function frame size
27 For each call
28 - call statement size, time and how often the parameters change
29
0bceb671 30 ipa_fn_summary data structures store above information locally (i.e.
27d020cf
JH
31 parameters of the function itself) and globally (i.e. parameters of
32 the function created by applying all the inline decisions already
33 present in the callgraph).
34
0bceb671 35 We provide access to the ipa_fn_summary data structure and
27d020cf
JH
36 basic logic updating the parameters when inlining is performed.
37
38 The summaries are context sensitive. Context means
39 1) partial assignment of known constant values of operands
40 2) whether function is inlined into the call or not.
41 It is easy to add more variants. To represent function size and time
42 that depends on context (i.e. it is known to be optimized away when
43 context is known either by inlining or from IP-CP and cloning),
44 we use predicates.
45
46 estimate_edge_size_and_time can be used to query
0bceb671 47 function size/time in the given context. ipa_merge_fn_summary_after_inlining merges
27d020cf
JH
48 properties of caller and callee after inlining.
49
50 Finally pass_inline_parameters is exported. This is used to drive
51 computation of function parameters used by the early inliner. IPA
52 inlined performs analysis via its analyze_function method. */
53
54#include "config.h"
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"
27d020cf
JH
82#include "cfgexpand.h"
83#include "gimplify.h"
314e6352
ML
84#include "stringpool.h"
85#include "attribs.h"
27d020cf
JH
86
87/* Summaries. */
0bceb671 88function_summary <ipa_fn_summary *> *ipa_fn_summaries;
27d020cf
JH
89call_summary <ipa_call_summary *> *ipa_call_summaries;
90
91/* Edge predicates goes here. */
92static object_allocator<predicate> edge_predicate_pool ("edge predicates");
93
94
0bceb671 95/* Dump IPA hints. */
27d020cf 96void
0bceb671 97ipa_dump_hints (FILE *f, ipa_hints hints)
27d020cf
JH
98{
99 if (!hints)
100 return;
0bceb671 101 fprintf (f, "IPA hints:");
27d020cf
JH
102 if (hints & INLINE_HINT_indirect_call)
103 {
104 hints &= ~INLINE_HINT_indirect_call;
105 fprintf (f, " indirect_call");
106 }
107 if (hints & INLINE_HINT_loop_iterations)
108 {
109 hints &= ~INLINE_HINT_loop_iterations;
110 fprintf (f, " loop_iterations");
111 }
112 if (hints & INLINE_HINT_loop_stride)
113 {
114 hints &= ~INLINE_HINT_loop_stride;
115 fprintf (f, " loop_stride");
116 }
117 if (hints & INLINE_HINT_same_scc)
118 {
119 hints &= ~INLINE_HINT_same_scc;
120 fprintf (f, " same_scc");
121 }
122 if (hints & INLINE_HINT_in_scc)
123 {
124 hints &= ~INLINE_HINT_in_scc;
125 fprintf (f, " in_scc");
126 }
127 if (hints & INLINE_HINT_cross_module)
128 {
129 hints &= ~INLINE_HINT_cross_module;
130 fprintf (f, " cross_module");
131 }
132 if (hints & INLINE_HINT_declared_inline)
133 {
134 hints &= ~INLINE_HINT_declared_inline;
135 fprintf (f, " declared_inline");
136 }
137 if (hints & INLINE_HINT_array_index)
138 {
139 hints &= ~INLINE_HINT_array_index;
140 fprintf (f, " array_index");
141 }
142 if (hints & INLINE_HINT_known_hot)
143 {
144 hints &= ~INLINE_HINT_known_hot;
145 fprintf (f, " known_hot");
146 }
147 gcc_assert (!hints);
148}
149
150
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. */
155
156void
0bceb671 157ipa_fn_summary::account_size_time (int size, sreal time,
27d020cf
JH
158 const predicate &exec_pred,
159 const predicate &nonconst_pred_in)
160{
161 size_time_entry *e;
162 bool found = false;
163 int i;
164 predicate nonconst_pred;
165
166 if (exec_pred == false)
167 return;
168
169 nonconst_pred = nonconst_pred_in & exec_pred;
170
171 if (nonconst_pred == false)
172 return;
173
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;
178
179 gcc_assert (time >= 0);
180
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)
184 {
185 found = true;
186 break;
187 }
188 if (i == 256)
189 {
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.");
197 }
198 if (dump_file && (dump_flags & TDF_DETAILS) && (time != 0 || size))
199 {
200 fprintf (dump_file,
201 "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
0bceb671 202 ((double) size) / ipa_fn_summary::size_scale,
27d020cf
JH
203 (time.to_double ()), found ? "" : "new ");
204 exec_pred.dump (dump_file, conds, 0);
205 if (exec_pred != nonconst_pred)
206 {
207 fprintf (dump_file, " nonconst:");
208 nonconst_pred.dump (dump_file, conds);
209 }
210 else
211 fprintf (dump_file, "\n");
212 }
213 if (!found)
214 {
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);
221 }
222 else
223 {
224 e->size += size;
225 e->time += time;
226 }
227}
228
229/* We proved E to be unreachable, redirect it to __bultin_unreachable. */
230
231static struct cgraph_edge *
232redirect_to_unreachable (struct cgraph_edge *e)
233{
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));
237
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);
56f62793 244 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf 245 e->inline_failed = CIF_UNREACHABLE;
3995f3a2 246 e->count = profile_count::zero ();
27d020cf
JH
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;
252}
253
254/* Set predicate for edge E. */
255
256static void
257edge_set_predicate (struct cgraph_edge *e, predicate *predicate)
258{
259 /* If the edge is determined to be never executed, redirect it
0bceb671
JH
260 to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
261 be optimized out. */
27d020cf
JH
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);
268
56f62793 269 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
270 if (predicate && *predicate != true)
271 {
272 if (!es->predicate)
273 es->predicate = edge_predicate_pool.allocate ();
274 *es->predicate = *predicate;
275 }
276 else
277 {
278 if (es->predicate)
279 edge_predicate_pool.remove (es->predicate);
280 es->predicate = NULL;
281 }
282}
283
284/* Set predicate for hint *P. */
285
286static void
287set_hint_predicate (predicate **p, predicate new_predicate)
288{
289 if (new_predicate == false || new_predicate == true)
290 {
291 if (*p)
292 edge_predicate_pool.remove (*p);
293 *p = NULL;
294 }
295 else
296 {
297 if (!*p)
298 *p = edge_predicate_pool.allocate ();
299 **p = new_predicate;
300 }
301}
302
303
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
67914693 310 is always false in the second and also builtin_constant_p tests cannot use
27d020cf
JH
311 the fact that parameter is indeed a constant.
312
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.
317
318 ERROR_MARK means compile time invariant. */
319
320static void
321evaluate_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)
328{
329 clause_t clause = inline_p ? 0 : 1 << predicate::not_inlined_condition;
330 clause_t nonspec_clause = 1 << predicate::not_inlined_condition;
56f62793 331 struct ipa_fn_summary *info = ipa_fn_summaries->get (node);
27d020cf
JH
332 int i;
333 struct condition *c;
334
335 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
336 {
337 tree val;
338 tree res;
339
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 ())
347 {
348 clause |= 1 << (i + predicate::first_dynamic_condition);
349 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
350 continue;
351 }
352
353 if (c->agg_contents)
354 {
355 struct ipa_agg_jump_function *agg;
356
357 if (c->code == predicate::changed
358 && !c->by_ref
359 && (known_vals[c->operand_num] == error_mark_node))
360 continue;
361
362 if (known_aggs.exists ())
363 {
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);
367 }
368 else
369 val = NULL_TREE;
370 }
371 else
372 {
373 val = known_vals[c->operand_num];
374 if (val == error_mark_node && c->code != predicate::changed)
375 val = NULL_TREE;
376 }
377
378 if (!val)
379 {
380 clause |= 1 << (i + predicate::first_dynamic_condition);
381 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
382 continue;
383 }
384 if (c->code == predicate::changed)
385 {
386 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
387 continue;
388 }
389
390 if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
391 {
392 clause |= 1 << (i + predicate::first_dynamic_condition);
393 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
394 continue;
395 }
396 if (c->code == predicate::is_not_constant)
397 {
398 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
399 continue;
400 }
401
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;
406
407 if (res && integer_zerop (res))
408 continue;
409
410 clause |= 1 << (i + predicate::first_dynamic_condition);
411 nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
412 }
413 *ret_clause = clause;
414 if (ret_nonspec_clause)
415 *ret_nonspec_clause = nonspec_clause;
416}
417
418
419/* Work out what conditions might be true at invocation of E. */
420
421void
422evaluate_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)
429{
430 struct cgraph_node *callee = e->callee->ultimate_alias_target ();
56f62793 431 struct ipa_fn_summary *info = ipa_fn_summaries->get (callee);
27d020cf
JH
432 vec<tree> known_vals = vNULL;
433 vec<ipa_agg_jump_function_p> known_aggs = vNULL;
434
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);
441
442 if (ipa_node_params_sum
443 && !e->call_stmt_cannot_inline_p
444 && ((clause_ptr && info->conds) || known_vals_ptr || known_contexts_ptr))
445 {
e5cf5e11 446 struct ipa_node_params *caller_parms_info, *callee_pi;
27d020cf 447 struct ipa_edge_args *args = IPA_EDGE_REF (e);
56f62793 448 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
449 int i, count = ipa_get_cs_argument_count (args);
450
451 if (e->caller->global.inlined_to)
e5cf5e11 452 caller_parms_info = IPA_NODE_REF (e->caller->global.inlined_to);
27d020cf 453 else
e5cf5e11
PK
454 caller_parms_info = IPA_NODE_REF (e->caller);
455 callee_pi = IPA_NODE_REF (e->callee);
27d020cf
JH
456
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);
463
464 for (i = 0; i < count; i++)
465 {
466 struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
e5cf5e11
PK
467 tree cst = ipa_value_from_jfunc (caller_parms_info, jf,
468 ipa_get_type (callee_pi, i));
27d020cf
JH
469
470 if (!cst && e->call_stmt
471 && i < (int)gimple_call_num_args (e->call_stmt))
472 {
473 cst = gimple_call_arg (e->call_stmt, i);
474 if (!is_gimple_min_invariant (cst))
475 cst = NULL;
476 }
477 if (cst)
478 {
479 gcc_checking_assert (TREE_CODE (cst) != TREE_BINFO);
480 if (known_vals.exists ())
481 known_vals[i] = cst;
482 }
483 else if (inline_p && !es->param[i].change_prob)
484 known_vals[i] = error_mark_node;
485
486 if (known_contexts_ptr)
e5cf5e11
PK
487 (*known_contexts_ptr)[i]
488 = ipa_context_from_jfunc (caller_parms_info, e, i, jf);
27d020cf
JH
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;
493 }
494 }
495 else if (e->call_stmt && !e->call_stmt_cannot_inline_p
496 && ((clause_ptr && info->conds) || known_vals_ptr))
497 {
498 int i, count = (int)gimple_call_num_args (e->call_stmt);
499
500 if (count && (info->conds || known_vals_ptr))
501 known_vals.safe_grow_cleared (count);
502 for (i = 0; i < count; i++)
503 {
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;
509 }
510 }
511
512 evaluate_conditions_for_known_args (callee, inline_p,
513 known_vals, known_aggs, clause_ptr,
514 nonspec_clause_ptr);
515
516 if (known_vals_ptr)
517 *known_vals_ptr = known_vals;
518 else
519 known_vals.release ();
520
521 if (known_aggs_ptr)
522 *known_aggs_ptr = known_aggs;
523 else
524 known_aggs.release ();
525}
526
527
0bceb671 528/* Allocate the function summary. */
27d020cf
JH
529
530static void
0bceb671 531ipa_fn_summary_alloc (void)
27d020cf 532{
0bceb671
JH
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);
27d020cf
JH
536}
537
56f62793 538ipa_call_summary::~ipa_call_summary ()
27d020cf 539{
27d020cf
JH
540 if (predicate)
541 edge_predicate_pool.remove (predicate);
56f62793 542
27d020cf
JH
543 param.release ();
544}
545
56f62793 546ipa_fn_summary::~ipa_fn_summary ()
27d020cf 547{
27d020cf 548 if (loop_iterations)
56f62793 549 edge_predicate_pool.remove (loop_iterations);
27d020cf 550 if (loop_stride)
56f62793 551 edge_predicate_pool.remove (loop_stride);
27d020cf 552 if (array_index)
56f62793 553 edge_predicate_pool.remove (array_index);
27d020cf
JH
554 vec_free (conds);
555 vec_free (size_time_table);
27d020cf
JH
556}
557
27d020cf 558void
56f62793 559ipa_fn_summary_t::remove_callees (cgraph_node *node)
27d020cf 560{
56f62793
ML
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);
27d020cf
JH
566}
567
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).
571 */
572
573static void
574remap_hint_predicate_after_duplication (predicate **p,
575 clause_t possible_truths)
576{
577 predicate new_predicate;
578
579 if (!*p)
580 return;
581
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);
586}
587
588
589/* Hook that is called by cgraph.c when a node is duplicated. */
590void
0bceb671 591ipa_fn_summary_t::duplicate (cgraph_node *src,
27d020cf 592 cgraph_node *dst,
0bceb671
JH
593 ipa_fn_summary *,
594 ipa_fn_summary *info)
27d020cf 595{
56f62793 596 new (info) ipa_fn_summary (*ipa_fn_summaries->get (src));
27d020cf
JH
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);
600
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)
604 {
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;
617
618 info->size_time_table = 0;
619 known_vals.safe_grow_cleared (count);
620 for (i = 0; i < count; i++)
621 {
622 struct ipa_replace_map *r;
623
624 for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++)
625 {
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)
629 {
630 known_vals[i] = r->new_tree;
631 break;
632 }
633 }
634 }
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 ();
643
644 info->account_size_time (0, 0, true_pred, true_pred);
645
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++)
652 {
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);
664 }
665
666 /* Remap edge predicates with the same simplification as above.
667 Also copy constantness arrays. */
668 for (edge = dst->callees; edge; edge = next)
669 {
670 predicate new_predicate;
99353fcf 671 struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
27d020cf
JH
672 next = edge->next_callee;
673
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)
0bceb671 681 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
27d020cf
JH
682 edge_set_predicate (edge, &new_predicate);
683 }
684
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)
688 {
689 predicate new_predicate;
99353fcf 690 struct ipa_call_summary *es = ipa_call_summaries->get_create (edge);
27d020cf
JH
691 next = edge->next_callee;
692
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)
0bceb671 699 optimized_out_size += es->call_stmt_size * ipa_fn_summary::size_scale;
27d020cf
JH
700 edge_set_predicate (edge, &new_predicate);
701 }
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);
708
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);
714 }
715 else
716 {
717 info->size_time_table = vec_safe_copy (info->size_time_table);
718 if (info->loop_iterations)
719 {
720 predicate p = *info->loop_iterations;
721 info->loop_iterations = NULL;
722 set_hint_predicate (&info->loop_iterations, p);
723 }
724 if (info->loop_stride)
725 {
726 predicate p = *info->loop_stride;
727 info->loop_stride = NULL;
728 set_hint_predicate (&info->loop_stride, p);
729 }
730 if (info->array_index)
731 {
732 predicate p = *info->array_index;
733 info->array_index = NULL;
734 set_hint_predicate (&info->array_index, p);
735 }
736 }
737 if (!dst->global.inlined_to)
0bceb671 738 ipa_update_overall_fn_summary (dst);
27d020cf
JH
739}
740
741
742/* Hook that is called by cgraph.c when a node is duplicated. */
743
744void
745ipa_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)
749{
56f62793 750 new (info) ipa_call_summary (*srcinfo);
27d020cf
JH
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)
755 {
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);
760 }
761}
762
27d020cf
JH
763/* Dump edge summaries associated to NODE and recursively to all clones.
764 Indent by INDENT. */
765
766static void
767dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
0bceb671 768 struct ipa_fn_summary *info)
27d020cf
JH
769{
770 struct cgraph_edge *edge;
771 for (edge = node->callees; edge; edge = edge->next_callee)
772 {
56f62793 773 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf
JH
774 struct cgraph_node *callee = edge->callee->ultimate_alias_target ();
775 int i;
776
777 fprintf (f,
56f62793 778 "%*s%s/%i %s\n%*s loop depth:%2i freq:%4.2f size:%2i time: %2i",
27d020cf
JH
779 indent, "", callee->name (), callee->order,
780 !edge->inline_failed
781 ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
41f0e819 782 indent, "", es->loop_depth, edge->sreal_frequency ().to_double (),
56f62793
ML
783 es->call_stmt_size, es->call_stmt_time);
784
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);
27d020cf
JH
790
791 if (es->predicate)
792 {
793 fprintf (f, " predicate: ");
794 es->predicate->dump (f, info->conds);
795 }
796 else
797 fprintf (f, "\n");
798 if (es->param.exists ())
799 for (i = 0; i < (int) es->param.length (); i++)
800 {
801 int prob = es->param[i].change_prob;
802
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);
809 }
810 if (!edge->inline_failed)
811 {
cf9b0b5f 812 ipa_fn_summary *s = ipa_fn_summaries->get (callee);
27d020cf
JH
813 fprintf (f, "%*sStack frame offset %i, callee self size %i,"
814 " callee size %i\n",
815 indent + 2, "",
99353fcf
ML
816 (int) s->stack_frame_offset,
817 (int) s->estimated_self_stack_size,
818 (int) s->estimated_stack_size);
27d020cf
JH
819 dump_ipa_call_summary (f, indent + 2, callee, info);
820 }
821 }
822 for (edge = node->indirect_calls; edge; edge = edge->next_callee)
823 {
56f62793 824 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
41f0e819 825 fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
27d020cf
JH
826 " time: %2i",
827 indent, "",
828 es->loop_depth,
41f0e819
JH
829 edge->sreal_frequency ().to_double (), es->call_stmt_size,
830 es->call_stmt_time);
27d020cf
JH
831 if (es->predicate)
832 {
833 fprintf (f, "predicate: ");
834 es->predicate->dump (f, info->conds);
835 }
836 else
837 fprintf (f, "\n");
838 }
839}
840
841
842void
0bceb671 843ipa_dump_fn_summary (FILE *f, struct cgraph_node *node)
27d020cf
JH
844{
845 if (node->definition)
846 {
56f62793
ML
847 struct ipa_fn_summary *s = ipa_fn_summaries->get (node);
848 if (s != NULL)
27d020cf 849 {
56f62793
ML
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++)
871 {
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)
876 {
877 fprintf (f, ", executed if:");
878 e->exec_predicate.dump (f, s->conds, 0);
879 }
880 if (e->exec_predicate != e->nonconst_predicate)
881 {
882 fprintf (f, ", nonconst if:");
883 e->nonconst_predicate.dump (f, s->conds, 0);
884 }
885 fprintf (f, "\n");
886 }
887 if (s->loop_iterations)
27d020cf 888 {
56f62793
ML
889 fprintf (f, " loop iterations:");
890 s->loop_iterations->dump (f, s->conds);
27d020cf 891 }
56f62793 892 if (s->loop_stride)
27d020cf 893 {
56f62793
ML
894 fprintf (f, " loop stride:");
895 s->loop_stride->dump (f, s->conds);
27d020cf 896 }
56f62793
ML
897 if (s->array_index)
898 {
899 fprintf (f, " array index:");
900 s->array_index->dump (f, s->conds);
901 }
902 fprintf (f, " calls:\n");
903 dump_ipa_call_summary (f, 4, node, s);
27d020cf
JH
904 fprintf (f, "\n");
905 }
56f62793
ML
906 else
907 fprintf (f, "IPA summary for %s is missing.\n", node->dump_name ());
27d020cf
JH
908 }
909}
910
911DEBUG_FUNCTION void
0bceb671 912ipa_debug_fn_summary (struct cgraph_node *node)
27d020cf 913{
0bceb671 914 ipa_dump_fn_summary (stderr, node);
27d020cf
JH
915}
916
917void
0bceb671 918ipa_dump_fn_summaries (FILE *f)
27d020cf
JH
919{
920 struct cgraph_node *node;
921
922 FOR_EACH_DEFINED_FUNCTION (node)
923 if (!node->global.inlined_to)
0bceb671 924 ipa_dump_fn_summary (f, node);
27d020cf
JH
925}
926
927/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
928 boolean variable pointed to by DATA. */
929
930static bool
931mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
932 void *data)
933{
934 bool *b = (bool *) data;
935 *b = true;
936 return true;
937}
938
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. */
942
943static tree
c628d1c3
MJ
944unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
945 HOST_WIDE_INT *size_p)
27d020cf
JH
946{
947 /* SSA_NAME referring to parm default def? */
948 if (TREE_CODE (op) == SSA_NAME
949 && SSA_NAME_IS_DEFAULT_DEF (op)
950 && TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
951 {
952 if (size_p)
953 *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
954 return SSA_NAME_VAR (op);
955 }
956 /* Non-SSA parm reference? */
957 if (TREE_CODE (op) == PARM_DECL)
958 {
959 bool modified = false;
960
961 ao_ref refd;
962 ao_ref_init (&refd, op);
c628d1c3
MJ
963 int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt),
964 mark_modified, &modified, NULL, NULL,
965 fbi->aa_walk_budget + 1);
966 if (walked < 0)
967 {
968 fbi->aa_walk_budget = 0;
969 return NULL_TREE;
970 }
27d020cf
JH
971 if (!modified)
972 {
973 if (size_p)
974 *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
975 return op;
976 }
977 }
978 return NULL_TREE;
979}
980
981/* If OP refers to value of function parameter, return the corresponding
982 parameter. Also traverse chains of SSA register assignments. If non-NULL,
983 the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
984 stored to *SIZE_P in that case too. */
985
986static tree
c628d1c3
MJ
987unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
988 HOST_WIDE_INT *size_p)
27d020cf 989{
c628d1c3 990 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
27d020cf
JH
991 if (res)
992 return res;
993
994 if (TREE_CODE (op) == SSA_NAME
995 && !SSA_NAME_IS_DEFAULT_DEF (op)
996 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
c628d1c3 997 return unmodified_parm (fbi, SSA_NAME_DEF_STMT (op),
27d020cf
JH
998 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
999 size_p);
1000 return NULL_TREE;
1001}
1002
1003/* If OP refers to a value of a function parameter or value loaded from an
1004 aggregate passed to a parameter (either by value or reference), return TRUE
1005 and store the number of the parameter to *INDEX_P, the access size into
1006 *SIZE_P, and information whether and how it has been loaded from an
1007 aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
1008 statement in which OP is used or loaded. */
1009
1010static bool
1011unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
1012 gimple *stmt, tree op, int *index_p,
1013 HOST_WIDE_INT *size_p,
1014 struct agg_position_info *aggpos)
1015{
c628d1c3 1016 tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
27d020cf
JH
1017
1018 gcc_checking_assert (aggpos);
1019 if (res)
1020 {
1021 *index_p = ipa_get_param_decl_index (fbi->info, res);
1022 if (*index_p < 0)
1023 return false;
1024 aggpos->agg_contents = false;
1025 aggpos->by_ref = false;
1026 return true;
1027 }
1028
1029 if (TREE_CODE (op) == SSA_NAME)
1030 {
1031 if (SSA_NAME_IS_DEFAULT_DEF (op)
1032 || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
1033 return false;
1034 stmt = SSA_NAME_DEF_STMT (op);
1035 op = gimple_assign_rhs1 (stmt);
1036 if (!REFERENCE_CLASS_P (op))
1037 return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
1038 aggpos);
1039 }
1040
1041 aggpos->agg_contents = true;
1042 return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
1043 stmt, op, index_p, &aggpos->offset,
1044 size_p, &aggpos->by_ref);
1045}
1046
1047/* See if statement might disappear after inlining.
1048 0 - means not eliminated
1049 1 - half of statements goes away
1050 2 - for sure it is eliminated.
1051 We are not terribly sophisticated, basically looking for simple abstraction
1052 penalty wrappers. */
1053
1054static int
c628d1c3 1055eliminated_by_inlining_prob (ipa_func_body_info *fbi, gimple *stmt)
27d020cf
JH
1056{
1057 enum gimple_code code = gimple_code (stmt);
1058 enum tree_code rhs_code;
1059
1060 if (!optimize)
1061 return 0;
1062
1063 switch (code)
1064 {
1065 case GIMPLE_RETURN:
1066 return 2;
1067 case GIMPLE_ASSIGN:
1068 if (gimple_num_ops (stmt) != 2)
1069 return 0;
1070
1071 rhs_code = gimple_assign_rhs_code (stmt);
1072
1073 /* Casts of parameters, loads from parameters passed by reference
1074 and stores to return value or parameters are often free after
1075 inlining dua to SRA and further combining.
1076 Assume that half of statements goes away. */
1077 if (CONVERT_EXPR_CODE_P (rhs_code)
1078 || rhs_code == VIEW_CONVERT_EXPR
1079 || rhs_code == ADDR_EXPR
1080 || gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
1081 {
1082 tree rhs = gimple_assign_rhs1 (stmt);
1083 tree lhs = gimple_assign_lhs (stmt);
1084 tree inner_rhs = get_base_address (rhs);
1085 tree inner_lhs = get_base_address (lhs);
1086 bool rhs_free = false;
1087 bool lhs_free = false;
1088
1089 if (!inner_rhs)
1090 inner_rhs = rhs;
1091 if (!inner_lhs)
1092 inner_lhs = lhs;
1093
1094 /* Reads of parameter are expected to be free. */
c628d1c3 1095 if (unmodified_parm (fbi, stmt, inner_rhs, NULL))
27d020cf
JH
1096 rhs_free = true;
1097 /* Match expressions of form &this->field. Those will most likely
1098 combine with something upstream after inlining. */
1099 else if (TREE_CODE (inner_rhs) == ADDR_EXPR)
1100 {
1101 tree op = get_base_address (TREE_OPERAND (inner_rhs, 0));
1102 if (TREE_CODE (op) == PARM_DECL)
1103 rhs_free = true;
1104 else if (TREE_CODE (op) == MEM_REF
c628d1c3
MJ
1105 && unmodified_parm (fbi, stmt, TREE_OPERAND (op, 0),
1106 NULL))
27d020cf
JH
1107 rhs_free = true;
1108 }
1109
1110 /* When parameter is not SSA register because its address is taken
1111 and it is just copied into one, the statement will be completely
1112 free after inlining (we will copy propagate backward). */
1113 if (rhs_free && is_gimple_reg (lhs))
1114 return 2;
1115
1116 /* Reads of parameters passed by reference
1117 expected to be free (i.e. optimized out after inlining). */
1118 if (TREE_CODE (inner_rhs) == MEM_REF
c628d1c3 1119 && unmodified_parm (fbi, stmt, TREE_OPERAND (inner_rhs, 0), NULL))
27d020cf
JH
1120 rhs_free = true;
1121
1122 /* Copying parameter passed by reference into gimple register is
1123 probably also going to copy propagate, but we can't be quite
1124 sure. */
1125 if (rhs_free && is_gimple_reg (lhs))
1126 lhs_free = true;
1127
1128 /* Writes to parameters, parameters passed by value and return value
1129 (either dirrectly or passed via invisible reference) are free.
1130
1131 TODO: We ought to handle testcase like
1132 struct a {int a,b;};
1133 struct a
1134 retrurnsturct (void)
1135 {
1136 struct a a ={1,2};
1137 return a;
1138 }
1139
1140 This translate into:
1141
1142 retrurnsturct ()
1143 {
1144 int a$b;
1145 int a$a;
1146 struct a a;
1147 struct a D.2739;
1148
1149 <bb 2>:
1150 D.2739.a = 1;
1151 D.2739.b = 2;
1152 return D.2739;
1153
1154 }
1155 For that we either need to copy ipa-split logic detecting writes
1156 to return value. */
1157 if (TREE_CODE (inner_lhs) == PARM_DECL
1158 || TREE_CODE (inner_lhs) == RESULT_DECL
1159 || (TREE_CODE (inner_lhs) == MEM_REF
c628d1c3
MJ
1160 && (unmodified_parm (fbi, stmt, TREE_OPERAND (inner_lhs, 0),
1161 NULL)
27d020cf
JH
1162 || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
1163 && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
1164 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1165 (inner_lhs,
1166 0))) == RESULT_DECL))))
1167 lhs_free = true;
1168 if (lhs_free
1169 && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs)))
1170 rhs_free = true;
1171 if (lhs_free && rhs_free)
1172 return 1;
1173 }
1174 return 0;
1175 default:
1176 return 0;
1177 }
1178}
1179
1180
1181/* If BB ends by a conditional we can turn into predicates, attach corresponding
1182 predicates to the CFG edges. */
1183
1184static void
1185set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
0bceb671 1186 struct ipa_fn_summary *summary,
27d020cf
JH
1187 basic_block bb)
1188{
1189 gimple *last;
1190 tree op;
1191 int index;
1192 HOST_WIDE_INT size;
1193 struct agg_position_info aggpos;
1194 enum tree_code code, inverted_code;
1195 edge e;
1196 edge_iterator ei;
1197 gimple *set_stmt;
1198 tree op2;
1199
1200 last = last_stmt (bb);
1201 if (!last || gimple_code (last) != GIMPLE_COND)
1202 return;
1203 if (!is_gimple_ip_invariant (gimple_cond_rhs (last)))
1204 return;
1205 op = gimple_cond_lhs (last);
1206 /* TODO: handle conditionals like
1207 var = op0 < 4;
1208 if (var != 0). */
1209 if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1210 {
1211 code = gimple_cond_code (last);
1212 inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
1213
1214 FOR_EACH_EDGE (e, ei, bb->succs)
1215 {
1216 enum tree_code this_code = (e->flags & EDGE_TRUE_VALUE
1217 ? code : inverted_code);
1218 /* invert_tree_comparison will return ERROR_MARK on FP
1219 comparsions that are not EQ/NE instead of returning proper
1220 unordered one. Be sure it is not confused with NON_CONSTANT. */
1221 if (this_code != ERROR_MARK)
1222 {
1223 predicate p
1224 = add_condition (summary, index, size, &aggpos, this_code,
1225 unshare_expr_without_location
1226 (gimple_cond_rhs (last)));
1227 e->aux = edge_predicate_pool.allocate ();
1228 *(predicate *) e->aux = p;
1229 }
1230 }
1231 }
1232
1233 if (TREE_CODE (op) != SSA_NAME)
1234 return;
1235 /* Special case
1236 if (builtin_constant_p (op))
1237 constant_code
1238 else
1239 nonconstant_code.
1240 Here we can predicate nonconstant_code. We can't
1241 really handle constant_code since we have no predicate
1242 for this and also the constant code is not known to be
1243 optimized away when inliner doen't see operand is constant.
1244 Other optimizers might think otherwise. */
1245 if (gimple_cond_code (last) != NE_EXPR
1246 || !integer_zerop (gimple_cond_rhs (last)))
1247 return;
1248 set_stmt = SSA_NAME_DEF_STMT (op);
1249 if (!gimple_call_builtin_p (set_stmt, BUILT_IN_CONSTANT_P)
1250 || gimple_call_num_args (set_stmt) != 1)
1251 return;
1252 op2 = gimple_call_arg (set_stmt, 0);
1253 if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size,
1254 &aggpos))
1255 return;
1256 FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
1257 {
1258 predicate p = add_condition (summary, index, size, &aggpos,
1259 predicate::is_not_constant, NULL_TREE);
1260 e->aux = edge_predicate_pool.allocate ();
1261 *(predicate *) e->aux = p;
1262 }
1263}
1264
1265
1266/* If BB ends by a switch we can turn into predicates, attach corresponding
1267 predicates to the CFG edges. */
1268
1269static void
1270set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
0bceb671 1271 struct ipa_fn_summary *summary,
27d020cf
JH
1272 basic_block bb)
1273{
1274 gimple *lastg;
1275 tree op;
1276 int index;
1277 HOST_WIDE_INT size;
1278 struct agg_position_info aggpos;
1279 edge e;
1280 edge_iterator ei;
1281 size_t n;
1282 size_t case_idx;
1283
1284 lastg = last_stmt (bb);
1285 if (!lastg || gimple_code (lastg) != GIMPLE_SWITCH)
1286 return;
1287 gswitch *last = as_a <gswitch *> (lastg);
1288 op = gimple_switch_index (last);
1289 if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
1290 return;
1291
1292 FOR_EACH_EDGE (e, ei, bb->succs)
1293 {
1294 e->aux = edge_predicate_pool.allocate ();
1295 *(predicate *) e->aux = false;
1296 }
1297 n = gimple_switch_num_labels (last);
1298 for (case_idx = 0; case_idx < n; ++case_idx)
1299 {
1300 tree cl = gimple_switch_label (last, case_idx);
1301 tree min, max;
1302 predicate p;
1303
61ff5d6f 1304 e = gimple_switch_edge (cfun, last, case_idx);
27d020cf
JH
1305 min = CASE_LOW (cl);
1306 max = CASE_HIGH (cl);
1307
1308 /* For default we might want to construct predicate that none
1309 of cases is met, but it is bit hard to do not having negations
1310 of conditionals handy. */
1311 if (!min && !max)
1312 p = true;
1313 else if (!max)
1314 p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
1315 unshare_expr_without_location (min));
1316 else
1317 {
1318 predicate p1, p2;
1319 p1 = add_condition (summary, index, size, &aggpos, GE_EXPR,
1320 unshare_expr_without_location (min));
1321 p2 = add_condition (summary, index, size, &aggpos, LE_EXPR,
1322 unshare_expr_without_location (max));
1323 p = p1 & p2;
1324 }
1325 *(struct predicate *) e->aux
1326 = p.or_with (summary->conds, *(struct predicate *) e->aux);
1327 }
1328}
1329
1330
1331/* For each BB in NODE attach to its AUX pointer predicate under
1332 which it is executable. */
1333
1334static void
1335compute_bb_predicates (struct ipa_func_body_info *fbi,
1336 struct cgraph_node *node,
0bceb671 1337 struct ipa_fn_summary *summary)
27d020cf
JH
1338{
1339 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
1340 bool done = false;
1341 basic_block bb;
1342
1343 FOR_EACH_BB_FN (bb, my_function)
1344 {
1345 set_cond_stmt_execution_predicate (fbi, summary, bb);
1346 set_switch_stmt_execution_predicate (fbi, summary, bb);
1347 }
1348
1349 /* Entry block is always executable. */
1350 ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux
1351 = edge_predicate_pool.allocate ();
1352 *(predicate *) ENTRY_BLOCK_PTR_FOR_FN (my_function)->aux = true;
1353
1354 /* A simple dataflow propagation of predicates forward in the CFG.
1355 TODO: work in reverse postorder. */
1356 while (!done)
1357 {
1358 done = true;
1359 FOR_EACH_BB_FN (bb, my_function)
1360 {
1361 predicate p = false;
1362 edge e;
1363 edge_iterator ei;
1364 FOR_EACH_EDGE (e, ei, bb->preds)
1365 {
1366 if (e->src->aux)
1367 {
1368 predicate this_bb_predicate
1369 = *(predicate *) e->src->aux;
1370 if (e->aux)
1371 this_bb_predicate &= (*(struct predicate *) e->aux);
1372 p = p.or_with (summary->conds, this_bb_predicate);
1373 if (p == true)
1374 break;
1375 }
1376 }
1377 if (p == false)
1378 gcc_checking_assert (!bb->aux);
1379 else
1380 {
1381 if (!bb->aux)
1382 {
1383 done = false;
1384 bb->aux = edge_predicate_pool.allocate ();
1385 *((predicate *) bb->aux) = p;
1386 }
1387 else if (p != *(predicate *) bb->aux)
1388 {
1389 /* This OR operation is needed to ensure monotonous data flow
1390 in the case we hit the limit on number of clauses and the
1391 and/or operations above give approximate answers. */
1392 p = p.or_with (summary->conds, *(predicate *)bb->aux);
1393 if (p != *(predicate *) bb->aux)
1394 {
1395 done = false;
1396 *((predicate *) bb->aux) = p;
1397 }
1398 }
1399 }
1400 }
1401 }
1402}
1403
1404
1405/* Return predicate specifying when the STMT might have result that is not
1406 a compile time constant. */
1407
1408static predicate
c628d1c3 1409will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
0bceb671 1410 struct ipa_fn_summary *summary,
27d020cf
JH
1411 tree expr,
1412 vec<predicate> nonconstant_names)
1413{
1414 tree parm;
1415 int index;
1416 HOST_WIDE_INT size;
1417
1418 while (UNARY_CLASS_P (expr))
1419 expr = TREE_OPERAND (expr, 0);
1420
c628d1c3
MJ
1421 parm = unmodified_parm (fbi, NULL, expr, &size);
1422 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
27d020cf
JH
1423 return add_condition (summary, index, size, NULL, predicate::changed,
1424 NULL_TREE);
1425 if (is_gimple_min_invariant (expr))
1426 return false;
1427 if (TREE_CODE (expr) == SSA_NAME)
1428 return nonconstant_names[SSA_NAME_VERSION (expr)];
1429 if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
1430 {
c628d1c3
MJ
1431 predicate p1
1432 = will_be_nonconstant_expr_predicate (fbi, summary,
1433 TREE_OPERAND (expr, 0),
1434 nonconstant_names);
27d020cf
JH
1435 if (p1 == true)
1436 return p1;
1437
c628d1c3
MJ
1438 predicate p2
1439 = will_be_nonconstant_expr_predicate (fbi, summary,
1440 TREE_OPERAND (expr, 1),
1441 nonconstant_names);
27d020cf
JH
1442 return p1.or_with (summary->conds, p2);
1443 }
1444 else if (TREE_CODE (expr) == COND_EXPR)
1445 {
c628d1c3
MJ
1446 predicate p1
1447 = will_be_nonconstant_expr_predicate (fbi, summary,
1448 TREE_OPERAND (expr, 0),
1449 nonconstant_names);
27d020cf
JH
1450 if (p1 == true)
1451 return p1;
1452
c628d1c3
MJ
1453 predicate p2
1454 = will_be_nonconstant_expr_predicate (fbi, summary,
1455 TREE_OPERAND (expr, 1),
1456 nonconstant_names);
27d020cf
JH
1457 if (p2 == true)
1458 return p2;
1459 p1 = p1.or_with (summary->conds, p2);
c628d1c3 1460 p2 = will_be_nonconstant_expr_predicate (fbi, summary,
27d020cf
JH
1461 TREE_OPERAND (expr, 2),
1462 nonconstant_names);
1463 return p2.or_with (summary->conds, p1);
1464 }
5126ae0c
KV
1465 else if (TREE_CODE (expr) == CALL_EXPR)
1466 return true;
27d020cf
JH
1467 else
1468 {
1469 debug_tree (expr);
1470 gcc_unreachable ();
1471 }
1472 return false;
1473}
1474
1475
1476/* Return predicate specifying when the STMT might have result that is not
1477 a compile time constant. */
1478
1479static predicate
1480will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
0bceb671 1481 struct ipa_fn_summary *summary,
27d020cf
JH
1482 gimple *stmt,
1483 vec<predicate> nonconstant_names)
1484{
1485 predicate p = true;
1486 ssa_op_iter iter;
1487 tree use;
1488 predicate op_non_const;
1489 bool is_load;
1490 int base_index;
1491 HOST_WIDE_INT size;
1492 struct agg_position_info aggpos;
1493
1494 /* What statments might be optimized away
1495 when their arguments are constant. */
1496 if (gimple_code (stmt) != GIMPLE_ASSIGN
1497 && gimple_code (stmt) != GIMPLE_COND
1498 && gimple_code (stmt) != GIMPLE_SWITCH
1499 && (gimple_code (stmt) != GIMPLE_CALL
1500 || !(gimple_call_flags (stmt) & ECF_CONST)))
1501 return p;
1502
1503 /* Stores will stay anyway. */
1504 if (gimple_store_p (stmt))
1505 return p;
1506
1507 is_load = gimple_assign_load_p (stmt);
1508
1509 /* Loads can be optimized when the value is known. */
1510 if (is_load)
1511 {
1512 tree op;
1513 gcc_assert (gimple_assign_single_p (stmt));
1514 op = gimple_assign_rhs1 (stmt);
1515 if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size,
1516 &aggpos))
1517 return p;
1518 }
1519 else
1520 base_index = -1;
1521
1522 /* See if we understand all operands before we start
1523 adding conditionals. */
1524 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1525 {
c628d1c3 1526 tree parm = unmodified_parm (fbi, stmt, use, NULL);
27d020cf
JH
1527 /* For arguments we can build a condition. */
1528 if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
1529 continue;
1530 if (TREE_CODE (use) != SSA_NAME)
1531 return p;
1532 /* If we know when operand is constant,
1533 we still can say something useful. */
1534 if (nonconstant_names[SSA_NAME_VERSION (use)] != true)
1535 continue;
1536 return p;
1537 }
1538
1539 if (is_load)
1540 op_non_const =
1541 add_condition (summary, base_index, size, &aggpos, predicate::changed,
1542 NULL);
1543 else
1544 op_non_const = false;
1545 FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
1546 {
1547 HOST_WIDE_INT size;
c628d1c3 1548 tree parm = unmodified_parm (fbi, stmt, use, &size);
27d020cf
JH
1549 int index;
1550
1551 if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
1552 {
1553 if (index != base_index)
1554 p = add_condition (summary, index, size, NULL, predicate::changed,
1555 NULL_TREE);
1556 else
1557 continue;
1558 }
1559 else
1560 p = nonconstant_names[SSA_NAME_VERSION (use)];
1561 op_non_const = p.or_with (summary->conds, op_non_const);
1562 }
1563 if ((gimple_code (stmt) == GIMPLE_ASSIGN || gimple_code (stmt) == GIMPLE_CALL)
1564 && gimple_op (stmt, 0)
1565 && TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME)
1566 nonconstant_names[SSA_NAME_VERSION (gimple_op (stmt, 0))]
1567 = op_non_const;
1568 return op_non_const;
1569}
1570
1571struct record_modified_bb_info
1572{
3b2a6901 1573 tree op;
27d020cf
JH
1574 bitmap bb_set;
1575 gimple *stmt;
1576};
1577
1578/* Value is initialized in INIT_BB and used in USE_BB. We want to copute
1579 probability how often it changes between USE_BB.
3b2a6901 1580 INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
27d020cf
JH
1581 is in different loop nest, we can do better.
1582 This is all just estimate. In theory we look for minimal cut separating
1583 INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
1584 anyway. */
1585
1586static basic_block
1587get_minimal_bb (basic_block init_bb, basic_block use_bb)
1588{
1589 struct loop *l = find_common_loop (init_bb->loop_father, use_bb->loop_father);
e7a74006 1590 if (l && l->header->count < init_bb->count)
27d020cf
JH
1591 return l->header;
1592 return init_bb;
1593}
1594
1595/* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
1596 set except for info->stmt. */
1597
1598static bool
1599record_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
1600{
1601 struct record_modified_bb_info *info =
1602 (struct record_modified_bb_info *) data;
1603 if (SSA_NAME_DEF_STMT (vdef) == info->stmt)
1604 return false;
3b2a6901
JH
1605 if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef)))
1606 return false;
27d020cf
JH
1607 bitmap_set_bit (info->bb_set,
1608 SSA_NAME_IS_DEFAULT_DEF (vdef)
1609 ? ENTRY_BLOCK_PTR_FOR_FN (cfun)->index
1610 : get_minimal_bb
1611 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1612 gimple_bb (info->stmt))->index);
3b2a6901
JH
1613 if (dump_file)
1614 {
1615 fprintf (dump_file, " Param ");
1616 print_generic_expr (dump_file, info->op, TDF_SLIM);
1617 fprintf (dump_file, " changed at bb %i, minimal: %i stmt: ",
1618 gimple_bb (SSA_NAME_DEF_STMT (vdef))->index,
1619 get_minimal_bb
1620 (gimple_bb (SSA_NAME_DEF_STMT (vdef)),
1621 gimple_bb (info->stmt))->index);
1622 print_gimple_stmt (dump_file, SSA_NAME_DEF_STMT (vdef), 0);
1623 }
27d020cf
JH
1624 return false;
1625}
1626
1627/* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
1628 will change since last invocation of STMT.
1629
1630 Value 0 is reserved for compile time invariants.
1631 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
1632 ought to be REG_BR_PROB_BASE / estimated_iters. */
1633
1634static int
c628d1c3 1635param_change_prob (ipa_func_body_info *fbi, gimple *stmt, int i)
27d020cf
JH
1636{
1637 tree op = gimple_call_arg (stmt, i);
1638 basic_block bb = gimple_bb (stmt);
1639
1640 if (TREE_CODE (op) == WITH_SIZE_EXPR)
1641 op = TREE_OPERAND (op, 0);
1642
1643 tree base = get_base_address (op);
1644
1645 /* Global invariants never change. */
1646 if (is_gimple_min_invariant (base))
1647 return 0;
1648
1649 /* We would have to do non-trivial analysis to really work out what
1650 is the probability of value to change (i.e. when init statement
1651 is in a sibling loop of the call).
1652
1653 We do an conservative estimate: when call is executed N times more often
1654 than the statement defining value, we take the frequency 1/N. */
1655 if (TREE_CODE (base) == SSA_NAME)
1656 {
3b2a6901 1657 profile_count init_count;
27d020cf 1658
3b2a6901 1659 if (!bb->count.nonzero_p ())
27d020cf
JH
1660 return REG_BR_PROB_BASE;
1661
1662 if (SSA_NAME_IS_DEFAULT_DEF (base))
3b2a6901 1663 init_count = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
27d020cf 1664 else
3b2a6901 1665 init_count = get_minimal_bb
27d020cf 1666 (gimple_bb (SSA_NAME_DEF_STMT (base)),
3b2a6901 1667 gimple_bb (stmt))->count;
27d020cf 1668
3b2a6901
JH
1669 if (init_count < bb->count)
1670 return MAX ((init_count.to_sreal_scale (bb->count)
1671 * REG_BR_PROB_BASE).to_int (), 1);
1672 return REG_BR_PROB_BASE;
27d020cf
JH
1673 }
1674 else
1675 {
1676 ao_ref refd;
3b2a6901 1677 profile_count max = ENTRY_BLOCK_PTR_FOR_FN (cfun)->count;
27d020cf 1678 struct record_modified_bb_info info;
27d020cf
JH
1679 tree init = ctor_for_folding (base);
1680
1681 if (init != error_mark_node)
1682 return 0;
3b2a6901 1683 if (!bb->count.nonzero_p ())
27d020cf 1684 return REG_BR_PROB_BASE;
3b2a6901
JH
1685 if (dump_file)
1686 {
1687 fprintf (dump_file, " Analyzing param change probablity of ");
1688 print_generic_expr (dump_file, op, TDF_SLIM);
1689 fprintf (dump_file, "\n");
1690 }
27d020cf 1691 ao_ref_init (&refd, op);
3b2a6901 1692 info.op = op;
27d020cf
JH
1693 info.stmt = stmt;
1694 info.bb_set = BITMAP_ALLOC (NULL);
c628d1c3
MJ
1695 int walked
1696 = walk_aliased_vdefs (&refd, gimple_vuse (stmt), record_modified, &info,
1697 NULL, NULL, fbi->aa_walk_budget);
1698 if (walked < 0 || bitmap_bit_p (info.bb_set, bb->index))
27d020cf 1699 {
3b2a6901 1700 if (dump_file)
c628d1c3
MJ
1701 {
1702 if (walked < 0)
1703 fprintf (dump_file, " Ran out of AA walking budget.\n");
1704 else
1705 fprintf (dump_file, " Set in same BB as used.\n");
1706 }
27d020cf
JH
1707 BITMAP_FREE (info.bb_set);
1708 return REG_BR_PROB_BASE;
1709 }
1710
3b2a6901
JH
1711 bitmap_iterator bi;
1712 unsigned index;
1713 /* Lookup the most frequent update of the value and believe that
1714 it dominates all the other; precise analysis here is difficult. */
27d020cf 1715 EXECUTE_IF_SET_IN_BITMAP (info.bb_set, 0, index, bi)
3b2a6901
JH
1716 max = max.max (BASIC_BLOCK_FOR_FN (cfun, index)->count);
1717 if (dump_file)
1718 {
1719 fprintf (dump_file, " Set with count ");
1720 max.dump (dump_file);
1721 fprintf (dump_file, " and used with count ");
1722 bb->count.dump (dump_file);
1723 fprintf (dump_file, " freq %f\n",
1724 max.to_sreal_scale (bb->count).to_double ());
1725 }
27d020cf
JH
1726
1727 BITMAP_FREE (info.bb_set);
3b2a6901
JH
1728 if (max < bb->count)
1729 return MAX ((max.to_sreal_scale (bb->count)
1730 * REG_BR_PROB_BASE).to_int (), 1);
1731 return REG_BR_PROB_BASE;
27d020cf
JH
1732 }
1733}
1734
1735/* Find whether a basic block BB is the final block of a (half) diamond CFG
1736 sub-graph and if the predicate the condition depends on is known. If so,
1737 return true and store the pointer the predicate in *P. */
1738
1739static bool
c628d1c3 1740phi_result_unknown_predicate (ipa_func_body_info *fbi,
0bceb671 1741 ipa_fn_summary *summary, basic_block bb,
27d020cf
JH
1742 predicate *p,
1743 vec<predicate> nonconstant_names)
1744{
1745 edge e;
1746 edge_iterator ei;
1747 basic_block first_bb = NULL;
1748 gimple *stmt;
1749
1750 if (single_pred_p (bb))
1751 {
1752 *p = false;
1753 return true;
1754 }
1755
1756 FOR_EACH_EDGE (e, ei, bb->preds)
1757 {
1758 if (single_succ_p (e->src))
1759 {
1760 if (!single_pred_p (e->src))
1761 return false;
1762 if (!first_bb)
1763 first_bb = single_pred (e->src);
1764 else if (single_pred (e->src) != first_bb)
1765 return false;
1766 }
1767 else
1768 {
1769 if (!first_bb)
1770 first_bb = e->src;
1771 else if (e->src != first_bb)
1772 return false;
1773 }
1774 }
1775
1776 if (!first_bb)
1777 return false;
1778
1779 stmt = last_stmt (first_bb);
1780 if (!stmt
1781 || gimple_code (stmt) != GIMPLE_COND
1782 || !is_gimple_ip_invariant (gimple_cond_rhs (stmt)))
1783 return false;
1784
c628d1c3 1785 *p = will_be_nonconstant_expr_predicate (fbi, summary,
27d020cf
JH
1786 gimple_cond_lhs (stmt),
1787 nonconstant_names);
1788 if (*p == true)
1789 return false;
1790 else
1791 return true;
1792}
1793
1794/* Given a PHI statement in a function described by inline properties SUMMARY
1795 and *P being the predicate describing whether the selected PHI argument is
1796 known, store a predicate for the result of the PHI statement into
1797 NONCONSTANT_NAMES, if possible. */
1798
1799static void
0bceb671 1800predicate_for_phi_result (struct ipa_fn_summary *summary, gphi *phi,
27d020cf
JH
1801 predicate *p,
1802 vec<predicate> nonconstant_names)
1803{
1804 unsigned i;
1805
1806 for (i = 0; i < gimple_phi_num_args (phi); i++)
1807 {
1808 tree arg = gimple_phi_arg (phi, i)->def;
1809 if (!is_gimple_min_invariant (arg))
1810 {
1811 gcc_assert (TREE_CODE (arg) == SSA_NAME);
1812 *p = p->or_with (summary->conds,
1813 nonconstant_names[SSA_NAME_VERSION (arg)]);
1814 if (*p == true)
1815 return;
1816 }
1817 }
1818
1819 if (dump_file && (dump_flags & TDF_DETAILS))
1820 {
1821 fprintf (dump_file, "\t\tphi predicate: ");
1822 p->dump (dump_file, summary->conds);
1823 }
1824 nonconstant_names[SSA_NAME_VERSION (gimple_phi_result (phi))] = *p;
1825}
1826
1827/* Return predicate specifying when array index in access OP becomes non-constant. */
1828
1829static predicate
0bceb671 1830array_index_predicate (ipa_fn_summary *info,
27d020cf
JH
1831 vec< predicate> nonconstant_names, tree op)
1832{
1833 predicate p = false;
1834 while (handled_component_p (op))
1835 {
1836 if (TREE_CODE (op) == ARRAY_REF || TREE_CODE (op) == ARRAY_RANGE_REF)
1837 {
1838 if (TREE_CODE (TREE_OPERAND (op, 1)) == SSA_NAME)
1839 p = p.or_with (info->conds,
1840 nonconstant_names[SSA_NAME_VERSION
1841 (TREE_OPERAND (op, 1))]);
1842 }
1843 op = TREE_OPERAND (op, 0);
1844 }
1845 return p;
1846}
1847
1848/* For a typical usage of __builtin_expect (a<b, 1), we
1849 may introduce an extra relation stmt:
1850 With the builtin, we have
1851 t1 = a <= b;
1852 t2 = (long int) t1;
1853 t3 = __builtin_expect (t2, 1);
1854 if (t3 != 0)
1855 goto ...
1856 Without the builtin, we have
1857 if (a<=b)
1858 goto...
1859 This affects the size/time estimation and may have
1860 an impact on the earlier inlining.
1861 Here find this pattern and fix it up later. */
1862
1863static gimple *
1864find_foldable_builtin_expect (basic_block bb)
1865{
1866 gimple_stmt_iterator bsi;
1867
1868 for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
1869 {
1870 gimple *stmt = gsi_stmt (bsi);
1871 if (gimple_call_builtin_p (stmt, BUILT_IN_EXPECT)
1e9168b2 1872 || gimple_call_builtin_p (stmt, BUILT_IN_EXPECT_WITH_PROBABILITY)
27d020cf
JH
1873 || gimple_call_internal_p (stmt, IFN_BUILTIN_EXPECT))
1874 {
1875 tree var = gimple_call_lhs (stmt);
1876 tree arg = gimple_call_arg (stmt, 0);
1877 use_operand_p use_p;
1878 gimple *use_stmt;
1879 bool match = false;
1880 bool done = false;
1881
1882 if (!var || !arg)
1883 continue;
1884 gcc_assert (TREE_CODE (var) == SSA_NAME);
1885
1886 while (TREE_CODE (arg) == SSA_NAME)
1887 {
1888 gimple *stmt_tmp = SSA_NAME_DEF_STMT (arg);
1889 if (!is_gimple_assign (stmt_tmp))
1890 break;
1891 switch (gimple_assign_rhs_code (stmt_tmp))
1892 {
1893 case LT_EXPR:
1894 case LE_EXPR:
1895 case GT_EXPR:
1896 case GE_EXPR:
1897 case EQ_EXPR:
1898 case NE_EXPR:
1899 match = true;
1900 done = true;
1901 break;
1902 CASE_CONVERT:
1903 break;
1904 default:
1905 done = true;
1906 break;
1907 }
1908 if (done)
1909 break;
1910 arg = gimple_assign_rhs1 (stmt_tmp);
1911 }
1912
1913 if (match && single_imm_use (var, &use_p, &use_stmt)
1914 && gimple_code (use_stmt) == GIMPLE_COND)
1915 return use_stmt;
1916 }
1917 }
1918 return NULL;
1919}
1920
1921/* Return true when the basic blocks contains only clobbers followed by RESX.
1922 Such BBs are kept around to make removal of dead stores possible with
1923 presence of EH and will be optimized out by optimize_clobbers later in the
1924 game.
1925
1926 NEED_EH is used to recurse in case the clobber has non-EH predecestors
1927 that can be clobber only, too.. When it is false, the RESX is not necessary
1928 on the end of basic block. */
1929
1930static bool
1931clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
1932{
1933 gimple_stmt_iterator gsi = gsi_last_bb (bb);
1934 edge_iterator ei;
1935 edge e;
1936
1937 if (need_eh)
1938 {
1939 if (gsi_end_p (gsi))
1940 return false;
1941 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_RESX)
1942 return false;
1943 gsi_prev (&gsi);
1944 }
1945 else if (!single_succ_p (bb))
1946 return false;
1947
1948 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
1949 {
1950 gimple *stmt = gsi_stmt (gsi);
1951 if (is_gimple_debug (stmt))
1952 continue;
1953 if (gimple_clobber_p (stmt))
1954 continue;
1955 if (gimple_code (stmt) == GIMPLE_LABEL)
1956 break;
1957 return false;
1958 }
1959
1960 /* See if all predecestors are either throws or clobber only BBs. */
1961 FOR_EACH_EDGE (e, ei, bb->preds)
1962 if (!(e->flags & EDGE_EH)
1963 && !clobber_only_eh_bb_p (e->src, false))
1964 return false;
1965
1966 return true;
1967}
1968
1969/* Return true if STMT compute a floating point expression that may be affected
1970 by -ffast-math and similar flags. */
1971
1972static bool
1973fp_expression_p (gimple *stmt)
1974{
1975 ssa_op_iter i;
1976 tree op;
1977
1978 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
1979 if (FLOAT_TYPE_P (TREE_TYPE (op)))
1980 return true;
1981 return false;
1982}
1983
0bceb671
JH
1984/* Analyze function body for NODE.
1985 EARLY indicates run from early optimization pipeline. */
27d020cf
JH
1986
1987static void
0bceb671 1988analyze_function_body (struct cgraph_node *node, bool early)
27d020cf 1989{
f256c274 1990 sreal time = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME);
27d020cf 1991 /* Estimate static overhead for function prologue/epilogue and alignment. */
f256c274 1992 int size = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS);
27d020cf
JH
1993 /* Benefits are scaled by probability of elimination that is in range
1994 <0,2>. */
1995 basic_block bb;
1996 struct function *my_function = DECL_STRUCT_FUNCTION (node->decl);
b71289b1 1997 sreal freq;
99353fcf 1998 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
27d020cf
JH
1999 predicate bb_predicate;
2000 struct ipa_func_body_info fbi;
2001 vec<predicate> nonconstant_names = vNULL;
2002 int nblocks, n;
2003 int *order;
2004 predicate array_index = true;
2005 gimple *fix_builtin_expect_stmt;
2006
2007 gcc_assert (my_function && my_function->cfg);
2008 gcc_assert (cfun == my_function);
2009
2010 memset(&fbi, 0, sizeof(fbi));
ddfb1317 2011 vec_free (info->conds);
27d020cf 2012 info->conds = NULL;
ddfb1317 2013 vec_free (info->size_time_table);
27d020cf
JH
2014 info->size_time_table = NULL;
2015
2016 /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
2017 so we can produce proper inline hints.
2018
2019 When optimizing and analyzing for early inliner, initialize node params
2020 so we can produce correct BB predicates. */
2021
2022 if (opt_for_fn (node->decl, optimize))
2023 {
2024 calculate_dominance_info (CDI_DOMINATORS);
2025 if (!early)
2026 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
2027 else
2028 {
2029 ipa_check_create_node_params ();
2030 ipa_initialize_node_params (node);
2031 }
2032
2033 if (ipa_node_params_sum)
2034 {
2035 fbi.node = node;
2036 fbi.info = IPA_NODE_REF (node);
2037 fbi.bb_infos = vNULL;
2038 fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
c628d1c3
MJ
2039 fbi.param_count = count_formal_params (node->decl);
2040 fbi.aa_walk_budget = PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
2041
27d020cf
JH
2042 nonconstant_names.safe_grow_cleared
2043 (SSANAMES (my_function)->length ());
2044 }
2045 }
2046
2047 if (dump_file)
2048 fprintf (dump_file, "\nAnalyzing function body size: %s\n",
2049 node->name ());
2050
2051 /* When we run into maximal number of entries, we assign everything to the
2052 constant truth case. Be sure to have it in list. */
2053 bb_predicate = true;
2054 info->account_size_time (0, 0, bb_predicate, bb_predicate);
2055
2056 bb_predicate = predicate::not_inlined ();
d06f73a3
JH
2057 info->account_size_time (PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS)
2058 * ipa_fn_summary::size_scale,
2059 PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME),
2060 bb_predicate,
27d020cf
JH
2061 bb_predicate);
2062
2063 if (fbi.info)
2064 compute_bb_predicates (&fbi, node, info);
2065 order = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
2066 nblocks = pre_and_rev_post_order_compute (NULL, order, false);
2067 for (n = 0; n < nblocks; n++)
2068 {
2069 bb = BASIC_BLOCK_FOR_FN (cfun, order[n]);
b71289b1 2070 freq = bb->count.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count);
27d020cf
JH
2071 if (clobber_only_eh_bb_p (bb))
2072 {
2073 if (dump_file && (dump_flags & TDF_DETAILS))
2074 fprintf (dump_file, "\n Ignoring BB %i;"
2075 " it will be optimized away by cleanup_clobbers\n",
2076 bb->index);
2077 continue;
2078 }
2079
2080 /* TODO: Obviously predicates can be propagated down across CFG. */
2081 if (fbi.info)
2082 {
2083 if (bb->aux)
2084 bb_predicate = *(predicate *) bb->aux;
2085 else
2086 bb_predicate = false;
2087 }
2088 else
2089 bb_predicate = true;
2090
2091 if (dump_file && (dump_flags & TDF_DETAILS))
2092 {
2093 fprintf (dump_file, "\n BB %i predicate:", bb->index);
2094 bb_predicate.dump (dump_file, info->conds);
2095 }
2096
2097 if (fbi.info && nonconstant_names.exists ())
2098 {
2099 predicate phi_predicate;
2100 bool first_phi = true;
2101
2102 for (gphi_iterator bsi = gsi_start_phis (bb); !gsi_end_p (bsi);
2103 gsi_next (&bsi))
2104 {
2105 if (first_phi
c628d1c3 2106 && !phi_result_unknown_predicate (&fbi, info, bb,
27d020cf
JH
2107 &phi_predicate,
2108 nonconstant_names))
2109 break;
2110 first_phi = false;
2111 if (dump_file && (dump_flags & TDF_DETAILS))
2112 {
2113 fprintf (dump_file, " ");
2114 print_gimple_stmt (dump_file, gsi_stmt (bsi), 0);
2115 }
2116 predicate_for_phi_result (info, bsi.phi (), &phi_predicate,
2117 nonconstant_names);
2118 }
2119 }
2120
2121 fix_builtin_expect_stmt = find_foldable_builtin_expect (bb);
2122
2123 for (gimple_stmt_iterator bsi = gsi_start_bb (bb); !gsi_end_p (bsi);
2124 gsi_next (&bsi))
2125 {
2126 gimple *stmt = gsi_stmt (bsi);
2127 int this_size = estimate_num_insns (stmt, &eni_size_weights);
2128 int this_time = estimate_num_insns (stmt, &eni_time_weights);
2129 int prob;
2130 predicate will_be_nonconstant;
2131
2132 /* This relation stmt should be folded after we remove
2133 buildin_expect call. Adjust the cost here. */
2134 if (stmt == fix_builtin_expect_stmt)
2135 {
2136 this_size--;
2137 this_time--;
2138 }
2139
2140 if (dump_file && (dump_flags & TDF_DETAILS))
2141 {
2142 fprintf (dump_file, " ");
2143 print_gimple_stmt (dump_file, stmt, 0);
2144 fprintf (dump_file, "\t\tfreq:%3.2f size:%3i time:%3i\n",
b71289b1 2145 freq.to_double (), this_size,
27d020cf
JH
2146 this_time);
2147 }
2148
2149 if (gimple_assign_load_p (stmt) && nonconstant_names.exists ())
2150 {
2151 predicate this_array_index;
2152 this_array_index =
2153 array_index_predicate (info, nonconstant_names,
2154 gimple_assign_rhs1 (stmt));
2155 if (this_array_index != false)
2156 array_index &= this_array_index;
2157 }
2158 if (gimple_store_p (stmt) && nonconstant_names.exists ())
2159 {
2160 predicate this_array_index;
2161 this_array_index =
2162 array_index_predicate (info, nonconstant_names,
2163 gimple_get_lhs (stmt));
2164 if (this_array_index != false)
2165 array_index &= this_array_index;
2166 }
2167
2168
2169 if (is_gimple_call (stmt)
2170 && !gimple_call_internal_p (stmt))
2171 {
2172 struct cgraph_edge *edge = node->get_edge (stmt);
99353fcf 2173 ipa_call_summary *es = ipa_call_summaries->get_create (edge);
27d020cf
JH
2174
2175 /* Special case: results of BUILT_IN_CONSTANT_P will be always
2176 resolved as constant. We however don't want to optimize
2177 out the cgraph edges. */
2178 if (nonconstant_names.exists ()
2179 && gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P)
2180 && gimple_call_lhs (stmt)
2181 && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME)
2182 {
2183 predicate false_p = false;
2184 nonconstant_names[SSA_NAME_VERSION (gimple_call_lhs (stmt))]
2185 = false_p;
2186 }
2187 if (ipa_node_params_sum)
2188 {
2189 int count = gimple_call_num_args (stmt);
2190 int i;
2191
2192 if (count)
2193 es->param.safe_grow_cleared (count);
2194 for (i = 0; i < count; i++)
2195 {
c628d1c3 2196 int prob = param_change_prob (&fbi, stmt, i);
27d020cf
JH
2197 gcc_assert (prob >= 0 && prob <= REG_BR_PROB_BASE);
2198 es->param[i].change_prob = prob;
2199 }
2200 }
2201
2202 es->call_stmt_size = this_size;
2203 es->call_stmt_time = this_time;
2204 es->loop_depth = bb_loop_depth (bb);
2205 edge_set_predicate (edge, &bb_predicate);
959b8c82
JH
2206 if (edge->speculative)
2207 {
2208 cgraph_edge *direct, *indirect;
2209 ipa_ref *ref;
2210 edge->speculative_call_info (direct, indirect, ref);
2211 gcc_assert (direct == edge);
2212 ipa_call_summary *es2
2213 = ipa_call_summaries->get_create (indirect);
2214 ipa_call_summaries->duplicate (edge, indirect,
2215 es, es2);
2216 }
27d020cf
JH
2217 }
2218
2219 /* TODO: When conditional jump or swithc is known to be constant, but
2220 we did not translate it into the predicates, we really can account
2221 just maximum of the possible paths. */
2222 if (fbi.info)
2223 will_be_nonconstant
2224 = will_be_nonconstant_predicate (&fbi, info,
2225 stmt, nonconstant_names);
2226 else
2227 will_be_nonconstant = true;
2228 if (this_time || this_size)
2229 {
b71289b1 2230 sreal final_time = (sreal)this_time * freq;
27d020cf 2231
c628d1c3 2232 prob = eliminated_by_inlining_prob (&fbi, stmt);
27d020cf
JH
2233 if (prob == 1 && dump_file && (dump_flags & TDF_DETAILS))
2234 fprintf (dump_file,
2235 "\t\t50%% will be eliminated by inlining\n");
2236 if (prob == 2 && dump_file && (dump_flags & TDF_DETAILS))
2237 fprintf (dump_file, "\t\tWill be eliminated by inlining\n");
2238
2239 struct predicate p = bb_predicate & will_be_nonconstant;
2240
2241 /* We can ignore statement when we proved it is never going
67914693 2242 to happen, but we cannot do that for call statements
27d020cf
JH
2243 because edges are accounted specially. */
2244
2245 if (*(is_gimple_call (stmt) ? &bb_predicate : &p) != false)
2246 {
b71289b1 2247 time += final_time;
27d020cf
JH
2248 size += this_size;
2249 }
2250
2251 /* We account everything but the calls. Calls have their own
2252 size/time info attached to cgraph edges. This is necessary
2253 in order to make the cost disappear after inlining. */
2254 if (!is_gimple_call (stmt))
2255 {
2256 if (prob)
2257 {
2258 predicate ip = bb_predicate & predicate::not_inlined ();
2259 info->account_size_time (this_size * prob,
121356b0 2260 (final_time * prob) / 2, ip,
27d020cf
JH
2261 p);
2262 }
2263 if (prob != 2)
2264 info->account_size_time (this_size * (2 - prob),
121356b0 2265 (final_time * (2 - prob) / 2),
27d020cf
JH
2266 bb_predicate,
2267 p);
2268 }
2269
2270 if (!info->fp_expressions && fp_expression_p (stmt))
2271 {
2272 info->fp_expressions = true;
2273 if (dump_file)
2274 fprintf (dump_file, " fp_expression set\n");
2275 }
2276
2277 gcc_assert (time >= 0);
2278 gcc_assert (size >= 0);
2279 }
2280 }
2281 }
99353fcf
ML
2282 set_hint_predicate (&ipa_fn_summaries->get_create (node)->array_index,
2283 array_index);
27d020cf
JH
2284 free (order);
2285
2286 if (nonconstant_names.exists () && !early)
2287 {
2288 struct loop *loop;
2289 predicate loop_iterations = true;
2290 predicate loop_stride = true;
2291
2292 if (dump_file && (dump_flags & TDF_DETAILS))
2293 flow_loops_dump (dump_file, NULL, 0);
2294 scev_initialize ();
2295 FOR_EACH_LOOP (loop, 0)
2296 {
2297 vec<edge> exits;
2298 edge ex;
2299 unsigned int j;
2300 struct tree_niter_desc niter_desc;
2301 bb_predicate = *(predicate *) loop->header->aux;
2302
2303 exits = get_loop_exit_edges (loop);
2304 FOR_EACH_VEC_ELT (exits, j, ex)
2305 if (number_of_iterations_exit (loop, ex, &niter_desc, false)
2306 && !is_gimple_min_invariant (niter_desc.niter))
2307 {
2308 predicate will_be_nonconstant
c628d1c3 2309 = will_be_nonconstant_expr_predicate (&fbi, info,
27d020cf
JH
2310 niter_desc.niter,
2311 nonconstant_names);
2312 if (will_be_nonconstant != true)
2313 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2314 if (will_be_nonconstant != true
2315 && will_be_nonconstant != false)
2316 /* This is slightly inprecise. We may want to represent each
2317 loop with independent predicate. */
2318 loop_iterations &= will_be_nonconstant;
2319 }
2320 exits.release ();
2321 }
2322
2323 /* To avoid quadratic behavior we analyze stride predicates only
2324 with respect to the containing loop. Thus we simply iterate
2325 over all defs in the outermost loop body. */
2326 for (loop = loops_for_fn (cfun)->tree_root->inner;
2327 loop != NULL; loop = loop->next)
2328 {
2329 basic_block *body = get_loop_body (loop);
2330 for (unsigned i = 0; i < loop->num_nodes; i++)
2331 {
2332 gimple_stmt_iterator gsi;
2333 bb_predicate = *(predicate *) body[i]->aux;
2334 for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi);
2335 gsi_next (&gsi))
2336 {
2337 gimple *stmt = gsi_stmt (gsi);
2338
2339 if (!is_gimple_assign (stmt))
2340 continue;
2341
2342 tree def = gimple_assign_lhs (stmt);
2343 if (TREE_CODE (def) != SSA_NAME)
2344 continue;
2345
2346 affine_iv iv;
2347 if (!simple_iv (loop_containing_stmt (stmt),
2348 loop_containing_stmt (stmt),
2349 def, &iv, true)
2350 || is_gimple_min_invariant (iv.step))
2351 continue;
2352
2353 predicate will_be_nonconstant
c628d1c3 2354 = will_be_nonconstant_expr_predicate (&fbi, info, iv.step,
27d020cf
JH
2355 nonconstant_names);
2356 if (will_be_nonconstant != true)
2357 will_be_nonconstant = bb_predicate & will_be_nonconstant;
2358 if (will_be_nonconstant != true
2359 && will_be_nonconstant != false)
2360 /* This is slightly inprecise. We may want to represent
2361 each loop with independent predicate. */
2362 loop_stride = loop_stride & will_be_nonconstant;
2363 }
2364 }
2365 free (body);
2366 }
56f62793 2367 ipa_fn_summary *s = ipa_fn_summaries->get (node);
cf9b0b5f
ML
2368 set_hint_predicate (&s->loop_iterations, loop_iterations);
2369 set_hint_predicate (&s->loop_stride, loop_stride);
27d020cf
JH
2370 scev_finalize ();
2371 }
2372 FOR_ALL_BB_FN (bb, my_function)
2373 {
2374 edge e;
2375 edge_iterator ei;
2376
2377 if (bb->aux)
2378 edge_predicate_pool.remove ((predicate *)bb->aux);
2379 bb->aux = NULL;
2380 FOR_EACH_EDGE (e, ei, bb->succs)
2381 {
2382 if (e->aux)
2383 edge_predicate_pool.remove ((predicate *) e->aux);
2384 e->aux = NULL;
2385 }
2386 }
56f62793 2387 ipa_fn_summary *s = ipa_fn_summaries->get (node);
cf9b0b5f
ML
2388 s->time = time;
2389 s->self_size = size;
27d020cf
JH
2390 nonconstant_names.release ();
2391 ipa_release_body_info (&fbi);
2392 if (opt_for_fn (node->decl, optimize))
2393 {
2394 if (!early)
2395 loop_optimizer_finalize ();
2396 else if (!ipa_edge_args_sum)
2397 ipa_free_all_node_params ();
2398 free_dominance_info (CDI_DOMINATORS);
2399 }
2400 if (dump_file)
2401 {
2402 fprintf (dump_file, "\n");
0bceb671 2403 ipa_dump_fn_summary (dump_file, node);
27d020cf
JH
2404 }
2405}
2406
2407
0bceb671
JH
2408/* Compute function summary.
2409 EARLY is true when we compute parameters during early opts. */
27d020cf
JH
2410
2411void
0bceb671 2412compute_fn_summary (struct cgraph_node *node, bool early)
27d020cf
JH
2413{
2414 HOST_WIDE_INT self_stack_size;
2415 struct cgraph_edge *e;
0bceb671 2416 struct ipa_fn_summary *info;
27d020cf
JH
2417
2418 gcc_assert (!node->global.inlined_to);
2419
0bceb671
JH
2420 if (!ipa_fn_summaries)
2421 ipa_fn_summary_alloc ();
27d020cf 2422
56f62793
ML
2423 /* Create a new ipa_fn_summary. */
2424 ((ipa_fn_summary_t *)ipa_fn_summaries)->remove_callees (node);
2425 ipa_fn_summaries->remove (node);
99353fcf 2426 info = ipa_fn_summaries->get_create (node);
27d020cf
JH
2427
2428 /* Estimate the stack size for the function if we're optimizing. */
2429 self_stack_size = optimize && !node->thunk.thunk_p
2430 ? estimated_stack_frame_size (node) : 0;
2431 info->estimated_self_stack_size = self_stack_size;
2432 info->estimated_stack_size = self_stack_size;
2433 info->stack_frame_offset = 0;
2434
2435 if (node->thunk.thunk_p)
2436 {
99353fcf 2437 ipa_call_summary *es = ipa_call_summaries->get_create (node->callees);
27d020cf
JH
2438 predicate t = true;
2439
2440 node->local.can_change_signature = false;
2441 es->call_stmt_size = eni_size_weights.call_cost;
2442 es->call_stmt_time = eni_time_weights.call_cost;
d06f73a3
JH
2443 info->account_size_time (ipa_fn_summary::size_scale
2444 * PARAM_VALUE
2445 (PARAM_UNINLINED_FUNCTION_THUNK_INSNS),
2446 PARAM_VALUE
2447 (PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);
27d020cf 2448 t = predicate::not_inlined ();
0bceb671
JH
2449 info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
2450 ipa_update_overall_fn_summary (node);
27d020cf 2451 info->self_size = info->size;
67914693 2452 /* We cannot inline instrumentation clones. */
27d020cf
JH
2453 if (node->thunk.add_pointer_bounds_args)
2454 {
2455 info->inlinable = false;
2456 node->callees->inline_failed = CIF_CHKP;
2457 }
ca04a532
ML
2458 else if (stdarg_p (TREE_TYPE (node->decl)))
2459 {
2460 info->inlinable = false;
2461 node->callees->inline_failed = CIF_VARIADIC_THUNK;
2462 }
27d020cf
JH
2463 else
2464 info->inlinable = true;
2465 }
2466 else
2467 {
2468 /* Even is_gimple_min_invariant rely on current_function_decl. */
2469 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2470
2471 /* Can this function be inlined at all? */
2472 if (!opt_for_fn (node->decl, optimize)
2473 && !lookup_attribute ("always_inline",
2474 DECL_ATTRIBUTES (node->decl)))
2475 info->inlinable = false;
2476 else
2477 info->inlinable = tree_inlinable_function_p (node->decl);
2478
27d020cf 2479 /* Type attributes can use parameter indices to describe them. */
3d8fb311
JJ
2480 if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl))
2481 /* Likewise for #pragma omp declare simd functions or functions
2482 with simd attribute. */
2483 || lookup_attribute ("omp declare simd",
2484 DECL_ATTRIBUTES (node->decl)))
27d020cf
JH
2485 node->local.can_change_signature = false;
2486 else
2487 {
2488 /* Otherwise, inlinable functions always can change signature. */
2489 if (info->inlinable)
2490 node->local.can_change_signature = true;
2491 else
2492 {
67914693 2493 /* Functions calling builtin_apply cannot change signature. */
27d020cf
JH
2494 for (e = node->callees; e; e = e->next_callee)
2495 {
2496 tree cdecl = e->callee->decl;
3d78e008
ML
2497 if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS)
2498 || fndecl_built_in_p (cdecl, BUILT_IN_VA_START))
27d020cf
JH
2499 break;
2500 }
2501 node->local.can_change_signature = !e;
2502 }
2503 }
2504 /* Functions called by instrumentation thunk can't change signature
2505 because instrumentation thunk modification is not supported. */
2506 if (node->local.can_change_signature)
2507 for (e = node->callers; e; e = e->next_caller)
2508 if (e->caller->thunk.thunk_p
2509 && e->caller->thunk.add_pointer_bounds_args)
2510 {
2511 node->local.can_change_signature = false;
2512 break;
2513 }
0bceb671 2514 analyze_function_body (node, early);
27d020cf
JH
2515 pop_cfun ();
2516 }
2517 for (e = node->callees; e; e = e->next_callee)
2518 if (e->callee->comdat_local_p ())
2519 break;
2520 node->calls_comdat_local = (e != NULL);
2521
2522 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
2523 info->size = info->self_size;
2524 info->stack_frame_offset = 0;
2525 info->estimated_stack_size = info->estimated_self_stack_size;
2526
2527 /* Code above should compute exactly the same result as
0bceb671 2528 ipa_update_overall_fn_summary but because computation happens in
27d020cf 2529 different order the roundoff errors result in slight changes. */
0bceb671 2530 ipa_update_overall_fn_summary (node);
959b8c82
JH
2531 /* In LTO mode we may have speculative edges set. */
2532 gcc_assert (in_lto_p || info->size == info->self_size);
27d020cf
JH
2533}
2534
2535
2536/* Compute parameters of functions used by inliner using
2537 current_function_decl. */
2538
2539static unsigned int
0bceb671 2540compute_fn_summary_for_current (void)
27d020cf 2541{
0bceb671 2542 compute_fn_summary (cgraph_node::get (current_function_decl), true);
27d020cf
JH
2543 return 0;
2544}
2545
27d020cf
JH
2546/* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS,
2547 KNOWN_CONTEXTS and KNOWN_AGGS. */
2548
2549static bool
2550estimate_edge_devirt_benefit (struct cgraph_edge *ie,
2551 int *size, int *time,
2552 vec<tree> known_vals,
2553 vec<ipa_polymorphic_call_context> known_contexts,
2554 vec<ipa_agg_jump_function_p> known_aggs)
2555{
2556 tree target;
2557 struct cgraph_node *callee;
0bceb671 2558 struct ipa_fn_summary *isummary;
27d020cf
JH
2559 enum availability avail;
2560 bool speculative;
2561
2562 if (!known_vals.exists () && !known_contexts.exists ())
2563 return false;
2564 if (!opt_for_fn (ie->caller->decl, flag_indirect_inlining))
2565 return false;
2566
2567 target = ipa_get_indirect_edge_target (ie, known_vals, known_contexts,
2568 known_aggs, &speculative);
2569 if (!target || speculative)
2570 return false;
2571
2572 /* Account for difference in cost between indirect and direct calls. */
2573 *size -= (eni_size_weights.indirect_call_cost - eni_size_weights.call_cost);
2574 *time -= (eni_time_weights.indirect_call_cost - eni_time_weights.call_cost);
2575 gcc_checking_assert (*time >= 0);
2576 gcc_checking_assert (*size >= 0);
2577
2578 callee = cgraph_node::get (target);
2579 if (!callee || !callee->definition)
2580 return false;
2581 callee = callee->function_symbol (&avail);
2582 if (avail < AVAIL_AVAILABLE)
2583 return false;
56f62793 2584 isummary = ipa_fn_summaries->get (callee);
1d546c60
ML
2585 if (isummary == NULL)
2586 return false;
2587
27d020cf
JH
2588 return isummary->inlinable;
2589}
2590
2591/* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
2592 handle edge E with probability PROB.
2593 Set HINTS if edge may be devirtualized.
2594 KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS describe context of the call
2595 site. */
2596
2597static inline void
2598estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
2599 sreal *time,
2600 int prob,
2601 vec<tree> known_vals,
2602 vec<ipa_polymorphic_call_context> known_contexts,
2603 vec<ipa_agg_jump_function_p> known_aggs,
0bceb671 2604 ipa_hints *hints)
27d020cf 2605{
56f62793 2606 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
2607 int call_size = es->call_stmt_size;
2608 int call_time = es->call_stmt_time;
2609 int cur_size;
2610 if (!e->callee
2611 && estimate_edge_devirt_benefit (e, &call_size, &call_time,
2612 known_vals, known_contexts, known_aggs)
2613 && hints && e->maybe_hot_p ())
2614 *hints |= INLINE_HINT_indirect_call;
0bceb671 2615 cur_size = call_size * ipa_fn_summary::size_scale;
27d020cf
JH
2616 *size += cur_size;
2617 if (min_size)
2618 *min_size += cur_size;
2619 if (prob == REG_BR_PROB_BASE)
41f0e819 2620 *time += ((sreal)call_time) * e->sreal_frequency ();
27d020cf 2621 else
30632c7a 2622 *time += ((sreal)call_time * prob) * e->sreal_frequency ();
27d020cf
JH
2623}
2624
2625
2626
2627/* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
2628 calls in NODE. POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2629 describe context of the call site. */
2630
2631static void
2632estimate_calls_size_and_time (struct cgraph_node *node, int *size,
2633 int *min_size, sreal *time,
0bceb671 2634 ipa_hints *hints,
27d020cf
JH
2635 clause_t possible_truths,
2636 vec<tree> known_vals,
2637 vec<ipa_polymorphic_call_context> known_contexts,
2638 vec<ipa_agg_jump_function_p> known_aggs)
2639{
2640 struct cgraph_edge *e;
2641 for (e = node->callees; e; e = e->next_callee)
2642 {
99353fcf 2643 struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
27d020cf
JH
2644
2645 /* Do not care about zero sized builtins. */
2646 if (e->inline_failed && !es->call_stmt_size)
2647 {
2648 gcc_checking_assert (!es->call_stmt_time);
2649 continue;
2650 }
2651 if (!es->predicate
2652 || es->predicate->evaluate (possible_truths))
2653 {
2654 if (e->inline_failed)
2655 {
2656 /* Predicates of calls shall not use NOT_CHANGED codes,
2657 sowe do not need to compute probabilities. */
2658 estimate_edge_size_and_time (e, size,
2659 es->predicate ? NULL : min_size,
2660 time, REG_BR_PROB_BASE,
2661 known_vals, known_contexts,
2662 known_aggs, hints);
2663 }
2664 else
2665 estimate_calls_size_and_time (e->callee, size, min_size, time,
2666 hints,
2667 possible_truths,
2668 known_vals, known_contexts,
2669 known_aggs);
2670 }
2671 }
2672 for (e = node->indirect_calls; e; e = e->next_callee)
2673 {
99353fcf 2674 struct ipa_call_summary *es = ipa_call_summaries->get_create (e);
27d020cf
JH
2675 if (!es->predicate
2676 || es->predicate->evaluate (possible_truths))
2677 estimate_edge_size_and_time (e, size,
2678 es->predicate ? NULL : min_size,
2679 time, REG_BR_PROB_BASE,
2680 known_vals, known_contexts, known_aggs,
2681 hints);
2682 }
2683}
2684
2685
2686/* Estimate size and time needed to execute NODE assuming
2687 POSSIBLE_TRUTHS clause, and KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
2688 information about NODE's arguments. If non-NULL use also probability
2689 information present in INLINE_PARAM_SUMMARY vector.
2690 Additionally detemine hints determined by the context. Finally compute
2691 minimal size needed for the call that is independent on the call context and
2692 can be used for fast estimates. Return the values in RET_SIZE,
2693 RET_MIN_SIZE, RET_TIME and RET_HINTS. */
2694
2695void
2696estimate_node_size_and_time (struct cgraph_node *node,
2697 clause_t possible_truths,
2698 clause_t nonspec_possible_truths,
2699 vec<tree> known_vals,
2700 vec<ipa_polymorphic_call_context> known_contexts,
2701 vec<ipa_agg_jump_function_p> known_aggs,
2702 int *ret_size, int *ret_min_size,
2703 sreal *ret_time,
2704 sreal *ret_nonspecialized_time,
0bceb671 2705 ipa_hints *ret_hints,
27d020cf
JH
2706 vec<inline_param_summary>
2707 inline_param_summary)
2708{
99353fcf 2709 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
27d020cf
JH
2710 size_time_entry *e;
2711 int size = 0;
2712 sreal time = 0;
2713 int min_size = 0;
0bceb671 2714 ipa_hints hints = 0;
27d020cf
JH
2715 int i;
2716
2717 if (dump_file && (dump_flags & TDF_DETAILS))
2718 {
2719 bool found = false;
2720 fprintf (dump_file, " Estimating body: %s/%i\n"
2721 " Known to be false: ", node->name (),
2722 node->order);
2723
2724 for (i = predicate::not_inlined_condition;
2725 i < (predicate::first_dynamic_condition
2726 + (int) vec_safe_length (info->conds)); i++)
2727 if (!(possible_truths & (1 << i)))
2728 {
2729 if (found)
2730 fprintf (dump_file, ", ");
2731 found = true;
2732 dump_condition (dump_file, info->conds, i);
2733 }
2734 }
2735
2736 estimate_calls_size_and_time (node, &size, &min_size, &time, &hints, possible_truths,
2737 known_vals, known_contexts, known_aggs);
2738 sreal nonspecialized_time = time;
2739
2740 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
2741 {
27d020cf 2742 bool exec = e->exec_predicate.evaluate (nonspec_possible_truths);
3494e738
JH
2743
2744 /* Because predicates are conservative, it can happen that nonconst is 1
2745 but exec is 0. */
27d020cf
JH
2746 if (exec)
2747 {
3494e738
JH
2748 bool nonconst = e->nonconst_predicate.evaluate (possible_truths);
2749
27d020cf
JH
2750 gcc_checking_assert (e->time >= 0);
2751 gcc_checking_assert (time >= 0);
2752
2753 /* We compute specialized size only because size of nonspecialized
2754 copy is context independent.
2755
2756 The difference between nonspecialized execution and specialized is
2757 that nonspecialized is not going to have optimized out computations
2758 known to be constant in a specialized setting. */
2759 if (nonconst)
2760 size += e->size;
2761 nonspecialized_time += e->time;
2762 if (!nonconst)
2763 ;
2764 else if (!inline_param_summary.exists ())
2765 {
2766 if (nonconst)
2767 time += e->time;
2768 }
2769 else
2770 {
2771 int prob = e->nonconst_predicate.probability
2772 (info->conds, possible_truths,
2773 inline_param_summary);
2774 gcc_checking_assert (prob >= 0);
2775 gcc_checking_assert (prob <= REG_BR_PROB_BASE);
2776 time += e->time * prob / REG_BR_PROB_BASE;
2777 }
2778 gcc_checking_assert (time >= 0);
2779 }
2780 }
2781 gcc_checking_assert ((*info->size_time_table)[0].exec_predicate == true);
2782 gcc_checking_assert ((*info->size_time_table)[0].nonconst_predicate == true);
2783 min_size = (*info->size_time_table)[0].size;
2784 gcc_checking_assert (size >= 0);
2785 gcc_checking_assert (time >= 0);
2786 /* nonspecialized_time should be always bigger than specialized time.
2787 Roundoff issues however may get into the way. */
59d27026 2788 gcc_checking_assert ((nonspecialized_time - time * 99 / 100) >= -1);
27d020cf
JH
2789
2790 /* Roundoff issues may make specialized time bigger than nonspecialized
2791 time. We do not really want that to happen because some heurstics
2792 may get confused by seeing negative speedups. */
2793 if (time > nonspecialized_time)
2794 time = nonspecialized_time;
2795
2796 if (info->loop_iterations
2797 && !info->loop_iterations->evaluate (possible_truths))
2798 hints |= INLINE_HINT_loop_iterations;
2799 if (info->loop_stride
2800 && !info->loop_stride->evaluate (possible_truths))
2801 hints |= INLINE_HINT_loop_stride;
2802 if (info->array_index
2803 && !info->array_index->evaluate (possible_truths))
2804 hints |= INLINE_HINT_array_index;
2805 if (info->scc_no)
2806 hints |= INLINE_HINT_in_scc;
2807 if (DECL_DECLARED_INLINE_P (node->decl))
2808 hints |= INLINE_HINT_declared_inline;
2809
0bceb671
JH
2810 size = RDIV (size, ipa_fn_summary::size_scale);
2811 min_size = RDIV (min_size, ipa_fn_summary::size_scale);
27d020cf
JH
2812
2813 if (dump_file && (dump_flags & TDF_DETAILS))
2814 fprintf (dump_file, "\n size:%i time:%f nonspec time:%f\n", (int) size,
2815 time.to_double (), nonspecialized_time.to_double ());
2816 if (ret_time)
2817 *ret_time = time;
2818 if (ret_nonspecialized_time)
2819 *ret_nonspecialized_time = nonspecialized_time;
2820 if (ret_size)
2821 *ret_size = size;
2822 if (ret_min_size)
2823 *ret_min_size = min_size;
2824 if (ret_hints)
2825 *ret_hints = hints;
2826 return;
2827}
2828
2829
2830/* Estimate size and time needed to execute callee of EDGE assuming that
2831 parameters known to be constant at caller of EDGE are propagated.
2832 KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
2833 and types for parameters. */
2834
2835void
2836estimate_ipcp_clone_size_and_time (struct cgraph_node *node,
2837 vec<tree> known_vals,
2838 vec<ipa_polymorphic_call_context>
2839 known_contexts,
2840 vec<ipa_agg_jump_function_p> known_aggs,
2841 int *ret_size, sreal *ret_time,
2842 sreal *ret_nonspec_time,
0bceb671 2843 ipa_hints *hints)
27d020cf
JH
2844{
2845 clause_t clause, nonspec_clause;
2846
2847 evaluate_conditions_for_known_args (node, false, known_vals, known_aggs,
2848 &clause, &nonspec_clause);
2849 estimate_node_size_and_time (node, clause, nonspec_clause,
2850 known_vals, known_contexts,
2851 known_aggs, ret_size, NULL, ret_time,
2852 ret_nonspec_time, hints, vNULL);
2853}
2854
2855
2856/* Update summary information of inline clones after inlining.
2857 Compute peak stack usage. */
2858
2859static void
2860inline_update_callee_summaries (struct cgraph_node *node, int depth)
2861{
2862 struct cgraph_edge *e;
56f62793
ML
2863 ipa_fn_summary *callee_info = ipa_fn_summaries->get (node);
2864 ipa_fn_summary *caller_info = ipa_fn_summaries->get (node->callers->caller);
27d020cf
JH
2865 HOST_WIDE_INT peak;
2866
2867 callee_info->stack_frame_offset
2868 = caller_info->stack_frame_offset
2869 + caller_info->estimated_self_stack_size;
2870 peak = callee_info->stack_frame_offset
2871 + callee_info->estimated_self_stack_size;
99353fcf 2872
56f62793 2873 ipa_fn_summary *s = ipa_fn_summaries->get (node->global.inlined_to);
99353fcf
ML
2874 if (s->estimated_stack_size < peak)
2875 s->estimated_stack_size = peak;
27d020cf
JH
2876 ipa_propagate_frequency (node);
2877 for (e = node->callees; e; e = e->next_callee)
2878 {
2879 if (!e->inline_failed)
2880 inline_update_callee_summaries (e->callee, depth);
56f62793 2881 ipa_call_summaries->get (e)->loop_depth += depth;
27d020cf
JH
2882 }
2883 for (e = node->indirect_calls; e; e = e->next_callee)
56f62793 2884 ipa_call_summaries->get (e)->loop_depth += depth;
27d020cf
JH
2885}
2886
2887/* Update change_prob of EDGE after INLINED_EDGE has been inlined.
2888 When functoin A is inlined in B and A calls C with parameter that
2889 changes with probability PROB1 and C is known to be passthroug
2890 of argument if B that change with probability PROB2, the probability
2891 of change is now PROB1*PROB2. */
2892
2893static void
2894remap_edge_change_prob (struct cgraph_edge *inlined_edge,
2895 struct cgraph_edge *edge)
2896{
2897 if (ipa_node_params_sum)
2898 {
2899 int i;
2900 struct ipa_edge_args *args = IPA_EDGE_REF (edge);
56f62793 2901 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf 2902 struct ipa_call_summary *inlined_es
56f62793 2903 = ipa_call_summaries->get (inlined_edge);
27d020cf 2904
8c02e054
JH
2905 if (es->param.length () == 0)
2906 return;
2907
27d020cf
JH
2908 for (i = 0; i < ipa_get_cs_argument_count (args); i++)
2909 {
2910 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
2911 if (jfunc->type == IPA_JF_PASS_THROUGH
2912 || jfunc->type == IPA_JF_ANCESTOR)
2913 {
2914 int id = jfunc->type == IPA_JF_PASS_THROUGH
2915 ? ipa_get_jf_pass_through_formal_id (jfunc)
2916 : ipa_get_jf_ancestor_formal_id (jfunc);
2917 if (id < (int) inlined_es->param.length ())
2918 {
2919 int prob1 = es->param[i].change_prob;
2920 int prob2 = inlined_es->param[id].change_prob;
2921 int prob = combine_probabilities (prob1, prob2);
2922
2923 if (prob1 && prob2 && !prob)
2924 prob = 1;
2925
2926 es->param[i].change_prob = prob;
2927 }
2928 }
2929 }
2930 }
2931}
2932
2933/* Update edge summaries of NODE after INLINED_EDGE has been inlined.
2934
2935 Remap predicates of callees of NODE. Rest of arguments match
2936 remap_predicate.
2937
2938 Also update change probabilities. */
2939
2940static void
2941remap_edge_summaries (struct cgraph_edge *inlined_edge,
2942 struct cgraph_node *node,
0bceb671
JH
2943 struct ipa_fn_summary *info,
2944 struct ipa_fn_summary *callee_info,
27d020cf
JH
2945 vec<int> operand_map,
2946 vec<int> offset_map,
2947 clause_t possible_truths,
2948 predicate *toplev_predicate)
2949{
2950 struct cgraph_edge *e, *next;
2951 for (e = node->callees; e; e = next)
2952 {
56f62793 2953 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
2954 predicate p;
2955 next = e->next_callee;
2956
2957 if (e->inline_failed)
2958 {
2959 remap_edge_change_prob (inlined_edge, e);
2960
2961 if (es->predicate)
2962 {
2963 p = es->predicate->remap_after_inlining
2964 (info, callee_info, operand_map,
2965 offset_map, possible_truths,
2966 *toplev_predicate);
2967 edge_set_predicate (e, &p);
2968 }
2969 else
2970 edge_set_predicate (e, toplev_predicate);
2971 }
2972 else
2973 remap_edge_summaries (inlined_edge, e->callee, info, callee_info,
2974 operand_map, offset_map, possible_truths,
2975 toplev_predicate);
2976 }
2977 for (e = node->indirect_calls; e; e = next)
2978 {
56f62793 2979 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
2980 predicate p;
2981 next = e->next_callee;
2982
2983 remap_edge_change_prob (inlined_edge, e);
2984 if (es->predicate)
2985 {
2986 p = es->predicate->remap_after_inlining
2987 (info, callee_info, operand_map, offset_map,
2988 possible_truths, *toplev_predicate);
2989 edge_set_predicate (e, &p);
2990 }
2991 else
2992 edge_set_predicate (e, toplev_predicate);
2993 }
2994}
2995
2996/* Same as remap_predicate, but set result into hint *HINT. */
2997
2998static void
0bceb671
JH
2999remap_hint_predicate (struct ipa_fn_summary *info,
3000 struct ipa_fn_summary *callee_info,
27d020cf
JH
3001 predicate **hint,
3002 vec<int> operand_map,
3003 vec<int> offset_map,
3004 clause_t possible_truths,
3005 predicate *toplev_predicate)
3006{
3007 predicate p;
3008
3009 if (!*hint)
3010 return;
3011 p = (*hint)->remap_after_inlining
3012 (info, callee_info,
3013 operand_map, offset_map,
3014 possible_truths, *toplev_predicate);
3015 if (p != false && p != true)
3016 {
3017 if (!*hint)
3018 set_hint_predicate (hint, p);
3019 else
3020 **hint &= p;
3021 }
3022}
3023
3024/* We inlined EDGE. Update summary of the function we inlined into. */
3025
3026void
0bceb671 3027ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
27d020cf 3028{
56f62793 3029 ipa_fn_summary *callee_info = ipa_fn_summaries->get (edge->callee);
27d020cf
JH
3030 struct cgraph_node *to = (edge->caller->global.inlined_to
3031 ? edge->caller->global.inlined_to : edge->caller);
56f62793 3032 struct ipa_fn_summary *info = ipa_fn_summaries->get (to);
27d020cf
JH
3033 clause_t clause = 0; /* not_inline is known to be false. */
3034 size_time_entry *e;
3035 vec<int> operand_map = vNULL;
3036 vec<int> offset_map = vNULL;
3037 int i;
3038 predicate toplev_predicate;
3039 predicate true_p = true;
56f62793 3040 struct ipa_call_summary *es = ipa_call_summaries->get (edge);
27d020cf
JH
3041
3042 if (es->predicate)
3043 toplev_predicate = *es->predicate;
3044 else
3045 toplev_predicate = true;
3046
3047 info->fp_expressions |= callee_info->fp_expressions;
3048
3049 if (callee_info->conds)
3050 evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL, NULL);
3051 if (ipa_node_params_sum && callee_info->conds)
3052 {
3053 struct ipa_edge_args *args = IPA_EDGE_REF (edge);
3054 int count = ipa_get_cs_argument_count (args);
3055 int i;
3056
3057 if (count)
3058 {
3059 operand_map.safe_grow_cleared (count);
3060 offset_map.safe_grow_cleared (count);
3061 }
3062 for (i = 0; i < count; i++)
3063 {
3064 struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
3065 int map = -1;
3066
3067 /* TODO: handle non-NOPs when merging. */
3068 if (jfunc->type == IPA_JF_PASS_THROUGH)
3069 {
3070 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3071 map = ipa_get_jf_pass_through_formal_id (jfunc);
3072 if (!ipa_get_jf_pass_through_agg_preserved (jfunc))
3073 offset_map[i] = -1;
3074 }
3075 else if (jfunc->type == IPA_JF_ANCESTOR)
3076 {
3077 HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc);
3078 if (offset >= 0 && offset < INT_MAX)
3079 {
3080 map = ipa_get_jf_ancestor_formal_id (jfunc);
3081 if (!ipa_get_jf_ancestor_agg_preserved (jfunc))
3082 offset = -1;
3083 offset_map[i] = offset;
3084 }
3085 }
3086 operand_map[i] = map;
3087 gcc_assert (map < ipa_get_param_count (IPA_NODE_REF (to)));
3088 }
3089 }
3090 for (i = 0; vec_safe_iterate (callee_info->size_time_table, i, &e); i++)
3091 {
3092 predicate p;
3093 p = e->exec_predicate.remap_after_inlining
3094 (info, callee_info, operand_map,
3095 offset_map, clause,
3096 toplev_predicate);
3097 predicate nonconstp;
3098 nonconstp = e->nonconst_predicate.remap_after_inlining
3099 (info, callee_info, operand_map,
3100 offset_map, clause,
3101 toplev_predicate);
3102 if (p != false && nonconstp != false)
3103 {
41f0e819 3104 sreal add_time = ((sreal)e->time * edge->sreal_frequency ());
27d020cf
JH
3105 int prob = e->nonconst_predicate.probability (callee_info->conds,
3106 clause, es->param);
3107 add_time = add_time * prob / REG_BR_PROB_BASE;
3108 if (prob != REG_BR_PROB_BASE
3109 && dump_file && (dump_flags & TDF_DETAILS))
3110 {
3111 fprintf (dump_file, "\t\tScaling time by probability:%f\n",
3112 (double) prob / REG_BR_PROB_BASE);
3113 }
3114 info->account_size_time (e->size, add_time, p, nonconstp);
3115 }
3116 }
3117 remap_edge_summaries (edge, edge->callee, info, callee_info, operand_map,
3118 offset_map, clause, &toplev_predicate);
3119 remap_hint_predicate (info, callee_info,
3120 &callee_info->loop_iterations,
3121 operand_map, offset_map, clause, &toplev_predicate);
3122 remap_hint_predicate (info, callee_info,
3123 &callee_info->loop_stride,
3124 operand_map, offset_map, clause, &toplev_predicate);
3125 remap_hint_predicate (info, callee_info,
3126 &callee_info->array_index,
3127 operand_map, offset_map, clause, &toplev_predicate);
3128
56f62793 3129 ipa_call_summary *s = ipa_call_summaries->get (edge);
99353fcf 3130 inline_update_callee_summaries (edge->callee, s->loop_depth);
27d020cf
JH
3131
3132 /* We do not maintain predicates of inlined edges, free it. */
3133 edge_set_predicate (edge, &true_p);
3134 /* Similarly remove param summaries. */
3135 es->param.release ();
3136 operand_map.release ();
3137 offset_map.release ();
3138}
3139
0bceb671 3140/* For performance reasons ipa_merge_fn_summary_after_inlining is not updating overall size
27d020cf
JH
3141 and time. Recompute it. */
3142
3143void
0bceb671 3144ipa_update_overall_fn_summary (struct cgraph_node *node)
27d020cf 3145{
99353fcf 3146 struct ipa_fn_summary *info = ipa_fn_summaries->get_create (node);
27d020cf
JH
3147 size_time_entry *e;
3148 int i;
3149
3150 info->size = 0;
3151 info->time = 0;
3152 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3153 {
3154 info->size += e->size;
3155 info->time += e->time;
3156 }
3157 estimate_calls_size_and_time (node, &info->size, &info->min_size,
3158 &info->time, NULL,
3159 ~(clause_t) (1 << predicate::false_condition),
3160 vNULL, vNULL, vNULL);
0bceb671 3161 info->size = (info->size + ipa_fn_summary::size_scale / 2) / ipa_fn_summary::size_scale;
27d020cf
JH
3162}
3163
3164
3165/* This function performs intraprocedural analysis in NODE that is required to
3166 inline indirect calls. */
3167
3168static void
3169inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
3170{
3171 ipa_analyze_node (node);
3172 if (dump_file && (dump_flags & TDF_DETAILS))
3173 {
3174 ipa_print_node_params (dump_file, node);
3175 ipa_print_node_jump_functions (dump_file, node);
3176 }
3177}
3178
3179
3180/* Note function body size. */
3181
3182void
3183inline_analyze_function (struct cgraph_node *node)
3184{
3185 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
3186
3187 if (dump_file)
3188 fprintf (dump_file, "\nAnalyzing function: %s/%u\n",
3189 node->name (), node->order);
3190 if (opt_for_fn (node->decl, optimize) && !node->thunk.thunk_p)
3191 inline_indirect_intraprocedural_analysis (node);
0bceb671 3192 compute_fn_summary (node, false);
27d020cf
JH
3193 if (!optimize)
3194 {
3195 struct cgraph_edge *e;
3196 for (e = node->callees; e; e = e->next_callee)
3197 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3198 for (e = node->indirect_calls; e; e = e->next_callee)
3199 e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
3200 }
3201
3202 pop_cfun ();
3203}
3204
3205
3206/* Called when new function is inserted to callgraph late. */
3207
3208void
0bceb671 3209ipa_fn_summary_t::insert (struct cgraph_node *node, ipa_fn_summary *)
27d020cf
JH
3210{
3211 inline_analyze_function (node);
3212}
3213
3214/* Note function body size. */
3215
d2db2e6b
JH
3216static void
3217ipa_fn_summary_generate (void)
27d020cf
JH
3218{
3219 struct cgraph_node *node;
3220
3221 FOR_EACH_DEFINED_FUNCTION (node)
3222 if (DECL_STRUCT_FUNCTION (node->decl))
0688f9c1 3223 node->local.versionable = tree_versionable_function_p (node->decl);
27d020cf 3224
0bceb671 3225 ipa_fn_summary_alloc ();
27d020cf 3226
0bceb671 3227 ipa_fn_summaries->enable_insertion_hook ();
27d020cf
JH
3228
3229 ipa_register_cgraph_hooks ();
27d020cf
JH
3230
3231 FOR_EACH_DEFINED_FUNCTION (node)
29f1e2b1
JH
3232 if (!node->alias
3233 && (flag_generate_lto || flag_generate_offload|| flag_wpa
3234 || opt_for_fn (node->decl, optimize)))
27d020cf
JH
3235 inline_analyze_function (node);
3236}
3237
3238
3239/* Write inline summary for edge E to OB. */
3240
3241static void
ddfb1317
JH
3242read_ipa_call_summary (struct lto_input_block *ib, struct cgraph_edge *e,
3243 bool prevails)
27d020cf 3244{
ddfb1317
JH
3245 struct ipa_call_summary *es = prevails
3246 ? ipa_call_summaries->get_create (e) : NULL;
27d020cf
JH
3247 predicate p;
3248 int length, i;
3249
ddfb1317
JH
3250 int size = streamer_read_uhwi (ib);
3251 int time = streamer_read_uhwi (ib);
3252 int depth = streamer_read_uhwi (ib);
3253
3254 if (es)
3255 {
3256 es->call_stmt_size = size;
3257 es->call_stmt_time = time;
3258 es->loop_depth = depth;
3259 }
0fab169b
PK
3260
3261 bitpack_d bp = streamer_read_bitpack (ib);
ddfb1317
JH
3262 if (es)
3263 es->is_return_callee_uncaptured = bp_unpack_value (&bp, 1);
3264 else
3265 bp_unpack_value (&bp, 1);
0fab169b 3266
27d020cf 3267 p.stream_in (ib);
ddfb1317
JH
3268 if (es)
3269 edge_set_predicate (e, &p);
27d020cf 3270 length = streamer_read_uhwi (ib);
ddfb1317 3271 if (length && es && e->possibly_call_in_translation_unit_p ())
27d020cf
JH
3272 {
3273 es->param.safe_grow_cleared (length);
3274 for (i = 0; i < length; i++)
3275 es->param[i].change_prob = streamer_read_uhwi (ib);
3276 }
ddfb1317
JH
3277 else
3278 {
3279 for (i = 0; i < length; i++)
3280 streamer_read_uhwi (ib);
3281 }
27d020cf
JH
3282}
3283
3284
3285/* Stream in inline summaries from the section. */
3286
3287static void
3288inline_read_section (struct lto_file_decl_data *file_data, const char *data,
3289 size_t len)
3290{
3291 const struct lto_function_header *header =
3292 (const struct lto_function_header *) data;
3293 const int cfg_offset = sizeof (struct lto_function_header);
3294 const int main_offset = cfg_offset + header->cfg_size;
3295 const int string_offset = main_offset + header->main_size;
3296 struct data_in *data_in;
3297 unsigned int i, count2, j;
3298 unsigned int f_count;
3299
3300 lto_input_block ib ((const char *) data + main_offset, header->main_size,
3301 file_data->mode_table);
3302
3303 data_in =
3304 lto_data_in_create (file_data, (const char *) data + string_offset,
3305 header->string_size, vNULL);
3306 f_count = streamer_read_uhwi (&ib);
3307 for (i = 0; i < f_count; i++)
3308 {
3309 unsigned int index;
3310 struct cgraph_node *node;
0bceb671 3311 struct ipa_fn_summary *info;
27d020cf
JH
3312 lto_symtab_encoder_t encoder;
3313 struct bitpack_d bp;
3314 struct cgraph_edge *e;
3315 predicate p;
3316
3317 index = streamer_read_uhwi (&ib);
3318 encoder = file_data->symtab_node_encoder;
3319 node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
3320 index));
ddfb1317 3321 info = node->prevailing_p () ? ipa_fn_summaries->get_create (node) : NULL;
27d020cf 3322
ddfb1317
JH
3323 int stack_size = streamer_read_uhwi (&ib);
3324 int size = streamer_read_uhwi (&ib);
3325 sreal time = sreal::stream_in (&ib);
3326
3327 if (info)
3328 {
3329 info->estimated_stack_size
3330 = info->estimated_self_stack_size = stack_size;
3331 info->size = info->self_size = size;
3332 info->time = time;
3333 }
27d020cf
JH
3334
3335 bp = streamer_read_bitpack (&ib);
ddfb1317
JH
3336 if (info)
3337 {
3338 info->inlinable = bp_unpack_value (&bp, 1);
3339 info->fp_expressions = bp_unpack_value (&bp, 1);
3340 }
3341 else
3342 {
3343 bp_unpack_value (&bp, 1);
3344 bp_unpack_value (&bp, 1);
3345 }
27d020cf
JH
3346
3347 count2 = streamer_read_uhwi (&ib);
ddfb1317 3348 gcc_assert (!info || !info->conds);
27d020cf
JH
3349 for (j = 0; j < count2; j++)
3350 {
3351 struct condition c;
3352 c.operand_num = streamer_read_uhwi (&ib);
3353 c.size = streamer_read_uhwi (&ib);
3354 c.code = (enum tree_code) streamer_read_uhwi (&ib);
3355 c.val = stream_read_tree (&ib, data_in);
3356 bp = streamer_read_bitpack (&ib);
3357 c.agg_contents = bp_unpack_value (&bp, 1);
3358 c.by_ref = bp_unpack_value (&bp, 1);
3359 if (c.agg_contents)
3360 c.offset = streamer_read_uhwi (&ib);
ddfb1317
JH
3361 if (info)
3362 vec_safe_push (info->conds, c);
27d020cf
JH
3363 }
3364 count2 = streamer_read_uhwi (&ib);
ddfb1317 3365 gcc_assert (!info || !info->size_time_table);
27d020cf
JH
3366 for (j = 0; j < count2; j++)
3367 {
3368 struct size_time_entry e;
3369
3370 e.size = streamer_read_uhwi (&ib);
3371 e.time = sreal::stream_in (&ib);
3372 e.exec_predicate.stream_in (&ib);
3373 e.nonconst_predicate.stream_in (&ib);
3374
ddfb1317
JH
3375 if (info)
3376 vec_safe_push (info->size_time_table, e);
27d020cf
JH
3377 }
3378
3379 p.stream_in (&ib);
ddfb1317
JH
3380 if (info)
3381 set_hint_predicate (&info->loop_iterations, p);
27d020cf 3382 p.stream_in (&ib);
ddfb1317
JH
3383 if (info)
3384 set_hint_predicate (&info->loop_stride, p);
27d020cf 3385 p.stream_in (&ib);
ddfb1317
JH
3386 if (info)
3387 set_hint_predicate (&info->array_index, p);
27d020cf 3388 for (e = node->callees; e; e = e->next_callee)
ddfb1317 3389 read_ipa_call_summary (&ib, e, info != NULL);
27d020cf 3390 for (e = node->indirect_calls; e; e = e->next_callee)
ddfb1317 3391 read_ipa_call_summary (&ib, e, info != NULL);
27d020cf
JH
3392 }
3393
0bceb671 3394 lto_free_section_data (file_data, LTO_section_ipa_fn_summary, NULL, data,
27d020cf
JH
3395 len);
3396 lto_data_in_delete (data_in);
3397}
3398
3399
3400/* Read inline summary. Jump functions are shared among ipa-cp
3401 and inliner, so when ipa-cp is active, we don't need to write them
3402 twice. */
3403
d2db2e6b
JH
3404static void
3405ipa_fn_summary_read (void)
27d020cf
JH
3406{
3407 struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
3408 struct lto_file_decl_data *file_data;
3409 unsigned int j = 0;
3410
0bceb671 3411 ipa_fn_summary_alloc ();
27d020cf
JH
3412
3413 while ((file_data = file_data_vec[j++]))
3414 {
3415 size_t len;
3416 const char *data = lto_get_section_data (file_data,
0bceb671 3417 LTO_section_ipa_fn_summary,
27d020cf
JH
3418 NULL, &len);
3419 if (data)
3420 inline_read_section (file_data, data, len);
3421 else
3422 /* Fatal error here. We do not want to support compiling ltrans units
3423 with different version of compiler or different flags than the WPA
3424 unit, so this should never happen. */
3425 fatal_error (input_location,
3426 "ipa inline summary is missing in input file");
3427 }
29f1e2b1
JH
3428 ipa_register_cgraph_hooks ();
3429 if (!flag_ipa_cp)
3430 ipa_prop_read_jump_functions ();
27d020cf 3431
0bceb671
JH
3432 gcc_assert (ipa_fn_summaries);
3433 ipa_fn_summaries->enable_insertion_hook ();
27d020cf
JH
3434}
3435
3436
3437/* Write inline summary for edge E to OB. */
3438
3439static void
3440write_ipa_call_summary (struct output_block *ob, struct cgraph_edge *e)
3441{
56f62793 3442 struct ipa_call_summary *es = ipa_call_summaries->get (e);
27d020cf
JH
3443 int i;
3444
3445 streamer_write_uhwi (ob, es->call_stmt_size);
3446 streamer_write_uhwi (ob, es->call_stmt_time);
3447 streamer_write_uhwi (ob, es->loop_depth);
0fab169b
PK
3448
3449 bitpack_d bp = bitpack_create (ob->main_stream);
3450 bp_pack_value (&bp, es->is_return_callee_uncaptured, 1);
3451 streamer_write_bitpack (&bp);
3452
27d020cf
JH
3453 if (es->predicate)
3454 es->predicate->stream_out (ob);
3455 else
3456 streamer_write_uhwi (ob, 0);
3457 streamer_write_uhwi (ob, es->param.length ());
3458 for (i = 0; i < (int) es->param.length (); i++)
3459 streamer_write_uhwi (ob, es->param[i].change_prob);
3460}
3461
3462
3463/* Write inline summary for node in SET.
3464 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
3465 active, we don't need to write them twice. */
3466
d2db2e6b
JH
3467static void
3468ipa_fn_summary_write (void)
27d020cf 3469{
0bceb671 3470 struct output_block *ob = create_output_block (LTO_section_ipa_fn_summary);
27d020cf
JH
3471 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
3472 unsigned int count = 0;
3473 int i;
3474
3475 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3476 {
3477 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3478 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3479 if (cnode && cnode->definition && !cnode->alias)
3480 count++;
3481 }
3482 streamer_write_uhwi (ob, count);
3483
3484 for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
3485 {
3486 symtab_node *snode = lto_symtab_encoder_deref (encoder, i);
3487 cgraph_node *cnode = dyn_cast <cgraph_node *> (snode);
3488 if (cnode && cnode->definition && !cnode->alias)
3489 {
56f62793 3490 struct ipa_fn_summary *info = ipa_fn_summaries->get (cnode);
27d020cf
JH
3491 struct bitpack_d bp;
3492 struct cgraph_edge *edge;
3493 int i;
3494 size_time_entry *e;
3495 struct condition *c;
3496
3497 streamer_write_uhwi (ob, lto_symtab_encoder_encode (encoder, cnode));
3498 streamer_write_hwi (ob, info->estimated_self_stack_size);
3499 streamer_write_hwi (ob, info->self_size);
3500 info->time.stream_out (ob);
3501 bp = bitpack_create (ob->main_stream);
3502 bp_pack_value (&bp, info->inlinable, 1);
5e9d6aa4 3503 bp_pack_value (&bp, false, 1);
27d020cf
JH
3504 bp_pack_value (&bp, info->fp_expressions, 1);
3505 streamer_write_bitpack (&bp);
3506 streamer_write_uhwi (ob, vec_safe_length (info->conds));
3507 for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
3508 {
3509 streamer_write_uhwi (ob, c->operand_num);
3510 streamer_write_uhwi (ob, c->size);
3511 streamer_write_uhwi (ob, c->code);
3512 stream_write_tree (ob, c->val, true);
3513 bp = bitpack_create (ob->main_stream);
3514 bp_pack_value (&bp, c->agg_contents, 1);
3515 bp_pack_value (&bp, c->by_ref, 1);
3516 streamer_write_bitpack (&bp);
3517 if (c->agg_contents)
3518 streamer_write_uhwi (ob, c->offset);
3519 }
3520 streamer_write_uhwi (ob, vec_safe_length (info->size_time_table));
3521 for (i = 0; vec_safe_iterate (info->size_time_table, i, &e); i++)
3522 {
3523 streamer_write_uhwi (ob, e->size);
3524 e->time.stream_out (ob);
3525 e->exec_predicate.stream_out (ob);
3526 e->nonconst_predicate.stream_out (ob);
3527 }
3528 if (info->loop_iterations)
3529 info->loop_iterations->stream_out (ob);
3530 else
3531 streamer_write_uhwi (ob, 0);
3532 if (info->loop_stride)
3533 info->loop_stride->stream_out (ob);
3534 else
3535 streamer_write_uhwi (ob, 0);
3536 if (info->array_index)
3537 info->array_index->stream_out (ob);
3538 else
3539 streamer_write_uhwi (ob, 0);
3540 for (edge = cnode->callees; edge; edge = edge->next_callee)
3541 write_ipa_call_summary (ob, edge);
3542 for (edge = cnode->indirect_calls; edge; edge = edge->next_callee)
3543 write_ipa_call_summary (ob, edge);
3544 }
3545 }
3546 streamer_write_char_stream (ob->main_stream, 0);
3547 produce_asm (ob, NULL);
3548 destroy_output_block (ob);
3549
29f1e2b1 3550 if (!flag_ipa_cp)
27d020cf
JH
3551 ipa_prop_write_jump_functions ();
3552}
3553
3554
3555/* Release inline summary. */
3556
3557void
d2db2e6b 3558ipa_free_fn_summary (void)
27d020cf
JH
3559{
3560 struct cgraph_node *node;
3561 if (!ipa_call_summaries)
3562 return;
3563 FOR_EACH_DEFINED_FUNCTION (node)
3564 if (!node->alias)
56f62793 3565 ipa_fn_summaries->remove (node);
0bceb671
JH
3566 ipa_fn_summaries->release ();
3567 ipa_fn_summaries = NULL;
27d020cf
JH
3568 ipa_call_summaries->release ();
3569 delete ipa_call_summaries;
3570 ipa_call_summaries = NULL;
3571 edge_predicate_pool.release ();
3572}
d2db2e6b
JH
3573
3574namespace {
3575
3576const pass_data pass_data_local_fn_summary =
3577{
3578 GIMPLE_PASS, /* type */
3579 "local-fnsummary", /* name */
3580 OPTGROUP_INLINE, /* optinfo_flags */
3581 TV_INLINE_PARAMETERS, /* tv_id */
3582 0, /* properties_required */
3583 0, /* properties_provided */
3584 0, /* properties_destroyed */
3585 0, /* todo_flags_start */
3586 0, /* todo_flags_finish */
3587};
3588
3589class pass_local_fn_summary : public gimple_opt_pass
3590{
3591public:
3592 pass_local_fn_summary (gcc::context *ctxt)
3593 : gimple_opt_pass (pass_data_local_fn_summary, ctxt)
3594 {}
3595
3596 /* opt_pass methods: */
3597 opt_pass * clone () { return new pass_local_fn_summary (m_ctxt); }
3598 virtual unsigned int execute (function *)
3599 {
3600 return compute_fn_summary_for_current ();
3601 }
3602
3603}; // class pass_local_fn_summary
3604
3605} // anon namespace
3606
3607gimple_opt_pass *
3608make_pass_local_fn_summary (gcc::context *ctxt)
3609{
3610 return new pass_local_fn_summary (ctxt);
3611}
3612
3613
3614/* Free inline summary. */
3615
3616namespace {
3617
3618const pass_data pass_data_ipa_free_fn_summary =
3619{
3620 SIMPLE_IPA_PASS, /* type */
3621 "free-fnsummary", /* name */
3622 OPTGROUP_NONE, /* optinfo_flags */
3623 TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
3624 0, /* properties_required */
3625 0, /* properties_provided */
3626 0, /* properties_destroyed */
3627 0, /* todo_flags_start */
442db276 3628 0, /* todo_flags_finish */
d2db2e6b
JH
3629};
3630
3631class pass_ipa_free_fn_summary : public simple_ipa_opt_pass
3632{
3633public:
3634 pass_ipa_free_fn_summary (gcc::context *ctxt)
442db276
JJ
3635 : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary, ctxt),
3636 small_p (false)
d2db2e6b
JH
3637 {}
3638
3639 /* opt_pass methods: */
442db276
JJ
3640 opt_pass *clone () { return new pass_ipa_free_fn_summary (m_ctxt); }
3641 void set_pass_param (unsigned int n, bool param)
3642 {
3643 gcc_assert (n == 0);
3644 small_p = param;
3645 }
3646 virtual bool gate (function *) { return small_p || !flag_wpa; }
d2db2e6b
JH
3647 virtual unsigned int execute (function *)
3648 {
3649 ipa_free_fn_summary ();
12485662 3650 return 0;
d2db2e6b
JH
3651 }
3652
442db276
JJ
3653private:
3654 bool small_p;
d2db2e6b
JH
3655}; // class pass_ipa_free_fn_summary
3656
3657} // anon namespace
3658
3659simple_ipa_opt_pass *
3660make_pass_ipa_free_fn_summary (gcc::context *ctxt)
3661{
3662 return new pass_ipa_free_fn_summary (ctxt);
3663}
3664
3665namespace {
3666
3667const pass_data pass_data_ipa_fn_summary =
3668{
3669 IPA_PASS, /* type */
3670 "fnsummary", /* name */
3671 OPTGROUP_INLINE, /* optinfo_flags */
66447ef0 3672 TV_IPA_FNSUMMARY, /* tv_id */
d2db2e6b
JH
3673 0, /* properties_required */
3674 0, /* properties_provided */
3675 0, /* properties_destroyed */
3676 0, /* todo_flags_start */
3677 ( TODO_dump_symtab ), /* todo_flags_finish */
3678};
3679
3680class pass_ipa_fn_summary : public ipa_opt_pass_d
3681{
3682public:
3683 pass_ipa_fn_summary (gcc::context *ctxt)
3684 : ipa_opt_pass_d (pass_data_ipa_fn_summary, ctxt,
3685 ipa_fn_summary_generate, /* generate_summary */
3686 ipa_fn_summary_write, /* write_summary */
3687 ipa_fn_summary_read, /* read_summary */
3688 NULL, /* write_optimization_summary */
3689 NULL, /* read_optimization_summary */
3690 NULL, /* stmt_fixup */
3691 0, /* function_transform_todo_flags_start */
3692 NULL, /* function_transform */
3693 NULL) /* variable_transform */
3694 {}
3695
3696 /* opt_pass methods: */
3697 virtual unsigned int execute (function *) { return 0; }
3698
3699}; // class pass_ipa_fn_summary
3700
3701} // anon namespace
3702
3703ipa_opt_pass_d *
3704make_pass_ipa_fn_summary (gcc::context *ctxt)
3705{
3706 return new pass_ipa_fn_summary (ctxt);
3707}
de4381a4
DM
3708
3709/* Reset all state within ipa-fnsummary.c so that we can rerun the compiler
3710 within the same process. For use by toplev::finalize. */
3711
3712void
3713ipa_fnsummary_c_finalize (void)
3714{
3715 ipa_free_fn_summary ();
3716}