1 /* Inlining decision heuristics.
2 Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* Analysis used by the inliner and other passes limiting code size growth.
24 We estimate for each function
26 - average function execution time
27 - inlining size benefit (that is how much of function body size
28 and its call sequence is expected to disappear by inlining)
29 - inlining time benefit
32 - call statement size and time
34 inlinie_summary datastructures store above information locally (i.e.
35 parameters of the function itself) and globally (i.e. parameters of
36 the function created by applying all the inline decisions already
37 present in the callgraph).
39 We provide accestor to the inline_summary datastructure and
40 basic logic updating the parameters when inlining is performed.
42 The summaries are context sensitive. Context means
43 1) partial assignment of known constant values of operands
44 2) whether function is inlined into the call or not.
45 It is easy to add more variants. To represent function size and time
46 that depends on context (i.e. it is known to be optimized away when
47 context is known either by inlining or from IP-CP and clonning),
48 we use predicates. Predicates are logical formulas in
49 conjunctive-disjunctive form consisting of clauses. Clauses are bitmaps
50 specifying what conditions must be true. Conditions are simple test
51 of the form described above.
53 In order to make predicate (possibly) true, all of its clauses must
54 be (possibly) true. To make clause (possibly) true, one of conditions
55 it mentions must be (possibly) true. There are fixed bounds on
56 number of clauses and conditions and all the manipulation functions
57 are conservative in positive direction. I.e. we may lose precision
58 by thinking that predicate may be true even when it is not.
60 estimate_edge_size and estimate_edge_growth can be used to query
61 function size/time in the given context. inline_merge_summary merges
62 properties of caller and callee after inlining.
64 Finally pass_inline_parameters is exported. This is used to drive
65 computation of function parameters used by the early inliner. IPA
66 inlined performs analysis via its analyze_function method. */
70 #include "coretypes.h"
73 #include "tree-inline.h"
74 #include "langhooks.h"
77 #include "diagnostic.h"
78 #include "gimple-pretty-print.h"
81 #include "tree-pass.h"
84 #include "tree-flow.h"
86 #include "lto-streamer.h"
87 #include "data-streamer.h"
88 #include "tree-streamer.h"
89 #include "ipa-inline.h"
90 #include "alloc-pool.h"
92 /* Estimate runtime of function can easilly run into huge numbers with many
93 nested loops. Be sure we can compute time * INLINE_SIZE_SCALE in integer.
94 For anything larger we use gcov_type. */
95 #define MAX_TIME 1000000
97 /* Number of bits in integer, but we really want to be stable across different
99 #define NUM_CONDITIONS 32
101 enum predicate_conditions
103 predicate_false_condition
= 0,
104 predicate_not_inlined_condition
= 1,
105 predicate_first_dynamic_condition
= 2
108 /* Special condition code we use to represent test that operand is compile time
110 #define IS_NOT_CONSTANT ERROR_MARK
111 /* Special condition code we use to represent test that operand is not changed
112 across invocation of the function. When operand IS_NOT_CONSTANT it is always
113 CHANGED, however i.e. loop invariants can be NOT_CHANGED given percentage
114 of executions even when they are not compile time constants. */
115 #define CHANGED IDENTIFIER_NODE
117 /* Holders of ipa cgraph hooks: */
118 static struct cgraph_node_hook_list
*function_insertion_hook_holder
;
119 static struct cgraph_node_hook_list
*node_removal_hook_holder
;
120 static struct cgraph_2node_hook_list
*node_duplication_hook_holder
;
121 static struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
122 static struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
123 static void inline_node_removal_hook (struct cgraph_node
*, void *);
124 static void inline_node_duplication_hook (struct cgraph_node
*,
125 struct cgraph_node
*, void *);
126 static void inline_edge_removal_hook (struct cgraph_edge
*, void *);
127 static void inline_edge_duplication_hook (struct cgraph_edge
*,
128 struct cgraph_edge
*,
131 /* VECtor holding inline summaries.
132 In GGC memory because conditions might point to constant trees. */
133 VEC(inline_summary_t
,gc
) *inline_summary_vec
;
134 VEC(inline_edge_summary_t
,heap
) *inline_edge_summary_vec
;
136 /* Cached node/edge growths. */
137 VEC(int,heap
) *node_growth_cache
;
138 VEC(edge_growth_cache_entry
,heap
) *edge_growth_cache
;
140 /* Edge predicates goes here. */
141 static alloc_pool edge_predicate_pool
;
143 /* Return true predicate (tautology).
144 We represent it by empty list of clauses. */
146 static inline struct predicate
147 true_predicate (void)
155 /* Return predicate testing single condition number COND. */
157 static inline struct predicate
158 single_cond_predicate (int cond
)
161 p
.clause
[0]=1 << cond
;
167 /* Return false predicate. First clause require false condition. */
169 static inline struct predicate
170 false_predicate (void)
172 return single_cond_predicate (predicate_false_condition
);
176 /* Return true if P is (false). */
179 true_predicate_p (struct predicate
*p
)
181 return !p
->clause
[0];
185 /* Return true if P is (false). */
188 false_predicate_p (struct predicate
*p
)
190 if (p
->clause
[0] == (1 << predicate_false_condition
))
192 gcc_checking_assert (!p
->clause
[1]
193 && p
->clause
[0] == 1 << predicate_false_condition
);
200 /* Return predicate that is set true when function is not inlined. */
201 static inline struct predicate
202 not_inlined_predicate (void)
204 return single_cond_predicate (predicate_not_inlined_condition
);
208 /* Add condition to condition list CONDS. */
210 static struct predicate
211 add_condition (struct inline_summary
*summary
, int operand_num
,
212 enum tree_code code
, tree val
)
216 struct condition new_cond
;
218 for (i
= 0; VEC_iterate (condition
, summary
->conds
, i
, c
); i
++)
220 if (c
->operand_num
== operand_num
223 return single_cond_predicate (i
+ predicate_first_dynamic_condition
);
225 /* Too many conditions. Give up and return constant true. */
226 if (i
== NUM_CONDITIONS
- predicate_first_dynamic_condition
)
227 return true_predicate ();
229 new_cond
.operand_num
= operand_num
;
230 new_cond
.code
= code
;
232 VEC_safe_push (condition
, gc
, summary
->conds
, &new_cond
);
233 return single_cond_predicate (i
+ predicate_first_dynamic_condition
);
237 /* Add clause CLAUSE into the predicate P. */
240 add_clause (conditions conditions
, struct predicate
*p
, clause_t clause
)
244 int insert_here
= -1;
251 /* False clause makes the whole predicate false. Kill the other variants. */
252 if (clause
== (1 << predicate_false_condition
))
254 p
->clause
[0] = (1 << predicate_false_condition
);
258 if (false_predicate_p (p
))
261 /* No one should be sily enough to add false into nontrivial clauses. */
262 gcc_checking_assert (!(clause
& (1 << predicate_false_condition
)));
264 /* Look where to insert the clause. At the same time prune out
265 clauses of P that are implied by the new clause and thus
267 for (i
= 0, i2
= 0; i
<= MAX_CLAUSES
; i
++)
269 p
->clause
[i2
] = p
->clause
[i
];
274 /* If p->clause[i] implies clause, there is nothing to add. */
275 if ((p
->clause
[i
] & clause
) == p
->clause
[i
])
277 /* We had nothing to add, none of clauses should've become
279 gcc_checking_assert (i
== i2
);
283 if (p
->clause
[i
] < clause
&& insert_here
< 0)
286 /* If clause implies p->clause[i], then p->clause[i] becomes redundant.
287 Otherwise the p->clause[i] has to stay. */
288 if ((p
->clause
[i
] & clause
) != clause
)
292 /* Look for clauses that are obviously true. I.e.
293 op0 == 5 || op0 != 5. */
294 for (c1
= predicate_first_dynamic_condition
; c1
< NUM_CONDITIONS
; c1
++)
297 if (!(clause
& (1 << c1
)))
299 cc1
= VEC_index (condition
,
301 c1
- predicate_first_dynamic_condition
);
302 /* We have no way to represent !CHANGED and !IS_NOT_CONSTANT
303 and thus there is no point for looking for them. */
304 if (cc1
->code
== CHANGED
305 || cc1
->code
== IS_NOT_CONSTANT
)
307 for (c2
= c1
+ 1; c2
<= NUM_CONDITIONS
; c2
++)
308 if (clause
& (1 << c2
))
310 condition
*cc1
= VEC_index (condition
,
312 c1
- predicate_first_dynamic_condition
);
313 condition
*cc2
= VEC_index (condition
,
315 c2
- predicate_first_dynamic_condition
);
316 if (cc1
->operand_num
== cc2
->operand_num
317 && cc1
->val
== cc2
->val
318 && cc2
->code
!= IS_NOT_CONSTANT
319 && cc2
->code
!= CHANGED
320 && cc1
->code
== invert_tree_comparison
322 HONOR_NANS (TYPE_MODE (TREE_TYPE (cc1
->val
)))))
328 /* We run out of variants. Be conservative in positive direction. */
329 if (i2
== MAX_CLAUSES
)
331 /* Keep clauses in decreasing order. This makes equivalence testing easy. */
332 p
->clause
[i2
+ 1] = 0;
333 if (insert_here
>= 0)
334 for (;i2
> insert_here
; i2
--)
335 p
->clause
[i2
] = p
->clause
[i2
- 1];
338 p
->clause
[insert_here
] = clause
;
344 static struct predicate
345 and_predicates (conditions conditions
,
346 struct predicate
*p
, struct predicate
*p2
)
348 struct predicate out
= *p
;
351 /* Avoid busy work. */
352 if (false_predicate_p (p2
) || true_predicate_p (p
))
354 if (false_predicate_p (p
) || true_predicate_p (p2
))
357 /* See how far predicates match. */
358 for (i
= 0; p
->clause
[i
] && p
->clause
[i
] == p2
->clause
[i
]; i
++)
360 gcc_checking_assert (i
< MAX_CLAUSES
);
363 /* Combine the predicates rest. */
364 for (; p2
->clause
[i
]; i
++)
366 gcc_checking_assert (i
< MAX_CLAUSES
);
367 add_clause (conditions
, &out
, p2
->clause
[i
]);
373 /* Return true if predicates are obviously equal. */
376 predicates_equal_p (struct predicate
*p
, struct predicate
*p2
)
379 for (i
= 0; p
->clause
[i
]; i
++)
381 gcc_checking_assert (i
< MAX_CLAUSES
);
382 gcc_checking_assert (p
->clause
[i
] > p
->clause
[i
+ 1]);
383 gcc_checking_assert (!p2
->clause
[i
]
384 || p2
->clause
[i
] > p2
->clause
[i
+ 1]);
385 if (p
->clause
[i
] != p2
->clause
[i
])
388 return !p2
->clause
[i
];
394 static struct predicate
395 or_predicates (conditions conditions
, struct predicate
*p
, struct predicate
*p2
)
397 struct predicate out
= true_predicate ();
400 /* Avoid busy work. */
401 if (false_predicate_p (p2
) || true_predicate_p (p
))
403 if (false_predicate_p (p
) || true_predicate_p (p2
))
405 if (predicates_equal_p (p
, p2
))
408 /* OK, combine the predicates. */
409 for (i
= 0; p
->clause
[i
]; i
++)
410 for (j
= 0; p2
->clause
[j
]; j
++)
412 gcc_checking_assert (i
< MAX_CLAUSES
&& j
< MAX_CLAUSES
);
413 add_clause (conditions
, &out
, p
->clause
[i
] | p2
->clause
[j
]);
419 /* Having partial truth assignment in POSSIBLE_TRUTHS, return false
420 if predicate P is known to be false. */
423 evaluate_predicate (struct predicate
*p
, clause_t possible_truths
)
427 /* True remains true. */
428 if (true_predicate_p (p
))
431 gcc_assert (!(possible_truths
& (1 << predicate_false_condition
)));
433 /* See if we can find clause we can disprove. */
434 for (i
= 0; p
->clause
[i
]; i
++)
436 gcc_checking_assert (i
< MAX_CLAUSES
);
437 if (!(p
->clause
[i
] & possible_truths
))
443 /* Return the probability in range 0...REG_BR_PROB_BASE that the predicated
444 instruction will be recomputed per invocation of the inlined call. */
447 predicate_probability (conditions conds
,
448 struct predicate
*p
, clause_t possible_truths
,
449 VEC (inline_param_summary_t
, heap
) *inline_param_summary
)
452 int combined_prob
= REG_BR_PROB_BASE
;
454 /* True remains true. */
455 if (true_predicate_p (p
))
456 return REG_BR_PROB_BASE
;
458 if (false_predicate_p (p
))
461 gcc_assert (!(possible_truths
& (1 << predicate_false_condition
)));
463 /* See if we can find clause we can disprove. */
464 for (i
= 0; p
->clause
[i
]; i
++)
466 gcc_checking_assert (i
< MAX_CLAUSES
);
467 if (!(p
->clause
[i
] & possible_truths
))
473 if (!inline_param_summary
)
474 return REG_BR_PROB_BASE
;
475 for (i2
= 0; i2
< NUM_CONDITIONS
; i2
++)
476 if ((p
->clause
[i
] & possible_truths
) & (1 << i2
))
478 if (i2
>= predicate_first_dynamic_condition
)
480 condition
*c
= VEC_index
482 i2
- predicate_first_dynamic_condition
);
483 if (c
->code
== CHANGED
485 < VEC_length (inline_param_summary_t
,
486 inline_param_summary
)))
488 int iprob
= VEC_index (inline_param_summary_t
,
489 inline_param_summary
,
490 c
->operand_num
)->change_prob
;
491 this_prob
= MAX (this_prob
, iprob
);
494 this_prob
= REG_BR_PROB_BASE
;
497 this_prob
= REG_BR_PROB_BASE
;
499 combined_prob
= MIN (this_prob
, combined_prob
);
504 return combined_prob
;
508 /* Dump conditional COND. */
511 dump_condition (FILE *f
, conditions conditions
, int cond
)
514 if (cond
== predicate_false_condition
)
515 fprintf (f
, "false");
516 else if (cond
== predicate_not_inlined_condition
)
517 fprintf (f
, "not inlined");
520 c
= VEC_index (condition
, conditions
,
521 cond
- predicate_first_dynamic_condition
);
522 fprintf (f
, "op%i", c
->operand_num
);
523 if (c
->code
== IS_NOT_CONSTANT
)
525 fprintf (f
, " not constant");
528 if (c
->code
== CHANGED
)
530 fprintf (f
, " changed");
533 fprintf (f
, " %s ", op_symbol_code (c
->code
));
534 print_generic_expr (f
, c
->val
, 1);
539 /* Dump clause CLAUSE. */
542 dump_clause (FILE *f
, conditions conds
, clause_t clause
)
549 for (i
= 0; i
< NUM_CONDITIONS
; i
++)
550 if (clause
& (1 << i
))
555 dump_condition (f
, conds
, i
);
561 /* Dump predicate PREDICATE. */
564 dump_predicate (FILE *f
, conditions conds
, struct predicate
*pred
)
567 if (true_predicate_p (pred
))
568 dump_clause (f
, conds
, 0);
570 for (i
= 0; pred
->clause
[i
]; i
++)
574 dump_clause (f
, conds
, pred
->clause
[i
]);
580 /* Record SIZE and TIME under condition PRED into the inline summary. */
583 account_size_time (struct inline_summary
*summary
, int size
, int time
,
584 struct predicate
*pred
)
590 if (false_predicate_p (pred
))
593 /* We need to create initial empty unconitional clause, but otherwie
594 we don't need to account empty times and sizes. */
595 if (!size
&& !time
&& summary
->entry
)
598 /* Watch overflow that might result from insane profiles. */
599 if (time
> MAX_TIME
* INLINE_TIME_SCALE
)
600 time
= MAX_TIME
* INLINE_TIME_SCALE
;
601 gcc_assert (time
>= 0);
603 for (i
= 0; VEC_iterate (size_time_entry
, summary
->entry
, i
, e
); i
++)
604 if (predicates_equal_p (&e
->predicate
, pred
))
613 e
= VEC_index (size_time_entry
, summary
->entry
, 0);
614 gcc_assert (!e
->predicate
.clause
[0]);
616 if (dump_file
&& (dump_flags
& TDF_DETAILS
) && (time
|| size
))
618 fprintf (dump_file
, "\t\tAccounting size:%3.2f, time:%3.2f on %spredicate:",
619 ((double)size
) / INLINE_SIZE_SCALE
,
620 ((double)time
) / INLINE_TIME_SCALE
,
621 found
? "" : "new ");
622 dump_predicate (dump_file
, summary
->conds
, pred
);
626 struct size_time_entry new_entry
;
627 new_entry
.size
= size
;
628 new_entry
.time
= time
;
629 new_entry
.predicate
= *pred
;
630 VEC_safe_push (size_time_entry
, gc
, summary
->entry
, &new_entry
);
636 if (e
->time
> MAX_TIME
* INLINE_TIME_SCALE
)
637 e
->time
= MAX_TIME
* INLINE_TIME_SCALE
;
641 /* Set predicate for edge E. */
644 edge_set_predicate (struct cgraph_edge
*e
, struct predicate
*predicate
)
646 struct inline_edge_summary
*es
= inline_edge_summary (e
);
647 if (predicate
&& !true_predicate_p (predicate
))
650 es
->predicate
= (struct predicate
*)pool_alloc (edge_predicate_pool
);
651 *es
->predicate
= *predicate
;
656 pool_free (edge_predicate_pool
, es
->predicate
);
657 es
->predicate
= NULL
;
662 /* KNOWN_VALS is partial mapping of parameters of NODE to constant values.
663 Return clause of possible truths. When INLINE_P is true, assume that
666 ERROR_MARK means compile time invariant. */
669 evaluate_conditions_for_known_args (struct cgraph_node
*node
,
671 VEC (tree
, heap
) *known_vals
)
673 clause_t clause
= inline_p
? 0 : 1 << predicate_not_inlined_condition
;
674 struct inline_summary
*info
= inline_summary (node
);
678 for (i
= 0; VEC_iterate (condition
, info
->conds
, i
, c
); i
++)
683 /* We allow call stmt to have fewer arguments than the callee
684 function (especially for K&R style programs). So bound
686 if (c
->operand_num
< (int)VEC_length (tree
, known_vals
))
687 val
= VEC_index (tree
, known_vals
, c
->operand_num
);
691 if (val
== error_mark_node
&& c
->code
!= CHANGED
)
696 clause
|= 1 << (i
+ predicate_first_dynamic_condition
);
699 if (c
->code
== IS_NOT_CONSTANT
|| c
->code
== CHANGED
)
701 res
= fold_binary_to_constant (c
->code
, boolean_type_node
, val
, c
->val
);
703 && integer_zerop (res
))
705 clause
|= 1 << (i
+ predicate_first_dynamic_condition
);
711 /* Work out what conditions might be true at invocation of E. */
714 evaluate_conditions_for_edge (struct cgraph_edge
*e
, bool inline_p
)
716 clause_t clause
= inline_p
? 0 : 1 << predicate_not_inlined_condition
;
717 struct cgraph_node
*callee
= cgraph_function_or_thunk_node (e
->callee
, NULL
);
718 struct inline_summary
*info
= inline_summary (callee
);
721 if (ipa_node_params_vector
&& info
->conds
)
723 struct ipa_node_params
*parms_info
;
724 struct ipa_edge_args
*args
= IPA_EDGE_REF (e
);
725 struct inline_edge_summary
*es
= inline_edge_summary (e
);
726 int i
, count
= ipa_get_cs_argument_count (args
);
727 VEC (tree
, heap
) *known_vals
= NULL
;
729 if (e
->caller
->global
.inlined_to
)
730 parms_info
= IPA_NODE_REF (e
->caller
->global
.inlined_to
);
732 parms_info
= IPA_NODE_REF (e
->caller
);
735 VEC_safe_grow_cleared (tree
, heap
, known_vals
, count
);
736 for (i
= 0; i
< count
; i
++)
738 tree cst
= ipa_cst_from_jfunc (parms_info
,
739 ipa_get_ith_jump_func (args
, i
));
741 VEC_replace (tree
, known_vals
, i
, cst
);
743 && !VEC_index (inline_param_summary_t
,
746 VEC_replace (tree
, known_vals
, i
, error_mark_node
);
748 clause
= evaluate_conditions_for_known_args (callee
,
749 inline_p
, known_vals
);
750 VEC_free (tree
, heap
, known_vals
);
753 for (i
= 0; i
< (int)VEC_length (condition
, info
->conds
); i
++)
754 clause
|= 1 << (i
+ predicate_first_dynamic_condition
);
760 /* Allocate the inline summary vector or resize it to cover all cgraph nodes. */
763 inline_summary_alloc (void)
765 if (!node_removal_hook_holder
)
766 node_removal_hook_holder
=
767 cgraph_add_node_removal_hook (&inline_node_removal_hook
, NULL
);
768 if (!edge_removal_hook_holder
)
769 edge_removal_hook_holder
=
770 cgraph_add_edge_removal_hook (&inline_edge_removal_hook
, NULL
);
771 if (!node_duplication_hook_holder
)
772 node_duplication_hook_holder
=
773 cgraph_add_node_duplication_hook (&inline_node_duplication_hook
, NULL
);
774 if (!edge_duplication_hook_holder
)
775 edge_duplication_hook_holder
=
776 cgraph_add_edge_duplication_hook (&inline_edge_duplication_hook
, NULL
);
778 if (VEC_length (inline_summary_t
, inline_summary_vec
)
779 <= (unsigned) cgraph_max_uid
)
780 VEC_safe_grow_cleared (inline_summary_t
, gc
,
781 inline_summary_vec
, cgraph_max_uid
+ 1);
782 if (VEC_length (inline_edge_summary_t
, inline_edge_summary_vec
)
783 <= (unsigned) cgraph_edge_max_uid
)
784 VEC_safe_grow_cleared (inline_edge_summary_t
, heap
,
785 inline_edge_summary_vec
, cgraph_edge_max_uid
+ 1);
786 if (!edge_predicate_pool
)
787 edge_predicate_pool
= create_alloc_pool ("edge predicates",
788 sizeof (struct predicate
),
792 /* Hook that is called by cgraph.c when a node is removed. */
795 inline_node_removal_hook (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
797 struct inline_summary
*info
;
798 if (VEC_length (inline_summary_t
, inline_summary_vec
)
799 <= (unsigned)node
->uid
)
801 info
= inline_summary (node
);
802 reset_node_growth_cache (node
);
803 VEC_free (condition
, gc
, info
->conds
);
804 VEC_free (size_time_entry
, gc
, info
->entry
);
807 memset (info
, 0, sizeof (inline_summary_t
));
811 /* Hook that is called by cgraph.c when a node is duplicated. */
814 inline_node_duplication_hook (struct cgraph_node
*src
, struct cgraph_node
*dst
,
815 ATTRIBUTE_UNUSED
void *data
)
817 struct inline_summary
*info
;
818 inline_summary_alloc ();
819 info
= inline_summary (dst
);
820 memcpy (info
, inline_summary (src
),
821 sizeof (struct inline_summary
));
822 /* TODO: as an optimization, we may avoid copying conditions
823 that are known to be false or true. */
824 info
->conds
= VEC_copy (condition
, gc
, info
->conds
);
826 /* When there are any replacements in the function body, see if we can figure
827 out that something was optimized out. */
828 if (ipa_node_params_vector
&& dst
->clone
.tree_map
)
830 VEC(size_time_entry
,gc
) *entry
= info
->entry
;
831 /* Use SRC parm info since it may not be copied yet. */
832 struct ipa_node_params
*parms_info
= IPA_NODE_REF (src
);
833 VEC (tree
, heap
) *known_vals
= NULL
;
834 int count
= ipa_get_param_count (parms_info
);
836 clause_t possible_truths
;
837 struct predicate true_pred
= true_predicate ();
839 int optimized_out_size
= 0;
840 gcov_type optimized_out_time
= 0;
841 bool inlined_to_p
= false;
842 struct cgraph_edge
*edge
;
845 VEC_safe_grow_cleared (tree
, heap
, known_vals
, count
);
846 for (i
= 0; i
< count
; i
++)
848 tree t
= ipa_get_param (parms_info
, i
);
849 struct ipa_replace_map
*r
;
852 VEC_iterate (ipa_replace_map_p
, dst
->clone
.tree_map
, j
, r
);
859 VEC_replace (tree
, known_vals
, i
, r
->new_tree
);
864 possible_truths
= evaluate_conditions_for_known_args (dst
,
866 VEC_free (tree
, heap
, known_vals
);
868 account_size_time (info
, 0, 0, &true_pred
);
870 /* Remap size_time vectors.
871 Simplify the predicate by prunning out alternatives that are known
873 TODO: as on optimization, we can also eliminate conditions known
875 for (i
= 0; VEC_iterate (size_time_entry
, entry
, i
, e
); i
++)
877 struct predicate new_predicate
= true_predicate ();
878 for (j
= 0; e
->predicate
.clause
[j
]; j
++)
879 if (!(possible_truths
& e
->predicate
.clause
[j
]))
881 new_predicate
= false_predicate ();
885 add_clause (info
->conds
, &new_predicate
,
886 possible_truths
& e
->predicate
.clause
[j
]);
887 if (false_predicate_p (&new_predicate
))
889 optimized_out_size
+= e
->size
;
890 optimized_out_time
+= e
->time
;
893 account_size_time (info
, e
->size
, e
->time
, &new_predicate
);
896 /* Remap edge predicates with the same simplification as above.
897 Also copy constantness arrays. */
898 for (edge
= dst
->callees
; edge
; edge
= edge
->next_callee
)
900 struct predicate new_predicate
= true_predicate ();
901 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
903 if (!edge
->inline_failed
)
907 for (j
= 0; es
->predicate
->clause
[j
]; j
++)
908 if (!(possible_truths
& es
->predicate
->clause
[j
]))
910 new_predicate
= false_predicate ();
914 add_clause (info
->conds
, &new_predicate
,
915 possible_truths
& es
->predicate
->clause
[j
]);
916 if (false_predicate_p (&new_predicate
)
917 && !false_predicate_p (es
->predicate
))
919 optimized_out_size
+= es
->call_stmt_size
* INLINE_SIZE_SCALE
;
920 optimized_out_time
+= (es
->call_stmt_time
921 * (INLINE_TIME_SCALE
/ CGRAPH_FREQ_BASE
)
925 *es
->predicate
= new_predicate
;
928 /* Remap indirect edge predicates with the same simplificaiton as above.
929 Also copy constantness arrays. */
930 for (edge
= dst
->indirect_calls
; edge
; edge
= edge
->next_callee
)
932 struct predicate new_predicate
= true_predicate ();
933 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
935 if (!edge
->inline_failed
)
939 for (j
= 0; es
->predicate
->clause
[j
]; j
++)
940 if (!(possible_truths
& es
->predicate
->clause
[j
]))
942 new_predicate
= false_predicate ();
946 add_clause (info
->conds
, &new_predicate
,
947 possible_truths
& es
->predicate
->clause
[j
]);
948 if (false_predicate_p (&new_predicate
)
949 && !false_predicate_p (es
->predicate
))
951 optimized_out_size
+= es
->call_stmt_size
* INLINE_SIZE_SCALE
;
952 optimized_out_time
+= (es
->call_stmt_time
953 * (INLINE_TIME_SCALE
/ CGRAPH_FREQ_BASE
)
957 *es
->predicate
= new_predicate
;
960 /* If inliner or someone after inliner will ever start producing
961 non-trivial clones, we will get trouble with lack of information
962 about updating self sizes, because size vectors already contains
963 sizes of the calees. */
964 gcc_assert (!inlined_to_p
965 || (!optimized_out_size
&& !optimized_out_time
));
967 info
->size
-= optimized_out_size
/ INLINE_SIZE_SCALE
;
968 info
->self_size
-= optimized_out_size
/ INLINE_SIZE_SCALE
;
969 gcc_assert (info
->size
> 0);
970 gcc_assert (info
->self_size
> 0);
972 optimized_out_time
/= INLINE_TIME_SCALE
;
973 if (optimized_out_time
> MAX_TIME
)
974 optimized_out_time
= MAX_TIME
;
975 info
->time
-= optimized_out_time
;
976 info
->self_time
-= optimized_out_time
;
979 if (info
->self_time
< 0)
983 info
->entry
= VEC_copy (size_time_entry
, gc
, info
->entry
);
987 /* Hook that is called by cgraph.c when a node is duplicated. */
990 inline_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
991 ATTRIBUTE_UNUSED
void *data
)
993 struct inline_edge_summary
*info
;
994 struct inline_edge_summary
*srcinfo
;
995 inline_summary_alloc ();
996 info
= inline_edge_summary (dst
);
997 srcinfo
= inline_edge_summary (src
);
998 memcpy (info
, srcinfo
,
999 sizeof (struct inline_edge_summary
));
1000 info
->predicate
= NULL
;
1001 edge_set_predicate (dst
, srcinfo
->predicate
);
1002 info
->param
= VEC_copy (inline_param_summary_t
, heap
, srcinfo
->param
);
1006 /* Keep edge cache consistent across edge removal. */
1009 inline_edge_removal_hook (struct cgraph_edge
*edge
, void *data ATTRIBUTE_UNUSED
)
1011 if (edge_growth_cache
)
1012 reset_edge_growth_cache (edge
);
1014 < (int)VEC_length (inline_edge_summary_t
, inline_edge_summary_vec
))
1016 edge_set_predicate (edge
, NULL
);
1017 VEC_free (inline_param_summary_t
, heap
,
1018 inline_edge_summary (edge
)->param
);
1019 memset (inline_edge_summary (edge
), 0,
1020 sizeof (struct inline_edge_summary
));
1025 /* Initialize growth caches. */
1028 initialize_growth_caches (void)
1030 if (cgraph_edge_max_uid
)
1031 VEC_safe_grow_cleared (edge_growth_cache_entry
, heap
, edge_growth_cache
,
1032 cgraph_edge_max_uid
);
1034 VEC_safe_grow_cleared (int, heap
, node_growth_cache
, cgraph_max_uid
);
1038 /* Free growth caches. */
1041 free_growth_caches (void)
1043 VEC_free (edge_growth_cache_entry
, heap
, edge_growth_cache
);
1044 edge_growth_cache
= 0;
1045 VEC_free (int, heap
, node_growth_cache
);
1046 node_growth_cache
= 0;
1050 /* Dump edge summaries associated to NODE and recursively to all clones.
1051 Indent by INDENT. */
1054 dump_inline_edge_summary (FILE * f
, int indent
, struct cgraph_node
*node
,
1055 struct inline_summary
*info
)
1057 struct cgraph_edge
*edge
;
1058 for (edge
= node
->callees
; edge
; edge
= edge
->next_callee
)
1060 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
1061 struct cgraph_node
*callee
= cgraph_function_or_thunk_node (edge
->callee
, NULL
);
1064 fprintf (f
, "%*s%s/%i %s\n%*s loop depth:%2i freq:%4i size:%2i time: %2i callee size:%2i stack:%2i",
1065 indent
, "", cgraph_node_name (callee
),
1067 !edge
->inline_failed
? "inlined"
1068 : cgraph_inline_failed_string (edge
->inline_failed
),
1074 (int)inline_summary (callee
)->size
/ INLINE_SIZE_SCALE
,
1075 (int)inline_summary (callee
)->estimated_stack_size
);
1079 fprintf (f
, " predicate: ");
1080 dump_predicate (f
, info
->conds
, es
->predicate
);
1085 for (i
= 0; i
< (int)VEC_length (inline_param_summary_t
, es
->param
);
1088 int prob
= VEC_index (inline_param_summary_t
,
1089 es
->param
, i
)->change_prob
;
1092 fprintf (f
, "%*s op%i is compile time invariant\n",
1094 else if (prob
!= REG_BR_PROB_BASE
)
1095 fprintf (f
, "%*s op%i change %f%% of time\n", indent
+ 2, "", i
,
1096 prob
* 100.0 / REG_BR_PROB_BASE
);
1098 if (!edge
->inline_failed
)
1100 fprintf (f
, "%*sStack frame offset %i, callee self size %i,"
1101 " callee size %i\n",
1103 (int)inline_summary (callee
)->stack_frame_offset
,
1104 (int)inline_summary (callee
)->estimated_self_stack_size
,
1105 (int)inline_summary (callee
)->estimated_stack_size
);
1106 dump_inline_edge_summary (f
, indent
+2, callee
, info
);
1109 for (edge
= node
->indirect_calls
; edge
; edge
= edge
->next_callee
)
1111 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
1112 fprintf (f
, "%*sindirect call loop depth:%2i freq:%4i size:%2i"
1118 es
->call_stmt_time
);
1121 fprintf (f
, "predicate: ");
1122 dump_predicate (f
, info
->conds
, es
->predicate
);
1131 dump_inline_summary (FILE * f
, struct cgraph_node
*node
)
1135 struct inline_summary
*s
= inline_summary (node
);
1138 fprintf (f
, "Inline summary for %s/%i", cgraph_node_name (node
),
1140 if (DECL_DISREGARD_INLINE_LIMITS (node
->decl
))
1141 fprintf (f
, " always_inline");
1143 fprintf (f
, " inlinable");
1144 fprintf (f
, "\n self time: %i\n",
1146 fprintf (f
, " global time: %i\n", s
->time
);
1147 fprintf (f
, " self size: %i\n",
1149 fprintf (f
, " global size: %i\n", s
->size
);
1150 fprintf (f
, " self stack: %i\n",
1151 (int) s
->estimated_self_stack_size
);
1152 fprintf (f
, " global stack: %i\n",
1153 (int) s
->estimated_stack_size
);
1155 VEC_iterate (size_time_entry
, s
->entry
, i
, e
);
1158 fprintf (f
, " size:%f, time:%f, predicate:",
1159 (double) e
->size
/ INLINE_SIZE_SCALE
,
1160 (double) e
->time
/ INLINE_TIME_SCALE
);
1161 dump_predicate (f
, s
->conds
, &e
->predicate
);
1163 fprintf (f
, " calls:\n");
1164 dump_inline_edge_summary (f
, 4, node
, s
);
1170 debug_inline_summary (struct cgraph_node
*node
)
1172 dump_inline_summary (stderr
, node
);
1176 dump_inline_summaries (FILE *f
)
1178 struct cgraph_node
*node
;
1180 for (node
= cgraph_nodes
; node
; node
= node
->next
)
1181 if (node
->analyzed
&& !node
->global
.inlined_to
)
1182 dump_inline_summary (f
, node
);
1185 /* Give initial reasons why inlining would fail on EDGE. This gets either
1186 nullified or usually overwritten by more precise reasons later. */
1189 initialize_inline_failed (struct cgraph_edge
*e
)
1191 struct cgraph_node
*callee
= e
->callee
;
1193 if (e
->indirect_unknown_callee
)
1194 e
->inline_failed
= CIF_INDIRECT_UNKNOWN_CALL
;
1195 else if (!callee
->analyzed
)
1196 e
->inline_failed
= CIF_BODY_NOT_AVAILABLE
;
1197 else if (callee
->local
.redefined_extern_inline
)
1198 e
->inline_failed
= CIF_REDEFINED_EXTERN_INLINE
;
1199 else if (e
->call_stmt
&& gimple_call_cannot_inline_p (e
->call_stmt
))
1200 e
->inline_failed
= CIF_MISMATCHED_ARGUMENTS
;
1202 e
->inline_failed
= CIF_FUNCTION_NOT_CONSIDERED
;
1205 /* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
1206 boolean variable pointed to by DATA. */
1209 mark_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef ATTRIBUTE_UNUSED
,
1212 bool *b
= (bool *) data
;
1217 /* If OP reffers to value of function parameter, return
1218 the corresponding parameter. */
1221 unmodified_parm (gimple stmt
, tree op
)
1223 /* SSA_NAME referring to parm default def? */
1224 if (TREE_CODE (op
) == SSA_NAME
1225 && SSA_NAME_IS_DEFAULT_DEF (op
)
1226 && TREE_CODE (SSA_NAME_VAR (op
)) == PARM_DECL
)
1227 return SSA_NAME_VAR (op
);
1228 /* Non-SSA parm reference? */
1229 if (TREE_CODE (op
) == PARM_DECL
)
1231 bool modified
= false;
1234 ao_ref_init (&refd
, op
);
1235 walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), mark_modified
, &modified
,
1240 /* Assignment from a parameter? */
1241 if (TREE_CODE (op
) == SSA_NAME
1242 && !SSA_NAME_IS_DEFAULT_DEF (op
)
1243 && gimple_assign_single_p (SSA_NAME_DEF_STMT (op
)))
1244 return unmodified_parm (SSA_NAME_DEF_STMT (op
),
1245 gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op
)));
1249 /* See if statement might disappear after inlining.
1250 0 - means not eliminated
1251 1 - half of statements goes away
1252 2 - for sure it is eliminated.
1253 We are not terribly sophisticated, basically looking for simple abstraction
1254 penalty wrappers. */
1257 eliminated_by_inlining_prob (gimple stmt
)
1259 enum gimple_code code
= gimple_code (stmt
);
1269 if (gimple_num_ops (stmt
) != 2)
1272 /* Casts of parameters, loads from parameters passed by reference
1273 and stores to return value or parameters are often free after
1274 inlining dua to SRA and further combining.
1275 Assume that half of statements goes away. */
1276 if (gimple_assign_rhs_code (stmt
) == CONVERT_EXPR
1277 || gimple_assign_rhs_code (stmt
) == NOP_EXPR
1278 || gimple_assign_rhs_code (stmt
) == VIEW_CONVERT_EXPR
1279 || gimple_assign_rhs_class (stmt
) == GIMPLE_SINGLE_RHS
)
1281 tree rhs
= gimple_assign_rhs1 (stmt
);
1282 tree lhs
= gimple_assign_lhs (stmt
);
1283 tree inner_rhs
= get_base_address (rhs
);
1284 tree inner_lhs
= get_base_address (lhs
);
1285 bool rhs_free
= false;
1286 bool lhs_free
= false;
1293 if (unmodified_parm (stmt
, inner_rhs
))
1295 if (rhs_free
&& is_gimple_reg (lhs
))
1297 if (((TREE_CODE (inner_lhs
) == PARM_DECL
1298 || (TREE_CODE (inner_lhs
) == SSA_NAME
1299 && SSA_NAME_IS_DEFAULT_DEF (inner_lhs
)
1300 && TREE_CODE (SSA_NAME_VAR (inner_lhs
)) == PARM_DECL
))
1301 && inner_lhs
!= lhs
)
1302 || TREE_CODE (inner_lhs
) == RESULT_DECL
1303 || (TREE_CODE (inner_lhs
) == SSA_NAME
1304 && TREE_CODE (SSA_NAME_VAR (inner_lhs
)) == RESULT_DECL
))
1307 && (is_gimple_reg (rhs
) || is_gimple_min_invariant (rhs
)))
1309 if (lhs_free
&& rhs_free
)
1319 /* If BB ends by a conditional we can turn into predicates, attach corresponding
1320 predicates to the CFG edges. */
1323 set_cond_stmt_execution_predicate (struct ipa_node_params
*info
,
1324 struct inline_summary
*summary
,
1330 enum tree_code code
, inverted_code
;
1338 last
= last_stmt (bb
);
1340 || gimple_code (last
) != GIMPLE_COND
)
1342 if (!is_gimple_ip_invariant (gimple_cond_rhs (last
)))
1344 op
= gimple_cond_lhs (last
);
1345 /* TODO: handle conditionals like
1348 parm
= unmodified_parm (last
, op
);
1351 index
= ipa_get_param_decl_index (info
, parm
);
1354 code
= gimple_cond_code (last
);
1356 = invert_tree_comparison (code
,
1357 HONOR_NANS (TYPE_MODE (TREE_TYPE (op
))));
1359 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1361 struct predicate p
= add_condition (summary
,
1363 e
->flags
& EDGE_TRUE_VALUE
1364 ? code
: inverted_code
,
1365 gimple_cond_rhs (last
));
1366 e
->aux
= pool_alloc (edge_predicate_pool
);
1367 *(struct predicate
*)e
->aux
= p
;
1371 if (TREE_CODE (op
) != SSA_NAME
)
1374 if (builtin_constant_p (op))
1378 Here we can predicate nonconstant_code. We can't
1379 really handle constant_code since we have no predicate
1380 for this and also the constant code is not known to be
1381 optimized away when inliner doen't see operand is constant.
1382 Other optimizers might think otherwise. */
1383 set_stmt
= SSA_NAME_DEF_STMT (op
);
1384 if (!gimple_call_builtin_p (set_stmt
, BUILT_IN_CONSTANT_P
)
1385 || gimple_call_num_args (set_stmt
) != 1)
1387 op2
= gimple_call_arg (set_stmt
, 0);
1388 base
= get_base_address (op2
);
1389 parm
= unmodified_parm (set_stmt
, base
? base
: op2
);
1392 index
= ipa_get_param_decl_index (info
, parm
);
1395 if (gimple_cond_code (last
) != NE_EXPR
1396 || !integer_zerop (gimple_cond_rhs (last
)))
1398 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1399 if (e
->flags
& EDGE_FALSE_VALUE
)
1401 struct predicate p
= add_condition (summary
,
1405 e
->aux
= pool_alloc (edge_predicate_pool
);
1406 *(struct predicate
*)e
->aux
= p
;
1411 /* If BB ends by a switch we can turn into predicates, attach corresponding
1412 predicates to the CFG edges. */
1415 set_switch_stmt_execution_predicate (struct ipa_node_params
*info
,
1416 struct inline_summary
*summary
,
1428 last
= last_stmt (bb
);
1430 || gimple_code (last
) != GIMPLE_SWITCH
)
1432 op
= gimple_switch_index (last
);
1433 parm
= unmodified_parm (last
, op
);
1436 index
= ipa_get_param_decl_index (info
, parm
);
1440 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1442 e
->aux
= pool_alloc (edge_predicate_pool
);
1443 *(struct predicate
*)e
->aux
= false_predicate ();
1445 n
= gimple_switch_num_labels(last
);
1446 for (case_idx
= 0; case_idx
< n
; ++case_idx
)
1448 tree cl
= gimple_switch_label (last
, case_idx
);
1452 e
= find_edge (bb
, label_to_block (CASE_LABEL (cl
)));
1453 min
= CASE_LOW (cl
);
1454 max
= CASE_HIGH (cl
);
1456 /* For default we might want to construct predicate that none
1457 of cases is met, but it is bit hard to do not having negations
1458 of conditionals handy. */
1460 p
= true_predicate ();
1462 p
= add_condition (summary
, index
,
1467 struct predicate p1
, p2
;
1468 p1
= add_condition (summary
, index
,
1471 p2
= add_condition (summary
, index
,
1474 p
= and_predicates (summary
->conds
, &p1
, &p2
);
1476 *(struct predicate
*)e
->aux
1477 = or_predicates (summary
->conds
, &p
, (struct predicate
*)e
->aux
);
1482 /* For each BB in NODE attach to its AUX pointer predicate under
1483 which it is executable. */
1486 compute_bb_predicates (struct cgraph_node
*node
,
1487 struct ipa_node_params
*parms_info
,
1488 struct inline_summary
*summary
)
1490 struct function
*my_function
= DECL_STRUCT_FUNCTION (node
->decl
);
1494 FOR_EACH_BB_FN (bb
, my_function
)
1496 set_cond_stmt_execution_predicate (parms_info
, summary
, bb
);
1497 set_switch_stmt_execution_predicate (parms_info
, summary
, bb
);
1500 /* Entry block is always executable. */
1501 ENTRY_BLOCK_PTR_FOR_FUNCTION (my_function
)->aux
1502 = pool_alloc (edge_predicate_pool
);
1503 *(struct predicate
*)ENTRY_BLOCK_PTR_FOR_FUNCTION (my_function
)->aux
1504 = true_predicate ();
1506 /* A simple dataflow propagation of predicates forward in the CFG.
1507 TODO: work in reverse postorder. */
1511 FOR_EACH_BB_FN (bb
, my_function
)
1513 struct predicate p
= false_predicate ();
1516 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1520 struct predicate this_bb_predicate
1521 = *(struct predicate
*)e
->src
->aux
;
1524 = and_predicates (summary
->conds
, &this_bb_predicate
,
1525 (struct predicate
*)e
->aux
);
1526 p
= or_predicates (summary
->conds
, &p
, &this_bb_predicate
);
1527 if (true_predicate_p (&p
))
1531 if (false_predicate_p (&p
))
1532 gcc_assert (!bb
->aux
);
1538 bb
->aux
= pool_alloc (edge_predicate_pool
);
1539 *((struct predicate
*)bb
->aux
) = p
;
1541 else if (!predicates_equal_p (&p
, (struct predicate
*)bb
->aux
))
1544 *((struct predicate
*)bb
->aux
) = p
;
1552 /* We keep info about constantness of SSA names. */
1554 typedef struct predicate predicate_t
;
1555 DEF_VEC_O (predicate_t
);
1556 DEF_VEC_ALLOC_O (predicate_t
, heap
);
1559 /* Return predicate specifying when the STMT might have result that is not
1560 a compile time constant. */
1562 static struct predicate
1563 will_be_nonconstant_predicate (struct ipa_node_params
*info
,
1564 struct inline_summary
*summary
,
1566 VEC (predicate_t
, heap
) *nonconstant_names
)
1569 struct predicate p
= true_predicate ();
1572 struct predicate op_non_const
;
1575 /* What statments might be optimized away
1576 when their arguments are constant
1577 TODO: also trivial builtins.
1578 builtin_constant_p is already handled later. */
1579 if (gimple_code (stmt
) != GIMPLE_ASSIGN
1580 && gimple_code (stmt
) != GIMPLE_COND
1581 && gimple_code (stmt
) != GIMPLE_SWITCH
)
1584 /* Stores will stay anyway. */
1585 if (gimple_vdef (stmt
))
1588 is_load
= gimple_vuse (stmt
) != NULL
;
1590 /* Loads can be optimized when the value is known. */
1593 tree op
= gimple_assign_rhs1 (stmt
);
1594 tree base
= get_base_address (op
);
1597 gcc_assert (gimple_assign_single_p (stmt
));
1600 parm
= unmodified_parm (stmt
, base
);
1603 if (ipa_get_param_decl_index (info
, parm
) < 0)
1607 /* See if we understand all operands before we start
1608 adding conditionals. */
1609 FOR_EACH_SSA_TREE_OPERAND (use
, stmt
, iter
, SSA_OP_USE
)
1611 tree parm
= unmodified_parm (stmt
, use
);
1612 /* For arguments we can build a condition. */
1613 if (parm
&& ipa_get_param_decl_index (info
, parm
) >= 0)
1615 if (TREE_CODE (use
) != SSA_NAME
)
1617 /* If we know when operand is constant,
1618 we still can say something useful. */
1619 if (!true_predicate_p (VEC_index (predicate_t
, nonconstant_names
,
1620 SSA_NAME_VERSION (use
))))
1624 op_non_const
= false_predicate ();
1627 tree parm
= unmodified_parm
1628 (stmt
, get_base_address (gimple_assign_rhs1 (stmt
)));
1629 p
= add_condition (summary
,
1630 ipa_get_param_decl_index (info
, parm
),
1632 op_non_const
= or_predicates (summary
->conds
, &p
, &op_non_const
);
1634 FOR_EACH_SSA_TREE_OPERAND (use
, stmt
, iter
, SSA_OP_USE
)
1636 tree parm
= unmodified_parm (stmt
, use
);
1637 if (parm
&& ipa_get_param_decl_index (info
, parm
) >= 0)
1638 p
= add_condition (summary
,
1639 ipa_get_param_decl_index (info
, parm
),
1642 p
= *VEC_index (predicate_t
, nonconstant_names
,
1643 SSA_NAME_VERSION (use
));
1644 op_non_const
= or_predicates (summary
->conds
, &p
, &op_non_const
);
1646 if (gimple_code (stmt
) == GIMPLE_ASSIGN
1647 && TREE_CODE (gimple_assign_lhs (stmt
)) == SSA_NAME
)
1648 VEC_replace (predicate_t
, nonconstant_names
,
1649 SSA_NAME_VERSION (gimple_assign_lhs (stmt
)), &op_non_const
);
1650 return op_non_const
;
1653 struct record_modified_bb_info
1659 /* Callback of walk_aliased_vdefs. Records basic blocks where the value may be
1660 set except for info->stmt. */
1663 record_modified (ao_ref
*ao ATTRIBUTE_UNUSED
, tree vdef
,
1666 struct record_modified_bb_info
*info
= (struct record_modified_bb_info
*) data
;
1667 if (SSA_NAME_DEF_STMT (vdef
) == info
->stmt
)
1669 bitmap_set_bit (info
->bb_set
,
1670 SSA_NAME_IS_DEFAULT_DEF (vdef
)
1671 ? ENTRY_BLOCK_PTR
->index
: gimple_bb (SSA_NAME_DEF_STMT (vdef
))->index
);
1675 /* Return probability (based on REG_BR_PROB_BASE) that I-th parameter of STMT
1676 will change since last invocation of STMT.
1678 Value 0 is reserved for compile time invariants.
1679 For common parameters it is REG_BR_PROB_BASE. For loop invariants it
1680 ought to be REG_BR_PROB_BASE / estimated_iters. */
1683 param_change_prob (gimple stmt
, int i
)
1685 tree op
= gimple_call_arg (stmt
, i
);
1686 basic_block bb
= gimple_bb (stmt
);
1689 if (is_gimple_min_invariant (op
))
1691 /* We would have to do non-trivial analysis to really work out what
1692 is the probability of value to change (i.e. when init statement
1693 is in a sibling loop of the call).
1695 We do an conservative estimate: when call is executed N times more often
1696 than the statement defining value, we take the frequency 1/N. */
1697 if (TREE_CODE (op
) == SSA_NAME
)
1702 return REG_BR_PROB_BASE
;
1704 if (SSA_NAME_IS_DEFAULT_DEF (op
))
1705 init_freq
= ENTRY_BLOCK_PTR
->frequency
;
1707 init_freq
= gimple_bb (SSA_NAME_DEF_STMT (op
))->frequency
;
1711 if (init_freq
< bb
->frequency
)
1712 return MAX ((init_freq
* REG_BR_PROB_BASE
+
1713 bb
->frequency
/ 2) / bb
->frequency
, 1);
1715 return REG_BR_PROB_BASE
;
1718 base
= get_base_address (op
);
1723 struct record_modified_bb_info info
;
1727 if (const_value_known_p (base
))
1730 return REG_BR_PROB_BASE
;
1731 ao_ref_init (&refd
, op
);
1733 info
.bb_set
= BITMAP_ALLOC (NULL
);
1734 walk_aliased_vdefs (&refd
, gimple_vuse (stmt
), record_modified
, &info
,
1736 if (bitmap_bit_p (info
.bb_set
, bb
->index
))
1738 BITMAP_FREE (info
.bb_set
);
1739 return REG_BR_PROB_BASE
;
1742 /* Assume that every memory is initialized at entry.
1743 TODO: Can we easilly determine if value is always defined
1744 and thus we may skip entry block? */
1745 if (ENTRY_BLOCK_PTR
->frequency
)
1746 max
= ENTRY_BLOCK_PTR
->frequency
;
1750 EXECUTE_IF_SET_IN_BITMAP (info
.bb_set
, 0, index
, bi
)
1751 max
= MIN (max
, BASIC_BLOCK (index
)->frequency
);
1753 BITMAP_FREE (info
.bb_set
);
1754 if (max
< bb
->frequency
)
1755 return MAX ((max
* REG_BR_PROB_BASE
+
1756 bb
->frequency
/ 2) / bb
->frequency
, 1);
1758 return REG_BR_PROB_BASE
;
1760 return REG_BR_PROB_BASE
;
1764 /* Compute function body size parameters for NODE.
1765 When EARLY is true, we compute only simple summaries without
1766 non-trivial predicates to drive the early inliner. */
1769 estimate_function_body_sizes (struct cgraph_node
*node
, bool early
)
1772 /* Estimate static overhead for function prologue/epilogue and alignment. */
1774 /* Benefits are scaled by probability of elimination that is in range
1777 gimple_stmt_iterator bsi
;
1778 struct function
*my_function
= DECL_STRUCT_FUNCTION (node
->decl
);
1780 struct inline_summary
*info
= inline_summary (node
);
1781 struct predicate bb_predicate
;
1782 struct ipa_node_params
*parms_info
= NULL
;
1783 VEC (predicate_t
, heap
) *nonconstant_names
= NULL
;
1785 if (ipa_node_params_vector
&& !early
&& optimize
)
1787 parms_info
= IPA_NODE_REF (node
);
1788 VEC_safe_grow_cleared (predicate_t
, heap
, nonconstant_names
,
1789 VEC_length (tree
, SSANAMES (my_function
)));
1797 fprintf (dump_file
, "\nAnalyzing function body size: %s\n",
1798 cgraph_node_name (node
));
1800 /* When we run into maximal number of entries, we assign everything to the
1801 constant truth case. Be sure to have it in list. */
1802 bb_predicate
= true_predicate ();
1803 account_size_time (info
, 0, 0, &bb_predicate
);
1805 bb_predicate
= not_inlined_predicate ();
1806 account_size_time (info
, 2 * INLINE_SIZE_SCALE
, 0, &bb_predicate
);
1808 gcc_assert (my_function
&& my_function
->cfg
);
1810 compute_bb_predicates (node
, parms_info
, info
);
1811 FOR_EACH_BB_FN (bb
, my_function
)
1813 freq
= compute_call_stmt_bb_frequency (node
->decl
, bb
);
1815 /* TODO: Obviously predicates can be propagated down across CFG. */
1819 bb_predicate
= *(struct predicate
*)bb
->aux
;
1821 bb_predicate
= false_predicate ();
1824 bb_predicate
= true_predicate ();
1826 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1828 fprintf (dump_file
, "\n BB %i predicate:", bb
->index
);
1829 dump_predicate (dump_file
, info
->conds
, &bb_predicate
);
1832 for (bsi
= gsi_start_bb (bb
); !gsi_end_p (bsi
); gsi_next (&bsi
))
1834 gimple stmt
= gsi_stmt (bsi
);
1835 int this_size
= estimate_num_insns (stmt
, &eni_size_weights
);
1836 int this_time
= estimate_num_insns (stmt
, &eni_time_weights
);
1838 struct predicate will_be_nonconstant
;
1840 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1842 fprintf (dump_file
, " ");
1843 print_gimple_stmt (dump_file
, stmt
, 0, 0);
1844 fprintf (dump_file
, "\t\tfreq:%3.2f size:%3i time:%3i\n",
1845 ((double)freq
)/CGRAPH_FREQ_BASE
, this_size
, this_time
);
1848 if (is_gimple_call (stmt
))
1850 struct cgraph_edge
*edge
= cgraph_edge (node
, stmt
);
1851 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
1853 /* Special case: results of BUILT_IN_CONSTANT_P will be always
1854 resolved as constant. We however don't want to optimize
1855 out the cgraph edges. */
1856 if (nonconstant_names
1857 && gimple_call_builtin_p (stmt
, BUILT_IN_CONSTANT_P
)
1858 && gimple_call_lhs (stmt
)
1859 && TREE_CODE (gimple_call_lhs (stmt
)) == SSA_NAME
)
1861 struct predicate false_p
= false_predicate ();
1862 VEC_replace (predicate_t
, nonconstant_names
,
1863 SSA_NAME_VERSION (gimple_call_lhs (stmt
)),
1866 if (ipa_node_params_vector
)
1868 int count
= gimple_call_num_args (stmt
);
1872 VEC_safe_grow_cleared (inline_param_summary_t
, heap
,
1874 for (i
= 0; i
< count
; i
++)
1876 int prob
= param_change_prob (stmt
, i
);
1877 gcc_assert (prob
>= 0 && prob
<= REG_BR_PROB_BASE
);
1878 VEC_index (inline_param_summary_t
,
1879 es
->param
, i
)->change_prob
= prob
;
1883 es
->call_stmt_size
= this_size
;
1884 es
->call_stmt_time
= this_time
;
1885 es
->loop_depth
= bb
->loop_depth
;
1886 edge_set_predicate (edge
, &bb_predicate
);
1888 /* Do not inline calls where we cannot triviall work around
1889 mismatches in argument or return types. */
1891 && cgraph_function_or_thunk_node (edge
->callee
, NULL
)
1892 && !gimple_check_call_matching_types
1893 (stmt
, cgraph_function_or_thunk_node (edge
->callee
,
1896 edge
->call_stmt_cannot_inline_p
= true;
1897 gimple_call_set_cannot_inline (stmt
, true);
1900 gcc_assert (!gimple_call_cannot_inline_p (stmt
));
1903 /* TODO: When conditional jump or swithc is known to be constant, but
1904 we did not translate it into the predicates, we really can account
1905 just maximum of the possible paths. */
1908 = will_be_nonconstant_predicate (parms_info
, info
,
1909 stmt
, nonconstant_names
);
1910 if (this_time
|| this_size
)
1918 prob
= eliminated_by_inlining_prob (stmt
);
1919 if (prob
== 1 && dump_file
&& (dump_flags
& TDF_DETAILS
))
1920 fprintf (dump_file
, "\t\t50%% will be eliminated by inlining\n");
1921 if (prob
== 2 && dump_file
&& (dump_flags
& TDF_DETAILS
))
1922 fprintf (dump_file
, "\t\twill eliminated by inlining\n");
1925 p
= and_predicates (info
->conds
, &bb_predicate
,
1926 &will_be_nonconstant
);
1928 p
= true_predicate ();
1930 /* We account everything but the calls. Calls have their own
1931 size/time info attached to cgraph edges. This is neccesary
1932 in order to make the cost disappear after inlining. */
1933 if (!is_gimple_call (stmt
))
1937 struct predicate ip
= not_inlined_predicate ();
1938 ip
= and_predicates (info
->conds
, &ip
, &p
);
1939 account_size_time (info
, this_size
* prob
,
1940 this_time
* prob
, &ip
);
1943 account_size_time (info
, this_size
* (2 - prob
),
1944 this_time
* (2 - prob
), &p
);
1947 gcc_assert (time
>= 0);
1948 gcc_assert (size
>= 0);
1952 FOR_ALL_BB_FN (bb
, my_function
)
1958 pool_free (edge_predicate_pool
, bb
->aux
);
1960 FOR_EACH_EDGE (e
, ei
, bb
->succs
)
1963 pool_free (edge_predicate_pool
, e
->aux
);
1967 time
= (time
+ CGRAPH_FREQ_BASE
/ 2) / CGRAPH_FREQ_BASE
;
1968 if (time
> MAX_TIME
)
1970 inline_summary (node
)->self_time
= time
;
1971 inline_summary (node
)->self_size
= size
;
1972 VEC_free (predicate_t
, heap
, nonconstant_names
);
1975 fprintf (dump_file
, "\n");
1976 dump_inline_summary (dump_file
, node
);
1981 /* Compute parameters of functions used by inliner.
1982 EARLY is true when we compute parameters for the early inliner */
1985 compute_inline_parameters (struct cgraph_node
*node
, bool early
)
1987 HOST_WIDE_INT self_stack_size
;
1988 struct cgraph_edge
*e
;
1989 struct inline_summary
*info
;
1990 tree old_decl
= current_function_decl
;
1992 gcc_assert (!node
->global
.inlined_to
);
1994 inline_summary_alloc ();
1996 info
= inline_summary (node
);
1998 /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
1999 Once this happen, we will need to more curefully predict call
2001 if (node
->thunk
.thunk_p
)
2003 struct inline_edge_summary
*es
= inline_edge_summary (node
->callees
);
2004 struct predicate t
= true_predicate ();
2006 info
->inlinable
= 0;
2007 node
->callees
->call_stmt_cannot_inline_p
= true;
2008 node
->local
.can_change_signature
= false;
2009 es
->call_stmt_time
= 1;
2010 es
->call_stmt_size
= 1;
2011 account_size_time (info
, 0, 0, &t
);
2015 /* Even is_gimple_min_invariant rely on current_function_decl. */
2016 current_function_decl
= node
->decl
;
2017 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
2019 /* Estimate the stack size for the function if we're optimizing. */
2020 self_stack_size
= optimize
? estimated_stack_frame_size (node
) : 0;
2021 info
->estimated_self_stack_size
= self_stack_size
;
2022 info
->estimated_stack_size
= self_stack_size
;
2023 info
->stack_frame_offset
= 0;
2025 /* Can this function be inlined at all? */
2026 info
->inlinable
= tree_inlinable_function_p (node
->decl
);
2028 /* Type attributes can use parameter indices to describe them. */
2029 if (TYPE_ATTRIBUTES (TREE_TYPE (node
->decl
)))
2030 node
->local
.can_change_signature
= false;
2033 /* Otherwise, inlinable functions always can change signature. */
2034 if (info
->inlinable
)
2035 node
->local
.can_change_signature
= true;
2038 /* Functions calling builtin_apply can not change signature. */
2039 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2041 tree
cdecl = e
->callee
->decl
;
2042 if (DECL_BUILT_IN (cdecl)
2043 && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
2044 && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
2045 || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START
))
2048 node
->local
.can_change_signature
= !e
;
2051 estimate_function_body_sizes (node
, early
);
2053 /* Inlining characteristics are maintained by the cgraph_mark_inline. */
2054 info
->time
= info
->self_time
;
2055 info
->size
= info
->self_size
;
2056 info
->stack_frame_offset
= 0;
2057 info
->estimated_stack_size
= info
->estimated_self_stack_size
;
2058 current_function_decl
= old_decl
;
2063 /* Compute parameters of functions used by inliner using
2064 current_function_decl. */
2067 compute_inline_parameters_for_current (void)
2069 compute_inline_parameters (cgraph_get_node (current_function_decl
), true);
2073 struct gimple_opt_pass pass_inline_parameters
=
2077 "inline_param", /* name */
2079 compute_inline_parameters_for_current
,/* execute */
2082 0, /* static_pass_number */
2083 TV_INLINE_HEURISTICS
, /* tv_id */
2084 0, /* properties_required */
2085 0, /* properties_provided */
2086 0, /* properties_destroyed */
2087 0, /* todo_flags_start */
2088 0 /* todo_flags_finish */
2093 /* Increase SIZE and TIME for size and time needed to handle edge E. */
2096 estimate_edge_size_and_time (struct cgraph_edge
*e
, int *size
, int *time
,
2099 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2100 *size
+= es
->call_stmt_size
* INLINE_SIZE_SCALE
;
2101 *time
+= (es
->call_stmt_time
* prob
/ REG_BR_PROB_BASE
2102 * e
->frequency
* (INLINE_TIME_SCALE
/ CGRAPH_FREQ_BASE
));
2103 if (*time
> MAX_TIME
* INLINE_TIME_SCALE
)
2104 *time
= MAX_TIME
* INLINE_TIME_SCALE
;
2108 /* Increase SIZE and TIME for size and time needed to handle all calls in NODE. */
2111 estimate_calls_size_and_time (struct cgraph_node
*node
, int *size
, int *time
,
2112 clause_t possible_truths
)
2114 struct cgraph_edge
*e
;
2115 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2117 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2118 if (!es
->predicate
|| evaluate_predicate (es
->predicate
, possible_truths
))
2120 if (e
->inline_failed
)
2122 /* Predicates of calls shall not use NOT_CHANGED codes,
2123 sowe do not need to compute probabilities. */
2124 estimate_edge_size_and_time (e
, size
, time
, REG_BR_PROB_BASE
);
2127 estimate_calls_size_and_time (e
->callee
, size
, time
,
2131 /* TODO: look for devirtualizing oppurtunities. */
2132 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
2134 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2135 if (!es
->predicate
|| evaluate_predicate (es
->predicate
, possible_truths
))
2136 estimate_edge_size_and_time (e
, size
, time
, REG_BR_PROB_BASE
);
2141 /* Estimate size and time needed to execute NODE assuming
2142 POSSIBLE_TRUTHS clause. */
2145 estimate_node_size_and_time (struct cgraph_node
*node
,
2146 clause_t possible_truths
,
2147 int *ret_size
, int *ret_time
,
2148 VEC (inline_param_summary_t
, heap
)
2149 *inline_param_summary
)
2151 struct inline_summary
*info
= inline_summary (node
);
2153 int size
= 0, time
= 0;
2157 && (dump_flags
& TDF_DETAILS
))
2160 fprintf (dump_file
, " Estimating body: %s/%i\n"
2161 " Known to be false: ",
2162 cgraph_node_name (node
),
2165 for (i
= predicate_not_inlined_condition
;
2166 i
< (predicate_first_dynamic_condition
2167 + (int)VEC_length (condition
, info
->conds
)); i
++)
2168 if (!(possible_truths
& (1 << i
)))
2171 fprintf (dump_file
, ", ");
2173 dump_condition (dump_file
, info
->conds
, i
);
2177 for (i
= 0; VEC_iterate (size_time_entry
, info
->entry
, i
, e
); i
++)
2178 if (evaluate_predicate (&e
->predicate
, possible_truths
))
2181 if (!inline_param_summary
)
2185 int prob
= predicate_probability (info
->conds
,
2188 inline_param_summary
);
2189 time
+= e
->time
* prob
/ REG_BR_PROB_BASE
;
2194 if (time
> MAX_TIME
* INLINE_TIME_SCALE
)
2195 time
= MAX_TIME
* INLINE_TIME_SCALE
;
2197 estimate_calls_size_and_time (node
, &size
, &time
, possible_truths
);
2198 time
= (time
+ INLINE_TIME_SCALE
/ 2) / INLINE_TIME_SCALE
;
2199 size
= (size
+ INLINE_SIZE_SCALE
/ 2) / INLINE_SIZE_SCALE
;
2203 && (dump_flags
& TDF_DETAILS
))
2204 fprintf (dump_file
, "\n size:%i time:%i\n", size
, time
);
2213 /* Estimate size and time needed to execute callee of EDGE assuming that
2214 parameters known to be constant at caller of EDGE are propagated.
2215 KNOWN_VALs is a vector of assumed known constant values for parameters. */
2218 estimate_ipcp_clone_size_and_time (struct cgraph_node
*node
,
2219 VEC (tree
, heap
) *known_vals
,
2220 int *ret_size
, int *ret_time
)
2224 clause
= evaluate_conditions_for_known_args (node
, false, known_vals
);
2225 estimate_node_size_and_time (node
, clause
, ret_size
, ret_time
,
2230 /* Translate all conditions from callee representation into caller
2231 representation and symbolically evaluate predicate P into new predicate.
2233 INFO is inline_summary of function we are adding predicate into,
2234 CALLEE_INFO is summary of function predicate P is from. OPERAND_MAP is
2235 array giving callee formal IDs the caller formal IDs. POSSSIBLE_TRUTHS is
2236 clausule of all callee conditions that may be true in caller context.
2237 TOPLEV_PREDICATE is predicate under which callee is executed. */
2239 static struct predicate
2240 remap_predicate (struct inline_summary
*info
,
2241 struct inline_summary
*callee_info
,
2242 struct predicate
*p
,
2243 VEC (int, heap
) *operand_map
,
2244 clause_t possible_truths
,
2245 struct predicate
*toplev_predicate
)
2248 struct predicate out
= true_predicate ();
2250 /* True predicate is easy. */
2251 if (true_predicate_p (p
))
2252 return *toplev_predicate
;
2253 for (i
= 0; p
->clause
[i
]; i
++)
2255 clause_t clause
= p
->clause
[i
];
2257 struct predicate clause_predicate
= false_predicate ();
2259 gcc_assert (i
< MAX_CLAUSES
);
2261 for (cond
= 0; cond
< NUM_CONDITIONS
; cond
++)
2262 /* Do we have condition we can't disprove? */
2263 if (clause
& possible_truths
& (1 << cond
))
2265 struct predicate cond_predicate
;
2266 /* Work out if the condition can translate to predicate in the
2267 inlined function. */
2268 if (cond
>= predicate_first_dynamic_condition
)
2270 struct condition
*c
;
2272 c
= VEC_index (condition
, callee_info
->conds
,
2273 cond
- predicate_first_dynamic_condition
);
2274 /* See if we can remap condition operand to caller's operand.
2275 Otherwise give up. */
2277 || (int)VEC_length (int, operand_map
) <= c
->operand_num
2278 || VEC_index (int, operand_map
, c
->operand_num
) == -1)
2279 cond_predicate
= true_predicate ();
2281 cond_predicate
= add_condition (info
,
2282 VEC_index (int, operand_map
,
2286 /* Fixed conditions remains same, construct single
2287 condition predicate. */
2290 cond_predicate
.clause
[0] = 1 << cond
;
2291 cond_predicate
.clause
[1] = 0;
2293 clause_predicate
= or_predicates (info
->conds
, &clause_predicate
,
2296 out
= and_predicates (info
->conds
, &out
, &clause_predicate
);
2298 return and_predicates (info
->conds
, &out
, toplev_predicate
);
2302 /* Update summary information of inline clones after inlining.
2303 Compute peak stack usage. */
2306 inline_update_callee_summaries (struct cgraph_node
*node
,
2309 struct cgraph_edge
*e
;
2310 struct inline_summary
*callee_info
= inline_summary (node
);
2311 struct inline_summary
*caller_info
= inline_summary (node
->callers
->caller
);
2314 callee_info
->stack_frame_offset
2315 = caller_info
->stack_frame_offset
2316 + caller_info
->estimated_self_stack_size
;
2317 peak
= callee_info
->stack_frame_offset
2318 + callee_info
->estimated_self_stack_size
;
2319 if (inline_summary (node
->global
.inlined_to
)->estimated_stack_size
2321 inline_summary (node
->global
.inlined_to
)->estimated_stack_size
= peak
;
2322 cgraph_propagate_frequency (node
);
2323 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2325 if (!e
->inline_failed
)
2326 inline_update_callee_summaries (e
->callee
, depth
);
2327 inline_edge_summary (e
)->loop_depth
+= depth
;
2329 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
2330 inline_edge_summary (e
)->loop_depth
+= depth
;
2333 /* Update change_prob of EDGE after INLINED_EDGE has been inlined.
2334 When functoin A is inlined in B and A calls C with parameter that
2335 changes with probability PROB1 and C is known to be passthroug
2336 of argument if B that change with probability PROB2, the probability
2337 of change is now PROB1*PROB2. */
2340 remap_edge_change_prob (struct cgraph_edge
*inlined_edge
,
2341 struct cgraph_edge
*edge
)
2343 if (ipa_node_params_vector
)
2346 struct ipa_edge_args
*args
= IPA_EDGE_REF (edge
);
2347 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
2348 struct inline_edge_summary
*inlined_es
2349 = inline_edge_summary (inlined_edge
);
2351 for (i
= 0; i
< ipa_get_cs_argument_count (args
); i
++)
2353 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, i
);
2354 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2355 && (jfunc
->value
.pass_through
.formal_id
2356 < VEC_length (inline_param_summary_t
,
2357 inlined_es
->param
)))
2359 int prob1
= VEC_index (inline_param_summary_t
,
2360 es
->param
, i
)->change_prob
;
2361 int prob2
= VEC_index
2362 (inline_param_summary_t
,
2364 jfunc
->value
.pass_through
.formal_id
)->change_prob
;
2365 int prob
= ((prob1
* prob2
+ REG_BR_PROB_BASE
/ 2)
2366 / REG_BR_PROB_BASE
);
2368 if (prob1
&& prob2
&& !prob
)
2371 VEC_index (inline_param_summary_t
,
2372 es
->param
, i
)->change_prob
= prob
;
2378 /* Update edge summaries of NODE after INLINED_EDGE has been inlined.
2380 Remap predicates of callees of NODE. Rest of arguments match
2383 Also update change probabilities. */
2386 remap_edge_summaries (struct cgraph_edge
*inlined_edge
,
2387 struct cgraph_node
*node
,
2388 struct inline_summary
*info
,
2389 struct inline_summary
*callee_info
,
2390 VEC (int, heap
) *operand_map
,
2391 clause_t possible_truths
,
2392 struct predicate
*toplev_predicate
)
2394 struct cgraph_edge
*e
;
2395 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2397 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2400 if (e
->inline_failed
)
2402 remap_edge_change_prob (inlined_edge
, e
);
2406 p
= remap_predicate (info
, callee_info
,
2407 es
->predicate
, operand_map
, possible_truths
,
2409 edge_set_predicate (e
, &p
);
2410 /* TODO: We should remove the edge for code that will be
2411 optimized out, but we need to keep verifiers and tree-inline
2412 happy. Make it cold for now. */
2413 if (false_predicate_p (&p
))
2420 edge_set_predicate (e
, toplev_predicate
);
2423 remap_edge_summaries (inlined_edge
, e
->callee
, info
, callee_info
,
2424 operand_map
, possible_truths
, toplev_predicate
);
2426 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
2428 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2431 remap_edge_change_prob (inlined_edge
, e
);
2434 p
= remap_predicate (info
, callee_info
,
2435 es
->predicate
, operand_map
, possible_truths
,
2437 edge_set_predicate (e
, &p
);
2438 /* TODO: We should remove the edge for code that will be optimized
2439 out, but we need to keep verifiers and tree-inline happy.
2440 Make it cold for now. */
2441 if (false_predicate_p (&p
))
2448 edge_set_predicate (e
, toplev_predicate
);
2453 /* We inlined EDGE. Update summary of the function we inlined into. */
2456 inline_merge_summary (struct cgraph_edge
*edge
)
2458 struct inline_summary
*callee_info
= inline_summary (edge
->callee
);
2459 struct cgraph_node
*to
= (edge
->caller
->global
.inlined_to
2460 ? edge
->caller
->global
.inlined_to
: edge
->caller
);
2461 struct inline_summary
*info
= inline_summary (to
);
2462 clause_t clause
= 0; /* not_inline is known to be false. */
2464 VEC (int, heap
) *operand_map
= NULL
;
2466 struct predicate toplev_predicate
;
2467 struct predicate true_p
= true_predicate ();
2468 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
2471 toplev_predicate
= *es
->predicate
;
2473 toplev_predicate
= true_predicate ();
2475 if (ipa_node_params_vector
&& callee_info
->conds
)
2477 struct ipa_edge_args
*args
= IPA_EDGE_REF (edge
);
2478 int count
= ipa_get_cs_argument_count (args
);
2481 clause
= evaluate_conditions_for_edge (edge
, true);
2483 VEC_safe_grow_cleared (int, heap
, operand_map
, count
);
2484 for (i
= 0; i
< count
; i
++)
2486 struct ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, i
);
2488 /* TODO: handle non-NOPs when merging. */
2489 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2490 && jfunc
->value
.pass_through
.operation
== NOP_EXPR
)
2491 map
= jfunc
->value
.pass_through
.formal_id
;
2492 VEC_replace (int, operand_map
, i
, map
);
2493 gcc_assert (map
< ipa_get_param_count (IPA_NODE_REF (to
)));
2496 for (i
= 0; VEC_iterate (size_time_entry
, callee_info
->entry
, i
, e
); i
++)
2498 struct predicate p
= remap_predicate (info
, callee_info
,
2499 &e
->predicate
, operand_map
, clause
,
2501 if (!false_predicate_p (&p
))
2503 gcov_type add_time
= ((gcov_type
)e
->time
* edge
->frequency
2504 + CGRAPH_FREQ_BASE
/ 2) / CGRAPH_FREQ_BASE
;
2505 int prob
= predicate_probability (callee_info
->conds
,
2508 add_time
= add_time
* prob
/ REG_BR_PROB_BASE
;
2509 if (add_time
> MAX_TIME
* INLINE_TIME_SCALE
)
2510 add_time
= MAX_TIME
* INLINE_TIME_SCALE
;
2511 if (prob
!= REG_BR_PROB_BASE
2512 && dump_file
&& (dump_flags
& TDF_DETAILS
))
2514 fprintf (dump_file
, "\t\tScaling time by probability:%f\n",
2515 (double)prob
/ REG_BR_PROB_BASE
);
2517 account_size_time (info
, e
->size
, add_time
, &p
);
2520 remap_edge_summaries (edge
, edge
->callee
, info
, callee_info
, operand_map
,
2521 clause
, &toplev_predicate
);
2524 for (i
= 0; VEC_iterate (size_time_entry
, info
->entry
, i
, e
); i
++)
2525 info
->size
+= e
->size
, info
->time
+= e
->time
;
2526 estimate_calls_size_and_time (to
, &info
->size
, &info
->time
,
2527 ~(clause_t
)(1 << predicate_false_condition
));
2529 inline_update_callee_summaries (edge
->callee
,
2530 inline_edge_summary (edge
)->loop_depth
);
2532 /* We do not maintain predicates of inlined edges, free it. */
2533 edge_set_predicate (edge
, &true_p
);
2534 /* Similarly remove param summaries. */
2535 VEC_free (inline_param_summary_t
, heap
, es
->param
);
2537 info
->time
= (info
->time
+ INLINE_TIME_SCALE
/ 2) / INLINE_TIME_SCALE
;
2538 info
->size
= (info
->size
+ INLINE_SIZE_SCALE
/ 2) / INLINE_SIZE_SCALE
;
2542 /* Estimate the time cost for the caller when inlining EDGE.
2543 Only to be called via estimate_edge_time, that handles the
2546 When caching, also update the cache entry. Compute both time and
2547 size, since we always need both metrics eventually. */
2550 do_estimate_edge_time (struct cgraph_edge
*edge
)
2555 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
2557 gcc_checking_assert (edge
->inline_failed
);
2558 estimate_node_size_and_time (cgraph_function_or_thunk_node (edge
->callee
,
2560 evaluate_conditions_for_edge (edge
, true),
2561 &size
, &time
, es
->param
);
2563 ret
= (((gcov_type
)time
2564 - es
->call_stmt_time
) * edge
->frequency
2565 + CGRAPH_FREQ_BASE
/ 2) / CGRAPH_FREQ_BASE
;
2567 /* When caching, update the cache entry. */
2568 if (edge_growth_cache
)
2571 if ((int)VEC_length (edge_growth_cache_entry
, edge_growth_cache
)
2573 VEC_safe_grow_cleared (edge_growth_cache_entry
, heap
, edge_growth_cache
,
2574 cgraph_edge_max_uid
);
2575 VEC_index (edge_growth_cache_entry
, edge_growth_cache
, edge
->uid
)->time
2578 ret_size
= size
- es
->call_stmt_size
;
2579 gcc_checking_assert (es
->call_stmt_size
);
2580 VEC_index (edge_growth_cache_entry
, edge_growth_cache
, edge
->uid
)->size
2581 = ret_size
+ (ret_size
>= 0);
2587 /* Estimate the growth of the caller when inlining EDGE.
2588 Only to be called via estimate_edge_size. */
2591 do_estimate_edge_growth (struct cgraph_edge
*edge
)
2594 struct cgraph_node
*callee
;
2596 /* When we do caching, use do_estimate_edge_time to populate the entry. */
2598 if (edge_growth_cache
)
2600 do_estimate_edge_time (edge
);
2601 size
= VEC_index (edge_growth_cache_entry
,
2604 gcc_checking_assert (size
);
2605 return size
- (size
> 0);
2607 callee
= cgraph_function_or_thunk_node (edge
->callee
, NULL
);
2609 /* Early inliner runs without caching, go ahead and do the dirty work. */
2610 gcc_checking_assert (edge
->inline_failed
);
2611 estimate_node_size_and_time (callee
,
2612 evaluate_conditions_for_edge (edge
, true),
2614 gcc_checking_assert (inline_edge_summary (edge
)->call_stmt_size
);
2615 return size
- inline_edge_summary (edge
)->call_stmt_size
;
2619 /* Estimate self time of the function NODE after inlining EDGE. */
2622 estimate_time_after_inlining (struct cgraph_node
*node
,
2623 struct cgraph_edge
*edge
)
2625 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
2626 if (!es
->predicate
|| !false_predicate_p (es
->predicate
))
2628 gcov_type time
= inline_summary (node
)->time
+ estimate_edge_time (edge
);
2631 if (time
> MAX_TIME
)
2635 return inline_summary (node
)->time
;
2639 /* Estimate the size of NODE after inlining EDGE which should be an
2640 edge to either NODE or a call inlined into NODE. */
2643 estimate_size_after_inlining (struct cgraph_node
*node
,
2644 struct cgraph_edge
*edge
)
2646 struct inline_edge_summary
*es
= inline_edge_summary (edge
);
2647 if (!es
->predicate
|| !false_predicate_p (es
->predicate
))
2649 int size
= inline_summary (node
)->size
+ estimate_edge_growth (edge
);
2650 gcc_assert (size
>= 0);
2653 return inline_summary (node
)->size
;
2659 bool self_recursive
;
2664 /* Worker for do_estimate_growth. Collect growth for all callers. */
2667 do_estimate_growth_1 (struct cgraph_node
*node
, void *data
)
2669 struct cgraph_edge
*e
;
2670 struct growth_data
*d
= (struct growth_data
*) data
;
2672 for (e
= node
->callers
; e
; e
= e
->next_caller
)
2674 gcc_checking_assert (e
->inline_failed
);
2676 if (e
->caller
== node
2677 || (e
->caller
->global
.inlined_to
2678 && e
->caller
->global
.inlined_to
== node
))
2679 d
->self_recursive
= true;
2680 d
->growth
+= estimate_edge_growth (e
);
2686 /* Estimate the growth caused by inlining NODE into all callees. */
2689 do_estimate_growth (struct cgraph_node
*node
)
2691 struct growth_data d
= {0, false};
2692 struct inline_summary
*info
= inline_summary (node
);
2694 cgraph_for_node_and_aliases (node
, do_estimate_growth_1
, &d
, true);
2696 /* For self recursive functions the growth estimation really should be
2697 infinity. We don't want to return very large values because the growth
2698 plays various roles in badness computation fractions. Be sure to not
2699 return zero or negative growths. */
2700 if (d
.self_recursive
)
2701 d
.growth
= d
.growth
< info
->size
? info
->size
: d
.growth
;
2704 if (!DECL_EXTERNAL (node
->decl
)
2705 && cgraph_will_be_removed_from_program_if_no_direct_calls (node
))
2706 d
.growth
-= info
->size
;
2707 /* COMDAT functions are very often not shared across multiple units
2708 since they come from various template instantiations.
2709 Take this into account. */
2710 else if (DECL_COMDAT (node
->decl
)
2711 && cgraph_can_remove_if_no_direct_calls_p (node
))
2712 d
.growth
-= (info
->size
2713 * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY
))
2717 if (node_growth_cache
)
2719 if ((int)VEC_length (int, node_growth_cache
) <= node
->uid
)
2720 VEC_safe_grow_cleared (int, heap
, node_growth_cache
, cgraph_max_uid
);
2721 VEC_replace (int, node_growth_cache
, node
->uid
,
2722 d
.growth
+ (d
.growth
>= 0));
2728 /* This function performs intraprocedural analysis in NODE that is required to
2729 inline indirect calls. */
2732 inline_indirect_intraprocedural_analysis (struct cgraph_node
*node
)
2734 ipa_analyze_node (node
);
2735 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2737 ipa_print_node_params (dump_file
, node
);
2738 ipa_print_node_jump_functions (dump_file
, node
);
2743 /* Note function body size. */
2746 inline_analyze_function (struct cgraph_node
*node
)
2748 push_cfun (DECL_STRUCT_FUNCTION (node
->decl
));
2749 current_function_decl
= node
->decl
;
2752 fprintf (dump_file
, "\nAnalyzing function: %s/%u\n",
2753 cgraph_node_name (node
), node
->uid
);
2754 if (optimize
&& !node
->thunk
.thunk_p
)
2755 inline_indirect_intraprocedural_analysis (node
);
2756 compute_inline_parameters (node
, false);
2758 current_function_decl
= NULL
;
2763 /* Called when new function is inserted to callgraph late. */
2766 add_new_function (struct cgraph_node
*node
, void *data ATTRIBUTE_UNUSED
)
2768 inline_analyze_function (node
);
2772 /* Note function body size. */
2775 inline_generate_summary (void)
2777 struct cgraph_node
*node
;
2779 function_insertion_hook_holder
=
2780 cgraph_add_function_insertion_hook (&add_new_function
, NULL
);
2782 ipa_register_cgraph_hooks ();
2784 FOR_EACH_DEFINED_FUNCTION (node
)
2786 inline_analyze_function (node
);
2790 /* Read predicate from IB. */
2792 static struct predicate
2793 read_predicate (struct lto_input_block
*ib
)
2795 struct predicate out
;
2801 gcc_assert (k
<= MAX_CLAUSES
);
2802 clause
= out
.clause
[k
++] = streamer_read_uhwi (ib
);
2806 /* Zero-initialize the remaining clauses in OUT. */
2807 while (k
<= MAX_CLAUSES
)
2808 out
.clause
[k
++] = 0;
2814 /* Write inline summary for edge E to OB. */
2817 read_inline_edge_summary (struct lto_input_block
*ib
, struct cgraph_edge
*e
)
2819 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2823 es
->call_stmt_size
= streamer_read_uhwi (ib
);
2824 es
->call_stmt_time
= streamer_read_uhwi (ib
);
2825 es
->loop_depth
= streamer_read_uhwi (ib
);
2826 p
= read_predicate (ib
);
2827 edge_set_predicate (e
, &p
);
2828 length
= streamer_read_uhwi (ib
);
2831 VEC_safe_grow_cleared (inline_param_summary_t
, heap
, es
->param
, length
);
2832 for (i
= 0; i
< length
; i
++)
2833 VEC_index (inline_param_summary_t
, es
->param
, i
)->change_prob
2834 = streamer_read_uhwi (ib
);
2839 /* Stream in inline summaries from the section. */
2842 inline_read_section (struct lto_file_decl_data
*file_data
, const char *data
,
2845 const struct lto_function_header
*header
=
2846 (const struct lto_function_header
*) data
;
2847 const int32_t cfg_offset
= sizeof (struct lto_function_header
);
2848 const int32_t main_offset
= cfg_offset
+ header
->cfg_size
;
2849 const int32_t string_offset
= main_offset
+ header
->main_size
;
2850 struct data_in
*data_in
;
2851 struct lto_input_block ib
;
2852 unsigned int i
, count2
, j
;
2853 unsigned int f_count
;
2855 LTO_INIT_INPUT_BLOCK (ib
, (const char *) data
+ main_offset
, 0,
2859 lto_data_in_create (file_data
, (const char *) data
+ string_offset
,
2860 header
->string_size
, NULL
);
2861 f_count
= streamer_read_uhwi (&ib
);
2862 for (i
= 0; i
< f_count
; i
++)
2865 struct cgraph_node
*node
;
2866 struct inline_summary
*info
;
2867 lto_cgraph_encoder_t encoder
;
2868 struct bitpack_d bp
;
2869 struct cgraph_edge
*e
;
2871 index
= streamer_read_uhwi (&ib
);
2872 encoder
= file_data
->cgraph_node_encoder
;
2873 node
= lto_cgraph_encoder_deref (encoder
, index
);
2874 info
= inline_summary (node
);
2876 info
->estimated_stack_size
2877 = info
->estimated_self_stack_size
= streamer_read_uhwi (&ib
);
2878 info
->size
= info
->self_size
= streamer_read_uhwi (&ib
);
2879 info
->time
= info
->self_time
= streamer_read_uhwi (&ib
);
2881 bp
= streamer_read_bitpack (&ib
);
2882 info
->inlinable
= bp_unpack_value (&bp
, 1);
2884 count2
= streamer_read_uhwi (&ib
);
2885 gcc_assert (!info
->conds
);
2886 for (j
= 0; j
< count2
; j
++)
2889 c
.operand_num
= streamer_read_uhwi (&ib
);
2890 c
.code
= (enum tree_code
) streamer_read_uhwi (&ib
);
2891 c
.val
= stream_read_tree (&ib
, data_in
);
2892 VEC_safe_push (condition
, gc
, info
->conds
, &c
);
2894 count2
= streamer_read_uhwi (&ib
);
2895 gcc_assert (!info
->entry
);
2896 for (j
= 0; j
< count2
; j
++)
2898 struct size_time_entry e
;
2900 e
.size
= streamer_read_uhwi (&ib
);
2901 e
.time
= streamer_read_uhwi (&ib
);
2902 e
.predicate
= read_predicate (&ib
);
2904 VEC_safe_push (size_time_entry
, gc
, info
->entry
, &e
);
2906 for (e
= node
->callees
; e
; e
= e
->next_callee
)
2907 read_inline_edge_summary (&ib
, e
);
2908 for (e
= node
->indirect_calls
; e
; e
= e
->next_callee
)
2909 read_inline_edge_summary (&ib
, e
);
2912 lto_free_section_data (file_data
, LTO_section_inline_summary
, NULL
, data
,
2914 lto_data_in_delete (data_in
);
2918 /* Read inline summary. Jump functions are shared among ipa-cp
2919 and inliner, so when ipa-cp is active, we don't need to write them
2923 inline_read_summary (void)
2925 struct lto_file_decl_data
**file_data_vec
= lto_get_file_decl_data ();
2926 struct lto_file_decl_data
*file_data
;
2929 inline_summary_alloc ();
2931 while ((file_data
= file_data_vec
[j
++]))
2934 const char *data
= lto_get_section_data (file_data
,
2935 LTO_section_inline_summary
,
2938 inline_read_section (file_data
, data
, len
);
2940 /* Fatal error here. We do not want to support compiling ltrans units
2941 with different version of compiler or different flags than the WPA
2942 unit, so this should never happen. */
2943 fatal_error ("ipa inline summary is missing in input file");
2947 ipa_register_cgraph_hooks ();
2949 ipa_prop_read_jump_functions ();
2951 function_insertion_hook_holder
=
2952 cgraph_add_function_insertion_hook (&add_new_function
, NULL
);
2956 /* Write predicate P to OB. */
2959 write_predicate (struct output_block
*ob
, struct predicate
*p
)
2963 for (j
= 0; p
->clause
[j
]; j
++)
2965 gcc_assert (j
< MAX_CLAUSES
);
2966 streamer_write_uhwi (ob
, p
->clause
[j
]);
2968 streamer_write_uhwi (ob
, 0);
2972 /* Write inline summary for edge E to OB. */
2975 write_inline_edge_summary (struct output_block
*ob
, struct cgraph_edge
*e
)
2977 struct inline_edge_summary
*es
= inline_edge_summary (e
);
2980 streamer_write_uhwi (ob
, es
->call_stmt_size
);
2981 streamer_write_uhwi (ob
, es
->call_stmt_time
);
2982 streamer_write_uhwi (ob
, es
->loop_depth
);
2983 write_predicate (ob
, es
->predicate
);
2984 streamer_write_uhwi (ob
, VEC_length (inline_param_summary_t
, es
->param
));
2985 for (i
= 0; i
< (int)VEC_length (inline_param_summary_t
, es
->param
); i
++)
2986 streamer_write_uhwi (ob
, VEC_index (inline_param_summary_t
,
2987 es
->param
, i
)->change_prob
);
2991 /* Write inline summary for node in SET.
2992 Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
2993 active, we don't need to write them twice. */
2996 inline_write_summary (cgraph_node_set set
,
2997 varpool_node_set vset ATTRIBUTE_UNUSED
)
2999 struct cgraph_node
*node
;
3000 struct output_block
*ob
= create_output_block (LTO_section_inline_summary
);
3001 lto_cgraph_encoder_t encoder
= ob
->decl_state
->cgraph_node_encoder
;
3002 unsigned int count
= 0;
3005 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
3006 if (lto_cgraph_encoder_deref (encoder
, i
)->analyzed
)
3008 streamer_write_uhwi (ob
, count
);
3010 for (i
= 0; i
< lto_cgraph_encoder_size (encoder
); i
++)
3012 node
= lto_cgraph_encoder_deref (encoder
, i
);
3015 struct inline_summary
*info
= inline_summary (node
);
3016 struct bitpack_d bp
;
3017 struct cgraph_edge
*edge
;
3020 struct condition
*c
;
3022 streamer_write_uhwi (ob
, lto_cgraph_encoder_encode (encoder
, node
));
3023 streamer_write_hwi (ob
, info
->estimated_self_stack_size
);
3024 streamer_write_hwi (ob
, info
->self_size
);
3025 streamer_write_hwi (ob
, info
->self_time
);
3026 bp
= bitpack_create (ob
->main_stream
);
3027 bp_pack_value (&bp
, info
->inlinable
, 1);
3028 streamer_write_bitpack (&bp
);
3029 streamer_write_uhwi (ob
, VEC_length (condition
, info
->conds
));
3030 for (i
= 0; VEC_iterate (condition
, info
->conds
, i
, c
); i
++)
3032 streamer_write_uhwi (ob
, c
->operand_num
);
3033 streamer_write_uhwi (ob
, c
->code
);
3034 stream_write_tree (ob
, c
->val
, true);
3036 streamer_write_uhwi (ob
, VEC_length (size_time_entry
, info
->entry
));
3038 VEC_iterate (size_time_entry
, info
->entry
, i
, e
);
3041 streamer_write_uhwi (ob
, e
->size
);
3042 streamer_write_uhwi (ob
, e
->time
);
3043 write_predicate (ob
, &e
->predicate
);
3045 for (edge
= node
->callees
; edge
; edge
= edge
->next_callee
)
3046 write_inline_edge_summary (ob
, edge
);
3047 for (edge
= node
->indirect_calls
; edge
; edge
= edge
->next_callee
)
3048 write_inline_edge_summary (ob
, edge
);
3051 streamer_write_char_stream (ob
->main_stream
, 0);
3052 produce_asm (ob
, NULL
);
3053 destroy_output_block (ob
);
3055 if (optimize
&& !flag_ipa_cp
)
3056 ipa_prop_write_jump_functions (set
);
3060 /* Release inline summary. */
3063 inline_free_summary (void)
3065 if (function_insertion_hook_holder
)
3066 cgraph_remove_function_insertion_hook (function_insertion_hook_holder
);
3067 function_insertion_hook_holder
= NULL
;
3068 if (node_removal_hook_holder
)
3069 cgraph_remove_node_removal_hook (node_removal_hook_holder
);
3070 if (edge_removal_hook_holder
)
3071 cgraph_remove_edge_removal_hook (edge_removal_hook_holder
);
3072 node_removal_hook_holder
= NULL
;
3073 if (node_duplication_hook_holder
)
3074 cgraph_remove_node_duplication_hook (node_duplication_hook_holder
);
3075 if (edge_duplication_hook_holder
)
3076 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder
);
3077 node_duplication_hook_holder
= NULL
;
3078 VEC_free (inline_summary_t
, gc
, inline_summary_vec
);
3079 inline_summary_vec
= NULL
;
3080 VEC_free (inline_edge_summary_t
, heap
, inline_edge_summary_vec
);
3081 inline_edge_summary_vec
= NULL
;
3082 if (edge_predicate_pool
)
3083 free_alloc_pool (edge_predicate_pool
);
3084 edge_predicate_pool
= 0;