1 /* Function summary pass.
2 Copyright (C) 2003-2020 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* Analysis of function bodies used by inter-procedural passes
23 We estimate for each function
24 - function body size and size after specializing into given context
25 - average function execution time in a given context
28 - call statement size, time and how often the parameters change
30 ipa_fn_summary data structures store above information locally (i.e.
31 parameters of the function itself) and globally (i.e. parameters of
32 the function created by applying all the inline decisions already
33 present in the callgraph).
35 We provide access to the ipa_fn_summary data structure and
36 basic logic updating the parameters when inlining is performed.
38 The summaries are context sensitive. Context means
39 1) partial assignment of known constant values of operands
40 2) whether function is inlined into the call or not.
41 It is easy to add more variants. To represent function size and time
42 that depends on context (i.e. it is known to be optimized away when
43 context is known either by inlining or from IP-CP and cloning),
46 estimate_edge_size_and_time can be used to query
47 function size/time in the given context. ipa_merge_fn_summary_after_inlining merges
48 properties of caller and callee after inlining.
50 Finally pass_inline_parameters is exported. This is used to drive
51 computation of function parameters used by the early inliner. IPA
52 inlined performs analysis via its analyze_function method. */
56 #include "coretypes.h"
60 #include "alloc-pool.h"
61 #include "tree-pass.h"
63 #include "tree-streamer.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"
71 #include "gimple-iterator.h"
73 #include "tree-ssa-loop-niter.h"
74 #include "tree-ssa-loop.h"
75 #include "symbol-summary.h"
77 #include "ipa-fnsummary.h"
79 #include "tree-scalar-evolution.h"
80 #include "ipa-utils.h"
81 #include "cfgexpand.h"
83 #include "stringpool.h"
85 #include "tree-into-ssa.h"
88 fast_function_summary
<ipa_fn_summary
*, va_gc
> *ipa_fn_summaries
;
89 fast_function_summary
<ipa_size_summary
*, va_heap
> *ipa_size_summaries
;
90 fast_call_summary
<ipa_call_summary
*, va_heap
> *ipa_call_summaries
;
92 /* Edge predicates goes here. */
93 static object_allocator
<predicate
> edge_predicate_pool ("edge predicates");
98 ipa_dump_hints (FILE *f
, ipa_hints hints
)
102 fprintf (f
, "IPA hints:");
103 if (hints
& INLINE_HINT_indirect_call
)
105 hints
&= ~INLINE_HINT_indirect_call
;
106 fprintf (f
, " indirect_call");
108 if (hints
& INLINE_HINT_loop_iterations
)
110 hints
&= ~INLINE_HINT_loop_iterations
;
111 fprintf (f
, " loop_iterations");
113 if (hints
& INLINE_HINT_loop_stride
)
115 hints
&= ~INLINE_HINT_loop_stride
;
116 fprintf (f
, " loop_stride");
118 if (hints
& INLINE_HINT_same_scc
)
120 hints
&= ~INLINE_HINT_same_scc
;
121 fprintf (f
, " same_scc");
123 if (hints
& INLINE_HINT_in_scc
)
125 hints
&= ~INLINE_HINT_in_scc
;
126 fprintf (f
, " in_scc");
128 if (hints
& INLINE_HINT_cross_module
)
130 hints
&= ~INLINE_HINT_cross_module
;
131 fprintf (f
, " cross_module");
133 if (hints
& INLINE_HINT_declared_inline
)
135 hints
&= ~INLINE_HINT_declared_inline
;
136 fprintf (f
, " declared_inline");
138 if (hints
& INLINE_HINT_known_hot
)
140 hints
&= ~INLINE_HINT_known_hot
;
141 fprintf (f
, " known_hot");
147 /* Record SIZE and TIME to SUMMARY.
148 The accounted code will be executed when EXEC_PRED is true.
149 When NONCONST_PRED is false the code will evaluate to constant and
150 will get optimized out in specialized clones of the function.
151 If CALL is true account to call_size_time_table rather than
155 ipa_fn_summary::account_size_time (int size
, sreal time
,
156 const predicate
&exec_pred
,
157 const predicate
&nonconst_pred_in
,
163 predicate nonconst_pred
;
164 vec
<size_time_entry
, va_gc
> *table
= call
165 ? call_size_time_table
: size_time_table
;
167 if (exec_pred
== false)
170 nonconst_pred
= nonconst_pred_in
& exec_pred
;
172 if (nonconst_pred
== false)
175 /* We need to create initial empty unconditional clause, but otherwise
176 we don't need to account empty times and sizes. */
177 if (!size
&& time
== 0 && table
)
180 /* Only for calls we are unaccounting what we previously recorded. */
181 gcc_checking_assert (time
>= 0 || call
);
183 for (i
= 0; vec_safe_iterate (table
, i
, &e
); i
++)
184 if (e
->exec_predicate
== exec_pred
185 && e
->nonconst_predicate
== nonconst_pred
)
190 if (i
== max_size_time_table_size
)
195 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
197 "\t\tReached limit on number of entries, "
198 "ignoring the predicate.");
200 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && (time
!= 0 || size
))
203 "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate exec:",
204 ((double) size
) / ipa_fn_summary::size_scale
,
205 (time
.to_double ()), found
? "" : "new ");
206 exec_pred
.dump (dump_file
, conds
, 0);
207 if (exec_pred
!= nonconst_pred
)
209 fprintf (dump_file
, " nonconst:");
210 nonconst_pred
.dump (dump_file
, conds
);
213 fprintf (dump_file
, "\n");
217 class size_time_entry new_entry
;
218 new_entry
.size
= size
;
219 new_entry
.time
= time
;
220 new_entry
.exec_predicate
= exec_pred
;
221 new_entry
.nonconst_predicate
= nonconst_pred
;
223 vec_safe_push (call_size_time_table
, new_entry
);
225 vec_safe_push (size_time_table
, new_entry
);
231 /* FIXME: PR bootstrap/92653 gcc_checking_assert (e->time >= -1); */
232 /* Tolerate small roundoff issues. */
238 /* We proved E to be unreachable, redirect it to __builtin_unreachable. */
240 static struct cgraph_edge
*
241 redirect_to_unreachable (struct cgraph_edge
*e
)
243 struct cgraph_node
*callee
= !e
->inline_failed
? e
->callee
: NULL
;
244 struct cgraph_node
*target
= cgraph_node::get_create
245 (builtin_decl_implicit (BUILT_IN_UNREACHABLE
));
248 e
= cgraph_edge::resolve_speculation (e
, target
->decl
);
250 e
= cgraph_edge::make_direct (e
, target
);
252 e
->redirect_callee (target
);
253 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
254 e
->inline_failed
= CIF_UNREACHABLE
;
255 e
->count
= profile_count::zero ();
256 es
->call_stmt_size
= 0;
257 es
->call_stmt_time
= 0;
259 callee
->remove_symbol_and_inline_clones ();
263 /* Set predicate for edge E. */
266 edge_set_predicate (struct cgraph_edge
*e
, predicate
*predicate
)
268 /* If the edge is determined to be never executed, redirect it
269 to BUILTIN_UNREACHABLE to make it clear to IPA passes the call will
271 if (predicate
&& *predicate
== false
272 /* When handling speculative edges, we need to do the redirection
273 just once. Do it always on the direct edge, so we do not
274 attempt to resolve speculation while duplicating the edge. */
275 && (!e
->speculative
|| e
->callee
))
276 e
= redirect_to_unreachable (e
);
278 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
279 if (predicate
&& *predicate
!= true)
282 es
->predicate
= edge_predicate_pool
.allocate ();
283 *es
->predicate
= *predicate
;
288 edge_predicate_pool
.remove (es
->predicate
);
289 es
->predicate
= NULL
;
293 /* Set predicate for hint *P. */
296 set_hint_predicate (predicate
**p
, predicate new_predicate
)
298 if (new_predicate
== false || new_predicate
== true)
301 edge_predicate_pool
.remove (*p
);
307 *p
= edge_predicate_pool
.allocate ();
313 /* Compute what conditions may or may not hold given information about
314 parameters. RET_CLAUSE returns truths that may hold in a specialized copy,
315 while RET_NONSPEC_CLAUSE returns truths that may hold in an nonspecialized
316 copy when called in a given context. It is a bitmask of conditions. Bit
317 0 means that condition is known to be false, while bit 1 means that condition
318 may or may not be true. These differs - for example NOT_INLINED condition
319 is always false in the second and also builtin_constant_p tests cannot use
320 the fact that parameter is indeed a constant.
322 KNOWN_VALS is partial mapping of parameters of NODE to constant values.
323 KNOWN_AGGS is a vector of aggregate known offset/value set for each
324 parameter. Return clause of possible truths. When INLINE_P is true, assume
325 that we are inlining.
327 ERROR_MARK means compile time invariant. */
330 evaluate_conditions_for_known_args (struct cgraph_node
*node
,
332 vec
<tree
> known_vals
,
333 vec
<value_range
> known_value_ranges
,
334 vec
<ipa_agg_value_set
> known_aggs
,
335 clause_t
*ret_clause
,
336 clause_t
*ret_nonspec_clause
)
338 clause_t clause
= inline_p
? 0 : 1 << predicate::not_inlined_condition
;
339 clause_t nonspec_clause
= 1 << predicate::not_inlined_condition
;
340 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (node
);
344 for (i
= 0; vec_safe_iterate (info
->conds
, i
, &c
); i
++)
349 struct expr_eval_op
*op
;
351 /* We allow call stmt to have fewer arguments than the callee function
352 (especially for K&R style programs). So bound check here (we assume
353 known_aggs vector, if non-NULL, has the same length as
355 gcc_checking_assert (!known_aggs
.length () || !known_vals
.length ()
356 || (known_vals
.length () == known_aggs
.length ()));
360 struct ipa_agg_value_set
*agg
;
362 if (c
->code
== predicate::changed
364 && c
->operand_num
< (int)known_vals
.length ()
365 && (known_vals
[c
->operand_num
] == error_mark_node
))
368 if (c
->operand_num
< (int)known_aggs
.length ())
370 agg
= &known_aggs
[c
->operand_num
];
371 val
= ipa_find_agg_cst_for_param (agg
,
373 < (int) known_vals
.length ()
374 ? known_vals
[c
->operand_num
]
376 c
->offset
, c
->by_ref
);
381 else if (c
->operand_num
< (int) known_vals
.length ())
383 val
= known_vals
[c
->operand_num
];
384 if (val
== error_mark_node
&& c
->code
!= predicate::changed
)
389 && (c
->code
== predicate::changed
390 || c
->code
== predicate::is_not_constant
))
392 clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
393 nonspec_clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
396 if (c
->code
== predicate::changed
)
398 nonspec_clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
402 if (c
->code
== predicate::is_not_constant
)
404 nonspec_clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
408 if (val
&& TYPE_SIZE (c
->type
) == TYPE_SIZE (TREE_TYPE (val
)))
410 if (c
->type
!= TREE_TYPE (val
))
411 val
= fold_unary (VIEW_CONVERT_EXPR
, c
->type
, val
);
412 for (j
= 0; vec_safe_iterate (c
->param_ops
, j
, &op
); j
++)
417 val
= fold_unary (op
->code
, op
->type
, val
);
418 else if (!op
->val
[1])
419 val
= fold_binary (op
->code
, op
->type
,
420 op
->index
? op
->val
[0] : val
,
421 op
->index
? val
: op
->val
[0]);
422 else if (op
->index
== 0)
423 val
= fold_ternary (op
->code
, op
->type
,
424 val
, op
->val
[0], op
->val
[1]);
425 else if (op
->index
== 1)
426 val
= fold_ternary (op
->code
, op
->type
,
427 op
->val
[0], val
, op
->val
[1]);
428 else if (op
->index
== 2)
429 val
= fold_ternary (op
->code
, op
->type
,
430 op
->val
[0], op
->val
[1], val
);
436 ? fold_binary_to_constant (c
->code
, boolean_type_node
, val
, c
->val
)
439 if (res
&& integer_zerop (res
))
441 if (res
&& integer_onep (res
))
443 clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
444 nonspec_clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
448 if (c
->operand_num
< (int) known_value_ranges
.length ()
450 && !known_value_ranges
[c
->operand_num
].undefined_p ()
451 && !known_value_ranges
[c
->operand_num
].varying_p ()
452 && TYPE_SIZE (c
->type
)
453 == TYPE_SIZE (known_value_ranges
[c
->operand_num
].type ())
454 && (!val
|| TREE_CODE (val
) != INTEGER_CST
))
456 value_range vr
= known_value_ranges
[c
->operand_num
];
457 if (!useless_type_conversion_p (c
->type
, vr
.type ()))
460 range_fold_unary_expr (&res
, NOP_EXPR
,
461 c
->type
, &vr
, vr
.type ());
466 for (j
= 0; vec_safe_iterate (c
->param_ops
, j
, &op
); j
++)
468 if (vr
.varying_p () || vr
.undefined_p ())
473 range_fold_unary_expr (&res
, op
->code
, op
->type
, &vr
, type
);
474 else if (!op
->val
[1])
476 value_range
op0 (op
->val
[0], op
->val
[0]);
477 range_fold_binary_expr (&res
, op
->code
, op
->type
,
478 op
->index
? &op0
: &vr
,
479 op
->index
? &vr
: &op0
);
486 if (!vr
.varying_p () && !vr
.undefined_p ())
489 value_range
val_vr (c
->val
, c
->val
);
490 range_fold_binary_expr (&res
, c
->code
, boolean_type_node
,
498 clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
499 nonspec_clause
|= 1 << (i
+ predicate::first_dynamic_condition
);
501 *ret_clause
= clause
;
502 if (ret_nonspec_clause
)
503 *ret_nonspec_clause
= nonspec_clause
;
507 /* Work out what conditions might be true at invocation of E.
508 Compute costs for inlined edge if INLINE_P is true.
510 Return in CLAUSE_PTR the evaluated conditions and in NONSPEC_CLAUSE_PTR
511 (if non-NULL) conditions evaluated for nonspecialized clone called
514 KNOWN_VALS_PTR and KNOWN_AGGS_PTR must be non-NULL and will be filled by
515 known constant and aggregate values of parameters.
517 KNOWN_CONTEXT_PTR, if non-NULL, will be filled by polymorphic call contexts
518 of parameter used by a polymorphic call. */
521 evaluate_properties_for_edge (struct cgraph_edge
*e
, bool inline_p
,
522 clause_t
*clause_ptr
,
523 clause_t
*nonspec_clause_ptr
,
524 vec
<tree
> *known_vals_ptr
,
525 vec
<ipa_polymorphic_call_context
>
527 vec
<ipa_agg_value_set
> *known_aggs_ptr
)
529 struct cgraph_node
*callee
= e
->callee
->ultimate_alias_target ();
530 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (callee
);
531 auto_vec
<value_range
, 32> known_value_ranges
;
532 class ipa_edge_args
*args
;
535 *clause_ptr
= inline_p
? 0 : 1 << predicate::not_inlined_condition
;
537 if (ipa_node_params_sum
538 && !e
->call_stmt_cannot_inline_p
539 && (info
->conds
|| known_contexts_ptr
)
540 && (args
= IPA_EDGE_REF (e
)) != NULL
)
542 struct cgraph_node
*caller
;
543 class ipa_node_params
*caller_parms_info
, *callee_pi
= NULL
;
544 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
545 int i
, count
= ipa_get_cs_argument_count (args
);
549 if (e
->caller
->inlined_to
)
550 caller
= e
->caller
->inlined_to
;
553 caller_parms_info
= IPA_NODE_REF (caller
);
554 callee_pi
= IPA_NODE_REF (callee
);
556 /* Watch for thunks. */
558 /* Watch for variadic functions. */
559 count
= MIN (count
, ipa_get_param_count (callee_pi
));
563 for (i
= 0; i
< count
; i
++)
565 struct ipa_jump_func
*jf
= ipa_get_ith_jump_func (args
, i
);
567 if (ipa_is_param_used_by_indirect_call (callee_pi
, i
)
568 || ipa_is_param_used_by_ipa_predicates (callee_pi
, i
))
570 /* Determine if we know constant value of the parameter. */
571 tree cst
= ipa_value_from_jfunc (caller_parms_info
, jf
,
572 ipa_get_type (callee_pi
, i
));
574 if (!cst
&& e
->call_stmt
575 && i
< (int)gimple_call_num_args (e
->call_stmt
))
577 cst
= gimple_call_arg (e
->call_stmt
, i
);
578 if (!is_gimple_min_invariant (cst
))
583 gcc_checking_assert (TREE_CODE (cst
) != TREE_BINFO
);
584 if (!known_vals_ptr
->length ())
585 vec_safe_grow_cleared (known_vals_ptr
, count
);
586 (*known_vals_ptr
)[i
] = cst
;
588 else if (inline_p
&& !es
->param
[i
].change_prob
)
590 if (!known_vals_ptr
->length ())
591 vec_safe_grow_cleared (known_vals_ptr
, count
);
592 (*known_vals_ptr
)[i
] = error_mark_node
;
595 /* If we failed to get simple constant, try value range. */
596 if ((!cst
|| TREE_CODE (cst
) != INTEGER_CST
)
597 && ipa_is_param_used_by_ipa_predicates (callee_pi
, i
))
600 = ipa_value_range_from_jfunc (caller_parms_info
, e
, jf
,
601 ipa_get_type (callee_pi
,
603 if (!vr
.undefined_p () && !vr
.varying_p ())
605 if (!known_value_ranges
.length ())
606 known_value_ranges
.safe_grow_cleared (count
);
607 known_value_ranges
[i
] = vr
;
611 /* Determine known aggregate values. */
612 ipa_agg_value_set agg
613 = ipa_agg_value_set_from_jfunc (caller_parms_info
,
615 if (agg
.items
.length ())
617 if (!known_aggs_ptr
->length ())
618 vec_safe_grow_cleared (known_aggs_ptr
, count
);
619 (*known_aggs_ptr
)[i
] = agg
;
623 /* For calls used in polymorphic calls we further determine
624 polymorphic call context. */
625 if (known_contexts_ptr
626 && ipa_is_param_used_by_polymorphic_call (callee_pi
, i
))
628 ipa_polymorphic_call_context
629 ctx
= ipa_context_from_jfunc (caller_parms_info
, e
, i
, jf
);
630 if (!ctx
.useless_p ())
632 if (!known_contexts_ptr
->length ())
633 known_contexts_ptr
->safe_grow_cleared (count
);
634 (*known_contexts_ptr
)[i
]
635 = ipa_context_from_jfunc (caller_parms_info
, e
, i
, jf
);
640 gcc_assert (!count
|| callee
->thunk
.thunk_p
);
642 else if (e
->call_stmt
&& !e
->call_stmt_cannot_inline_p
&& info
->conds
)
644 int i
, count
= (int)gimple_call_num_args (e
->call_stmt
);
646 for (i
= 0; i
< count
; i
++)
648 tree cst
= gimple_call_arg (e
->call_stmt
, i
);
649 if (!is_gimple_min_invariant (cst
))
653 if (!known_vals_ptr
->length ())
654 vec_safe_grow_cleared (known_vals_ptr
, count
);
655 (*known_vals_ptr
)[i
] = cst
;
660 evaluate_conditions_for_known_args (callee
, inline_p
,
669 /* Allocate the function summary. */
672 ipa_fn_summary_alloc (void)
674 gcc_checking_assert (!ipa_fn_summaries
);
675 ipa_size_summaries
= new ipa_size_summary_t (symtab
);
676 ipa_fn_summaries
= ipa_fn_summary_t::create_ggc (symtab
);
677 ipa_call_summaries
= new ipa_call_summary_t (symtab
);
680 ipa_call_summary::~ipa_call_summary ()
683 edge_predicate_pool
.remove (predicate
);
688 ipa_fn_summary::~ipa_fn_summary ()
691 edge_predicate_pool
.remove (loop_iterations
);
693 edge_predicate_pool
.remove (loop_stride
);
695 vec_free (size_time_table
);
696 vec_free (call_size_time_table
);
700 ipa_fn_summary_t::remove_callees (cgraph_node
*node
)
703 for (e
= node
->callees
; e
; e
= e
->next_callee
)
704 ipa_call_summaries
->remove (e
);
705 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
706 ipa_call_summaries
->remove (e
);
709 /* Same as remap_predicate_after_duplication but handle hint predicate *P.
710 Additionally care about allocating new memory slot for updated predicate
711 and set it to NULL when it becomes true or false (and thus uninteresting).
715 remap_hint_predicate_after_duplication (predicate
**p
,
716 clause_t possible_truths
)
718 predicate new_predicate
;
723 new_predicate
= (*p
)->remap_after_duplication (possible_truths
);
724 /* We do not want to free previous predicate; it is used by node origin. */
726 set_hint_predicate (p
, new_predicate
);
730 /* Hook that is called by cgraph.c when a node is duplicated. */
732 ipa_fn_summary_t::duplicate (cgraph_node
*src
,
735 ipa_fn_summary
*info
)
737 new (info
) ipa_fn_summary (*ipa_fn_summaries
->get (src
));
738 /* TODO: as an optimization, we may avoid copying conditions
739 that are known to be false or true. */
740 info
->conds
= vec_safe_copy (info
->conds
);
742 /* When there are any replacements in the function body, see if we can figure
743 out that something was optimized out. */
744 if (ipa_node_params_sum
&& dst
->clone
.tree_map
)
746 vec
<size_time_entry
, va_gc
> *entry
= info
->size_time_table
;
747 /* Use SRC parm info since it may not be copied yet. */
748 class ipa_node_params
*parms_info
= IPA_NODE_REF (src
);
749 vec
<tree
> known_vals
= vNULL
;
750 int count
= ipa_get_param_count (parms_info
);
752 clause_t possible_truths
;
753 predicate true_pred
= true;
755 int optimized_out_size
= 0;
756 bool inlined_to_p
= false;
757 struct cgraph_edge
*edge
, *next
;
759 info
->size_time_table
= 0;
760 known_vals
.safe_grow_cleared (count
);
761 for (i
= 0; i
< count
; i
++)
763 struct ipa_replace_map
*r
;
765 for (j
= 0; vec_safe_iterate (dst
->clone
.tree_map
, j
, &r
); j
++)
767 if (r
->parm_num
== i
)
769 known_vals
[i
] = r
->new_tree
;
774 evaluate_conditions_for_known_args (dst
, false,
779 /* We are going to specialize,
780 so ignore nonspec truths. */
782 known_vals
.release ();
784 info
->account_size_time (0, 0, true_pred
, true_pred
);
786 /* Remap size_time vectors.
787 Simplify the predicate by pruning out alternatives that are known
789 TODO: as on optimization, we can also eliminate conditions known
791 for (i
= 0; vec_safe_iterate (entry
, i
, &e
); i
++)
793 predicate new_exec_pred
;
794 predicate new_nonconst_pred
;
795 new_exec_pred
= e
->exec_predicate
.remap_after_duplication
797 new_nonconst_pred
= e
->nonconst_predicate
.remap_after_duplication
799 if (new_exec_pred
== false || new_nonconst_pred
== false)
800 optimized_out_size
+= e
->size
;
802 info
->account_size_time (e
->size
, e
->time
, new_exec_pred
,
806 /* Remap edge predicates with the same simplification as above.
807 Also copy constantness arrays. */
808 for (edge
= dst
->callees
; edge
; edge
= next
)
810 predicate new_predicate
;
811 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
812 next
= edge
->next_callee
;
814 if (!edge
->inline_failed
)
818 new_predicate
= es
->predicate
->remap_after_duplication
820 if (new_predicate
== false && *es
->predicate
!= false)
821 optimized_out_size
+= es
->call_stmt_size
* ipa_fn_summary::size_scale
;
822 edge_set_predicate (edge
, &new_predicate
);
825 /* Remap indirect edge predicates with the same simplification as above.
826 Also copy constantness arrays. */
827 for (edge
= dst
->indirect_calls
; edge
; edge
= next
)
829 predicate new_predicate
;
830 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
831 next
= edge
->next_callee
;
833 gcc_checking_assert (edge
->inline_failed
);
836 new_predicate
= es
->predicate
->remap_after_duplication
838 if (new_predicate
== false && *es
->predicate
!= false)
839 optimized_out_size
+= es
->call_stmt_size
* ipa_fn_summary::size_scale
;
840 edge_set_predicate (edge
, &new_predicate
);
842 remap_hint_predicate_after_duplication (&info
->loop_iterations
,
844 remap_hint_predicate_after_duplication (&info
->loop_stride
,
847 /* If inliner or someone after inliner will ever start producing
848 non-trivial clones, we will get trouble with lack of information
849 about updating self sizes, because size vectors already contains
850 sizes of the callees. */
851 gcc_assert (!inlined_to_p
|| !optimized_out_size
);
855 info
->size_time_table
= vec_safe_copy (info
->size_time_table
);
856 if (info
->loop_iterations
)
858 predicate p
= *info
->loop_iterations
;
859 info
->loop_iterations
= NULL
;
860 set_hint_predicate (&info
->loop_iterations
, p
);
862 if (info
->loop_stride
)
864 predicate p
= *info
->loop_stride
;
865 info
->loop_stride
= NULL
;
866 set_hint_predicate (&info
->loop_stride
, p
);
869 if (!dst
->inlined_to
)
870 ipa_update_overall_fn_summary (dst
);
874 /* Hook that is called by cgraph.c when a node is duplicated. */
877 ipa_call_summary_t::duplicate (struct cgraph_edge
*src
,
878 struct cgraph_edge
*dst
,
879 class ipa_call_summary
*srcinfo
,
880 class ipa_call_summary
*info
)
882 new (info
) ipa_call_summary (*srcinfo
);
883 info
->predicate
= NULL
;
884 edge_set_predicate (dst
, srcinfo
->predicate
);
885 info
->param
= srcinfo
->param
.copy ();
886 if (!dst
->indirect_unknown_callee
&& src
->indirect_unknown_callee
)
888 info
->call_stmt_size
-= (eni_size_weights
.indirect_call_cost
889 - eni_size_weights
.call_cost
);
890 info
->call_stmt_time
-= (eni_time_weights
.indirect_call_cost
891 - eni_time_weights
.call_cost
);
895 /* Dump edge summaries associated to NODE and recursively to all clones.
899 dump_ipa_call_summary (FILE *f
, int indent
, struct cgraph_node
*node
,
900 class ipa_fn_summary
*info
)
902 struct cgraph_edge
*edge
;
903 for (edge
= node
->callees
; edge
; edge
= edge
->next_callee
)
905 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
906 struct cgraph_node
*callee
= edge
->callee
->ultimate_alias_target ();
910 "%*s%s %s\n%*s freq:%4.2f",
911 indent
, "", callee
->dump_name (),
913 ? "inlined" : cgraph_inline_failed_string (edge
-> inline_failed
),
914 indent
, "", edge
->sreal_frequency ().to_double ());
916 if (cross_module_call_p (edge
))
917 fprintf (f
, " cross module");
920 fprintf (f
, " loop depth:%2i size:%2i time: %2i",
921 es
->loop_depth
, es
->call_stmt_size
, es
->call_stmt_time
);
923 ipa_fn_summary
*s
= ipa_fn_summaries
->get (callee
);
924 ipa_size_summary
*ss
= ipa_size_summaries
->get (callee
);
926 fprintf (f
, " callee size:%2i stack:%2i",
927 (int) (ss
->size
/ ipa_fn_summary::size_scale
),
928 (int) s
->estimated_stack_size
);
930 if (es
&& es
->predicate
)
932 fprintf (f
, " predicate: ");
933 es
->predicate
->dump (f
, info
->conds
);
937 if (es
&& es
->param
.exists ())
938 for (i
= 0; i
< (int) es
->param
.length (); i
++)
940 int prob
= es
->param
[i
].change_prob
;
943 fprintf (f
, "%*s op%i is compile time invariant\n",
945 else if (prob
!= REG_BR_PROB_BASE
)
946 fprintf (f
, "%*s op%i change %f%% of time\n", indent
+ 2, "", i
,
947 prob
* 100.0 / REG_BR_PROB_BASE
);
949 if (!edge
->inline_failed
)
951 ipa_size_summary
*ss
= ipa_size_summaries
->get (callee
);
952 fprintf (f
, "%*sStack frame offset %i, callee self size %i\n",
954 (int) ipa_get_stack_frame_offset (callee
),
955 (int) ss
->estimated_self_stack_size
);
956 dump_ipa_call_summary (f
, indent
+ 2, callee
, info
);
959 for (edge
= node
->indirect_calls
; edge
; edge
= edge
->next_callee
)
961 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
962 fprintf (f
, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
966 edge
->sreal_frequency ().to_double (), es
->call_stmt_size
,
970 fprintf (f
, "predicate: ");
971 es
->predicate
->dump (f
, info
->conds
);
980 ipa_dump_fn_summary (FILE *f
, struct cgraph_node
*node
)
982 if (node
->definition
)
984 class ipa_fn_summary
*s
= ipa_fn_summaries
->get (node
);
985 class ipa_size_summary
*ss
= ipa_size_summaries
->get (node
);
990 fprintf (f
, "IPA function summary for %s", node
->dump_name ());
991 if (DECL_DISREGARD_INLINE_LIMITS (node
->decl
))
992 fprintf (f
, " always_inline");
994 fprintf (f
, " inlinable");
995 if (s
->fp_expressions
)
996 fprintf (f
, " fp_expression");
997 fprintf (f
, "\n global time: %f\n", s
->time
.to_double ());
998 fprintf (f
, " self size: %i\n", ss
->self_size
);
999 fprintf (f
, " global size: %i\n", ss
->size
);
1000 fprintf (f
, " min size: %i\n", s
->min_size
);
1001 fprintf (f
, " self stack: %i\n",
1002 (int) ss
->estimated_self_stack_size
);
1003 fprintf (f
, " global stack: %i\n", (int) s
->estimated_stack_size
);
1005 fprintf (f
, " estimated growth:%i\n", (int) s
->growth
);
1007 fprintf (f
, " In SCC: %i\n", (int) s
->scc_no
);
1008 for (i
= 0; vec_safe_iterate (s
->size_time_table
, i
, &e
); i
++)
1010 fprintf (f
, " size:%f, time:%f",
1011 (double) e
->size
/ ipa_fn_summary::size_scale
,
1012 e
->time
.to_double ());
1013 if (e
->exec_predicate
!= true)
1015 fprintf (f
, ", executed if:");
1016 e
->exec_predicate
.dump (f
, s
->conds
, 0);
1018 if (e
->exec_predicate
!= e
->nonconst_predicate
)
1020 fprintf (f
, ", nonconst if:");
1021 e
->nonconst_predicate
.dump (f
, s
->conds
, 0);
1025 if (s
->loop_iterations
)
1027 fprintf (f
, " loop iterations:");
1028 s
->loop_iterations
->dump (f
, s
->conds
);
1032 fprintf (f
, " loop stride:");
1033 s
->loop_stride
->dump (f
, s
->conds
);
1035 fprintf (f
, " calls:\n");
1036 dump_ipa_call_summary (f
, 4, node
, s
);
1040 fprintf (f
, "IPA summary for %s is missing.\n", node
->dump_name ());
1045 ipa_debug_fn_summary (struct cgraph_node
*node
)
1047 ipa_dump_fn_summary (stderr
, node
);
1051 ipa_dump_fn_summaries (FILE *f
)
1053 struct cgraph_node
*node
;
1055 FOR_EACH_DEFINED_FUNCTION (node
)
1056 if (!node
->inlined_to
)
1057 ipa_dump_fn_summary (f
, node
);
1060 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
1061 boolean variable pointed to by DATA. */
1064 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
1067 bool *b
= (bool *) data
;
1072 /* If OP refers to value of function parameter, return the corresponding
1073 parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
1074 PARM_DECL) will be stored to *SIZE_P in that case too. */
1077 unmodified_parm_1 (ipa_func_body_info
*fbi
, gimple
*stmt
, tree op
,
1080 /* SSA_NAME referring to parm default def? */
1081 if (TREE_CODE (op
) == SSA_NAME
1082 && SSA_NAME_IS_DEFAULT_DEF (op
)
1083 && TREE_CODE (SSA_NAME_VAR (op
)) == PARM_DECL
)
1086 *size_p
= tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op
)));
1087 return SSA_NAME_VAR (op
);
1089 /* Non-SSA parm reference? */
1090 if (TREE_CODE (op
) == PARM_DECL
)
1092 bool modified
= false;
1095 ao_ref_init (&refd
, op
);
1096 int walked
= walk_aliased_vdefs (&refd
, gimple_vuse (stmt
),
1097 mark_modified
, &modified
, NULL
, NULL
,
1098 fbi
->aa_walk_budget
+ 1);
1101 fbi
->aa_walk_budget
= 0;
1107 *size_p
= tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op
)));
1114 /* If OP refers to value of function parameter, return the corresponding
1115 parameter. Also traverse chains of SSA register assignments. If non-NULL,
1116 the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
1117 stored to *SIZE_P in that case too. */
1120 unmodified_parm (ipa_func_body_info
*fbi
, gimple
*stmt
, tree op
,
1123 tree res
= unmodified_parm_1 (fbi
, stmt
, op
, size_p
);
1127 if (TREE_CODE (op
) == SSA_NAME
1128 && !SSA_NAME_IS_DEFAULT_DEF (op
)
1129 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op
)))
1130 return unmodified_parm (fbi
, SSA_NAME_DEF_STMT (op
),
1131 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op
)),
1136 /* If OP refers to a value of a function parameter or value loaded from an
1137 aggregate passed to a parameter (either by value or reference), return TRUE
1138 and store the number of the parameter to *INDEX_P, the access size into
1139 *SIZE_P, and information whether and how it has been loaded from an
1140 aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
1141 statement in which OP is used or loaded. */
1144 unmodified_parm_or_parm_agg_item (struct ipa_func_body_info
*fbi
,
1145 gimple
*stmt
, tree op
, int *index_p
,
1147 struct agg_position_info
*aggpos
)
1149 tree res
= unmodified_parm_1 (fbi
, stmt
, op
, size_p
);
1151 gcc_checking_assert (aggpos
);
1154 *index_p
= ipa_get_param_decl_index (fbi
->info
, res
);
1157 aggpos
->agg_contents
= false;
1158 aggpos
->by_ref
= false;
1162 if (TREE_CODE (op
) == SSA_NAME
)
1164 if (SSA_NAME_IS_DEFAULT_DEF (op
)
1165 || !gimple_assign_single_p (SSA_NAME_DEF_STMT (op
)))
1167 stmt
= SSA_NAME_DEF_STMT (op
);
1168 op
= gimple_assign_rhs1 (stmt
);
1169 if (!REFERENCE_CLASS_P (op
))
1170 return unmodified_parm_or_parm_agg_item (fbi
, stmt
, op
, index_p
, size_p
,
1174 aggpos
->agg_contents
= true;
1175 return ipa_load_from_parm_agg (fbi
, fbi
->info
->descriptors
,
1176 stmt
, op
, index_p
, &aggpos
->offset
,
1177 size_p
, &aggpos
->by_ref
);
1180 /* See if statement might disappear after inlining.
1181 0 - means not eliminated
1182 1 - half of statements goes away
1183 2 - for sure it is eliminated.
1184 We are not terribly sophisticated, basically looking for simple abstraction
1185 penalty wrappers. */
1188 eliminated_by_inlining_prob (ipa_func_body_info
*fbi
, gimple
*stmt
)
1190 enum gimple_code code
= gimple_code (stmt
);
1191 enum tree_code rhs_code
;
1201 if (gimple_num_ops (stmt
) != 2)
1204 rhs_code
= gimple_assign_rhs_code (stmt
);
1206 /* Casts of parameters, loads from parameters passed by reference
1207 and stores to return value or parameters are often free after
1208 inlining due to SRA and further combining.
1209 Assume that half of statements goes away. */
1210 if (CONVERT_EXPR_CODE_P (rhs_code
)
1211 || rhs_code
== VIEW_CONVERT_EXPR
1212 || rhs_code
== ADDR_EXPR
1213 || gimple_assign_rhs_class (stmt
) == GIMPLE_SINGLE_RHS
)
1215 tree rhs
= gimple_assign_rhs1 (stmt
);
1216 tree lhs
= gimple_assign_lhs (stmt
);
1217 tree inner_rhs
= get_base_address (rhs
);
1218 tree inner_lhs
= get_base_address (lhs
);
1219 bool rhs_free
= false;
1220 bool lhs_free
= false;
1227 /* Reads of parameter are expected to be free. */
1228 if (unmodified_parm (fbi
, stmt
, inner_rhs
, NULL
))
1230 /* Match expressions of form &this->field. Those will most likely
1231 combine with something upstream after inlining. */
1232 else if (TREE_CODE (inner_rhs
) == ADDR_EXPR
)
1234 tree op
= get_base_address (TREE_OPERAND (inner_rhs
, 0));
1235 if (TREE_CODE (op
) == PARM_DECL
)
1237 else if (TREE_CODE (op
) == MEM_REF
1238 && unmodified_parm (fbi
, stmt
, TREE_OPERAND (op
, 0),
1243 /* When parameter is not SSA register because its address is taken
1244 and it is just copied into one, the statement will be completely
1245 free after inlining (we will copy propagate backward). */
1246 if (rhs_free
&& is_gimple_reg (lhs
))
1249 /* Reads of parameters passed by reference
1250 expected to be free (i.e. optimized out after inlining). */
1251 if (TREE_CODE (inner_rhs
) == MEM_REF
1252 && unmodified_parm (fbi
, stmt
, TREE_OPERAND (inner_rhs
, 0), NULL
))
1255 /* Copying parameter passed by reference into gimple register is
1256 probably also going to copy propagate, but we can't be quite
1258 if (rhs_free
&& is_gimple_reg (lhs
))
1261 /* Writes to parameters, parameters passed by value and return value
1262 (either directly or passed via invisible reference) are free.
1264 TODO: We ought to handle testcase like
1265 struct a {int a,b;};
1273 This translate into:
1288 For that we either need to copy ipa-split logic detecting writes
1290 if (TREE_CODE (inner_lhs
) == PARM_DECL
1291 || TREE_CODE (inner_lhs
) == RESULT_DECL
1292 || (TREE_CODE (inner_lhs
) == MEM_REF
1293 && (unmodified_parm (fbi
, stmt
, TREE_OPERAND (inner_lhs
, 0),
1295 || (TREE_CODE (TREE_OPERAND (inner_lhs
, 0)) == SSA_NAME
1296 && SSA_NAME_VAR (TREE_OPERAND (inner_lhs
, 0))
1297 && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
1299 0))) == RESULT_DECL
))))
1302 && (is_gimple_reg (rhs
) || is_gimple_min_invariant (rhs
)))
1304 if (lhs_free
&& rhs_free
)
1313 /* Analyze EXPR if it represents a series of simple operations performed on
1314 a function parameter and return true if so. FBI, STMT, EXPR, INDEX_P and
1315 AGGPOS have the same meaning like in unmodified_parm_or_parm_agg_item.
1316 Type of the parameter or load from an aggregate via the parameter is
1317 stored in *TYPE_P. Operations on the parameter are recorded to
1318 PARAM_OPS_P if it is not NULL. */
1321 decompose_param_expr (struct ipa_func_body_info
*fbi
,
1322 gimple
*stmt
, tree expr
,
1323 int *index_p
, tree
*type_p
,
1324 struct agg_position_info
*aggpos
,
1325 expr_eval_ops
*param_ops_p
= NULL
)
1327 int op_limit
= opt_for_fn (fbi
->node
->decl
, param_ipa_max_param_expr_ops
);
1331 *param_ops_p
= NULL
;
1335 expr_eval_op eval_op
;
1337 unsigned cst_count
= 0;
1339 if (unmodified_parm_or_parm_agg_item (fbi
, stmt
, expr
, index_p
, NULL
,
1342 tree type
= TREE_TYPE (expr
);
1344 if (aggpos
->agg_contents
)
1346 /* Stop if containing bit-field. */
1347 if (TREE_CODE (expr
) == BIT_FIELD_REF
1348 || contains_bitfld_component_ref_p (expr
))
1356 if (TREE_CODE (expr
) != SSA_NAME
|| SSA_NAME_IS_DEFAULT_DEF (expr
))
1359 if (!is_gimple_assign (stmt
= SSA_NAME_DEF_STMT (expr
)))
1362 switch (gimple_assign_rhs_class (stmt
))
1364 case GIMPLE_SINGLE_RHS
:
1365 expr
= gimple_assign_rhs1 (stmt
);
1368 case GIMPLE_UNARY_RHS
:
1372 case GIMPLE_BINARY_RHS
:
1376 case GIMPLE_TERNARY_RHS
:
1384 /* Stop if expression is too complex. */
1385 if (op_count
++ == op_limit
)
1390 eval_op
.code
= gimple_assign_rhs_code (stmt
);
1391 eval_op
.type
= TREE_TYPE (gimple_assign_lhs (stmt
));
1392 eval_op
.val
[0] = NULL_TREE
;
1393 eval_op
.val
[1] = NULL_TREE
;
1397 for (unsigned i
= 0; i
< rhs_count
; i
++)
1399 tree op
= gimple_op (stmt
, i
+ 1);
1401 gcc_assert (op
&& !TYPE_P (op
));
1402 if (is_gimple_ip_invariant (op
))
1404 if (++cst_count
== rhs_count
)
1407 eval_op
.val
[cst_count
- 1] = op
;
1411 /* Found a non-constant operand, and record its index in rhs
1418 /* Found more than one non-constant operands. */
1424 vec_safe_insert (*param_ops_p
, 0, eval_op
);
1427 /* Failed to decompose, free resource and return. */
1430 vec_free (*param_ops_p
);
1435 /* If BB ends by a conditional we can turn into predicates, attach corresponding
1436 predicates to the CFG edges. */
1439 set_cond_stmt_execution_predicate (struct ipa_func_body_info
*fbi
,
1440 class ipa_fn_summary
*summary
,
1441 class ipa_node_params
*params_summary
,
1447 struct agg_position_info aggpos
;
1448 enum tree_code code
, inverted_code
;
1453 expr_eval_ops param_ops
;
1455 last
= last_stmt (bb
);
1456 if (!last
|| gimple_code (last
) != GIMPLE_COND
)
1458 if (!is_gimple_ip_invariant (gimple_cond_rhs (last
)))
1460 op
= gimple_cond_lhs (last
);
1462 if (decompose_param_expr (fbi
, last
, op
, &index
, ¶m_type
, &aggpos
,
1465 code
= gimple_cond_code (last
);
1466 inverted_code
= invert_tree_comparison (code
, HONOR_NANS (op
));
1468 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1470 enum tree_code this_code
= (e
->flags
& EDGE_TRUE_VALUE
1471 ? code
: inverted_code
);
1472 /* invert_tree_comparison will return ERROR_MARK on FP
1473 comparisons that are not EQ/NE instead of returning proper
1474 unordered one. Be sure it is not confused with NON_CONSTANT.
1476 And if the edge's target is the final block of diamond CFG graph
1477 of this conditional statement, we do not need to compute
1478 predicate for the edge because the final block's predicate must
1479 be at least as that of the first block of the statement. */
1480 if (this_code
!= ERROR_MARK
1481 && !dominated_by_p (CDI_POST_DOMINATORS
, bb
, e
->dest
))
1484 = add_condition (summary
, params_summary
, index
,
1485 param_type
, &aggpos
,
1486 this_code
, gimple_cond_rhs (last
), param_ops
);
1487 e
->aux
= edge_predicate_pool
.allocate ();
1488 *(predicate
*) e
->aux
= p
;
1491 vec_free (param_ops
);
1494 if (TREE_CODE (op
) != SSA_NAME
)
1497 if (builtin_constant_p (op))
1501 Here we can predicate nonconstant_code. We can't
1502 really handle constant_code since we have no predicate
1503 for this and also the constant code is not known to be
1504 optimized away when inliner doesn't see operand is constant.
1505 Other optimizers might think otherwise. */
1506 if (gimple_cond_code (last
) != NE_EXPR
1507 || !integer_zerop (gimple_cond_rhs (last
)))
1509 set_stmt
= SSA_NAME_DEF_STMT (op
);
1510 if (!gimple_call_builtin_p (set_stmt
, BUILT_IN_CONSTANT_P
)
1511 || gimple_call_num_args (set_stmt
) != 1)
1513 op2
= gimple_call_arg (set_stmt
, 0);
1514 if (!decompose_param_expr (fbi
, set_stmt
, op2
, &index
, ¶m_type
, &aggpos
))
1516 FOR_EACH_EDGE (e
, ei
, bb
->succs
) if (e
->flags
& EDGE_FALSE_VALUE
)
1518 predicate p
= add_condition (summary
, params_summary
, index
,
1519 param_type
, &aggpos
,
1520 predicate::is_not_constant
, NULL_TREE
);
1521 e
->aux
= edge_predicate_pool
.allocate ();
1522 *(predicate
*) e
->aux
= p
;
1527 /* If BB ends by a switch we can turn into predicates, attach corresponding
1528 predicates to the CFG edges. */
1531 set_switch_stmt_execution_predicate (struct ipa_func_body_info
*fbi
,
1532 class ipa_fn_summary
*summary
,
1533 class ipa_node_params
*params_summary
,
1539 struct agg_position_info aggpos
;
1545 expr_eval_ops param_ops
;
1547 lastg
= last_stmt (bb
);
1548 if (!lastg
|| gimple_code (lastg
) != GIMPLE_SWITCH
)
1550 gswitch
*last
= as_a
<gswitch
*> (lastg
);
1551 op
= gimple_switch_index (last
);
1552 if (!decompose_param_expr (fbi
, last
, op
, &index
, ¶m_type
, &aggpos
,
1556 auto_vec
<std::pair
<tree
, tree
> > ranges
;
1557 tree type
= TREE_TYPE (op
);
1558 int bound_limit
= opt_for_fn (fbi
->node
->decl
,
1559 param_ipa_max_switch_predicate_bounds
);
1560 int bound_count
= 0;
1561 wide_int vr_wmin
, vr_wmax
;
1562 value_range_kind vr_type
= get_range_info (op
, &vr_wmin
, &vr_wmax
);
1564 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1566 e
->aux
= edge_predicate_pool
.allocate ();
1567 *(predicate
*) e
->aux
= false;
1570 e
= gimple_switch_edge (cfun
, last
, 0);
1571 /* Set BOUND_COUNT to maximum count to bypass computing predicate for
1572 default case if its target basic block is in convergence point of all
1573 switch cases, which can be determined by checking whether it
1574 post-dominates the switch statement. */
1575 if (dominated_by_p (CDI_POST_DOMINATORS
, bb
, e
->dest
))
1576 bound_count
= INT_MAX
;
1578 n
= gimple_switch_num_labels (last
);
1579 for (case_idx
= 1; case_idx
< n
; ++case_idx
)
1581 tree cl
= gimple_switch_label (last
, case_idx
);
1582 tree min
= CASE_LOW (cl
);
1583 tree max
= CASE_HIGH (cl
);
1586 e
= gimple_switch_edge (cfun
, last
, case_idx
);
1588 /* The case value might not have same type as switch expression,
1589 extend the value based on the expression type. */
1590 if (TREE_TYPE (min
) != type
)
1591 min
= wide_int_to_tree (type
, wi::to_wide (min
));
1595 else if (TREE_TYPE (max
) != type
)
1596 max
= wide_int_to_tree (type
, wi::to_wide (max
));
1598 /* The case's target basic block is in convergence point of all switch
1599 cases, its predicate should be at least as that of the switch
1601 if (dominated_by_p (CDI_POST_DOMINATORS
, bb
, e
->dest
))
1603 else if (min
== max
)
1604 p
= add_condition (summary
, params_summary
, index
, param_type
,
1605 &aggpos
, EQ_EXPR
, min
, param_ops
);
1609 p1
= add_condition (summary
, params_summary
, index
, param_type
,
1610 &aggpos
, GE_EXPR
, min
, param_ops
);
1611 p2
= add_condition (summary
, params_summary
,index
, param_type
,
1612 &aggpos
, LE_EXPR
, max
, param_ops
);
1615 *(class predicate
*) e
->aux
1616 = p
.or_with (summary
->conds
, *(class predicate
*) e
->aux
);
1618 /* If there are too many disjoint case ranges, predicate for default
1619 case might become too complicated. So add a limit here. */
1620 if (bound_count
> bound_limit
)
1623 bool new_range
= true;
1625 if (!ranges
.is_empty ())
1627 wide_int curr_wmin
= wi::to_wide (min
);
1628 wide_int last_wmax
= wi::to_wide (ranges
.last ().second
);
1630 /* Merge case ranges if they are continuous. */
1631 if (curr_wmin
== last_wmax
+ 1)
1633 else if (vr_type
== VR_ANTI_RANGE
)
1635 /* If two disjoint case ranges can be connected by anti-range
1636 of switch index, combine them to one range. */
1637 if (wi::lt_p (vr_wmax
, curr_wmin
- 1, TYPE_SIGN (type
)))
1638 vr_type
= VR_UNDEFINED
;
1639 else if (wi::le_p (vr_wmin
, last_wmax
+ 1, TYPE_SIGN (type
)))
1644 /* Create/extend a case range. And we count endpoints of range set,
1645 this number nearly equals to number of conditions that we will create
1646 for predicate of default case. */
1649 bound_count
+= (min
== max
) ? 1 : 2;
1650 ranges
.safe_push (std::make_pair (min
, max
));
1654 bound_count
+= (ranges
.last ().first
== ranges
.last ().second
);
1655 ranges
.last ().second
= max
;
1659 e
= gimple_switch_edge (cfun
, last
, 0);
1660 if (bound_count
> bound_limit
)
1662 *(class predicate
*) e
->aux
= true;
1663 vec_free (param_ops
);
1667 predicate p_seg
= true;
1668 predicate p_all
= false;
1670 if (vr_type
!= VR_RANGE
)
1672 vr_wmin
= wi::to_wide (TYPE_MIN_VALUE (type
));
1673 vr_wmax
= wi::to_wide (TYPE_MAX_VALUE (type
));
1676 /* Construct predicate to represent default range set that is negation of
1677 all case ranges. Case range is classified as containing single/non-single
1678 values. Suppose a piece of case ranges in the following.
1680 [D1...D2] [S1] ... [Sn] [D3...D4]
1682 To represent default case's range sets between two non-single value
1683 case ranges (From D2 to D3), we construct predicate as:
1685 D2 < x < D3 && x != S1 && ... && x != Sn
1687 for (size_t i
= 0; i
< ranges
.length (); i
++)
1689 tree min
= ranges
[i
].first
;
1690 tree max
= ranges
[i
].second
;
1693 p_seg
&= add_condition (summary
, params_summary
, index
,
1694 param_type
, &aggpos
, NE_EXPR
,
1698 /* Do not create sub-predicate for range that is beyond low bound
1700 if (wi::lt_p (vr_wmin
, wi::to_wide (min
), TYPE_SIGN (type
)))
1702 p_seg
&= add_condition (summary
, params_summary
, index
,
1703 param_type
, &aggpos
,
1704 LT_EXPR
, min
, param_ops
);
1705 p_all
= p_all
.or_with (summary
->conds
, p_seg
);
1708 /* Do not create sub-predicate for range that is beyond up bound
1710 if (wi::le_p (vr_wmax
, wi::to_wide (max
), TYPE_SIGN (type
)))
1716 p_seg
= add_condition (summary
, params_summary
, index
,
1717 param_type
, &aggpos
, GT_EXPR
,
1722 p_all
= p_all
.or_with (summary
->conds
, p_seg
);
1723 *(class predicate
*) e
->aux
1724 = p_all
.or_with (summary
->conds
, *(class predicate
*) e
->aux
);
1726 vec_free (param_ops
);
1730 /* For each BB in NODE attach to its AUX pointer predicate under
1731 which it is executable. */
1734 compute_bb_predicates (struct ipa_func_body_info
*fbi
,
1735 struct cgraph_node
*node
,
1736 class ipa_fn_summary
*summary
,
1737 class ipa_node_params
*params_summary
)
1739 struct function
*my_function
= DECL_STRUCT_FUNCTION (node
->decl
);
1743 FOR_EACH_BB_FN (bb
, my_function
)
1745 set_cond_stmt_execution_predicate (fbi
, summary
, params_summary
, bb
);
1746 set_switch_stmt_execution_predicate (fbi
, summary
, params_summary
, bb
);
1749 /* Entry block is always executable. */
1750 ENTRY_BLOCK_PTR_FOR_FN (my_function
)->aux
1751 = edge_predicate_pool
.allocate ();
1752 *(predicate
*) ENTRY_BLOCK_PTR_FOR_FN (my_function
)->aux
= true;
1754 /* A simple dataflow propagation of predicates forward in the CFG.
1755 TODO: work in reverse postorder. */
1759 FOR_EACH_BB_FN (bb
, my_function
)
1761 predicate p
= false;
1764 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1768 predicate this_bb_predicate
1769 = *(predicate
*) e
->src
->aux
;
1771 this_bb_predicate
&= (*(class predicate
*) e
->aux
);
1772 p
= p
.or_with (summary
->conds
, this_bb_predicate
);
1779 basic_block pdom_bb
;
1784 bb
->aux
= edge_predicate_pool
.allocate ();
1785 *((predicate
*) bb
->aux
) = p
;
1787 else if (p
!= *(predicate
*) bb
->aux
)
1789 /* This OR operation is needed to ensure monotonous data flow
1790 in the case we hit the limit on number of clauses and the
1791 and/or operations above give approximate answers. */
1792 p
= p
.or_with (summary
->conds
, *(predicate
*)bb
->aux
);
1793 if (p
!= *(predicate
*) bb
->aux
)
1796 *((predicate
*) bb
->aux
) = p
;
1800 /* For switch/if statement, we can OR-combine predicates of all
1801 its cases/branches to get predicate for basic block in their
1802 convergence point, but sometimes this will generate very
1803 complicated predicate. Actually, we can get simplified
1804 predicate in another way by using the fact that predicate
1805 for a basic block must also hold true for its post dominators.
1806 To be specific, basic block in convergence point of
1807 conditional statement should include predicate of the
1809 pdom_bb
= get_immediate_dominator (CDI_POST_DOMINATORS
, bb
);
1810 if (pdom_bb
== EXIT_BLOCK_PTR_FOR_FN (my_function
) || !pdom_bb
)
1812 else if (!pdom_bb
->aux
)
1815 pdom_bb
->aux
= edge_predicate_pool
.allocate ();
1816 *((predicate
*) pdom_bb
->aux
) = p
;
1818 else if (p
!= *(predicate
*) pdom_bb
->aux
)
1820 p
= p
.or_with (summary
->conds
, *(predicate
*)pdom_bb
->aux
);
1821 if (p
!= *(predicate
*) pdom_bb
->aux
)
1824 *((predicate
*) pdom_bb
->aux
) = p
;
1833 /* Return predicate specifying when the STMT might have result that is not
1834 a compile time constant. */
1837 will_be_nonconstant_expr_predicate (ipa_func_body_info
*fbi
,
1838 class ipa_fn_summary
*summary
,
1839 class ipa_node_params
*params_summary
,
1841 vec
<predicate
> nonconstant_names
)
1846 while (UNARY_CLASS_P (expr
))
1847 expr
= TREE_OPERAND (expr
, 0);
1849 parm
= unmodified_parm (fbi
, NULL
, expr
, NULL
);
1850 if (parm
&& (index
= ipa_get_param_decl_index (fbi
->info
, parm
)) >= 0)
1851 return add_condition (summary
, params_summary
, index
, TREE_TYPE (parm
), NULL
,
1852 predicate::changed
, NULL_TREE
);
1853 if (is_gimple_min_invariant (expr
))
1855 if (TREE_CODE (expr
) == SSA_NAME
)
1856 return nonconstant_names
[SSA_NAME_VERSION (expr
)];
1857 if (BINARY_CLASS_P (expr
) || COMPARISON_CLASS_P (expr
))
1860 = will_be_nonconstant_expr_predicate (fbi
, summary
,
1862 TREE_OPERAND (expr
, 0),
1868 = will_be_nonconstant_expr_predicate (fbi
, summary
,
1870 TREE_OPERAND (expr
, 1),
1872 return p1
.or_with (summary
->conds
, p2
);
1874 else if (TREE_CODE (expr
) == COND_EXPR
)
1877 = will_be_nonconstant_expr_predicate (fbi
, summary
,
1879 TREE_OPERAND (expr
, 0),
1885 = will_be_nonconstant_expr_predicate (fbi
, summary
,
1887 TREE_OPERAND (expr
, 1),
1891 p1
= p1
.or_with (summary
->conds
, p2
);
1892 p2
= will_be_nonconstant_expr_predicate (fbi
, summary
,
1894 TREE_OPERAND (expr
, 2),
1896 return p2
.or_with (summary
->conds
, p1
);
1898 else if (TREE_CODE (expr
) == CALL_EXPR
)
1909 /* Return predicate specifying when the STMT might have result that is not
1910 a compile time constant. */
1913 will_be_nonconstant_predicate (struct ipa_func_body_info
*fbi
,
1914 class ipa_fn_summary
*summary
,
1915 class ipa_node_params
*params_summary
,
1917 vec
<predicate
> nonconstant_names
)
1922 tree param_type
= NULL_TREE
;
1923 predicate op_non_const
;
1926 struct agg_position_info aggpos
;
1928 /* What statements might be optimized away
1929 when their arguments are constant. */
1930 if (gimple_code (stmt
) != GIMPLE_ASSIGN
1931 && gimple_code (stmt
) != GIMPLE_COND
1932 && gimple_code (stmt
) != GIMPLE_SWITCH
1933 && (gimple_code (stmt
) != GIMPLE_CALL
1934 || !(gimple_call_flags (stmt
) & ECF_CONST
)))
1937 /* Stores will stay anyway. */
1938 if (gimple_store_p (stmt
))
1941 is_load
= gimple_assign_load_p (stmt
);
1943 /* Loads can be optimized when the value is known. */
1946 tree op
= gimple_assign_rhs1 (stmt
);
1947 if (!decompose_param_expr (fbi
, stmt
, op
, &base_index
, ¶m_type
,
1954 /* See if we understand all operands before we start
1955 adding conditionals. */
1956 FOR_EACH_SSA_TREE_OPERAND (use
, stmt
, iter
, SSA_OP_USE
)
1958 tree parm
= unmodified_parm (fbi
, stmt
, use
, NULL
);
1959 /* For arguments we can build a condition. */
1960 if (parm
&& ipa_get_param_decl_index (fbi
->info
, parm
) >= 0)
1962 if (TREE_CODE (use
) != SSA_NAME
)
1964 /* If we know when operand is constant,
1965 we still can say something useful. */
1966 if (nonconstant_names
[SSA_NAME_VERSION (use
)] != true)
1973 add_condition (summary
, params_summary
,
1974 base_index
, param_type
, &aggpos
,
1975 predicate::changed
, NULL_TREE
);
1977 op_non_const
= false;
1978 FOR_EACH_SSA_TREE_OPERAND (use
, stmt
, iter
, SSA_OP_USE
)
1980 tree parm
= unmodified_parm (fbi
, stmt
, use
, NULL
);
1983 if (parm
&& (index
= ipa_get_param_decl_index (fbi
->info
, parm
)) >= 0)
1985 if (index
!= base_index
)
1986 p
= add_condition (summary
, params_summary
, index
,
1987 TREE_TYPE (parm
), NULL
,
1988 predicate::changed
, NULL_TREE
);
1993 p
= nonconstant_names
[SSA_NAME_VERSION (use
)];
1994 op_non_const
= p
.or_with (summary
->conds
, op_non_const
);
1996 if ((gimple_code (stmt
) == GIMPLE_ASSIGN
|| gimple_code (stmt
) == GIMPLE_CALL
)
1997 && gimple_op (stmt
, 0)
1998 && TREE_CODE (gimple_op (stmt
, 0)) == SSA_NAME
)
1999 nonconstant_names
[SSA_NAME_VERSION (gimple_op (stmt
, 0))]
2001 return op_non_const
;
2004 struct record_modified_bb_info
2011 /* Value is initialized in INIT_BB and used in USE_BB. We want to compute
2012 probability how often it changes between USE_BB.
2013 INIT_BB->count/USE_BB->count is an estimate, but if INIT_BB
2014 is in different loop nest, we can do better.
2015 This is all just estimate. In theory we look for minimal cut separating
2016 INIT_BB and USE_BB, but we only want to anticipate loop invariant motion
2020 get_minimal_bb (basic_block init_bb
, basic_block use_bb
)
2022 class loop
*l
= find_common_loop (init_bb
->loop_father
, use_bb
->loop_father
);
2023 if (l
&& l
->header
->count
< init_bb
->count
)
2028 /* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
2029 set except for info->stmt. */
2032 record_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
, void *data
)
2034 struct record_modified_bb_info
*info
=
2035 (struct record_modified_bb_info
*) data
;
2036 if (SSA_NAME_DEF_STMT (vdef
) == info
->stmt
)
2038 if (gimple_clobber_p (SSA_NAME_DEF_STMT (vdef
)))
2040 bitmap_set_bit (info
->bb_set
,
2041 SSA_NAME_IS_DEFAULT_DEF (vdef
)
2042 ? ENTRY_BLOCK_PTR_FOR_FN (cfun
)->index
2044 (gimple_bb (SSA_NAME_DEF_STMT (vdef
)),
2045 gimple_bb (info
->stmt
))->index
);
2048 fprintf (dump_file
, " Param ");
2049 print_generic_expr (dump_file
, info
->op
, TDF_SLIM
);
2050 fprintf (dump_file
, " changed at bb %i, minimal: %i stmt: ",
2051 gimple_bb (SSA_NAME_DEF_STMT (vdef
))->index
,
2053 (gimple_bb (SSA_NAME_DEF_STMT (vdef
)),
2054 gimple_bb (info
->stmt
))->index
);
2055 print_gimple_stmt (dump_file
, SSA_NAME_DEF_STMT (vdef
), 0);
2060 /* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
2061 will change since last invocation of STMT.
2063 Value 0 is reserved for compile time invariants.
2064 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
2065 ought to be REG_BR_PROB_BASE / estimated_iters. */
2068 param_change_prob (ipa_func_body_info
*fbi
, gimple
*stmt
, int i
)
2070 tree op
= gimple_call_arg (stmt
, i
);
2071 basic_block bb
= gimple_bb (stmt
);
2073 if (TREE_CODE (op
) == WITH_SIZE_EXPR
)
2074 op
= TREE_OPERAND (op
, 0);
2076 tree base
= get_base_address (op
);
2078 /* Global invariants never change. */
2079 if (is_gimple_min_invariant (base
))
2082 /* We would have to do non-trivial analysis to really work out what
2083 is the probability of value to change (i.e. when init statement
2084 is in a sibling loop of the call).
2086 We do an conservative estimate: when call is executed N times more often
2087 than the statement defining value, we take the frequency 1/N. */
2088 if (TREE_CODE (base
) == SSA_NAME
)
2090 profile_count init_count
;
2092 if (!bb
->count
.nonzero_p ())
2093 return REG_BR_PROB_BASE
;
2095 if (SSA_NAME_IS_DEFAULT_DEF (base
))
2096 init_count
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
2098 init_count
= get_minimal_bb
2099 (gimple_bb (SSA_NAME_DEF_STMT (base
)),
2100 gimple_bb (stmt
))->count
;
2102 if (init_count
< bb
->count
)
2103 return MAX ((init_count
.to_sreal_scale (bb
->count
)
2104 * REG_BR_PROB_BASE
).to_int (), 1);
2105 return REG_BR_PROB_BASE
;
2110 profile_count max
= ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
;
2111 struct record_modified_bb_info info
;
2112 tree init
= ctor_for_folding (base
);
2114 if (init
!= error_mark_node
)
2116 if (!bb
->count
.nonzero_p ())
2117 return REG_BR_PROB_BASE
;
2120 fprintf (dump_file
, " Analyzing param change probability of ");
2121 print_generic_expr (dump_file
, op
, TDF_SLIM
);
2122 fprintf (dump_file
, "\n");
2124 ao_ref_init (&refd
, op
);
2127 info
.bb_set
= BITMAP_ALLOC (NULL
);
2129 = walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), record_modified
, &info
,
2130 NULL
, NULL
, fbi
->aa_walk_budget
);
2131 if (walked
< 0 || bitmap_bit_p (info
.bb_set
, bb
->index
))
2136 fprintf (dump_file
, " Ran out of AA walking budget.\n");
2138 fprintf (dump_file
, " Set in same BB as used.\n");
2140 BITMAP_FREE (info
.bb_set
);
2141 return REG_BR_PROB_BASE
;
2146 /* Lookup the most frequent update of the value and believe that
2147 it dominates all the other; precise analysis here is difficult. */
2148 EXECUTE_IF_SET_IN_BITMAP (info
.bb_set
, 0, index
, bi
)
2149 max
= max
.max (BASIC_BLOCK_FOR_FN (cfun
, index
)->count
);
2152 fprintf (dump_file
, " Set with count ");
2153 max
.dump (dump_file
);
2154 fprintf (dump_file
, " and used with count ");
2155 bb
->count
.dump (dump_file
);
2156 fprintf (dump_file
, " freq %f\n",
2157 max
.to_sreal_scale (bb
->count
).to_double ());
2160 BITMAP_FREE (info
.bb_set
);
2161 if (max
< bb
->count
)
2162 return MAX ((max
.to_sreal_scale (bb
->count
)
2163 * REG_BR_PROB_BASE
).to_int (), 1);
2164 return REG_BR_PROB_BASE
;
2168 /* Find whether a basic block BB is the final block of a (half) diamond CFG
2169 sub-graph and if the predicate the condition depends on is known. If so,
2170 return true and store the pointer the predicate in *P. */
2173 phi_result_unknown_predicate (ipa_func_body_info
*fbi
,
2174 ipa_fn_summary
*summary
,
2175 class ipa_node_params
*params_summary
,
2178 vec
<predicate
> nonconstant_names
)
2182 basic_block first_bb
= NULL
;
2185 if (single_pred_p (bb
))
2191 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
2193 if (single_succ_p (e
->src
))
2195 if (!single_pred_p (e
->src
))
2198 first_bb
= single_pred (e
->src
);
2199 else if (single_pred (e
->src
) != first_bb
)
2206 else if (e
->src
!= first_bb
)
2214 stmt
= last_stmt (first_bb
);
2216 || gimple_code (stmt
) != GIMPLE_COND
2217 || !is_gimple_ip_invariant (gimple_cond_rhs (stmt
)))
2220 *p
= will_be_nonconstant_expr_predicate (fbi
, summary
, params_summary
,
2221 gimple_cond_lhs (stmt
),
2229 /* Given a PHI statement in a function described by inline properties SUMMARY
2230 and *P being the predicate describing whether the selected PHI argument is
2231 known, store a predicate for the result of the PHI statement into
2232 NONCONSTANT_NAMES, if possible. */
2235 predicate_for_phi_result (class ipa_fn_summary
*summary
, gphi
*phi
,
2237 vec
<predicate
> nonconstant_names
)
2241 for (i
= 0; i
< gimple_phi_num_args (phi
); i
++)
2243 tree arg
= gimple_phi_arg (phi
, i
)->def
;
2244 if (!is_gimple_min_invariant (arg
))
2246 gcc_assert (TREE_CODE (arg
) == SSA_NAME
);
2247 *p
= p
->or_with (summary
->conds
,
2248 nonconstant_names
[SSA_NAME_VERSION (arg
)]);
2254 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2256 fprintf (dump_file
, "\t\tphi predicate: ");
2257 p
->dump (dump_file
, summary
->conds
);
2259 nonconstant_names
[SSA_NAME_VERSION (gimple_phi_result (phi
))] = *p
;
2262 /* For a typical usage of __builtin_expect (a<b, 1), we
2263 may introduce an extra relation stmt:
2264 With the builtin, we have
2267 t3 = __builtin_expect (t2, 1);
2270 Without the builtin, we have
2273 This affects the size/time estimation and may have
2274 an impact on the earlier inlining.
2275 Here find this pattern and fix it up later. */
2278 find_foldable_builtin_expect (basic_block bb
)
2280 gimple_stmt_iterator bsi
;
2282 for (bsi
= gsi_start_bb (bb
); !gsi_end_p (bsi
); gsi_next (&bsi
))
2284 gimple
*stmt
= gsi_stmt (bsi
);
2285 if (gimple_call_builtin_p (stmt
, BUILT_IN_EXPECT
)
2286 || gimple_call_builtin_p (stmt
, BUILT_IN_EXPECT_WITH_PROBABILITY
)
2287 || gimple_call_internal_p (stmt
, IFN_BUILTIN_EXPECT
))
2289 tree var
= gimple_call_lhs (stmt
);
2290 tree arg
= gimple_call_arg (stmt
, 0);
2291 use_operand_p use_p
;
2298 gcc_assert (TREE_CODE (var
) == SSA_NAME
);
2300 while (TREE_CODE (arg
) == SSA_NAME
)
2302 gimple
*stmt_tmp
= SSA_NAME_DEF_STMT (arg
);
2303 if (!is_gimple_assign (stmt_tmp
))
2305 switch (gimple_assign_rhs_code (stmt_tmp
))
2324 arg
= gimple_assign_rhs1 (stmt_tmp
);
2327 if (match
&& single_imm_use (var
, &use_p
, &use_stmt
)
2328 && gimple_code (use_stmt
) == GIMPLE_COND
)
2335 /* Return true when the basic blocks contains only clobbers followed by RESX.
2336 Such BBs are kept around to make removal of dead stores possible with
2337 presence of EH and will be optimized out by optimize_clobbers later in the
2340 NEED_EH is used to recurse in case the clobber has non-EH predecessors
2341 that can be clobber only, too.. When it is false, the RESX is not necessary
2342 on the end of basic block. */
2345 clobber_only_eh_bb_p (basic_block bb
, bool need_eh
= true)
2347 gimple_stmt_iterator gsi
= gsi_last_bb (bb
);
2353 if (gsi_end_p (gsi
))
2355 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_RESX
)
2359 else if (!single_succ_p (bb
))
2362 for (; !gsi_end_p (gsi
); gsi_prev (&gsi
))
2364 gimple
*stmt
= gsi_stmt (gsi
);
2365 if (is_gimple_debug (stmt
))
2367 if (gimple_clobber_p (stmt
))
2369 if (gimple_code (stmt
) == GIMPLE_LABEL
)
2374 /* See if all predecessors are either throws or clobber only BBs. */
2375 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
2376 if (!(e
->flags
& EDGE_EH
)
2377 && !clobber_only_eh_bb_p (e
->src
, false))
2383 /* Return true if STMT compute a floating point expression that may be affected
2384 by -ffast-math and similar flags. */
2387 fp_expression_p (gimple
*stmt
)
2392 FOR_EACH_SSA_TREE_OPERAND (op
, stmt
, i
, SSA_OP_DEF
|SSA_OP_USE
)
2393 if (FLOAT_TYPE_P (TREE_TYPE (op
)))
2398 /* Analyze function body for NODE.
2399 EARLY indicates run from early optimization pipeline. */
2402 analyze_function_body (struct cgraph_node
*node
, bool early
)
2404 sreal time
= opt_for_fn (node
->decl
, param_uninlined_function_time
);
2405 /* Estimate static overhead for function prologue/epilogue and alignment. */
2406 int size
= opt_for_fn (node
->decl
, param_uninlined_function_insns
);
2407 /* Benefits are scaled by probability of elimination that is in range
2410 struct function
*my_function
= DECL_STRUCT_FUNCTION (node
->decl
);
2412 class ipa_fn_summary
*info
= ipa_fn_summaries
->get_create (node
);
2413 class ipa_node_params
*params_summary
= early
? NULL
: IPA_NODE_REF (node
);
2414 predicate bb_predicate
;
2415 struct ipa_func_body_info fbi
;
2416 vec
<predicate
> nonconstant_names
= vNULL
;
2419 gimple
*fix_builtin_expect_stmt
;
2421 gcc_assert (my_function
&& my_function
->cfg
);
2422 gcc_assert (cfun
== my_function
);
2424 memset(&fbi
, 0, sizeof(fbi
));
2425 vec_free (info
->conds
);
2427 vec_free (info
->size_time_table
);
2428 info
->size_time_table
= NULL
;
2430 /* When optimizing and analyzing for IPA inliner, initialize loop optimizer
2431 so we can produce proper inline hints.
2433 When optimizing and analyzing for early inliner, initialize node params
2434 so we can produce correct BB predicates. */
2436 if (opt_for_fn (node
->decl
, optimize
))
2438 calculate_dominance_info (CDI_DOMINATORS
);
2439 calculate_dominance_info (CDI_POST_DOMINATORS
);
2441 loop_optimizer_init (LOOPS_NORMAL
| LOOPS_HAVE_RECORDED_EXITS
);
2444 ipa_check_create_node_params ();
2445 ipa_initialize_node_params (node
);
2448 if (ipa_node_params_sum
)
2451 fbi
.info
= IPA_NODE_REF (node
);
2452 fbi
.bb_infos
= vNULL
;
2453 fbi
.bb_infos
.safe_grow_cleared (last_basic_block_for_fn (cfun
));
2454 fbi
.param_count
= count_formal_params (node
->decl
);
2455 fbi
.aa_walk_budget
= opt_for_fn (node
->decl
, param_ipa_max_aa_steps
);
2457 nonconstant_names
.safe_grow_cleared
2458 (SSANAMES (my_function
)->length ());
2463 fprintf (dump_file
, "\nAnalyzing function body size: %s\n",
2464 node
->dump_name ());
2466 /* When we run into maximal number of entries, we assign everything to the
2467 constant truth case. Be sure to have it in list. */
2468 bb_predicate
= true;
2469 info
->account_size_time (0, 0, bb_predicate
, bb_predicate
);
2471 bb_predicate
= predicate::not_inlined ();
2472 info
->account_size_time (opt_for_fn (node
->decl
,
2473 param_uninlined_function_insns
)
2474 * ipa_fn_summary::size_scale
,
2475 opt_for_fn (node
->decl
,
2476 param_uninlined_function_time
),
2481 compute_bb_predicates (&fbi
, node
, info
, params_summary
);
2482 order
= XNEWVEC (int, n_basic_blocks_for_fn (cfun
));
2483 nblocks
= pre_and_rev_post_order_compute (NULL
, order
, false);
2484 for (n
= 0; n
< nblocks
; n
++)
2486 bb
= BASIC_BLOCK_FOR_FN (cfun
, order
[n
]);
2487 freq
= bb
->count
.to_sreal_scale (ENTRY_BLOCK_PTR_FOR_FN (cfun
)->count
);
2488 if (clobber_only_eh_bb_p (bb
))
2490 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2491 fprintf (dump_file
, "\n Ignoring BB %i;"
2492 " it will be optimized away by cleanup_clobbers\n",
2497 /* TODO: Obviously predicates can be propagated down across CFG. */
2501 bb_predicate
= *(predicate
*) bb
->aux
;
2503 bb_predicate
= false;
2506 bb_predicate
= true;
2508 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2510 fprintf (dump_file
, "\n BB %i predicate:", bb
->index
);
2511 bb_predicate
.dump (dump_file
, info
->conds
);
2514 if (fbi
.info
&& nonconstant_names
.exists ())
2516 predicate phi_predicate
;
2517 bool first_phi
= true;
2519 for (gphi_iterator bsi
= gsi_start_phis (bb
); !gsi_end_p (bsi
);
2523 && !phi_result_unknown_predicate (&fbi
, info
,
2530 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2532 fprintf (dump_file
, " ");
2533 print_gimple_stmt (dump_file
, gsi_stmt (bsi
), 0);
2535 predicate_for_phi_result (info
, bsi
.phi (), &phi_predicate
,
2540 fix_builtin_expect_stmt
= find_foldable_builtin_expect (bb
);
2542 for (gimple_stmt_iterator bsi
= gsi_start_nondebug_bb (bb
);
2543 !gsi_end_p (bsi
); gsi_next_nondebug (&bsi
))
2545 gimple
*stmt
= gsi_stmt (bsi
);
2546 int this_size
= estimate_num_insns (stmt
, &eni_size_weights
);
2547 int this_time
= estimate_num_insns (stmt
, &eni_time_weights
);
2549 predicate will_be_nonconstant
;
2551 /* This relation stmt should be folded after we remove
2552 __builtin_expect call. Adjust the cost here. */
2553 if (stmt
== fix_builtin_expect_stmt
)
2559 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2561 fprintf (dump_file
, " ");
2562 print_gimple_stmt (dump_file
, stmt
, 0);
2563 fprintf (dump_file
, "\t\tfreq:%3.2f size:%3i time:%3i\n",
2564 freq
.to_double (), this_size
,
2568 if (is_gimple_call (stmt
)
2569 && !gimple_call_internal_p (stmt
))
2571 struct cgraph_edge
*edge
= node
->get_edge (stmt
);
2572 ipa_call_summary
*es
= ipa_call_summaries
->get_create (edge
);
2574 /* Special case: results of BUILT_IN_CONSTANT_P will be always
2575 resolved as constant. We however don't want to optimize
2576 out the cgraph edges. */
2577 if (nonconstant_names
.exists ()
2578 && gimple_call_builtin_p (stmt
, BUILT_IN_CONSTANT_P
)
2579 && gimple_call_lhs (stmt
)
2580 && TREE_CODE (gimple_call_lhs (stmt
)) == SSA_NAME
)
2582 predicate false_p
= false;
2583 nonconstant_names
[SSA_NAME_VERSION (gimple_call_lhs (stmt
))]
2586 if (ipa_node_params_sum
)
2588 int count
= gimple_call_num_args (stmt
);
2592 es
->param
.safe_grow_cleared (count
);
2593 for (i
= 0; i
< count
; i
++)
2595 int prob
= param_change_prob (&fbi
, stmt
, i
);
2596 gcc_assert (prob
>= 0 && prob
<= REG_BR_PROB_BASE
);
2597 es
->param
[i
].change_prob
= prob
;
2601 es
->call_stmt_size
= this_size
;
2602 es
->call_stmt_time
= this_time
;
2603 es
->loop_depth
= bb_loop_depth (bb
);
2604 edge_set_predicate (edge
, &bb_predicate
);
2605 if (edge
->speculative
)
2607 cgraph_edge
*direct
, *indirect
;
2609 edge
->speculative_call_info (direct
, indirect
, ref
);
2610 gcc_assert (direct
== edge
);
2611 ipa_call_summary
*es2
2612 = ipa_call_summaries
->get_create (indirect
);
2613 ipa_call_summaries
->duplicate (edge
, indirect
,
2618 /* TODO: When conditional jump or switch is known to be constant, but
2619 we did not translate it into the predicates, we really can account
2620 just maximum of the possible paths. */
2623 = will_be_nonconstant_predicate (&fbi
, info
, params_summary
,
2624 stmt
, nonconstant_names
);
2626 will_be_nonconstant
= true;
2627 if (this_time
|| this_size
)
2629 sreal final_time
= (sreal
)this_time
* freq
;
2631 prob
= eliminated_by_inlining_prob (&fbi
, stmt
);
2632 if (prob
== 1 && dump_file
&& (dump_flags
& TDF_DETAILS
))
2634 "\t\t50%% will be eliminated by inlining\n");
2635 if (prob
== 2 && dump_file
&& (dump_flags
& TDF_DETAILS
))
2636 fprintf (dump_file
, "\t\tWill be eliminated by inlining\n");
2638 class predicate p
= bb_predicate
& will_be_nonconstant
;
2640 /* We can ignore statement when we proved it is never going
2641 to happen, but we cannot do that for call statements
2642 because edges are accounted specially. */
2644 if (*(is_gimple_call (stmt
) ? &bb_predicate
: &p
) != false)
2650 /* We account everything but the calls. Calls have their own
2651 size/time info attached to cgraph edges. This is necessary
2652 in order to make the cost disappear after inlining. */
2653 if (!is_gimple_call (stmt
))
2657 predicate ip
= bb_predicate
& predicate::not_inlined ();
2658 info
->account_size_time (this_size
* prob
,
2659 (final_time
* prob
) / 2, ip
,
2663 info
->account_size_time (this_size
* (2 - prob
),
2664 (final_time
* (2 - prob
) / 2),
2669 if (!info
->fp_expressions
&& fp_expression_p (stmt
))
2671 info
->fp_expressions
= true;
2673 fprintf (dump_file
, " fp_expression set\n");
2677 /* Account cost of address calculations in the statements. */
2678 for (unsigned int i
= 0; i
< gimple_num_ops (stmt
); i
++)
2680 for (tree op
= gimple_op (stmt
, i
);
2681 op
&& handled_component_p (op
);
2682 op
= TREE_OPERAND (op
, 0))
2683 if ((TREE_CODE (op
) == ARRAY_REF
2684 || TREE_CODE (op
) == ARRAY_RANGE_REF
)
2685 && TREE_CODE (TREE_OPERAND (op
, 1)) == SSA_NAME
)
2687 predicate p
= bb_predicate
;
2689 p
= p
& will_be_nonconstant_expr_predicate
2690 (&fbi
, info
, params_summary
,
2691 TREE_OPERAND (op
, 1),
2699 "\t\tAccounting address calculation.\n");
2700 info
->account_size_time (ipa_fn_summary::size_scale
,
2712 if (nonconstant_names
.exists () && !early
)
2715 predicate loop_iterations
= true;
2716 predicate loop_stride
= true;
2718 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2719 flow_loops_dump (dump_file
, NULL
, 0);
2721 FOR_EACH_LOOP (loop
, 0)
2726 class tree_niter_desc niter_desc
;
2727 bb_predicate
= *(predicate
*) loop
->header
->aux
;
2729 exits
= get_loop_exit_edges (loop
);
2730 FOR_EACH_VEC_ELT (exits
, j
, ex
)
2731 if (number_of_iterations_exit (loop
, ex
, &niter_desc
, false)
2732 && !is_gimple_min_invariant (niter_desc
.niter
))
2734 predicate will_be_nonconstant
2735 = will_be_nonconstant_expr_predicate (&fbi
, info
,
2739 if (will_be_nonconstant
!= true)
2740 will_be_nonconstant
= bb_predicate
& will_be_nonconstant
;
2741 if (will_be_nonconstant
!= true
2742 && will_be_nonconstant
!= false)
2743 /* This is slightly inprecise. We may want to represent each
2744 loop with independent predicate. */
2745 loop_iterations
&= will_be_nonconstant
;
2750 /* To avoid quadratic behavior we analyze stride predicates only
2751 with respect to the containing loop. Thus we simply iterate
2752 over all defs in the outermost loop body. */
2753 for (loop
= loops_for_fn (cfun
)->tree_root
->inner
;
2754 loop
!= NULL
; loop
= loop
->next
)
2756 basic_block
*body
= get_loop_body (loop
);
2757 for (unsigned i
= 0; i
< loop
->num_nodes
; i
++)
2759 gimple_stmt_iterator gsi
;
2760 bb_predicate
= *(predicate
*) body
[i
]->aux
;
2761 for (gsi
= gsi_start_bb (body
[i
]); !gsi_end_p (gsi
);
2764 gimple
*stmt
= gsi_stmt (gsi
);
2766 if (!is_gimple_assign (stmt
))
2769 tree def
= gimple_assign_lhs (stmt
);
2770 if (TREE_CODE (def
) != SSA_NAME
)
2774 if (!simple_iv (loop_containing_stmt (stmt
),
2775 loop_containing_stmt (stmt
),
2777 || is_gimple_min_invariant (iv
.step
))
2780 predicate will_be_nonconstant
2781 = will_be_nonconstant_expr_predicate (&fbi
, info
,
2785 if (will_be_nonconstant
!= true)
2786 will_be_nonconstant
= bb_predicate
& will_be_nonconstant
;
2787 if (will_be_nonconstant
!= true
2788 && will_be_nonconstant
!= false)
2789 /* This is slightly inprecise. We may want to represent
2790 each loop with independent predicate. */
2791 loop_stride
= loop_stride
& will_be_nonconstant
;
2796 ipa_fn_summary
*s
= ipa_fn_summaries
->get (node
);
2797 set_hint_predicate (&s
->loop_iterations
, loop_iterations
);
2798 set_hint_predicate (&s
->loop_stride
, loop_stride
);
2801 FOR_ALL_BB_FN (bb
, my_function
)
2807 edge_predicate_pool
.remove ((predicate
*)bb
->aux
);
2809 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
2812 edge_predicate_pool
.remove ((predicate
*) e
->aux
);
2816 ipa_fn_summary
*s
= ipa_fn_summaries
->get (node
);
2817 ipa_size_summary
*ss
= ipa_size_summaries
->get (node
);
2819 ss
->self_size
= size
;
2820 nonconstant_names
.release ();
2821 ipa_release_body_info (&fbi
);
2822 if (opt_for_fn (node
->decl
, optimize
))
2825 loop_optimizer_finalize ();
2826 else if (!ipa_edge_args_sum
)
2827 ipa_free_all_node_params ();
2828 free_dominance_info (CDI_DOMINATORS
);
2829 free_dominance_info (CDI_POST_DOMINATORS
);
2833 fprintf (dump_file
, "\n");
2834 ipa_dump_fn_summary (dump_file
, node
);
2839 /* Compute function summary.
2840 EARLY is true when we compute parameters during early opts. */
2843 compute_fn_summary (struct cgraph_node
*node
, bool early
)
2845 HOST_WIDE_INT self_stack_size
;
2846 struct cgraph_edge
*e
;
2848 gcc_assert (!node
->inlined_to
);
2850 if (!ipa_fn_summaries
)
2851 ipa_fn_summary_alloc ();
2853 /* Create a new ipa_fn_summary. */
2854 ((ipa_fn_summary_t
*)ipa_fn_summaries
)->remove_callees (node
);
2855 ipa_fn_summaries
->remove (node
);
2856 class ipa_fn_summary
*info
= ipa_fn_summaries
->get_create (node
);
2857 class ipa_size_summary
*size_info
= ipa_size_summaries
->get_create (node
);
2859 /* Estimate the stack size for the function if we're optimizing. */
2860 self_stack_size
= optimize
&& !node
->thunk
.thunk_p
2861 ? estimated_stack_frame_size (node
) : 0;
2862 size_info
->estimated_self_stack_size
= self_stack_size
;
2863 info
->estimated_stack_size
= self_stack_size
;
2865 if (node
->thunk
.thunk_p
)
2867 ipa_call_summary
*es
= ipa_call_summaries
->get_create (node
->callees
);
2870 node
->can_change_signature
= false;
2871 es
->call_stmt_size
= eni_size_weights
.call_cost
;
2872 es
->call_stmt_time
= eni_time_weights
.call_cost
;
2873 info
->account_size_time (ipa_fn_summary::size_scale
2874 * opt_for_fn (node
->decl
,
2875 param_uninlined_function_thunk_insns
),
2876 opt_for_fn (node
->decl
,
2877 param_uninlined_function_thunk_time
), t
, t
);
2878 t
= predicate::not_inlined ();
2879 info
->account_size_time (2 * ipa_fn_summary::size_scale
, 0, t
, t
);
2880 ipa_update_overall_fn_summary (node
);
2881 size_info
->self_size
= size_info
->size
;
2882 if (stdarg_p (TREE_TYPE (node
->decl
)))
2884 info
->inlinable
= false;
2885 node
->callees
->inline_failed
= CIF_VARIADIC_THUNK
;
2888 info
->inlinable
= true;
2892 /* Even is_gimple_min_invariant rely on current_function_decl. */
2893 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
2895 /* During IPA profile merging we may be called w/o virtual SSA form
2897 update_ssa (TODO_update_ssa_only_virtuals
);
2899 /* Can this function be inlined at all? */
2900 if (!opt_for_fn (node
->decl
, optimize
)
2901 && !lookup_attribute ("always_inline",
2902 DECL_ATTRIBUTES (node
->decl
)))
2903 info
->inlinable
= false;
2905 info
->inlinable
= tree_inlinable_function_p (node
->decl
);
2907 /* Type attributes can use parameter indices to describe them. */
2908 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
))
2909 /* Likewise for #pragma omp declare simd functions or functions
2910 with simd attribute. */
2911 || lookup_attribute ("omp declare simd",
2912 DECL_ATTRIBUTES (node
->decl
)))
2913 node
->can_change_signature
= false;
2916 /* Otherwise, inlinable functions always can change signature. */
2917 if (info
->inlinable
)
2918 node
->can_change_signature
= true;
2921 /* Functions calling builtin_apply cannot change signature. */
2922 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2924 tree
cdecl = e
->callee
->decl
;
2925 if (fndecl_built_in_p (cdecl, BUILT_IN_APPLY_ARGS
)
2926 || fndecl_built_in_p (cdecl, BUILT_IN_VA_START
))
2929 node
->can_change_signature
= !e
;
2932 analyze_function_body (node
, early
);
2935 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2936 if (e
->callee
->comdat_local_p ())
2938 node
->calls_comdat_local
= (e
!= NULL
);
2940 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
2941 size_info
->size
= size_info
->self_size
;
2942 info
->estimated_stack_size
= size_info
->estimated_self_stack_size
;
2944 /* Code above should compute exactly the same result as
2945 ipa_update_overall_fn_summary but because computation happens in
2946 different order the roundoff errors result in slight changes. */
2947 ipa_update_overall_fn_summary (node
);
2948 /* In LTO mode we may have speculative edges set. */
2949 gcc_assert (in_lto_p
|| size_info
->size
== size_info
->self_size
);
2953 /* Compute parameters of functions used by inliner using
2954 current_function_decl. */
2957 compute_fn_summary_for_current (void)
2959 compute_fn_summary (cgraph_node::get (current_function_decl
), true);
2963 /* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS,
2964 KNOWN_CONTEXTS and KNOWN_AGGS. */
2967 estimate_edge_devirt_benefit (struct cgraph_edge
*ie
,
2968 int *size
, int *time
,
2969 vec
<tree
> known_vals
,
2970 vec
<ipa_polymorphic_call_context
> known_contexts
,
2971 vec
<ipa_agg_value_set
> known_aggs
)
2974 struct cgraph_node
*callee
;
2975 class ipa_fn_summary
*isummary
;
2976 enum availability avail
;
2979 if (!known_vals
.length () && !known_contexts
.length ())
2981 if (!opt_for_fn (ie
->caller
->decl
, flag_indirect_inlining
))
2984 target
= ipa_get_indirect_edge_target (ie
, known_vals
, known_contexts
,
2985 known_aggs
, &speculative
);
2986 if (!target
|| speculative
)
2989 /* Account for difference in cost between indirect and direct calls. */
2990 *size
-= (eni_size_weights
.indirect_call_cost
- eni_size_weights
.call_cost
);
2991 *time
-= (eni_time_weights
.indirect_call_cost
- eni_time_weights
.call_cost
);
2992 gcc_checking_assert (*time
>= 0);
2993 gcc_checking_assert (*size
>= 0);
2995 callee
= cgraph_node::get (target
);
2996 if (!callee
|| !callee
->definition
)
2998 callee
= callee
->function_symbol (&avail
);
2999 if (avail
< AVAIL_AVAILABLE
)
3001 isummary
= ipa_fn_summaries
->get (callee
);
3002 if (isummary
== NULL
)
3005 return isummary
->inlinable
;
3008 /* Increase SIZE, MIN_SIZE (if non-NULL) and TIME for size and time needed to
3009 handle edge E with probability PROB.
3010 Set HINTS if edge may be devirtualized.
3011 KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS describe context of the call
3015 estimate_edge_size_and_time (struct cgraph_edge
*e
, int *size
, int *min_size
,
3017 vec
<tree
> known_vals
,
3018 vec
<ipa_polymorphic_call_context
> known_contexts
,
3019 vec
<ipa_agg_value_set
> known_aggs
,
3022 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3023 int call_size
= es
->call_stmt_size
;
3024 int call_time
= es
->call_stmt_time
;
3027 if (!e
->callee
&& hints
&& e
->maybe_hot_p ()
3028 && estimate_edge_devirt_benefit (e
, &call_size
, &call_time
,
3029 known_vals
, known_contexts
, known_aggs
))
3030 *hints
|= INLINE_HINT_indirect_call
;
3031 cur_size
= call_size
* ipa_fn_summary::size_scale
;
3034 *min_size
+= cur_size
;
3036 *time
+= ((sreal
)call_time
) * e
->sreal_frequency ();
3040 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
3041 calls in NODE. POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
3042 describe context of the call site.
3044 Helper for estimate_calls_size_and_time which does the same but
3045 (in most cases) faster. */
3048 estimate_calls_size_and_time_1 (struct cgraph_node
*node
, int *size
,
3049 int *min_size
, sreal
*time
,
3051 clause_t possible_truths
,
3052 vec
<tree
> known_vals
,
3053 vec
<ipa_polymorphic_call_context
> known_contexts
,
3054 vec
<ipa_agg_value_set
> known_aggs
)
3056 struct cgraph_edge
*e
;
3057 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3059 if (!e
->inline_failed
)
3061 gcc_checking_assert (!ipa_call_summaries
->get (e
));
3062 estimate_calls_size_and_time_1 (e
->callee
, size
, min_size
, time
,
3065 known_vals
, known_contexts
,
3069 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3071 /* Do not care about zero sized builtins. */
3072 if (!es
->call_stmt_size
)
3074 gcc_checking_assert (!es
->call_stmt_time
);
3078 || es
->predicate
->evaluate (possible_truths
))
3080 /* Predicates of calls shall not use NOT_CHANGED codes,
3081 so we do not need to compute probabilities. */
3082 estimate_edge_size_and_time (e
, size
,
3083 es
->predicate
? NULL
: min_size
,
3085 known_vals
, known_contexts
,
3089 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3091 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3093 || es
->predicate
->evaluate (possible_truths
))
3094 estimate_edge_size_and_time (e
, size
,
3095 es
->predicate
? NULL
: min_size
,
3097 known_vals
, known_contexts
, known_aggs
,
3102 /* Populate sum->call_size_time_table for edges from NODE. */
3105 summarize_calls_size_and_time (struct cgraph_node
*node
,
3106 ipa_fn_summary
*sum
)
3108 struct cgraph_edge
*e
;
3109 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3111 if (!e
->inline_failed
)
3113 gcc_checking_assert (!ipa_call_summaries
->get (e
));
3114 summarize_calls_size_and_time (e
->callee
, sum
);
3120 estimate_edge_size_and_time (e
, &size
, NULL
, &time
,
3121 vNULL
, vNULL
, vNULL
, NULL
);
3123 struct predicate pred
= true;
3124 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3127 pred
= *es
->predicate
;
3128 sum
->account_size_time (size
, time
, pred
, pred
, true);
3130 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3135 estimate_edge_size_and_time (e
, &size
, NULL
, &time
,
3136 vNULL
, vNULL
, vNULL
, NULL
);
3137 struct predicate pred
= true;
3138 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3141 pred
= *es
->predicate
;
3142 sum
->account_size_time (size
, time
, pred
, pred
, true);
3146 /* Increase SIZE, MIN_SIZE and TIME for size and time needed to handle all
3147 calls in NODE. POSSIBLE_TRUTHS, KNOWN_VALS, KNOWN_AGGS and KNOWN_CONTEXTS
3148 describe context of the call site. */
3151 estimate_calls_size_and_time (struct cgraph_node
*node
, int *size
,
3152 int *min_size
, sreal
*time
,
3154 clause_t possible_truths
,
3155 vec
<tree
> known_vals
,
3156 vec
<ipa_polymorphic_call_context
> known_contexts
,
3157 vec
<ipa_agg_value_set
> known_aggs
)
3159 class ipa_fn_summary
*sum
= ipa_fn_summaries
->get (node
);
3160 bool use_table
= true;
3162 gcc_assert (node
->callees
|| node
->indirect_calls
);
3164 /* During early inlining we do not calculate info for very
3165 large functions and thus there is no need for producing
3167 if (!ipa_node_params_sum
)
3169 /* Do not calculate summaries for simple wrappers; it is waste
3171 else if (node
->callees
&& node
->indirect_calls
3172 && node
->callees
->inline_failed
&& !node
->callees
->next_callee
)
3174 /* If there is an indirect edge that may be optimized, we need
3175 to go the slow way. */
3176 else if ((known_vals
.length ()
3177 || known_contexts
.length ()
3178 || known_aggs
.length ()) && hints
)
3180 class ipa_node_params
*params_summary
= IPA_NODE_REF (node
);
3181 unsigned int nargs
= params_summary
3182 ? ipa_get_param_count (params_summary
) : 0;
3184 for (unsigned int i
= 0; i
< nargs
&& use_table
; i
++)
3186 if (ipa_is_param_used_by_indirect_call (params_summary
, i
)
3187 && ((known_vals
.length () > i
&& known_vals
[i
])
3188 || (known_aggs
.length () > i
3189 && known_aggs
[i
].items
.length ())))
3191 else if (ipa_is_param_used_by_polymorphic_call (params_summary
, i
)
3192 && (known_contexts
.length () > i
3193 && !known_contexts
[i
].useless_p ()))
3198 /* Fast path is via the call size time table. */
3201 /* Build summary if it is absent. */
3202 if (!sum
->call_size_time_table
)
3204 predicate true_pred
= true;
3205 sum
->account_size_time (0, 0, true_pred
, true_pred
, true);
3206 summarize_calls_size_and_time (node
, sum
);
3209 int old_size
= *size
;
3210 sreal old_time
= time
? *time
: 0;
3213 *min_size
+= (*sum
->call_size_time_table
)[0].size
;
3218 /* Walk the table and account sizes and times. */
3219 for (i
= 0; vec_safe_iterate (sum
->call_size_time_table
, i
, &e
);
3221 if (e
->exec_predicate
.evaluate (possible_truths
))
3228 /* Be careful and see if both methods agree. */
3229 if ((flag_checking
|| dump_file
)
3230 /* Do not try to sanity check when we know we lost some
3232 && sum
->call_size_time_table
->length ()
3233 < ipa_fn_summary::max_size_time_table_size
)
3235 estimate_calls_size_and_time_1 (node
, &old_size
, NULL
, &old_time
, NULL
,
3236 possible_truths
, known_vals
,
3237 known_contexts
, known_aggs
);
3238 gcc_assert (*size
== old_size
);
3239 if (time
&& (*time
- old_time
> 1 || *time
- old_time
< -1)
3241 fprintf (dump_file
, "Time mismatch in call summary %f!=%f",
3242 old_time
.to_double (),
3243 time
->to_double ());
3246 /* Slow path by walking all edges. */
3248 estimate_calls_size_and_time_1 (node
, size
, min_size
, time
, hints
,
3249 possible_truths
, known_vals
, known_contexts
,
3253 /* Default constructor for ipa call context.
3254 Memory allocation of known_vals, known_contexts
3255 and known_aggs vectors is owned by the caller, but can
3256 be release by ipa_call_context::release.
3258 inline_param_summary is owned by the caller. */
3259 ipa_call_context::ipa_call_context (cgraph_node
*node
,
3260 clause_t possible_truths
,
3261 clause_t nonspec_possible_truths
,
3262 vec
<tree
> known_vals
,
3263 vec
<ipa_polymorphic_call_context
>
3265 vec
<ipa_agg_value_set
> known_aggs
,
3266 vec
<inline_param_summary
>
3267 inline_param_summary
)
3268 : m_node (node
), m_possible_truths (possible_truths
),
3269 m_nonspec_possible_truths (nonspec_possible_truths
),
3270 m_inline_param_summary (inline_param_summary
),
3271 m_known_vals (known_vals
),
3272 m_known_contexts (known_contexts
),
3273 m_known_aggs (known_aggs
)
3277 /* Set THIS to be a duplicate of CTX. Copy all relevant info. */
3280 ipa_call_context::duplicate_from (const ipa_call_context
&ctx
)
3282 m_node
= ctx
.m_node
;
3283 m_possible_truths
= ctx
.m_possible_truths
;
3284 m_nonspec_possible_truths
= ctx
.m_nonspec_possible_truths
;
3285 class ipa_node_params
*params_summary
= IPA_NODE_REF (m_node
);
3286 unsigned int nargs
= params_summary
3287 ? ipa_get_param_count (params_summary
) : 0;
3289 m_inline_param_summary
= vNULL
;
3290 /* Copy the info only if there is at least one useful entry. */
3291 if (ctx
.m_inline_param_summary
.exists ())
3293 unsigned int n
= MIN (ctx
.m_inline_param_summary
.length (), nargs
);
3295 for (unsigned int i
= 0; i
< n
; i
++)
3296 if (ipa_is_param_used_by_ipa_predicates (params_summary
, i
)
3297 && !ctx
.m_inline_param_summary
[i
].useless_p ())
3299 m_inline_param_summary
3300 = ctx
.m_inline_param_summary
.copy ();
3304 m_known_vals
= vNULL
;
3305 if (ctx
.m_known_vals
.exists ())
3307 unsigned int n
= MIN (ctx
.m_known_vals
.length (), nargs
);
3309 for (unsigned int i
= 0; i
< n
; i
++)
3310 if (ipa_is_param_used_by_indirect_call (params_summary
, i
)
3311 && ctx
.m_known_vals
[i
])
3313 m_known_vals
= ctx
.m_known_vals
.copy ();
3318 m_known_contexts
= vNULL
;
3319 if (ctx
.m_known_contexts
.exists ())
3321 unsigned int n
= MIN (ctx
.m_known_contexts
.length (), nargs
);
3323 for (unsigned int i
= 0; i
< n
; i
++)
3324 if (ipa_is_param_used_by_polymorphic_call (params_summary
, i
)
3325 && !ctx
.m_known_contexts
[i
].useless_p ())
3327 m_known_contexts
= ctx
.m_known_contexts
.copy ();
3332 m_known_aggs
= vNULL
;
3333 if (ctx
.m_known_aggs
.exists ())
3335 unsigned int n
= MIN (ctx
.m_known_aggs
.length (), nargs
);
3337 for (unsigned int i
= 0; i
< n
; i
++)
3338 if (ipa_is_param_used_by_indirect_call (params_summary
, i
)
3339 && !ctx
.m_known_aggs
[i
].is_empty ())
3341 m_known_aggs
= ipa_copy_agg_values (ctx
.m_known_aggs
);
3347 /* Release memory used by known_vals/contexts/aggs vectors.
3348 If ALL is true release also inline_param_summary.
3349 This happens when context was previously duplicated to be stored
3353 ipa_call_context::release (bool all
)
3355 /* See if context is initialized at first place. */
3358 ipa_release_agg_values (m_known_aggs
, all
);
3361 m_known_vals
.release ();
3362 m_known_contexts
.release ();
3363 m_inline_param_summary
.release ();
3367 /* Return true if CTX describes the same call context as THIS. */
3370 ipa_call_context::equal_to (const ipa_call_context
&ctx
)
3372 if (m_node
!= ctx
.m_node
3373 || m_possible_truths
!= ctx
.m_possible_truths
3374 || m_nonspec_possible_truths
!= ctx
.m_nonspec_possible_truths
)
3377 class ipa_node_params
*params_summary
= IPA_NODE_REF (m_node
);
3378 unsigned int nargs
= params_summary
3379 ? ipa_get_param_count (params_summary
) : 0;
3381 if (m_inline_param_summary
.exists () || ctx
.m_inline_param_summary
.exists ())
3383 for (unsigned int i
= 0; i
< nargs
; i
++)
3385 if (!ipa_is_param_used_by_ipa_predicates (params_summary
, i
))
3387 if (i
>= m_inline_param_summary
.length ()
3388 || m_inline_param_summary
[i
].useless_p ())
3390 if (i
< ctx
.m_inline_param_summary
.length ()
3391 && !ctx
.m_inline_param_summary
[i
].useless_p ())
3395 if (i
>= ctx
.m_inline_param_summary
.length ()
3396 || ctx
.m_inline_param_summary
[i
].useless_p ())
3398 if (i
< m_inline_param_summary
.length ()
3399 && !m_inline_param_summary
[i
].useless_p ())
3403 if (!m_inline_param_summary
[i
].equal_to
3404 (ctx
.m_inline_param_summary
[i
]))
3408 if (m_known_vals
.exists () || ctx
.m_known_vals
.exists ())
3410 for (unsigned int i
= 0; i
< nargs
; i
++)
3412 if (!ipa_is_param_used_by_indirect_call (params_summary
, i
))
3414 if (i
>= m_known_vals
.length () || !m_known_vals
[i
])
3416 if (i
< ctx
.m_known_vals
.length () && ctx
.m_known_vals
[i
])
3420 if (i
>= ctx
.m_known_vals
.length () || !ctx
.m_known_vals
[i
])
3422 if (i
< m_known_vals
.length () && m_known_vals
[i
])
3426 if (m_known_vals
[i
] != ctx
.m_known_vals
[i
])
3430 if (m_known_contexts
.exists () || ctx
.m_known_contexts
.exists ())
3432 for (unsigned int i
= 0; i
< nargs
; i
++)
3434 if (!ipa_is_param_used_by_polymorphic_call (params_summary
, i
))
3436 if (i
>= m_known_contexts
.length ()
3437 || m_known_contexts
[i
].useless_p ())
3439 if (i
< ctx
.m_known_contexts
.length ()
3440 && !ctx
.m_known_contexts
[i
].useless_p ())
3444 if (i
>= ctx
.m_known_contexts
.length ()
3445 || ctx
.m_known_contexts
[i
].useless_p ())
3447 if (i
< m_known_contexts
.length ()
3448 && !m_known_contexts
[i
].useless_p ())
3452 if (!m_known_contexts
[i
].equal_to
3453 (ctx
.m_known_contexts
[i
]))
3457 if (m_known_aggs
.exists () || ctx
.m_known_aggs
.exists ())
3459 for (unsigned int i
= 0; i
< nargs
; i
++)
3461 if (!ipa_is_param_used_by_indirect_call (params_summary
, i
))
3463 if (i
>= m_known_aggs
.length () || m_known_aggs
[i
].is_empty ())
3465 if (i
< ctx
.m_known_aggs
.length ()
3466 && !ctx
.m_known_aggs
[i
].is_empty ())
3470 if (i
>= ctx
.m_known_aggs
.length ()
3471 || ctx
.m_known_aggs
[i
].is_empty ())
3473 if (i
< m_known_aggs
.length ()
3474 && !m_known_aggs
[i
].is_empty ())
3478 if (!m_known_aggs
[i
].equal_to (ctx
.m_known_aggs
[i
]))
3485 /* Estimate size and time needed to execute call in the given context.
3486 Additionally determine hints determined by the context. Finally compute
3487 minimal size needed for the call that is independent on the call context and
3488 can be used for fast estimates. Return the values in RET_SIZE,
3489 RET_MIN_SIZE, RET_TIME and RET_HINTS. */
3492 ipa_call_context::estimate_size_and_time (int *ret_size
,
3495 sreal
*ret_nonspecialized_time
,
3496 ipa_hints
*ret_hints
)
3498 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (m_node
);
3503 ipa_hints hints
= 0;
3506 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3509 fprintf (dump_file
, " Estimating body: %s\n"
3510 " Known to be false: ", m_node
->dump_name ());
3512 for (i
= predicate::not_inlined_condition
;
3513 i
< (predicate::first_dynamic_condition
3514 + (int) vec_safe_length (info
->conds
)); i
++)
3515 if (!(m_possible_truths
& (1 << i
)))
3518 fprintf (dump_file
, ", ");
3520 dump_condition (dump_file
, info
->conds
, i
);
3524 if (m_node
->callees
|| m_node
->indirect_calls
)
3525 estimate_calls_size_and_time (m_node
, &size
, &min_size
,
3526 ret_time
? &time
: NULL
,
3527 ret_hints
? &hints
: NULL
, m_possible_truths
,
3528 m_known_vals
, m_known_contexts
, m_known_aggs
);
3530 sreal nonspecialized_time
= time
;
3532 min_size
+= (*info
->size_time_table
)[0].size
;
3533 for (i
= 0; vec_safe_iterate (info
->size_time_table
, i
, &e
); i
++)
3535 bool exec
= e
->exec_predicate
.evaluate (m_nonspec_possible_truths
);
3537 /* Because predicates are conservative, it can happen that nonconst is 1
3541 bool nonconst
= e
->nonconst_predicate
.evaluate (m_possible_truths
);
3543 gcc_checking_assert (e
->time
>= 0);
3544 gcc_checking_assert (time
>= 0);
3546 /* We compute specialized size only because size of nonspecialized
3547 copy is context independent.
3549 The difference between nonspecialized execution and specialized is
3550 that nonspecialized is not going to have optimized out computations
3551 known to be constant in a specialized setting. */
3556 nonspecialized_time
+= e
->time
;
3559 else if (!m_inline_param_summary
.exists ())
3566 int prob
= e
->nonconst_predicate
.probability
3567 (info
->conds
, m_possible_truths
,
3568 m_inline_param_summary
);
3569 gcc_checking_assert (prob
>= 0);
3570 gcc_checking_assert (prob
<= REG_BR_PROB_BASE
);
3571 if (prob
== REG_BR_PROB_BASE
)
3574 time
+= e
->time
* prob
/ REG_BR_PROB_BASE
;
3576 gcc_checking_assert (time
>= 0);
3579 gcc_checking_assert ((*info
->size_time_table
)[0].exec_predicate
== true);
3580 gcc_checking_assert ((*info
->size_time_table
)[0].nonconst_predicate
== true);
3581 gcc_checking_assert (min_size
>= 0);
3582 gcc_checking_assert (size
>= 0);
3583 gcc_checking_assert (time
>= 0);
3584 /* nonspecialized_time should be always bigger than specialized time.
3585 Roundoff issues however may get into the way. */
3586 gcc_checking_assert ((nonspecialized_time
- time
* 99 / 100) >= -1);
3588 /* Roundoff issues may make specialized time bigger than nonspecialized
3589 time. We do not really want that to happen because some heuristics
3590 may get confused by seeing negative speedups. */
3591 if (time
> nonspecialized_time
)
3592 time
= nonspecialized_time
;
3596 if (info
->loop_iterations
3597 && !info
->loop_iterations
->evaluate (m_possible_truths
))
3598 hints
|= INLINE_HINT_loop_iterations
;
3599 if (info
->loop_stride
3600 && !info
->loop_stride
->evaluate (m_possible_truths
))
3601 hints
|= INLINE_HINT_loop_stride
;
3603 hints
|= INLINE_HINT_in_scc
;
3604 if (DECL_DECLARED_INLINE_P (m_node
->decl
))
3605 hints
|= INLINE_HINT_declared_inline
;
3608 size
= RDIV (size
, ipa_fn_summary::size_scale
);
3609 min_size
= RDIV (min_size
, ipa_fn_summary::size_scale
);
3611 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3612 fprintf (dump_file
, "\n size:%i time:%f nonspec time:%f\n", (int) size
,
3613 time
.to_double (), nonspecialized_time
.to_double ());
3616 if (ret_nonspecialized_time
)
3617 *ret_nonspecialized_time
= nonspecialized_time
;
3621 *ret_min_size
= min_size
;
3628 /* Estimate size and time needed to execute callee of EDGE assuming that
3629 parameters known to be constant at caller of EDGE are propagated.
3630 KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values
3631 and types for parameters. */
3634 estimate_ipcp_clone_size_and_time (struct cgraph_node
*node
,
3635 vec
<tree
> known_vals
,
3636 vec
<ipa_polymorphic_call_context
>
3638 vec
<ipa_agg_value_set
> known_aggs
,
3639 int *ret_size
, sreal
*ret_time
,
3640 sreal
*ret_nonspec_time
,
3643 clause_t clause
, nonspec_clause
;
3645 /* TODO: Also pass known value ranges. */
3646 evaluate_conditions_for_known_args (node
, false, known_vals
, vNULL
,
3647 known_aggs
, &clause
, &nonspec_clause
);
3648 ipa_call_context
ctx (node
, clause
, nonspec_clause
,
3649 known_vals
, known_contexts
,
3651 ctx
.estimate_size_and_time (ret_size
, NULL
, ret_time
,
3652 ret_nonspec_time
, hints
);
3655 /* Return stack frame offset where frame of NODE is supposed to start inside
3656 of the function it is inlined to.
3657 Return 0 for functions that are not inlined. */
3660 ipa_get_stack_frame_offset (struct cgraph_node
*node
)
3662 HOST_WIDE_INT offset
= 0;
3663 if (!node
->inlined_to
)
3665 node
= node
->callers
->caller
;
3668 offset
+= ipa_size_summaries
->get (node
)->estimated_self_stack_size
;
3669 if (!node
->inlined_to
)
3671 node
= node
->callers
->caller
;
3676 /* Update summary information of inline clones after inlining.
3677 Compute peak stack usage. */
3680 inline_update_callee_summaries (struct cgraph_node
*node
, int depth
)
3682 struct cgraph_edge
*e
;
3684 ipa_propagate_frequency (node
);
3685 for (e
= node
->callees
; e
; e
= e
->next_callee
)
3687 if (!e
->inline_failed
)
3688 inline_update_callee_summaries (e
->callee
, depth
);
3690 ipa_call_summaries
->get (e
)->loop_depth
+= depth
;
3692 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
3693 ipa_call_summaries
->get (e
)->loop_depth
+= depth
;
3696 /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
3697 When function A is inlined in B and A calls C with parameter that
3698 changes with probability PROB1 and C is known to be passthrough
3699 of argument if B that change with probability PROB2, the probability
3700 of change is now PROB1*PROB2. */
3703 remap_edge_change_prob (struct cgraph_edge
*inlined_edge
,
3704 struct cgraph_edge
*edge
)
3706 if (ipa_node_params_sum
)
3709 class ipa_edge_args
*args
= IPA_EDGE_REF (edge
);
3712 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
3713 class ipa_call_summary
*inlined_es
3714 = ipa_call_summaries
->get (inlined_edge
);
3716 if (es
->param
.length () == 0)
3719 for (i
= 0; i
< ipa_get_cs_argument_count (args
); i
++)
3721 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, i
);
3722 if (jfunc
->type
== IPA_JF_PASS_THROUGH
3723 || jfunc
->type
== IPA_JF_ANCESTOR
)
3725 int id
= jfunc
->type
== IPA_JF_PASS_THROUGH
3726 ? ipa_get_jf_pass_through_formal_id (jfunc
)
3727 : ipa_get_jf_ancestor_formal_id (jfunc
);
3728 if (id
< (int) inlined_es
->param
.length ())
3730 int prob1
= es
->param
[i
].change_prob
;
3731 int prob2
= inlined_es
->param
[id
].change_prob
;
3732 int prob
= combine_probabilities (prob1
, prob2
);
3734 if (prob1
&& prob2
&& !prob
)
3737 es
->param
[i
].change_prob
= prob
;
3744 /* Update edge summaries of NODE after INLINED_EDGE has been inlined.
3746 Remap predicates of callees of NODE. Rest of arguments match
3749 Also update change probabilities. */
3752 remap_edge_summaries (struct cgraph_edge
*inlined_edge
,
3753 struct cgraph_node
*node
,
3754 class ipa_fn_summary
*info
,
3755 class ipa_node_params
*params_summary
,
3756 class ipa_fn_summary
*callee_info
,
3757 vec
<int> operand_map
,
3758 vec
<int> offset_map
,
3759 clause_t possible_truths
,
3760 predicate
*toplev_predicate
)
3762 struct cgraph_edge
*e
, *next
;
3763 for (e
= node
->callees
; e
; e
= next
)
3766 next
= e
->next_callee
;
3768 if (e
->inline_failed
)
3770 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3771 remap_edge_change_prob (inlined_edge
, e
);
3775 p
= es
->predicate
->remap_after_inlining
3776 (info
, params_summary
,
3777 callee_info
, operand_map
,
3778 offset_map
, possible_truths
,
3780 edge_set_predicate (e
, &p
);
3783 edge_set_predicate (e
, toplev_predicate
);
3786 remap_edge_summaries (inlined_edge
, e
->callee
, info
,
3787 params_summary
, callee_info
,
3788 operand_map
, offset_map
, possible_truths
,
3791 for (e
= node
->indirect_calls
; e
; e
= next
)
3793 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
3795 next
= e
->next_callee
;
3797 remap_edge_change_prob (inlined_edge
, e
);
3800 p
= es
->predicate
->remap_after_inlining
3801 (info
, params_summary
,
3802 callee_info
, operand_map
, offset_map
,
3803 possible_truths
, *toplev_predicate
);
3804 edge_set_predicate (e
, &p
);
3807 edge_set_predicate (e
, toplev_predicate
);
3811 /* Same as remap_predicate, but set result into hint *HINT. */
3814 remap_hint_predicate (class ipa_fn_summary
*info
,
3815 class ipa_node_params
*params_summary
,
3816 class ipa_fn_summary
*callee_info
,
3818 vec
<int> operand_map
,
3819 vec
<int> offset_map
,
3820 clause_t possible_truths
,
3821 predicate
*toplev_predicate
)
3827 p
= (*hint
)->remap_after_inlining
3828 (info
, params_summary
, callee_info
,
3829 operand_map
, offset_map
,
3830 possible_truths
, *toplev_predicate
);
3831 if (p
!= false && p
!= true)
3834 set_hint_predicate (hint
, p
);
3840 /* We inlined EDGE. Update summary of the function we inlined into. */
3843 ipa_merge_fn_summary_after_inlining (struct cgraph_edge
*edge
)
3845 ipa_fn_summary
*callee_info
= ipa_fn_summaries
->get (edge
->callee
);
3846 struct cgraph_node
*to
= (edge
->caller
->inlined_to
3847 ? edge
->caller
->inlined_to
: edge
->caller
);
3848 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (to
);
3849 clause_t clause
= 0; /* not_inline is known to be false. */
3851 auto_vec
<int, 8> operand_map
;
3852 auto_vec
<int, 8> offset_map
;
3854 predicate toplev_predicate
;
3855 class ipa_call_summary
*es
= ipa_call_summaries
->get (edge
);
3856 class ipa_node_params
*params_summary
= (ipa_node_params_sum
3857 ? IPA_NODE_REF (to
) : NULL
);
3860 toplev_predicate
= *es
->predicate
;
3862 toplev_predicate
= true;
3864 info
->fp_expressions
|= callee_info
->fp_expressions
;
3866 if (callee_info
->conds
)
3868 auto_vec
<tree
, 32> known_vals
;
3869 auto_vec
<ipa_agg_value_set
, 32> known_aggs
;
3870 evaluate_properties_for_edge (edge
, true, &clause
, NULL
,
3871 &known_vals
, NULL
, &known_aggs
);
3873 if (ipa_node_params_sum
&& callee_info
->conds
)
3875 class ipa_edge_args
*args
= IPA_EDGE_REF (edge
);
3876 int count
= args
? ipa_get_cs_argument_count (args
) : 0;
3881 operand_map
.safe_grow_cleared (count
);
3882 offset_map
.safe_grow_cleared (count
);
3884 for (i
= 0; i
< count
; i
++)
3886 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, i
);
3889 /* TODO: handle non-NOPs when merging. */
3890 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
3892 if (ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
3893 map
= ipa_get_jf_pass_through_formal_id (jfunc
);
3894 if (!ipa_get_jf_pass_through_agg_preserved (jfunc
))
3897 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
3899 HOST_WIDE_INT offset
= ipa_get_jf_ancestor_offset (jfunc
);
3900 if (offset
>= 0 && offset
< INT_MAX
)
3902 map
= ipa_get_jf_ancestor_formal_id (jfunc
);
3903 if (!ipa_get_jf_ancestor_agg_preserved (jfunc
))
3905 offset_map
[i
] = offset
;
3908 operand_map
[i
] = map
;
3909 gcc_assert (map
< ipa_get_param_count (params_summary
));
3912 sreal freq
= edge
->sreal_frequency ();
3913 for (i
= 0; vec_safe_iterate (callee_info
->size_time_table
, i
, &e
); i
++)
3916 p
= e
->exec_predicate
.remap_after_inlining
3917 (info
, params_summary
,
3918 callee_info
, operand_map
,
3921 predicate nonconstp
;
3922 nonconstp
= e
->nonconst_predicate
.remap_after_inlining
3923 (info
, params_summary
,
3924 callee_info
, operand_map
,
3927 if (p
!= false && nonconstp
!= false)
3929 sreal add_time
= ((sreal
)e
->time
* freq
);
3930 int prob
= e
->nonconst_predicate
.probability (callee_info
->conds
,
3932 if (prob
!= REG_BR_PROB_BASE
)
3933 add_time
= add_time
* prob
/ REG_BR_PROB_BASE
;
3934 if (prob
!= REG_BR_PROB_BASE
3935 && dump_file
&& (dump_flags
& TDF_DETAILS
))
3937 fprintf (dump_file
, "\t\tScaling time by probability:%f\n",
3938 (double) prob
/ REG_BR_PROB_BASE
);
3940 info
->account_size_time (e
->size
, add_time
, p
, nonconstp
);
3943 remap_edge_summaries (edge
, edge
->callee
, info
, params_summary
,
3944 callee_info
, operand_map
,
3945 offset_map
, clause
, &toplev_predicate
);
3946 remap_hint_predicate (info
, params_summary
, callee_info
,
3947 &callee_info
->loop_iterations
,
3948 operand_map
, offset_map
, clause
, &toplev_predicate
);
3949 remap_hint_predicate (info
, params_summary
, callee_info
,
3950 &callee_info
->loop_stride
,
3951 operand_map
, offset_map
, clause
, &toplev_predicate
);
3953 HOST_WIDE_INT stack_frame_offset
= ipa_get_stack_frame_offset (edge
->callee
);
3954 HOST_WIDE_INT peak
= stack_frame_offset
+ callee_info
->estimated_stack_size
;
3956 if (info
->estimated_stack_size
< peak
)
3957 info
->estimated_stack_size
= peak
;
3959 inline_update_callee_summaries (edge
->callee
, es
->loop_depth
);
3960 if (info
->call_size_time_table
)
3963 sreal edge_time
= 0;
3965 estimate_edge_size_and_time (edge
, &edge_size
, NULL
, &edge_time
, vNULL
,
3967 /* Unaccount size and time of the optimized out call. */
3968 info
->account_size_time (-edge_size
, -edge_time
,
3969 es
->predicate
? *es
->predicate
: true,
3970 es
->predicate
? *es
->predicate
: true,
3972 /* Account new calls. */
3973 summarize_calls_size_and_time (edge
->callee
, info
);
3976 /* Free summaries that are not maintained for inline clones/edges. */
3977 ipa_call_summaries
->remove (edge
);
3978 ipa_fn_summaries
->remove (edge
->callee
);
3979 ipa_remove_from_growth_caches (edge
);
3982 /* For performance reasons ipa_merge_fn_summary_after_inlining is not updating
3983 overall size and time. Recompute it.
3984 If RESET is true also recompute call_time_size_table. */
3987 ipa_update_overall_fn_summary (struct cgraph_node
*node
, bool reset
)
3989 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (node
);
3990 class ipa_size_summary
*size_info
= ipa_size_summaries
->get (node
);
3994 size_info
->size
= 0;
3996 for (i
= 0; vec_safe_iterate (info
->size_time_table
, i
, &e
); i
++)
3998 size_info
->size
+= e
->size
;
3999 info
->time
+= e
->time
;
4001 info
->min_size
= (*info
->size_time_table
)[0].size
;
4003 vec_free (info
->call_size_time_table
);
4004 if (node
->callees
|| node
->indirect_calls
)
4005 estimate_calls_size_and_time (node
, &size_info
->size
, &info
->min_size
,
4007 ~(clause_t
) (1 << predicate::false_condition
),
4008 vNULL
, vNULL
, vNULL
);
4009 size_info
->size
= RDIV (size_info
->size
, ipa_fn_summary::size_scale
);
4010 info
->min_size
= RDIV (info
->min_size
, ipa_fn_summary::size_scale
);
4014 /* This function performs intraprocedural analysis in NODE that is required to
4015 inline indirect calls. */
4018 inline_indirect_intraprocedural_analysis (struct cgraph_node
*node
)
4020 ipa_analyze_node (node
);
4021 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4023 ipa_print_node_params (dump_file
, node
);
4024 ipa_print_node_jump_functions (dump_file
, node
);
4029 /* Note function body size. */
4032 inline_analyze_function (struct cgraph_node
*node
)
4034 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
4037 fprintf (dump_file
, "\nAnalyzing function: %s\n", node
->dump_name ());
4038 if (opt_for_fn (node
->decl
, optimize
) && !node
->thunk
.thunk_p
)
4039 inline_indirect_intraprocedural_analysis (node
);
4040 compute_fn_summary (node
, false);
4043 struct cgraph_edge
*e
;
4044 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4045 e
->inline_failed
= CIF_FUNCTION_NOT_OPTIMIZED
;
4046 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4047 e
->inline_failed
= CIF_FUNCTION_NOT_OPTIMIZED
;
4054 /* Called when new function is inserted to callgraph late. */
4057 ipa_fn_summary_t::insert (struct cgraph_node
*node
, ipa_fn_summary
*)
4059 inline_analyze_function (node
);
4062 /* Note function body size. */
4065 ipa_fn_summary_generate (void)
4067 struct cgraph_node
*node
;
4069 FOR_EACH_DEFINED_FUNCTION (node
)
4070 if (DECL_STRUCT_FUNCTION (node
->decl
))
4071 node
->versionable
= tree_versionable_function_p (node
->decl
);
4073 ipa_fn_summary_alloc ();
4075 ipa_fn_summaries
->enable_insertion_hook ();
4077 ipa_register_cgraph_hooks ();
4079 FOR_EACH_DEFINED_FUNCTION (node
)
4081 && (flag_generate_lto
|| flag_generate_offload
|| flag_wpa
4082 || opt_for_fn (node
->decl
, optimize
)))
4083 inline_analyze_function (node
);
4087 /* Write inline summary for edge E to OB. */
4090 read_ipa_call_summary (class lto_input_block
*ib
, struct cgraph_edge
*e
,
4093 class ipa_call_summary
*es
= prevails
4094 ? ipa_call_summaries
->get_create (e
) : NULL
;
4098 int size
= streamer_read_uhwi (ib
);
4099 int time
= streamer_read_uhwi (ib
);
4100 int depth
= streamer_read_uhwi (ib
);
4104 es
->call_stmt_size
= size
;
4105 es
->call_stmt_time
= time
;
4106 es
->loop_depth
= depth
;
4109 bitpack_d bp
= streamer_read_bitpack (ib
);
4111 es
->is_return_callee_uncaptured
= bp_unpack_value (&bp
, 1);
4113 bp_unpack_value (&bp
, 1);
4117 edge_set_predicate (e
, &p
);
4118 length
= streamer_read_uhwi (ib
);
4119 if (length
&& es
&& e
->possibly_call_in_translation_unit_p ())
4121 es
->param
.safe_grow_cleared (length
);
4122 for (i
= 0; i
< length
; i
++)
4123 es
->param
[i
].change_prob
= streamer_read_uhwi (ib
);
4127 for (i
= 0; i
< length
; i
++)
4128 streamer_read_uhwi (ib
);
4133 /* Stream in inline summaries from the section. */
4136 inline_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
4139 const struct lto_function_header
*header
=
4140 (const struct lto_function_header
*) data
;
4141 const int cfg_offset
= sizeof (struct lto_function_header
);
4142 const int main_offset
= cfg_offset
+ header
->cfg_size
;
4143 const int string_offset
= main_offset
+ header
->main_size
;
4144 class data_in
*data_in
;
4145 unsigned int i
, count2
, j
;
4146 unsigned int f_count
;
4148 lto_input_block
ib ((const char *) data
+ main_offset
, header
->main_size
,
4149 file_data
->mode_table
);
4152 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
4153 header
->string_size
, vNULL
);
4154 f_count
= streamer_read_uhwi (&ib
);
4155 for (i
= 0; i
< f_count
; i
++)
4158 struct cgraph_node
*node
;
4159 class ipa_fn_summary
*info
;
4160 class ipa_node_params
*params_summary
;
4161 class ipa_size_summary
*size_info
;
4162 lto_symtab_encoder_t encoder
;
4163 struct bitpack_d bp
;
4164 struct cgraph_edge
*e
;
4167 index
= streamer_read_uhwi (&ib
);
4168 encoder
= file_data
->symtab_node_encoder
;
4169 node
= dyn_cast
<cgraph_node
*> (lto_symtab_encoder_deref (encoder
,
4171 info
= node
->prevailing_p () ? ipa_fn_summaries
->get_create (node
) : NULL
;
4172 params_summary
= node
->prevailing_p () ? IPA_NODE_REF (node
) : NULL
;
4173 size_info
= node
->prevailing_p ()
4174 ? ipa_size_summaries
->get_create (node
) : NULL
;
4176 int stack_size
= streamer_read_uhwi (&ib
);
4177 int size
= streamer_read_uhwi (&ib
);
4178 sreal time
= sreal::stream_in (&ib
);
4182 info
->estimated_stack_size
4183 = size_info
->estimated_self_stack_size
= stack_size
;
4184 size_info
->size
= size_info
->self_size
= size
;
4188 bp
= streamer_read_bitpack (&ib
);
4191 info
->inlinable
= bp_unpack_value (&bp
, 1);
4192 info
->fp_expressions
= bp_unpack_value (&bp
, 1);
4196 bp_unpack_value (&bp
, 1);
4197 bp_unpack_value (&bp
, 1);
4200 count2
= streamer_read_uhwi (&ib
);
4201 gcc_assert (!info
|| !info
->conds
);
4203 vec_safe_reserve_exact (info
->conds
, count2
);
4204 for (j
= 0; j
< count2
; j
++)
4207 unsigned int k
, count3
;
4208 c
.operand_num
= streamer_read_uhwi (&ib
);
4209 c
.code
= (enum tree_code
) streamer_read_uhwi (&ib
);
4210 c
.type
= stream_read_tree (&ib
, data_in
);
4211 c
.val
= stream_read_tree (&ib
, data_in
);
4212 bp
= streamer_read_bitpack (&ib
);
4213 c
.agg_contents
= bp_unpack_value (&bp
, 1);
4214 c
.by_ref
= bp_unpack_value (&bp
, 1);
4216 c
.offset
= streamer_read_uhwi (&ib
);
4217 count3
= streamer_read_uhwi (&ib
);
4220 vec_safe_reserve_exact (c
.param_ops
, count3
);
4222 ipa_set_param_used_by_ipa_predicates
4223 (params_summary
, c
.operand_num
, true);
4224 for (k
= 0; k
< count3
; k
++)
4226 struct expr_eval_op op
;
4227 enum gimple_rhs_class rhs_class
;
4228 op
.code
= (enum tree_code
) streamer_read_uhwi (&ib
);
4229 op
.type
= stream_read_tree (&ib
, data_in
);
4230 switch (rhs_class
= get_gimple_rhs_class (op
.code
))
4232 case GIMPLE_UNARY_RHS
:
4234 op
.val
[0] = NULL_TREE
;
4235 op
.val
[1] = NULL_TREE
;
4238 case GIMPLE_BINARY_RHS
:
4239 case GIMPLE_TERNARY_RHS
:
4240 bp
= streamer_read_bitpack (&ib
);
4241 op
.index
= bp_unpack_value (&bp
, 2);
4242 op
.val
[0] = stream_read_tree (&ib
, data_in
);
4243 if (rhs_class
== GIMPLE_BINARY_RHS
)
4244 op
.val
[1] = NULL_TREE
;
4246 op
.val
[1] = stream_read_tree (&ib
, data_in
);
4250 fatal_error (UNKNOWN_LOCATION
,
4251 "invalid fnsummary in LTO stream");
4254 c
.param_ops
->quick_push (op
);
4257 info
->conds
->quick_push (c
);
4259 count2
= streamer_read_uhwi (&ib
);
4260 gcc_assert (!info
|| !info
->size_time_table
);
4262 vec_safe_reserve_exact (info
->size_time_table
, count2
);
4263 for (j
= 0; j
< count2
; j
++)
4265 class size_time_entry e
;
4267 e
.size
= streamer_read_uhwi (&ib
);
4268 e
.time
= sreal::stream_in (&ib
);
4269 e
.exec_predicate
.stream_in (&ib
);
4270 e
.nonconst_predicate
.stream_in (&ib
);
4273 info
->size_time_table
->quick_push (e
);
4278 set_hint_predicate (&info
->loop_iterations
, p
);
4281 set_hint_predicate (&info
->loop_stride
, p
);
4282 for (e
= node
->callees
; e
; e
= e
->next_callee
)
4283 read_ipa_call_summary (&ib
, e
, info
!= NULL
);
4284 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
4285 read_ipa_call_summary (&ib
, e
, info
!= NULL
);
4288 lto_free_section_data (file_data
, LTO_section_ipa_fn_summary
, NULL
, data
,
4290 lto_data_in_delete (data_in
);
4294 /* Read inline summary. Jump functions are shared among ipa-cp
4295 and inliner, so when ipa-cp is active, we don't need to write them
4299 ipa_fn_summary_read (void)
4301 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
4302 struct lto_file_decl_data
*file_data
;
4305 ipa_fn_summary_alloc ();
4307 while ((file_data
= file_data_vec
[j
++]))
4311 = lto_get_summary_section_data (file_data
, LTO_section_ipa_fn_summary
,
4314 inline_read_section (file_data
, data
, len
);
4316 /* Fatal error here. We do not want to support compiling ltrans units
4317 with different version of compiler or different flags than the WPA
4318 unit, so this should never happen. */
4319 fatal_error (input_location
,
4320 "ipa inline summary is missing in input file");
4322 ipa_register_cgraph_hooks ();
4324 ipa_prop_read_jump_functions ();
4326 gcc_assert (ipa_fn_summaries
);
4327 ipa_fn_summaries
->enable_insertion_hook ();
4331 /* Write inline summary for edge E to OB. */
4334 write_ipa_call_summary (struct output_block
*ob
, struct cgraph_edge
*e
)
4336 class ipa_call_summary
*es
= ipa_call_summaries
->get (e
);
4339 streamer_write_uhwi (ob
, es
->call_stmt_size
);
4340 streamer_write_uhwi (ob
, es
->call_stmt_time
);
4341 streamer_write_uhwi (ob
, es
->loop_depth
);
4343 bitpack_d bp
= bitpack_create (ob
->main_stream
);
4344 bp_pack_value (&bp
, es
->is_return_callee_uncaptured
, 1);
4345 streamer_write_bitpack (&bp
);
4348 es
->predicate
->stream_out (ob
);
4350 streamer_write_uhwi (ob
, 0);
4351 streamer_write_uhwi (ob
, es
->param
.length ());
4352 for (i
= 0; i
< (int) es
->param
.length (); i
++)
4353 streamer_write_uhwi (ob
, es
->param
[i
].change_prob
);
4357 /* Write inline summary for node in SET.
4358 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
4359 active, we don't need to write them twice. */
4362 ipa_fn_summary_write (void)
4364 struct output_block
*ob
= create_output_block (LTO_section_ipa_fn_summary
);
4365 lto_symtab_encoder_iterator lsei
;
4366 lto_symtab_encoder_t encoder
= ob
->decl_state
->symtab_node_encoder
;
4367 unsigned int count
= 0;
4369 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4370 lsei_next_function_in_partition (&lsei
))
4372 cgraph_node
*cnode
= lsei_cgraph_node (lsei
);
4373 if (cnode
->definition
&& !cnode
->alias
)
4376 streamer_write_uhwi (ob
, count
);
4378 for (lsei
= lsei_start_function_in_partition (encoder
); !lsei_end_p (lsei
);
4379 lsei_next_function_in_partition (&lsei
))
4381 cgraph_node
*cnode
= lsei_cgraph_node (lsei
);
4382 if (cnode
->definition
&& !cnode
->alias
)
4384 class ipa_fn_summary
*info
= ipa_fn_summaries
->get (cnode
);
4385 class ipa_size_summary
*size_info
= ipa_size_summaries
->get (cnode
);
4386 struct bitpack_d bp
;
4387 struct cgraph_edge
*edge
;
4390 struct condition
*c
;
4392 streamer_write_uhwi (ob
, lto_symtab_encoder_encode (encoder
, cnode
));
4393 streamer_write_hwi (ob
, size_info
->estimated_self_stack_size
);
4394 streamer_write_hwi (ob
, size_info
->self_size
);
4395 info
->time
.stream_out (ob
);
4396 bp
= bitpack_create (ob
->main_stream
);
4397 bp_pack_value (&bp
, info
->inlinable
, 1);
4398 bp_pack_value (&bp
, false, 1);
4399 bp_pack_value (&bp
, info
->fp_expressions
, 1);
4400 streamer_write_bitpack (&bp
);
4401 streamer_write_uhwi (ob
, vec_safe_length (info
->conds
));
4402 for (i
= 0; vec_safe_iterate (info
->conds
, i
, &c
); i
++)
4405 struct expr_eval_op
*op
;
4407 streamer_write_uhwi (ob
, c
->operand_num
);
4408 streamer_write_uhwi (ob
, c
->code
);
4409 stream_write_tree (ob
, c
->type
, true);
4410 stream_write_tree (ob
, c
->val
, true);
4411 bp
= bitpack_create (ob
->main_stream
);
4412 bp_pack_value (&bp
, c
->agg_contents
, 1);
4413 bp_pack_value (&bp
, c
->by_ref
, 1);
4414 streamer_write_bitpack (&bp
);
4415 if (c
->agg_contents
)
4416 streamer_write_uhwi (ob
, c
->offset
);
4417 streamer_write_uhwi (ob
, vec_safe_length (c
->param_ops
));
4418 for (j
= 0; vec_safe_iterate (c
->param_ops
, j
, &op
); j
++)
4420 streamer_write_uhwi (ob
, op
->code
);
4421 stream_write_tree (ob
, op
->type
, true);
4424 bp
= bitpack_create (ob
->main_stream
);
4425 bp_pack_value (&bp
, op
->index
, 2);
4426 streamer_write_bitpack (&bp
);
4427 stream_write_tree (ob
, op
->val
[0], true);
4429 stream_write_tree (ob
, op
->val
[1], true);
4433 streamer_write_uhwi (ob
, vec_safe_length (info
->size_time_table
));
4434 for (i
= 0; vec_safe_iterate (info
->size_time_table
, i
, &e
); i
++)
4436 streamer_write_uhwi (ob
, e
->size
);
4437 e
->time
.stream_out (ob
);
4438 e
->exec_predicate
.stream_out (ob
);
4439 e
->nonconst_predicate
.stream_out (ob
);
4441 if (info
->loop_iterations
)
4442 info
->loop_iterations
->stream_out (ob
);
4444 streamer_write_uhwi (ob
, 0);
4445 if (info
->loop_stride
)
4446 info
->loop_stride
->stream_out (ob
);
4448 streamer_write_uhwi (ob
, 0);
4449 for (edge
= cnode
->callees
; edge
; edge
= edge
->next_callee
)
4450 write_ipa_call_summary (ob
, edge
);
4451 for (edge
= cnode
->indirect_calls
; edge
; edge
= edge
->next_callee
)
4452 write_ipa_call_summary (ob
, edge
);
4455 streamer_write_char_stream (ob
->main_stream
, 0);
4456 produce_asm (ob
, NULL
);
4457 destroy_output_block (ob
);
4460 ipa_prop_write_jump_functions ();
4464 /* Release function summary. */
4467 ipa_free_fn_summary (void)
4469 if (!ipa_call_summaries
)
4471 ggc_delete (ipa_fn_summaries
);
4472 ipa_fn_summaries
= NULL
;
4473 delete ipa_call_summaries
;
4474 ipa_call_summaries
= NULL
;
4475 edge_predicate_pool
.release ();
4476 /* During IPA this is one of largest datastructures to release. */
4481 /* Release function summary. */
4484 ipa_free_size_summary (void)
4486 if (!ipa_size_summaries
)
4488 delete ipa_size_summaries
;
4489 ipa_size_summaries
= NULL
;
4494 const pass_data pass_data_local_fn_summary
=
4496 GIMPLE_PASS
, /* type */
4497 "local-fnsummary", /* name */
4498 OPTGROUP_INLINE
, /* optinfo_flags */
4499 TV_INLINE_PARAMETERS
, /* tv_id */
4500 0, /* properties_required */
4501 0, /* properties_provided */
4502 0, /* properties_destroyed */
4503 0, /* todo_flags_start */
4504 0, /* todo_flags_finish */
4507 class pass_local_fn_summary
: public gimple_opt_pass
4510 pass_local_fn_summary (gcc::context
*ctxt
)
4511 : gimple_opt_pass (pass_data_local_fn_summary
, ctxt
)
4514 /* opt_pass methods: */
4515 opt_pass
* clone () { return new pass_local_fn_summary (m_ctxt
); }
4516 virtual unsigned int execute (function
*)
4518 return compute_fn_summary_for_current ();
4521 }; // class pass_local_fn_summary
4526 make_pass_local_fn_summary (gcc::context
*ctxt
)
4528 return new pass_local_fn_summary (ctxt
);
4532 /* Free inline summary. */
4536 const pass_data pass_data_ipa_free_fn_summary
=
4538 SIMPLE_IPA_PASS
, /* type */
4539 "free-fnsummary", /* name */
4540 OPTGROUP_NONE
, /* optinfo_flags */
4541 TV_IPA_FREE_INLINE_SUMMARY
, /* tv_id */
4542 0, /* properties_required */
4543 0, /* properties_provided */
4544 0, /* properties_destroyed */
4545 0, /* todo_flags_start */
4546 0, /* todo_flags_finish */
4549 class pass_ipa_free_fn_summary
: public simple_ipa_opt_pass
4552 pass_ipa_free_fn_summary (gcc::context
*ctxt
)
4553 : simple_ipa_opt_pass (pass_data_ipa_free_fn_summary
, ctxt
),
4557 /* opt_pass methods: */
4558 opt_pass
*clone () { return new pass_ipa_free_fn_summary (m_ctxt
); }
4559 void set_pass_param (unsigned int n
, bool param
)
4561 gcc_assert (n
== 0);
4564 virtual bool gate (function
*) { return true; }
4565 virtual unsigned int execute (function
*)
4567 ipa_free_fn_summary ();
4569 ipa_free_size_summary ();
4575 }; // class pass_ipa_free_fn_summary
4579 simple_ipa_opt_pass
*
4580 make_pass_ipa_free_fn_summary (gcc::context
*ctxt
)
4582 return new pass_ipa_free_fn_summary (ctxt
);
4587 const pass_data pass_data_ipa_fn_summary
=
4589 IPA_PASS
, /* type */
4590 "fnsummary", /* name */
4591 OPTGROUP_INLINE
, /* optinfo_flags */
4592 TV_IPA_FNSUMMARY
, /* tv_id */
4593 0, /* properties_required */
4594 0, /* properties_provided */
4595 0, /* properties_destroyed */
4596 0, /* todo_flags_start */
4597 ( TODO_dump_symtab
), /* todo_flags_finish */
4600 class pass_ipa_fn_summary
: public ipa_opt_pass_d
4603 pass_ipa_fn_summary (gcc::context
*ctxt
)
4604 : ipa_opt_pass_d (pass_data_ipa_fn_summary
, ctxt
,
4605 ipa_fn_summary_generate
, /* generate_summary */
4606 ipa_fn_summary_write
, /* write_summary */
4607 ipa_fn_summary_read
, /* read_summary */
4608 NULL
, /* write_optimization_summary */
4609 NULL
, /* read_optimization_summary */
4610 NULL
, /* stmt_fixup */
4611 0, /* function_transform_todo_flags_start */
4612 NULL
, /* function_transform */
4613 NULL
) /* variable_transform */
4616 /* opt_pass methods: */
4617 virtual unsigned int execute (function
*) { return 0; }
4619 }; // class pass_ipa_fn_summary
4624 make_pass_ipa_fn_summary (gcc::context
*ctxt
)
4626 return new pass_ipa_fn_summary (ctxt
);
4629 /* Reset all state within ipa-fnsummary.c so that we can rerun the compiler
4630 within the same process. For use by toplev::finalize. */
4633 ipa_fnsummary_c_finalize (void)
4635 ipa_free_fn_summary ();