1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2018 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* Interprocedural constant propagation (IPA-CP).
25 The goal of this transformation is to
27 1) discover functions which are always invoked with some arguments with the
28 same known constant values and modify the functions so that the
29 subsequent optimizations can take advantage of the knowledge, and
31 2) partial specialization - create specialized versions of functions
32 transformed in this way if some parameters are known constants only in
33 certain contexts but the estimated tradeoff between speedup and cost size
36 The algorithm also propagates types and attempts to perform type based
37 devirtualization. Types are propagated much like constants.
39 The algorithm basically consists of three stages. In the first, functions
40 are analyzed one at a time and jump functions are constructed for all known
41 call-sites. In the second phase, the pass propagates information from the
42 jump functions across the call to reveal what values are available at what
43 call sites, performs estimations of effects of known values on functions and
44 their callees, and finally decides what specialized extra versions should be
45 created. In the third, the special versions materialize and appropriate
48 The algorithm used is to a certain extent based on "Interprocedural Constant
49 Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
50 Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
51 Cooper, Mary W. Hall, and Ken Kennedy.
54 First stage - intraprocedural analysis
55 =======================================
57 This phase computes jump_function and modification flags.
59 A jump function for a call-site represents the values passed as an actual
60 arguments of a given call-site. In principle, there are three types of
63 Pass through - the caller's formal parameter is passed as an actual
64 argument, plus an operation on it can be performed.
65 Constant - a constant is passed as an actual argument.
66 Unknown - neither of the above.
68 All jump function types are described in detail in ipa-prop.h, together with
69 the data structures that represent them and methods of accessing them.
71 ipcp_generate_summary() is the main function of the first stage.
73 Second stage - interprocedural analysis
74 ========================================
76 This stage is itself divided into two phases. In the first, we propagate
77 known values over the call graph, in the second, we make cloning decisions.
78 It uses a different algorithm than the original Callahan's paper.
80 First, we traverse the functions topologically from callers to callees and,
81 for each strongly connected component (SCC), we propagate constants
82 according to previously computed jump functions. We also record what known
83 values depend on other known values and estimate local effects. Finally, we
84 propagate cumulative information about these effects from dependent values
85 to those on which they depend.
87 Second, we again traverse the call graph in the same topological order and
88 make clones for functions which we know are called with the same values in
89 all contexts and decide about extra specialized clones of functions just for
90 some contexts - these decisions are based on both local estimates and
91 cumulative estimates propagated from callees.
93 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
96 Third phase - materialization of clones, call statement updates.
97 ============================================
99 This stage is currently performed by call graph code (mainly in cgraphunit.c
100 and tree-inline.c) according to instructions inserted to the call graph by
105 #include "coretypes.h"
108 #include "gimple-expr.h"
110 #include "alloc-pool.h"
111 #include "tree-pass.h"
113 #include "diagnostic.h"
114 #include "fold-const.h"
115 #include "gimple-fold.h"
116 #include "symbol-summary.h"
117 #include "tree-vrp.h"
118 #include "ipa-prop.h"
119 #include "tree-pretty-print.h"
120 #include "tree-inline.h"
122 #include "ipa-fnsummary.h"
123 #include "ipa-utils.h"
124 #include "tree-ssa-ccp.h"
125 #include "stringpool.h"
128 template <typename valtype
> class ipcp_value
;
130 /* Describes a particular source for an IPA-CP value. */
132 template <typename valtype
>
133 class ipcp_value_source
136 /* Aggregate offset of the source, negative if the source is scalar value of
137 the argument itself. */
138 HOST_WIDE_INT offset
;
139 /* The incoming edge that brought the value. */
141 /* If the jump function that resulted into his value was a pass-through or an
142 ancestor, this is the ipcp_value of the caller from which the described
143 value has been derived. Otherwise it is NULL. */
144 ipcp_value
<valtype
> *val
;
145 /* Next pointer in a linked list of sources of a value. */
146 ipcp_value_source
*next
;
147 /* If the jump function that resulted into his value was a pass-through or an
148 ancestor, this is the index of the parameter of the caller the jump
149 function references. */
153 /* Common ancestor for all ipcp_value instantiations. */
155 class ipcp_value_base
158 /* Time benefit and size cost that specializing the function for this value
159 would bring about in this function alone. */
160 int local_time_benefit
, local_size_cost
;
161 /* Time benefit and size cost that specializing the function for this value
162 can bring about in it's callees (transitively). */
163 int prop_time_benefit
, prop_size_cost
;
166 : local_time_benefit (0), local_size_cost (0),
167 prop_time_benefit (0), prop_size_cost (0) {}
170 /* Describes one particular value stored in struct ipcp_lattice. */
172 template <typename valtype
>
173 class ipcp_value
: public ipcp_value_base
176 /* The actual value for the given parameter. */
178 /* The list of sources from which this value originates. */
179 ipcp_value_source
<valtype
> *sources
;
180 /* Next pointers in a linked list of all values in a lattice. */
182 /* Next pointers in a linked list of values in a strongly connected component
184 ipcp_value
*scc_next
;
185 /* Next pointers in a linked list of SCCs of values sorted topologically
186 according their sources. */
187 ipcp_value
*topo_next
;
188 /* A specialized node created for this value, NULL if none has been (so far)
190 cgraph_node
*spec_node
;
191 /* Depth first search number and low link for topological sorting of
194 /* True if this value is currently on the topo-sort stack. */
198 : sources (0), next (0), scc_next (0), topo_next (0),
199 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
201 void add_source (cgraph_edge
*cs
, ipcp_value
*src_val
, int src_idx
,
202 HOST_WIDE_INT offset
);
205 /* Lattice describing potential values of a formal parameter of a function, or
206 a part of an aggregate. TOP is represented by a lattice with zero values
207 and with contains_variable and bottom flags cleared. BOTTOM is represented
208 by a lattice with the bottom flag set. In that case, values and
209 contains_variable flag should be disregarded. */
211 template <typename valtype
>
215 /* The list of known values and types in this lattice. Note that values are
216 not deallocated if a lattice is set to bottom because there may be value
217 sources referencing them. */
218 ipcp_value
<valtype
> *values
;
219 /* Number of known values and types in this lattice. */
221 /* The lattice contains a variable component (in addition to values). */
222 bool contains_variable
;
223 /* The value of the lattice is bottom (i.e. variable and unusable for any
227 inline bool is_single_const ();
228 inline bool set_to_bottom ();
229 inline bool set_contains_variable ();
230 bool add_value (valtype newval
, cgraph_edge
*cs
,
231 ipcp_value
<valtype
> *src_val
= NULL
,
232 int src_idx
= 0, HOST_WIDE_INT offset
= -1);
233 void print (FILE * f
, bool dump_sources
, bool dump_benefits
);
236 /* Lattice of tree values with an offset to describe a part of an
239 class ipcp_agg_lattice
: public ipcp_lattice
<tree
>
242 /* Offset that is being described by this lattice. */
243 HOST_WIDE_INT offset
;
244 /* Size so that we don't have to re-compute it every time we traverse the
245 list. Must correspond to TYPE_SIZE of all lat values. */
247 /* Next element of the linked list. */
248 struct ipcp_agg_lattice
*next
;
251 /* Lattice of known bits, only capable of holding one value.
252 Bitwise constant propagation propagates which bits of a
268 In the above case, the param 'x' will always have all
269 the bits (except the bits in lsb) set to 0.
270 Hence the mask of 'x' would be 0xff. The mask
271 reflects that the bits in lsb are unknown.
272 The actual propagated value is given by m_value & ~m_mask. */
274 class ipcp_bits_lattice
277 bool bottom_p () { return m_lattice_val
== IPA_BITS_VARYING
; }
278 bool top_p () { return m_lattice_val
== IPA_BITS_UNDEFINED
; }
279 bool constant_p () { return m_lattice_val
== IPA_BITS_CONSTANT
; }
280 bool set_to_bottom ();
281 bool set_to_constant (widest_int
, widest_int
);
283 widest_int
get_value () { return m_value
; }
284 widest_int
get_mask () { return m_mask
; }
286 bool meet_with (ipcp_bits_lattice
& other
, unsigned, signop
,
287 enum tree_code
, tree
);
289 bool meet_with (widest_int
, widest_int
, unsigned);
294 enum { IPA_BITS_UNDEFINED
, IPA_BITS_CONSTANT
, IPA_BITS_VARYING
} m_lattice_val
;
296 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
297 If a bit in mask is set to 0, then the corresponding bit in
298 value is known to be constant. */
299 widest_int m_value
, m_mask
;
301 bool meet_with_1 (widest_int
, widest_int
, unsigned);
302 void get_value_and_mask (tree
, widest_int
*, widest_int
*);
305 /* Lattice of value ranges. */
307 class ipcp_vr_lattice
310 value_range_base m_vr
;
312 inline bool bottom_p () const;
313 inline bool top_p () const;
314 inline bool set_to_bottom ();
315 bool meet_with (const value_range_base
*p_vr
);
316 bool meet_with (const ipcp_vr_lattice
&other
);
317 void init () { gcc_assert (m_vr
.undefined_p ()); }
318 void print (FILE * f
);
321 bool meet_with_1 (const value_range_base
*other_vr
);
324 /* Structure containing lattices for a parameter itself and for pieces of
325 aggregates that are passed in the parameter or by a reference in a parameter
326 plus some other useful flags. */
328 class ipcp_param_lattices
331 /* Lattice describing the value of the parameter itself. */
332 ipcp_lattice
<tree
> itself
;
333 /* Lattice describing the polymorphic contexts of a parameter. */
334 ipcp_lattice
<ipa_polymorphic_call_context
> ctxlat
;
335 /* Lattices describing aggregate parts. */
336 ipcp_agg_lattice
*aggs
;
337 /* Lattice describing known bits. */
338 ipcp_bits_lattice bits_lattice
;
339 /* Lattice describing value range. */
340 ipcp_vr_lattice m_value_range
;
341 /* Number of aggregate lattices */
343 /* True if aggregate data were passed by reference (as opposed to by
346 /* All aggregate lattices contain a variable component (in addition to
348 bool aggs_contain_variable
;
349 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
350 for any propagation). */
353 /* There is a virtual call based on this parameter. */
357 /* Allocation pools for values and their sources in ipa-cp. */
359 object_allocator
<ipcp_value
<tree
> > ipcp_cst_values_pool
360 ("IPA-CP constant values");
362 object_allocator
<ipcp_value
<ipa_polymorphic_call_context
> >
363 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
365 object_allocator
<ipcp_value_source
<tree
> > ipcp_sources_pool
366 ("IPA-CP value sources");
368 object_allocator
<ipcp_agg_lattice
> ipcp_agg_lattice_pool
369 ("IPA_CP aggregate lattices");
371 /* Maximal count found in program. */
373 static profile_count max_count
;
375 /* Original overall size of the program. */
377 static long overall_size
, max_new_size
;
379 /* Node name to unique clone suffix number map. */
380 static hash_map
<const char *, unsigned> *clone_num_suffixes
;
382 /* Return the param lattices structure corresponding to the Ith formal
383 parameter of the function described by INFO. */
384 static inline struct ipcp_param_lattices
*
385 ipa_get_parm_lattices (struct ipa_node_params
*info
, int i
)
387 gcc_assert (i
>= 0 && i
< ipa_get_param_count (info
));
388 gcc_checking_assert (!info
->ipcp_orig_node
);
389 gcc_checking_assert (info
->lattices
);
390 return &(info
->lattices
[i
]);
393 /* Return the lattice corresponding to the scalar value of the Ith formal
394 parameter of the function described by INFO. */
395 static inline ipcp_lattice
<tree
> *
396 ipa_get_scalar_lat (struct ipa_node_params
*info
, int i
)
398 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
399 return &plats
->itself
;
402 /* Return the lattice corresponding to the scalar value of the Ith formal
403 parameter of the function described by INFO. */
404 static inline ipcp_lattice
<ipa_polymorphic_call_context
> *
405 ipa_get_poly_ctx_lat (struct ipa_node_params
*info
, int i
)
407 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
408 return &plats
->ctxlat
;
411 /* Return whether LAT is a lattice with a single constant and without an
414 template <typename valtype
>
416 ipcp_lattice
<valtype
>::is_single_const ()
418 if (bottom
|| contains_variable
|| values_count
!= 1)
424 /* Print V which is extracted from a value in a lattice to F. */
427 print_ipcp_constant_value (FILE * f
, tree v
)
429 if (TREE_CODE (v
) == ADDR_EXPR
430 && TREE_CODE (TREE_OPERAND (v
, 0)) == CONST_DECL
)
433 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (v
, 0)));
436 print_generic_expr (f
, v
);
439 /* Print V which is extracted from a value in a lattice to F. */
442 print_ipcp_constant_value (FILE * f
, ipa_polymorphic_call_context v
)
447 /* Print a lattice LAT to F. */
449 template <typename valtype
>
451 ipcp_lattice
<valtype
>::print (FILE * f
, bool dump_sources
, bool dump_benefits
)
453 ipcp_value
<valtype
> *val
;
458 fprintf (f
, "BOTTOM\n");
462 if (!values_count
&& !contains_variable
)
464 fprintf (f
, "TOP\n");
468 if (contains_variable
)
470 fprintf (f
, "VARIABLE");
476 for (val
= values
; val
; val
= val
->next
)
478 if (dump_benefits
&& prev
)
480 else if (!dump_benefits
&& prev
)
485 print_ipcp_constant_value (f
, val
->value
);
489 ipcp_value_source
<valtype
> *s
;
491 fprintf (f
, " [from:");
492 for (s
= val
->sources
; s
; s
= s
->next
)
493 fprintf (f
, " %i(%f)", s
->cs
->caller
->order
,
494 s
->cs
->sreal_frequency ().to_double ());
499 fprintf (f
, " [loc_time: %i, loc_size: %i, "
500 "prop_time: %i, prop_size: %i]\n",
501 val
->local_time_benefit
, val
->local_size_cost
,
502 val
->prop_time_benefit
, val
->prop_size_cost
);
509 ipcp_bits_lattice::print (FILE *f
)
512 fprintf (f
, " Bits unknown (TOP)\n");
513 else if (bottom_p ())
514 fprintf (f
, " Bits unusable (BOTTOM)\n");
517 fprintf (f
, " Bits: value = "); print_hex (get_value (), f
);
518 fprintf (f
, ", mask = "); print_hex (get_mask (), f
);
523 /* Print value range lattice to F. */
526 ipcp_vr_lattice::print (FILE * f
)
528 dump_value_range (f
, &m_vr
);
531 /* Print all ipcp_lattices of all functions to F. */
534 print_all_lattices (FILE * f
, bool dump_sources
, bool dump_benefits
)
536 struct cgraph_node
*node
;
539 fprintf (f
, "\nLattices:\n");
540 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
542 struct ipa_node_params
*info
;
544 info
= IPA_NODE_REF (node
);
545 /* Skip constprop clones since we don't make lattices for them. */
546 if (info
->ipcp_orig_node
)
548 fprintf (f
, " Node: %s:\n", node
->dump_name ());
549 count
= ipa_get_param_count (info
);
550 for (i
= 0; i
< count
; i
++)
552 struct ipcp_agg_lattice
*aglat
;
553 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
554 fprintf (f
, " param [%d]: ", i
);
555 plats
->itself
.print (f
, dump_sources
, dump_benefits
);
556 fprintf (f
, " ctxs: ");
557 plats
->ctxlat
.print (f
, dump_sources
, dump_benefits
);
558 plats
->bits_lattice
.print (f
);
560 plats
->m_value_range
.print (f
);
562 if (plats
->virt_call
)
563 fprintf (f
, " virt_call flag set\n");
565 if (plats
->aggs_bottom
)
567 fprintf (f
, " AGGS BOTTOM\n");
570 if (plats
->aggs_contain_variable
)
571 fprintf (f
, " AGGS VARIABLE\n");
572 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
574 fprintf (f
, " %soffset " HOST_WIDE_INT_PRINT_DEC
": ",
575 plats
->aggs_by_ref
? "ref " : "", aglat
->offset
);
576 aglat
->print (f
, dump_sources
, dump_benefits
);
582 /* Determine whether it is at all technically possible to create clones of NODE
583 and store this information in the ipa_node_params structure associated
587 determine_versionability (struct cgraph_node
*node
,
588 struct ipa_node_params
*info
)
590 const char *reason
= NULL
;
592 /* There are a number of generic reasons functions cannot be versioned. We
593 also cannot remove parameters if there are type attributes such as fnspec
595 if (node
->alias
|| node
->thunk
.thunk_p
)
596 reason
= "alias or thunk";
597 else if (!node
->local
.versionable
)
598 reason
= "not a tree_versionable_function";
599 else if (node
->get_availability () <= AVAIL_INTERPOSABLE
)
600 reason
= "insufficient body availability";
601 else if (!opt_for_fn (node
->decl
, optimize
)
602 || !opt_for_fn (node
->decl
, flag_ipa_cp
))
603 reason
= "non-optimized function";
604 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node
->decl
)))
606 /* Ideally we should clone the SIMD clones themselves and create
607 vector copies of them, so IPA-cp and SIMD clones can happily
608 coexist, but that may not be worth the effort. */
609 reason
= "function has SIMD clones";
611 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node
->decl
)))
613 /* Ideally we should clone the target clones themselves and create
614 copies of them, so IPA-cp and target clones can happily
615 coexist, but that may not be worth the effort. */
616 reason
= "function target_clones attribute";
618 /* Don't clone decls local to a comdat group; it breaks and for C++
619 decloned constructors, inlining is always better anyway. */
620 else if (node
->comdat_local_p ())
621 reason
= "comdat-local function";
622 else if (node
->calls_comdat_local
)
624 /* TODO: call is versionable if we make sure that all
625 callers are inside of a comdat group. */
626 reason
= "calls comdat-local function";
629 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
630 work only when inlined. Cloning them may still lead to better code
631 because ipa-cp will not give up on cloning further. If the function is
632 external this however leads to wrong code because we may end up producing
633 offline copy of the function. */
634 if (DECL_EXTERNAL (node
->decl
))
635 for (cgraph_edge
*edge
= node
->callees
; !reason
&& edge
;
636 edge
= edge
->next_callee
)
637 if (fndecl_built_in_p (edge
->callee
->decl
, BUILT_IN_NORMAL
))
639 if (DECL_FUNCTION_CODE (edge
->callee
->decl
) == BUILT_IN_VA_ARG_PACK
)
640 reason
= "external function which calls va_arg_pack";
641 if (DECL_FUNCTION_CODE (edge
->callee
->decl
)
642 == BUILT_IN_VA_ARG_PACK_LEN
)
643 reason
= "external function which calls va_arg_pack_len";
646 if (reason
&& dump_file
&& !node
->alias
&& !node
->thunk
.thunk_p
)
647 fprintf (dump_file
, "Function %s is not versionable, reason: %s.\n",
648 node
->dump_name (), reason
);
650 info
->versionable
= (reason
== NULL
);
653 /* Return true if it is at all technically possible to create clones of a
657 ipcp_versionable_function_p (struct cgraph_node
*node
)
659 return IPA_NODE_REF (node
)->versionable
;
662 /* Structure holding accumulated information about callers of a node. */
664 struct caller_statistics
666 profile_count count_sum
;
667 int n_calls
, n_hot_calls
, freq_sum
;
670 /* Initialize fields of STAT to zeroes. */
673 init_caller_stats (struct caller_statistics
*stats
)
675 stats
->count_sum
= profile_count::zero ();
677 stats
->n_hot_calls
= 0;
681 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
682 non-thunk incoming edges to NODE. */
685 gather_caller_stats (struct cgraph_node
*node
, void *data
)
687 struct caller_statistics
*stats
= (struct caller_statistics
*) data
;
688 struct cgraph_edge
*cs
;
690 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
691 if (!cs
->caller
->thunk
.thunk_p
)
693 if (cs
->count
.ipa ().initialized_p ())
694 stats
->count_sum
+= cs
->count
.ipa ();
695 stats
->freq_sum
+= cs
->frequency ();
697 if (cs
->maybe_hot_p ())
698 stats
->n_hot_calls
++;
704 /* Return true if this NODE is viable candidate for cloning. */
707 ipcp_cloning_candidate_p (struct cgraph_node
*node
)
709 struct caller_statistics stats
;
711 gcc_checking_assert (node
->has_gimple_body_p ());
713 if (!opt_for_fn (node
->decl
, flag_ipa_cp_clone
))
716 fprintf (dump_file
, "Not considering %s for cloning; "
717 "-fipa-cp-clone disabled.\n",
722 if (node
->optimize_for_size_p ())
725 fprintf (dump_file
, "Not considering %s for cloning; "
726 "optimizing it for size.\n",
731 init_caller_stats (&stats
);
732 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
, false);
734 if (ipa_fn_summaries
->get (node
)->self_size
< stats
.n_calls
)
737 fprintf (dump_file
, "Considering %s for cloning; code might shrink.\n",
742 /* When profile is available and function is hot, propagate into it even if
743 calls seems cold; constant propagation can improve function's speed
745 if (max_count
> profile_count::zero ())
747 if (stats
.count_sum
> node
->count
.ipa ().apply_scale (90, 100))
750 fprintf (dump_file
, "Considering %s for cloning; "
751 "usually called directly.\n",
756 if (!stats
.n_hot_calls
)
759 fprintf (dump_file
, "Not considering %s for cloning; no hot calls.\n",
764 fprintf (dump_file
, "Considering %s for cloning.\n",
769 template <typename valtype
>
770 class value_topo_info
773 /* Head of the linked list of topologically sorted values. */
774 ipcp_value
<valtype
> *values_topo
;
775 /* Stack for creating SCCs, represented by a linked list too. */
776 ipcp_value
<valtype
> *stack
;
777 /* Counter driving the algorithm in add_val_to_toposort. */
780 value_topo_info () : values_topo (NULL
), stack (NULL
), dfs_counter (0)
782 void add_val (ipcp_value
<valtype
> *cur_val
);
783 void propagate_effects ();
786 /* Arrays representing a topological ordering of call graph nodes and a stack
787 of nodes used during constant propagation and also data required to perform
788 topological sort of values and propagation of benefits in the determined
794 /* Array with obtained topological order of cgraph nodes. */
795 struct cgraph_node
**order
;
796 /* Stack of cgraph nodes used during propagation within SCC until all values
797 in the SCC stabilize. */
798 struct cgraph_node
**stack
;
799 int nnodes
, stack_top
;
801 value_topo_info
<tree
> constants
;
802 value_topo_info
<ipa_polymorphic_call_context
> contexts
;
804 ipa_topo_info () : order(NULL
), stack(NULL
), nnodes(0), stack_top(0),
809 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
812 build_toporder_info (struct ipa_topo_info
*topo
)
814 topo
->order
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
815 topo
->stack
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
817 gcc_checking_assert (topo
->stack_top
== 0);
818 topo
->nnodes
= ipa_reduced_postorder (topo
->order
, true, true, NULL
);
821 /* Free information about strongly connected components and the arrays in
825 free_toporder_info (struct ipa_topo_info
*topo
)
827 ipa_free_postorder_info ();
832 /* Add NODE to the stack in TOPO, unless it is already there. */
835 push_node_to_stack (struct ipa_topo_info
*topo
, struct cgraph_node
*node
)
837 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
838 if (info
->node_enqueued
)
840 info
->node_enqueued
= 1;
841 topo
->stack
[topo
->stack_top
++] = node
;
844 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
847 static struct cgraph_node
*
848 pop_node_from_stack (struct ipa_topo_info
*topo
)
852 struct cgraph_node
*node
;
854 node
= topo
->stack
[topo
->stack_top
];
855 IPA_NODE_REF (node
)->node_enqueued
= 0;
862 /* Set lattice LAT to bottom and return true if it previously was not set as
865 template <typename valtype
>
867 ipcp_lattice
<valtype
>::set_to_bottom ()
874 /* Mark lattice as containing an unknown value and return true if it previously
875 was not marked as such. */
877 template <typename valtype
>
879 ipcp_lattice
<valtype
>::set_contains_variable ()
881 bool ret
= !contains_variable
;
882 contains_variable
= true;
886 /* Set all aggregate lattices in PLATS to bottom and return true if they were
887 not previously set as such. */
890 set_agg_lats_to_bottom (struct ipcp_param_lattices
*plats
)
892 bool ret
= !plats
->aggs_bottom
;
893 plats
->aggs_bottom
= true;
897 /* Mark all aggregate lattices in PLATS as containing an unknown value and
898 return true if they were not previously marked as such. */
901 set_agg_lats_contain_variable (struct ipcp_param_lattices
*plats
)
903 bool ret
= !plats
->aggs_contain_variable
;
904 plats
->aggs_contain_variable
= true;
909 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice
&other
)
911 return meet_with_1 (&other
.m_vr
);
914 /* Meet the current value of the lattice with value range described by VR
918 ipcp_vr_lattice::meet_with (const value_range_base
*p_vr
)
920 return meet_with_1 (p_vr
);
923 /* Meet the current value of the lattice with value range described by
924 OTHER_VR lattice. Return TRUE if anything changed. */
927 ipcp_vr_lattice::meet_with_1 (const value_range_base
*other_vr
)
932 if (other_vr
->varying_p ())
933 return set_to_bottom ();
935 value_range_base
save (m_vr
);
936 m_vr
.union_ (other_vr
);
937 return !m_vr
.equal_p (save
);
940 /* Return true if value range information in the lattice is yet unknown. */
943 ipcp_vr_lattice::top_p () const
945 return m_vr
.undefined_p ();
948 /* Return true if value range information in the lattice is known to be
952 ipcp_vr_lattice::bottom_p () const
954 return m_vr
.varying_p ();
957 /* Set value range information in the lattice to bottom. Return true if it
958 previously was in a different state. */
961 ipcp_vr_lattice::set_to_bottom ()
963 if (m_vr
.varying_p ())
969 /* Set lattice value to bottom, if it already isn't the case. */
972 ipcp_bits_lattice::set_to_bottom ()
976 m_lattice_val
= IPA_BITS_VARYING
;
982 /* Set to constant if it isn't already. Only meant to be called
983 when switching state from TOP. */
986 ipcp_bits_lattice::set_to_constant (widest_int value
, widest_int mask
)
988 gcc_assert (top_p ());
989 m_lattice_val
= IPA_BITS_CONSTANT
;
995 /* Convert operand to value, mask form. */
998 ipcp_bits_lattice::get_value_and_mask (tree operand
, widest_int
*valuep
, widest_int
*maskp
)
1000 wide_int
get_nonzero_bits (const_tree
);
1002 if (TREE_CODE (operand
) == INTEGER_CST
)
1004 *valuep
= wi::to_widest (operand
);
1014 /* Meet operation, similar to ccp_lattice_meet, we xor values
1015 if this->value, value have different values at same bit positions, we want
1016 to drop that bit to varying. Return true if mask is changed.
1017 This function assumes that the lattice value is in CONSTANT state */
1020 ipcp_bits_lattice::meet_with_1 (widest_int value
, widest_int mask
,
1023 gcc_assert (constant_p ());
1025 widest_int old_mask
= m_mask
;
1026 m_mask
= (m_mask
| mask
) | (m_value
^ value
);
1028 if (wi::sext (m_mask
, precision
) == -1)
1029 return set_to_bottom ();
1031 return m_mask
!= old_mask
;
1034 /* Meet the bits lattice with operand
1035 described by <value, mask, sgn, precision. */
1038 ipcp_bits_lattice::meet_with (widest_int value
, widest_int mask
,
1046 if (wi::sext (mask
, precision
) == -1)
1047 return set_to_bottom ();
1048 return set_to_constant (value
, mask
);
1051 return meet_with_1 (value
, mask
, precision
);
1054 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1055 if code is binary operation or bit_value_unop (other) if code is unary op.
1056 In the case when code is nop_expr, no adjustment is required. */
1059 ipcp_bits_lattice::meet_with (ipcp_bits_lattice
& other
, unsigned precision
,
1060 signop sgn
, enum tree_code code
, tree operand
)
1062 if (other
.bottom_p ())
1063 return set_to_bottom ();
1065 if (bottom_p () || other
.top_p ())
1068 widest_int adjusted_value
, adjusted_mask
;
1070 if (TREE_CODE_CLASS (code
) == tcc_binary
)
1072 tree type
= TREE_TYPE (operand
);
1073 gcc_assert (INTEGRAL_TYPE_P (type
));
1074 widest_int o_value
, o_mask
;
1075 get_value_and_mask (operand
, &o_value
, &o_mask
);
1077 bit_value_binop (code
, sgn
, precision
, &adjusted_value
, &adjusted_mask
,
1078 sgn
, precision
, other
.get_value (), other
.get_mask (),
1079 TYPE_SIGN (type
), TYPE_PRECISION (type
), o_value
, o_mask
);
1081 if (wi::sext (adjusted_mask
, precision
) == -1)
1082 return set_to_bottom ();
1085 else if (TREE_CODE_CLASS (code
) == tcc_unary
)
1087 bit_value_unop (code
, sgn
, precision
, &adjusted_value
,
1088 &adjusted_mask
, sgn
, precision
, other
.get_value (),
1091 if (wi::sext (adjusted_mask
, precision
) == -1)
1092 return set_to_bottom ();
1096 return set_to_bottom ();
1100 if (wi::sext (adjusted_mask
, precision
) == -1)
1101 return set_to_bottom ();
1102 return set_to_constant (adjusted_value
, adjusted_mask
);
1105 return meet_with_1 (adjusted_value
, adjusted_mask
, precision
);
1108 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1109 return true is any of them has not been marked as such so far. */
1112 set_all_contains_variable (struct ipcp_param_lattices
*plats
)
1115 ret
= plats
->itself
.set_contains_variable ();
1116 ret
|= plats
->ctxlat
.set_contains_variable ();
1117 ret
|= set_agg_lats_contain_variable (plats
);
1118 ret
|= plats
->bits_lattice
.set_to_bottom ();
1119 ret
|= plats
->m_value_range
.set_to_bottom ();
1123 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1124 points to by the number of callers to NODE. */
1127 count_callers (cgraph_node
*node
, void *data
)
1129 int *caller_count
= (int *) data
;
1131 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
1132 /* Local thunks can be handled transparently, but if the thunk can not
1133 be optimized out, count it as a real use. */
1134 if (!cs
->caller
->thunk
.thunk_p
|| !cs
->caller
->local
.local
)
1139 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1140 the one caller of some other node. Set the caller's corresponding flag. */
1143 set_single_call_flag (cgraph_node
*node
, void *)
1145 cgraph_edge
*cs
= node
->callers
;
1146 /* Local thunks can be handled transparently, skip them. */
1147 while (cs
&& cs
->caller
->thunk
.thunk_p
&& cs
->caller
->local
.local
)
1148 cs
= cs
->next_caller
;
1151 IPA_NODE_REF (cs
->caller
)->node_calling_single_call
= true;
1157 /* Initialize ipcp_lattices. */
1160 initialize_node_lattices (struct cgraph_node
*node
)
1162 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
1163 struct cgraph_edge
*ie
;
1164 bool disable
= false, variable
= false;
1167 gcc_checking_assert (node
->has_gimple_body_p ());
1168 if (node
->local
.local
)
1170 int caller_count
= 0;
1171 node
->call_for_symbol_thunks_and_aliases (count_callers
, &caller_count
,
1173 gcc_checking_assert (caller_count
> 0);
1174 if (caller_count
== 1)
1175 node
->call_for_symbol_thunks_and_aliases (set_single_call_flag
,
1180 /* When cloning is allowed, we can assume that externally visible
1181 functions are not called. We will compensate this by cloning
1183 if (ipcp_versionable_function_p (node
)
1184 && ipcp_cloning_candidate_p (node
))
1190 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1192 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1193 plats
->m_value_range
.init ();
1196 if (disable
|| variable
)
1198 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1200 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1203 plats
->itself
.set_to_bottom ();
1204 plats
->ctxlat
.set_to_bottom ();
1205 set_agg_lats_to_bottom (plats
);
1206 plats
->bits_lattice
.set_to_bottom ();
1207 plats
->m_value_range
.set_to_bottom ();
1210 set_all_contains_variable (plats
);
1212 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1213 && !node
->alias
&& !node
->thunk
.thunk_p
)
1214 fprintf (dump_file
, "Marking all lattices of %s as %s\n",
1215 node
->dump_name (), disable
? "BOTTOM" : "VARIABLE");
1218 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
1219 if (ie
->indirect_info
->polymorphic
1220 && ie
->indirect_info
->param_index
>= 0)
1222 gcc_checking_assert (ie
->indirect_info
->param_index
>= 0);
1223 ipa_get_parm_lattices (info
,
1224 ie
->indirect_info
->param_index
)->virt_call
= 1;
1228 /* Return the result of a (possibly arithmetic) pass through jump function
1229 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1230 to which the result is passed. Return NULL_TREE if that cannot be
1231 determined or be considered an interprocedural invariant. */
1234 ipa_get_jf_pass_through_result (struct ipa_jump_func
*jfunc
, tree input
,
1239 if (ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
1241 if (!is_gimple_ip_invariant (input
))
1244 tree_code opcode
= ipa_get_jf_pass_through_operation (jfunc
);
1247 if (TREE_CODE_CLASS (opcode
) == tcc_comparison
)
1248 res_type
= boolean_type_node
;
1249 else if (expr_type_first_operand_type_p (opcode
))
1250 res_type
= TREE_TYPE (input
);
1255 if (TREE_CODE_CLASS (opcode
) == tcc_unary
)
1256 res
= fold_unary (opcode
, res_type
, input
);
1258 res
= fold_binary (opcode
, res_type
, input
,
1259 ipa_get_jf_pass_through_operand (jfunc
));
1261 if (res
&& !is_gimple_ip_invariant (res
))
1267 /* Return the result of an ancestor jump function JFUNC on the constant value
1268 INPUT. Return NULL_TREE if that cannot be determined. */
1271 ipa_get_jf_ancestor_result (struct ipa_jump_func
*jfunc
, tree input
)
1273 gcc_checking_assert (TREE_CODE (input
) != TREE_BINFO
);
1274 if (TREE_CODE (input
) == ADDR_EXPR
)
1276 tree t
= TREE_OPERAND (input
, 0);
1277 t
= build_ref_for_offset (EXPR_LOCATION (t
), t
,
1278 ipa_get_jf_ancestor_offset (jfunc
), false,
1279 ptr_type_node
, NULL
, false);
1280 return build_fold_addr_expr (t
);
1286 /* Determine whether JFUNC evaluates to a single known constant value and if
1287 so, return it. Otherwise return NULL. INFO describes the caller node or
1288 the one it is inlined to, so that pass-through jump functions can be
1289 evaluated. PARM_TYPE is the type of the parameter to which the result is
1293 ipa_value_from_jfunc (struct ipa_node_params
*info
, struct ipa_jump_func
*jfunc
,
1296 if (jfunc
->type
== IPA_JF_CONST
)
1297 return ipa_get_jf_constant (jfunc
);
1298 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1299 || jfunc
->type
== IPA_JF_ANCESTOR
)
1304 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1305 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1307 idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1309 if (info
->ipcp_orig_node
)
1310 input
= info
->known_csts
[idx
];
1313 ipcp_lattice
<tree
> *lat
;
1316 || idx
>= ipa_get_param_count (info
))
1318 lat
= ipa_get_scalar_lat (info
, idx
);
1319 if (!lat
->is_single_const ())
1321 input
= lat
->values
->value
;
1327 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1328 return ipa_get_jf_pass_through_result (jfunc
, input
, parm_type
);
1330 return ipa_get_jf_ancestor_result (jfunc
, input
);
1336 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1337 that INFO describes the caller node or the one it is inlined to, CS is the
1338 call graph edge corresponding to JFUNC and CSIDX index of the described
1341 ipa_polymorphic_call_context
1342 ipa_context_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
, int csidx
,
1343 ipa_jump_func
*jfunc
)
1345 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1346 ipa_polymorphic_call_context ctx
;
1347 ipa_polymorphic_call_context
*edge_ctx
1348 = cs
? ipa_get_ith_polymorhic_call_context (args
, csidx
) : NULL
;
1350 if (edge_ctx
&& !edge_ctx
->useless_p ())
1353 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1354 || jfunc
->type
== IPA_JF_ANCESTOR
)
1356 ipa_polymorphic_call_context srcctx
;
1358 bool type_preserved
= true;
1359 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1361 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1363 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1364 srcidx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1368 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1369 srcidx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1371 if (info
->ipcp_orig_node
)
1373 if (info
->known_contexts
.exists ())
1374 srcctx
= info
->known_contexts
[srcidx
];
1379 || srcidx
>= ipa_get_param_count (info
))
1381 ipcp_lattice
<ipa_polymorphic_call_context
> *lat
;
1382 lat
= ipa_get_poly_ctx_lat (info
, srcidx
);
1383 if (!lat
->is_single_const ())
1385 srcctx
= lat
->values
->value
;
1387 if (srcctx
.useless_p ())
1389 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1390 srcctx
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1391 if (!type_preserved
)
1392 srcctx
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1393 srcctx
.combine_with (ctx
);
1400 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1401 bottom, not containing a variable component and without any known value at
1405 ipcp_verify_propagated_values (void)
1407 struct cgraph_node
*node
;
1409 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1411 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
1412 int i
, count
= ipa_get_param_count (info
);
1414 for (i
= 0; i
< count
; i
++)
1416 ipcp_lattice
<tree
> *lat
= ipa_get_scalar_lat (info
, i
);
1419 && !lat
->contains_variable
1420 && lat
->values_count
== 0)
1424 symtab
->dump (dump_file
);
1425 fprintf (dump_file
, "\nIPA lattices after constant "
1426 "propagation, before gcc_unreachable:\n");
1427 print_all_lattices (dump_file
, true, false);
1436 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1439 values_equal_for_ipcp_p (tree x
, tree y
)
1441 gcc_checking_assert (x
!= NULL_TREE
&& y
!= NULL_TREE
);
1446 if (TREE_CODE (x
) == ADDR_EXPR
1447 && TREE_CODE (y
) == ADDR_EXPR
1448 && TREE_CODE (TREE_OPERAND (x
, 0)) == CONST_DECL
1449 && TREE_CODE (TREE_OPERAND (y
, 0)) == CONST_DECL
)
1450 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x
, 0)),
1451 DECL_INITIAL (TREE_OPERAND (y
, 0)), 0);
1453 return operand_equal_p (x
, y
, 0);
1456 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1459 values_equal_for_ipcp_p (ipa_polymorphic_call_context x
,
1460 ipa_polymorphic_call_context y
)
1462 return x
.equal_to (y
);
1466 /* Add a new value source to the value represented by THIS, marking that a
1467 value comes from edge CS and (if the underlying jump function is a
1468 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1469 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1470 scalar value of the parameter itself or the offset within an aggregate. */
1472 template <typename valtype
>
1474 ipcp_value
<valtype
>::add_source (cgraph_edge
*cs
, ipcp_value
*src_val
,
1475 int src_idx
, HOST_WIDE_INT offset
)
1477 ipcp_value_source
<valtype
> *src
;
1479 src
= new (ipcp_sources_pool
.allocate ()) ipcp_value_source
<valtype
>;
1480 src
->offset
= offset
;
1483 src
->index
= src_idx
;
1485 src
->next
= sources
;
1489 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1490 SOURCE and clear all other fields. */
1492 static ipcp_value
<tree
> *
1493 allocate_and_init_ipcp_value (tree source
)
1495 ipcp_value
<tree
> *val
;
1497 val
= new (ipcp_cst_values_pool
.allocate ()) ipcp_value
<tree
>();
1498 val
->value
= source
;
1502 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1503 value to SOURCE and clear all other fields. */
1505 static ipcp_value
<ipa_polymorphic_call_context
> *
1506 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source
)
1508 ipcp_value
<ipa_polymorphic_call_context
> *val
;
1511 val
= new (ipcp_poly_ctx_values_pool
.allocate ())
1512 ipcp_value
<ipa_polymorphic_call_context
>();
1513 val
->value
= source
;
1517 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1518 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1519 meaning. OFFSET -1 means the source is scalar and not a part of an
1522 template <typename valtype
>
1524 ipcp_lattice
<valtype
>::add_value (valtype newval
, cgraph_edge
*cs
,
1525 ipcp_value
<valtype
> *src_val
,
1526 int src_idx
, HOST_WIDE_INT offset
)
1528 ipcp_value
<valtype
> *val
;
1533 for (val
= values
; val
; val
= val
->next
)
1534 if (values_equal_for_ipcp_p (val
->value
, newval
))
1536 if (ipa_edge_within_scc (cs
))
1538 ipcp_value_source
<valtype
> *s
;
1539 for (s
= val
->sources
; s
; s
= s
->next
)
1546 val
->add_source (cs
, src_val
, src_idx
, offset
);
1550 if (values_count
== PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE
))
1552 /* We can only free sources, not the values themselves, because sources
1553 of other values in this SCC might point to them. */
1554 for (val
= values
; val
; val
= val
->next
)
1556 while (val
->sources
)
1558 ipcp_value_source
<valtype
> *src
= val
->sources
;
1559 val
->sources
= src
->next
;
1560 ipcp_sources_pool
.remove ((ipcp_value_source
<tree
>*)src
);
1565 return set_to_bottom ();
1569 val
= allocate_and_init_ipcp_value (newval
);
1570 val
->add_source (cs
, src_val
, src_idx
, offset
);
1576 /* Propagate values through a pass-through jump function JFUNC associated with
1577 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1578 is the index of the source parameter. PARM_TYPE is the type of the
1579 parameter to which the result is passed. */
1582 propagate_vals_across_pass_through (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
1583 ipcp_lattice
<tree
> *src_lat
,
1584 ipcp_lattice
<tree
> *dest_lat
, int src_idx
,
1587 ipcp_value
<tree
> *src_val
;
1590 /* Do not create new values when propagating within an SCC because if there
1591 are arithmetic functions with circular dependencies, there is infinite
1592 number of them and we would just make lattices bottom. If this condition
1593 is ever relaxed we have to detect self-feeding recursive calls in
1594 cgraph_edge_brings_value_p in a smarter way. */
1595 if ((ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1596 && ipa_edge_within_scc (cs
))
1597 ret
= dest_lat
->set_contains_variable ();
1599 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1601 tree cstval
= ipa_get_jf_pass_through_result (jfunc
, src_val
->value
,
1605 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
);
1607 ret
|= dest_lat
->set_contains_variable ();
1613 /* Propagate values through an ancestor jump function JFUNC associated with
1614 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1615 is the index of the source parameter. */
1618 propagate_vals_across_ancestor (struct cgraph_edge
*cs
,
1619 struct ipa_jump_func
*jfunc
,
1620 ipcp_lattice
<tree
> *src_lat
,
1621 ipcp_lattice
<tree
> *dest_lat
, int src_idx
)
1623 ipcp_value
<tree
> *src_val
;
1626 if (ipa_edge_within_scc (cs
))
1627 return dest_lat
->set_contains_variable ();
1629 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1631 tree t
= ipa_get_jf_ancestor_result (jfunc
, src_val
->value
);
1634 ret
|= dest_lat
->add_value (t
, cs
, src_val
, src_idx
);
1636 ret
|= dest_lat
->set_contains_variable ();
1642 /* Propagate scalar values across jump function JFUNC that is associated with
1643 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
1644 parameter to which the result is passed. */
1647 propagate_scalar_across_jump_function (struct cgraph_edge
*cs
,
1648 struct ipa_jump_func
*jfunc
,
1649 ipcp_lattice
<tree
> *dest_lat
,
1652 if (dest_lat
->bottom
)
1655 if (jfunc
->type
== IPA_JF_CONST
)
1657 tree val
= ipa_get_jf_constant (jfunc
);
1658 return dest_lat
->add_value (val
, cs
, NULL
, 0);
1660 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1661 || jfunc
->type
== IPA_JF_ANCESTOR
)
1663 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1664 ipcp_lattice
<tree
> *src_lat
;
1668 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1669 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1671 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1673 src_lat
= ipa_get_scalar_lat (caller_info
, src_idx
);
1674 if (src_lat
->bottom
)
1675 return dest_lat
->set_contains_variable ();
1677 /* If we would need to clone the caller and cannot, do not propagate. */
1678 if (!ipcp_versionable_function_p (cs
->caller
)
1679 && (src_lat
->contains_variable
1680 || (src_lat
->values_count
> 1)))
1681 return dest_lat
->set_contains_variable ();
1683 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1684 ret
= propagate_vals_across_pass_through (cs
, jfunc
, src_lat
,
1685 dest_lat
, src_idx
, param_type
);
1687 ret
= propagate_vals_across_ancestor (cs
, jfunc
, src_lat
, dest_lat
,
1690 if (src_lat
->contains_variable
)
1691 ret
|= dest_lat
->set_contains_variable ();
1696 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
1697 use it for indirect inlining), we should propagate them too. */
1698 return dest_lat
->set_contains_variable ();
1701 /* Propagate scalar values across jump function JFUNC that is associated with
1702 edge CS and describes argument IDX and put the values into DEST_LAT. */
1705 propagate_context_across_jump_function (cgraph_edge
*cs
,
1706 ipa_jump_func
*jfunc
, int idx
,
1707 ipcp_lattice
<ipa_polymorphic_call_context
> *dest_lat
)
1709 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1710 if (dest_lat
->bottom
)
1713 bool added_sth
= false;
1714 bool type_preserved
= true;
1716 ipa_polymorphic_call_context edge_ctx
, *edge_ctx_ptr
1717 = ipa_get_ith_polymorhic_call_context (args
, idx
);
1720 edge_ctx
= *edge_ctx_ptr
;
1722 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1723 || jfunc
->type
== IPA_JF_ANCESTOR
)
1725 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1727 ipcp_lattice
<ipa_polymorphic_call_context
> *src_lat
;
1729 /* TODO: Once we figure out how to propagate speculations, it will
1730 probably be a good idea to switch to speculation if type_preserved is
1731 not set instead of punting. */
1732 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1734 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1736 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1737 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1741 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1742 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1745 src_lat
= ipa_get_poly_ctx_lat (caller_info
, src_idx
);
1746 /* If we would need to clone the caller and cannot, do not propagate. */
1747 if (!ipcp_versionable_function_p (cs
->caller
)
1748 && (src_lat
->contains_variable
1749 || (src_lat
->values_count
> 1)))
1752 ipcp_value
<ipa_polymorphic_call_context
> *src_val
;
1753 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1755 ipa_polymorphic_call_context cur
= src_val
->value
;
1757 if (!type_preserved
)
1758 cur
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1759 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1760 cur
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1761 /* TODO: In cases we know how the context is going to be used,
1762 we can improve the result by passing proper OTR_TYPE. */
1763 cur
.combine_with (edge_ctx
);
1764 if (!cur
.useless_p ())
1766 if (src_lat
->contains_variable
1767 && !edge_ctx
.equal_to (cur
))
1768 ret
|= dest_lat
->set_contains_variable ();
1769 ret
|= dest_lat
->add_value (cur
, cs
, src_val
, src_idx
);
1779 if (!edge_ctx
.useless_p ())
1780 ret
|= dest_lat
->add_value (edge_ctx
, cs
);
1782 ret
|= dest_lat
->set_contains_variable ();
1788 /* Propagate bits across jfunc that is associated with
1789 edge cs and update dest_lattice accordingly. */
1792 propagate_bits_across_jump_function (cgraph_edge
*cs
, int idx
,
1793 ipa_jump_func
*jfunc
,
1794 ipcp_bits_lattice
*dest_lattice
)
1796 if (dest_lattice
->bottom_p ())
1799 enum availability availability
;
1800 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
1801 struct ipa_node_params
*callee_info
= IPA_NODE_REF (callee
);
1802 tree parm_type
= ipa_get_type (callee_info
, idx
);
1804 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
1805 transform for these cases. Similarly, we can have bad type mismatches
1806 with LTO, avoid doing anything with those too. */
1808 || (!INTEGRAL_TYPE_P (parm_type
) && !POINTER_TYPE_P (parm_type
)))
1810 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1811 fprintf (dump_file
, "Setting dest_lattice to bottom, because type of "
1812 "param %i of %s is NULL or unsuitable for bits propagation\n",
1813 idx
, cs
->callee
->name ());
1815 return dest_lattice
->set_to_bottom ();
1818 unsigned precision
= TYPE_PRECISION (parm_type
);
1819 signop sgn
= TYPE_SIGN (parm_type
);
1821 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1822 || jfunc
->type
== IPA_JF_ANCESTOR
)
1824 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1825 tree operand
= NULL_TREE
;
1826 enum tree_code code
;
1829 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1831 code
= ipa_get_jf_pass_through_operation (jfunc
);
1832 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1833 if (code
!= NOP_EXPR
)
1834 operand
= ipa_get_jf_pass_through_operand (jfunc
);
1838 code
= POINTER_PLUS_EXPR
;
1839 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1840 unsigned HOST_WIDE_INT offset
= ipa_get_jf_ancestor_offset (jfunc
) / BITS_PER_UNIT
;
1841 operand
= build_int_cstu (size_type_node
, offset
);
1844 struct ipcp_param_lattices
*src_lats
1845 = ipa_get_parm_lattices (caller_info
, src_idx
);
1847 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
1853 Assume lattice for x is bottom, however we can still propagate
1854 result of x & 0xff == 0xff, which gets computed during ccp1 pass
1855 and we store it in jump function during analysis stage. */
1857 if (src_lats
->bits_lattice
.bottom_p ()
1859 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
1862 return dest_lattice
->meet_with (src_lats
->bits_lattice
, precision
, sgn
,
1866 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
1867 return dest_lattice
->set_to_bottom ();
1868 else if (jfunc
->bits
)
1869 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
1872 return dest_lattice
->set_to_bottom ();
1875 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1876 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1877 the result is a range or an anti-range. */
1880 ipa_vr_operation_and_type_effects (value_range_base
*dst_vr
,
1881 value_range_base
*src_vr
,
1882 enum tree_code operation
,
1883 tree dst_type
, tree src_type
)
1885 extract_range_from_unary_expr (dst_vr
, operation
, dst_type
,
1887 if (dst_vr
->varying_p () || dst_vr
->undefined_p ())
1892 /* Propagate value range across jump function JFUNC that is associated with
1893 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
1897 propagate_vr_across_jump_function (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
1898 struct ipcp_param_lattices
*dest_plats
,
1901 ipcp_vr_lattice
*dest_lat
= &dest_plats
->m_value_range
;
1903 if (dest_lat
->bottom_p ())
1907 || (!INTEGRAL_TYPE_P (param_type
)
1908 && !POINTER_TYPE_P (param_type
)))
1909 return dest_lat
->set_to_bottom ();
1911 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1913 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
1915 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
1917 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1918 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1919 tree operand_type
= ipa_get_type (caller_info
, src_idx
);
1920 struct ipcp_param_lattices
*src_lats
1921 = ipa_get_parm_lattices (caller_info
, src_idx
);
1923 if (src_lats
->m_value_range
.bottom_p ())
1924 return dest_lat
->set_to_bottom ();
1925 value_range_base vr
;
1926 if (ipa_vr_operation_and_type_effects (&vr
,
1927 &src_lats
->m_value_range
.m_vr
,
1928 operation
, param_type
,
1930 return dest_lat
->meet_with (&vr
);
1933 else if (jfunc
->type
== IPA_JF_CONST
)
1935 tree val
= ipa_get_jf_constant (jfunc
);
1936 if (TREE_CODE (val
) == INTEGER_CST
)
1938 val
= fold_convert (param_type
, val
);
1939 if (TREE_OVERFLOW_P (val
))
1940 val
= drop_tree_overflow (val
);
1942 value_range_base
tmpvr (VR_RANGE
, val
, val
);
1943 return dest_lat
->meet_with (&tmpvr
);
1947 value_range_base vr
;
1949 && ipa_vr_operation_and_type_effects (&vr
, jfunc
->m_vr
, NOP_EXPR
,
1951 jfunc
->m_vr
->type ()))
1952 return dest_lat
->meet_with (&vr
);
1954 return dest_lat
->set_to_bottom ();
1957 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
1958 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
1959 other cases, return false). If there are no aggregate items, set
1960 aggs_by_ref to NEW_AGGS_BY_REF. */
1963 set_check_aggs_by_ref (struct ipcp_param_lattices
*dest_plats
,
1964 bool new_aggs_by_ref
)
1966 if (dest_plats
->aggs
)
1968 if (dest_plats
->aggs_by_ref
!= new_aggs_by_ref
)
1970 set_agg_lats_to_bottom (dest_plats
);
1975 dest_plats
->aggs_by_ref
= new_aggs_by_ref
;
1979 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
1980 already existing lattice for the given OFFSET and SIZE, marking all skipped
1981 lattices as containing variable and checking for overlaps. If there is no
1982 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
1983 it with offset, size and contains_variable to PRE_EXISTING, and return true,
1984 unless there are too many already. If there are two many, return false. If
1985 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
1986 skipped lattices were newly marked as containing variable, set *CHANGE to
1990 merge_agg_lats_step (struct ipcp_param_lattices
*dest_plats
,
1991 HOST_WIDE_INT offset
, HOST_WIDE_INT val_size
,
1992 struct ipcp_agg_lattice
***aglat
,
1993 bool pre_existing
, bool *change
)
1995 gcc_checking_assert (offset
>= 0);
1997 while (**aglat
&& (**aglat
)->offset
< offset
)
1999 if ((**aglat
)->offset
+ (**aglat
)->size
> offset
)
2001 set_agg_lats_to_bottom (dest_plats
);
2004 *change
|= (**aglat
)->set_contains_variable ();
2005 *aglat
= &(**aglat
)->next
;
2008 if (**aglat
&& (**aglat
)->offset
== offset
)
2010 if ((**aglat
)->size
!= val_size
2012 && (**aglat
)->next
->offset
< offset
+ val_size
))
2014 set_agg_lats_to_bottom (dest_plats
);
2017 gcc_checking_assert (!(**aglat
)->next
2018 || (**aglat
)->next
->offset
>= offset
+ val_size
);
2023 struct ipcp_agg_lattice
*new_al
;
2025 if (**aglat
&& (**aglat
)->offset
< offset
+ val_size
)
2027 set_agg_lats_to_bottom (dest_plats
);
2030 if (dest_plats
->aggs_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
2032 dest_plats
->aggs_count
++;
2033 new_al
= ipcp_agg_lattice_pool
.allocate ();
2034 memset (new_al
, 0, sizeof (*new_al
));
2036 new_al
->offset
= offset
;
2037 new_al
->size
= val_size
;
2038 new_al
->contains_variable
= pre_existing
;
2040 new_al
->next
= **aglat
;
2046 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2047 containing an unknown value. */
2050 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice
*aglat
)
2055 ret
|= aglat
->set_contains_variable ();
2056 aglat
= aglat
->next
;
2061 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2062 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2063 parameter used for lattice value sources. Return true if DEST_PLATS changed
2067 merge_aggregate_lattices (struct cgraph_edge
*cs
,
2068 struct ipcp_param_lattices
*dest_plats
,
2069 struct ipcp_param_lattices
*src_plats
,
2070 int src_idx
, HOST_WIDE_INT offset_delta
)
2072 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2073 struct ipcp_agg_lattice
**dst_aglat
;
2076 if (set_check_aggs_by_ref (dest_plats
, src_plats
->aggs_by_ref
))
2078 if (src_plats
->aggs_bottom
)
2079 return set_agg_lats_contain_variable (dest_plats
);
2080 if (src_plats
->aggs_contain_variable
)
2081 ret
|= set_agg_lats_contain_variable (dest_plats
);
2082 dst_aglat
= &dest_plats
->aggs
;
2084 for (struct ipcp_agg_lattice
*src_aglat
= src_plats
->aggs
;
2086 src_aglat
= src_aglat
->next
)
2088 HOST_WIDE_INT new_offset
= src_aglat
->offset
- offset_delta
;
2092 if (merge_agg_lats_step (dest_plats
, new_offset
, src_aglat
->size
,
2093 &dst_aglat
, pre_existing
, &ret
))
2095 struct ipcp_agg_lattice
*new_al
= *dst_aglat
;
2097 dst_aglat
= &(*dst_aglat
)->next
;
2098 if (src_aglat
->bottom
)
2100 ret
|= new_al
->set_contains_variable ();
2103 if (src_aglat
->contains_variable
)
2104 ret
|= new_al
->set_contains_variable ();
2105 for (ipcp_value
<tree
> *val
= src_aglat
->values
;
2108 ret
|= new_al
->add_value (val
->value
, cs
, val
, src_idx
,
2111 else if (dest_plats
->aggs_bottom
)
2114 ret
|= set_chain_of_aglats_contains_variable (*dst_aglat
);
2118 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2119 pass-through JFUNC and if so, whether it has conform and conforms to the
2120 rules about propagating values passed by reference. */
2123 agg_pass_through_permissible_p (struct ipcp_param_lattices
*src_plats
,
2124 struct ipa_jump_func
*jfunc
)
2126 return src_plats
->aggs
2127 && (!src_plats
->aggs_by_ref
2128 || ipa_get_jf_pass_through_agg_preserved (jfunc
));
2131 /* Propagate scalar values across jump function JFUNC that is associated with
2132 edge CS and put the values into DEST_LAT. */
2135 propagate_aggs_across_jump_function (struct cgraph_edge
*cs
,
2136 struct ipa_jump_func
*jfunc
,
2137 struct ipcp_param_lattices
*dest_plats
)
2141 if (dest_plats
->aggs_bottom
)
2144 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2145 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
2147 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2148 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2149 struct ipcp_param_lattices
*src_plats
;
2151 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2152 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
2154 /* Currently we do not produce clobber aggregate jump
2155 functions, replace with merging when we do. */
2156 gcc_assert (!jfunc
->agg
.items
);
2157 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
,
2161 ret
|= set_agg_lats_contain_variable (dest_plats
);
2163 else if (jfunc
->type
== IPA_JF_ANCESTOR
2164 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
2166 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2167 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2168 struct ipcp_param_lattices
*src_plats
;
2170 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2171 if (src_plats
->aggs
&& src_plats
->aggs_by_ref
)
2173 /* Currently we do not produce clobber aggregate jump
2174 functions, replace with merging when we do. */
2175 gcc_assert (!jfunc
->agg
.items
);
2176 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
, src_idx
,
2177 ipa_get_jf_ancestor_offset (jfunc
));
2179 else if (!src_plats
->aggs_by_ref
)
2180 ret
|= set_agg_lats_to_bottom (dest_plats
);
2182 ret
|= set_agg_lats_contain_variable (dest_plats
);
2184 else if (jfunc
->agg
.items
)
2186 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2187 struct ipcp_agg_lattice
**aglat
= &dest_plats
->aggs
;
2188 struct ipa_agg_jf_item
*item
;
2191 if (set_check_aggs_by_ref (dest_plats
, jfunc
->agg
.by_ref
))
2194 FOR_EACH_VEC_ELT (*jfunc
->agg
.items
, i
, item
)
2196 HOST_WIDE_INT val_size
;
2198 if (item
->offset
< 0)
2200 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
2201 val_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (item
->value
)));
2203 if (merge_agg_lats_step (dest_plats
, item
->offset
, val_size
,
2204 &aglat
, pre_existing
, &ret
))
2206 ret
|= (*aglat
)->add_value (item
->value
, cs
, NULL
, 0, 0);
2207 aglat
= &(*aglat
)->next
;
2209 else if (dest_plats
->aggs_bottom
)
2213 ret
|= set_chain_of_aglats_contains_variable (*aglat
);
2216 ret
|= set_agg_lats_contain_variable (dest_plats
);
2221 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2222 non-thunk) destination, the call passes through a thunk. */
2225 call_passes_through_thunk_p (cgraph_edge
*cs
)
2227 cgraph_node
*alias_or_thunk
= cs
->callee
;
2228 while (alias_or_thunk
->alias
)
2229 alias_or_thunk
= alias_or_thunk
->get_alias_target ();
2230 return alias_or_thunk
->thunk
.thunk_p
;
2233 /* Propagate constants from the caller to the callee of CS. INFO describes the
2237 propagate_constants_across_call (struct cgraph_edge
*cs
)
2239 struct ipa_node_params
*callee_info
;
2240 enum availability availability
;
2241 cgraph_node
*callee
;
2242 struct ipa_edge_args
*args
;
2244 int i
, args_count
, parms_count
;
2246 callee
= cs
->callee
->function_symbol (&availability
);
2247 if (!callee
->definition
)
2249 gcc_checking_assert (callee
->has_gimple_body_p ());
2250 callee_info
= IPA_NODE_REF (callee
);
2252 args
= IPA_EDGE_REF (cs
);
2253 args_count
= ipa_get_cs_argument_count (args
);
2254 parms_count
= ipa_get_param_count (callee_info
);
2255 if (parms_count
== 0)
2258 /* If this call goes through a thunk we must not propagate to the first (0th)
2259 parameter. However, we might need to uncover a thunk from below a series
2260 of aliases first. */
2261 if (call_passes_through_thunk_p (cs
))
2263 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2270 for (; (i
< args_count
) && (i
< parms_count
); i
++)
2272 struct ipa_jump_func
*jump_func
= ipa_get_ith_jump_func (args
, i
);
2273 struct ipcp_param_lattices
*dest_plats
;
2274 tree param_type
= ipa_get_type (callee_info
, i
);
2276 dest_plats
= ipa_get_parm_lattices (callee_info
, i
);
2277 if (availability
== AVAIL_INTERPOSABLE
)
2278 ret
|= set_all_contains_variable (dest_plats
);
2281 ret
|= propagate_scalar_across_jump_function (cs
, jump_func
,
2282 &dest_plats
->itself
,
2284 ret
|= propagate_context_across_jump_function (cs
, jump_func
, i
,
2285 &dest_plats
->ctxlat
);
2287 |= propagate_bits_across_jump_function (cs
, i
, jump_func
,
2288 &dest_plats
->bits_lattice
);
2289 ret
|= propagate_aggs_across_jump_function (cs
, jump_func
,
2291 if (opt_for_fn (callee
->decl
, flag_ipa_vrp
))
2292 ret
|= propagate_vr_across_jump_function (cs
, jump_func
,
2293 dest_plats
, param_type
);
2295 ret
|= dest_plats
->m_value_range
.set_to_bottom ();
2298 for (; i
< parms_count
; i
++)
2299 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
, i
));
2304 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2305 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2306 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2309 ipa_get_indirect_edge_target_1 (struct cgraph_edge
*ie
,
2310 vec
<tree
> known_csts
,
2311 vec
<ipa_polymorphic_call_context
> known_contexts
,
2312 vec
<ipa_agg_jump_function_p
> known_aggs
,
2313 struct ipa_agg_replacement_value
*agg_reps
,
2316 int param_index
= ie
->indirect_info
->param_index
;
2317 HOST_WIDE_INT anc_offset
;
2321 *speculative
= false;
2323 if (param_index
== -1
2324 || known_csts
.length () <= (unsigned int) param_index
)
2327 if (!ie
->indirect_info
->polymorphic
)
2331 if (ie
->indirect_info
->agg_contents
)
2334 if (agg_reps
&& ie
->indirect_info
->guaranteed_unmodified
)
2338 if (agg_reps
->index
== param_index
2339 && agg_reps
->offset
== ie
->indirect_info
->offset
2340 && agg_reps
->by_ref
== ie
->indirect_info
->by_ref
)
2342 t
= agg_reps
->value
;
2345 agg_reps
= agg_reps
->next
;
2350 struct ipa_agg_jump_function
*agg
;
2351 if (known_aggs
.length () > (unsigned int) param_index
)
2352 agg
= known_aggs
[param_index
];
2355 bool from_global_constant
;
2356 t
= ipa_find_agg_cst_for_param (agg
, known_csts
[param_index
],
2357 ie
->indirect_info
->offset
,
2358 ie
->indirect_info
->by_ref
,
2359 &from_global_constant
);
2361 && !from_global_constant
2362 && !ie
->indirect_info
->guaranteed_unmodified
)
2367 t
= known_csts
[param_index
];
2370 && TREE_CODE (t
) == ADDR_EXPR
2371 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
)
2372 return TREE_OPERAND (t
, 0);
2377 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
2380 gcc_assert (!ie
->indirect_info
->agg_contents
);
2381 anc_offset
= ie
->indirect_info
->offset
;
2385 /* Try to work out value of virtual table pointer value in replacements. */
2386 if (!t
&& agg_reps
&& !ie
->indirect_info
->by_ref
)
2390 if (agg_reps
->index
== param_index
2391 && agg_reps
->offset
== ie
->indirect_info
->offset
2392 && agg_reps
->by_ref
)
2394 t
= agg_reps
->value
;
2397 agg_reps
= agg_reps
->next
;
2401 /* Try to work out value of virtual table pointer value in known
2402 aggregate values. */
2403 if (!t
&& known_aggs
.length () > (unsigned int) param_index
2404 && !ie
->indirect_info
->by_ref
)
2406 struct ipa_agg_jump_function
*agg
;
2407 agg
= known_aggs
[param_index
];
2408 t
= ipa_find_agg_cst_for_param (agg
, known_csts
[param_index
],
2409 ie
->indirect_info
->offset
, true);
2412 /* If we found the virtual table pointer, lookup the target. */
2416 unsigned HOST_WIDE_INT offset
;
2417 if (vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
2420 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
2421 vtable
, offset
, &can_refer
);
2425 || (TREE_CODE (TREE_TYPE (target
)) == FUNCTION_TYPE
2426 && DECL_FUNCTION_CODE (target
) == BUILT_IN_UNREACHABLE
)
2427 || !possible_polymorphic_call_target_p
2428 (ie
, cgraph_node::get (target
)))
2430 /* Do not speculate builtin_unreachable, it is stupid! */
2431 if (ie
->indirect_info
->vptr_changed
)
2433 target
= ipa_impossible_devirt_target (ie
, target
);
2435 *speculative
= ie
->indirect_info
->vptr_changed
;
2442 /* Do we know the constant value of pointer? */
2444 t
= known_csts
[param_index
];
2446 gcc_checking_assert (!t
|| TREE_CODE (t
) != TREE_BINFO
);
2448 ipa_polymorphic_call_context context
;
2449 if (known_contexts
.length () > (unsigned int) param_index
)
2451 context
= known_contexts
[param_index
];
2452 context
.offset_by (anc_offset
);
2453 if (ie
->indirect_info
->vptr_changed
)
2454 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
2455 ie
->indirect_info
->otr_type
);
2458 ipa_polymorphic_call_context ctx2
= ipa_polymorphic_call_context
2459 (t
, ie
->indirect_info
->otr_type
, anc_offset
);
2460 if (!ctx2
.useless_p ())
2461 context
.combine_with (ctx2
, ie
->indirect_info
->otr_type
);
2466 context
= ipa_polymorphic_call_context (t
, ie
->indirect_info
->otr_type
,
2468 if (ie
->indirect_info
->vptr_changed
)
2469 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
2470 ie
->indirect_info
->otr_type
);
2475 vec
<cgraph_node
*>targets
;
2478 targets
= possible_polymorphic_call_targets
2479 (ie
->indirect_info
->otr_type
,
2480 ie
->indirect_info
->otr_token
,
2482 if (!final
|| targets
.length () > 1)
2484 struct cgraph_node
*node
;
2487 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
2488 || ie
->speculative
|| !ie
->maybe_hot_p ())
2490 node
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
2491 ie
->indirect_info
->otr_token
,
2495 *speculative
= true;
2496 target
= node
->decl
;
2503 *speculative
= false;
2504 if (targets
.length () == 1)
2505 target
= targets
[0]->decl
;
2507 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
2510 if (target
&& !possible_polymorphic_call_target_p (ie
,
2511 cgraph_node::get (target
)))
2515 target
= ipa_impossible_devirt_target (ie
, target
);
2522 /* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
2523 KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
2524 return the destination. */
2527 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
2528 vec
<tree
> known_csts
,
2529 vec
<ipa_polymorphic_call_context
> known_contexts
,
2530 vec
<ipa_agg_jump_function_p
> known_aggs
,
2533 return ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
2534 known_aggs
, NULL
, speculative
);
2537 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
2538 and KNOWN_CONTEXTS. */
2541 devirtualization_time_bonus (struct cgraph_node
*node
,
2542 vec
<tree
> known_csts
,
2543 vec
<ipa_polymorphic_call_context
> known_contexts
,
2544 vec
<ipa_agg_jump_function_p
> known_aggs
)
2546 struct cgraph_edge
*ie
;
2549 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
2551 struct cgraph_node
*callee
;
2552 struct ipa_fn_summary
*isummary
;
2553 enum availability avail
;
2557 target
= ipa_get_indirect_edge_target (ie
, known_csts
, known_contexts
,
2558 known_aggs
, &speculative
);
2562 /* Only bare minimum benefit for clearly un-inlineable targets. */
2564 callee
= cgraph_node::get (target
);
2565 if (!callee
|| !callee
->definition
)
2567 callee
= callee
->function_symbol (&avail
);
2568 if (avail
< AVAIL_AVAILABLE
)
2570 isummary
= ipa_fn_summaries
->get (callee
);
2571 if (!isummary
->inlinable
)
2574 /* FIXME: The values below need re-considering and perhaps also
2575 integrating into the cost metrics, at lest in some very basic way. */
2576 if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
/ 4)
2577 res
+= 31 / ((int)speculative
+ 1);
2578 else if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
/ 2)
2579 res
+= 15 / ((int)speculative
+ 1);
2580 else if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
2581 || DECL_DECLARED_INLINE_P (callee
->decl
))
2582 res
+= 7 / ((int)speculative
+ 1);
2588 /* Return time bonus incurred because of HINTS. */
2591 hint_time_bonus (ipa_hints hints
)
2594 if (hints
& (INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride
))
2595 result
+= PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS
);
2596 if (hints
& INLINE_HINT_array_index
)
2597 result
+= PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS
);
2601 /* If there is a reason to penalize the function described by INFO in the
2602 cloning goodness evaluation, do so. */
2604 static inline int64_t
2605 incorporate_penalties (ipa_node_params
*info
, int64_t evaluation
)
2607 if (info
->node_within_scc
)
2608 evaluation
= (evaluation
2609 * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY
))) / 100;
2611 if (info
->node_calling_single_call
)
2612 evaluation
= (evaluation
2613 * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY
)))
2619 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
2620 and SIZE_COST and with the sum of frequencies of incoming edges to the
2621 potential new clone in FREQUENCIES. */
2624 good_cloning_opportunity_p (struct cgraph_node
*node
, int time_benefit
,
2625 int freq_sum
, profile_count count_sum
, int size_cost
)
2627 if (time_benefit
== 0
2628 || !opt_for_fn (node
->decl
, flag_ipa_cp_clone
)
2629 || node
->optimize_for_size_p ())
2632 gcc_assert (size_cost
> 0);
2634 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2635 if (max_count
> profile_count::zero ())
2637 int factor
= RDIV (count_sum
.probability_in
2638 (max_count
).to_reg_br_prob_base ()
2639 * 1000, REG_BR_PROB_BASE
);
2640 int64_t evaluation
= (((int64_t) time_benefit
* factor
)
2642 evaluation
= incorporate_penalties (info
, evaluation
);
2644 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2646 fprintf (dump_file
, " good_cloning_opportunity_p (time: %i, "
2647 "size: %i, count_sum: ", time_benefit
, size_cost
);
2648 count_sum
.dump (dump_file
);
2649 fprintf (dump_file
, "%s%s) -> evaluation: " "%" PRId64
2650 ", threshold: %i\n",
2651 info
->node_within_scc
? ", scc" : "",
2652 info
->node_calling_single_call
? ", single_call" : "",
2653 evaluation
, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
));
2656 return evaluation
>= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
);
2660 int64_t evaluation
= (((int64_t) time_benefit
* freq_sum
)
2662 evaluation
= incorporate_penalties (info
, evaluation
);
2664 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2665 fprintf (dump_file
, " good_cloning_opportunity_p (time: %i, "
2666 "size: %i, freq_sum: %i%s%s) -> evaluation: "
2667 "%" PRId64
", threshold: %i\n",
2668 time_benefit
, size_cost
, freq_sum
,
2669 info
->node_within_scc
? ", scc" : "",
2670 info
->node_calling_single_call
? ", single_call" : "",
2671 evaluation
, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
));
2673 return evaluation
>= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
);
2677 /* Return all context independent values from aggregate lattices in PLATS in a
2678 vector. Return NULL if there are none. */
2680 static vec
<ipa_agg_jf_item
, va_gc
> *
2681 context_independent_aggregate_values (struct ipcp_param_lattices
*plats
)
2683 vec
<ipa_agg_jf_item
, va_gc
> *res
= NULL
;
2685 if (plats
->aggs_bottom
2686 || plats
->aggs_contain_variable
2687 || plats
->aggs_count
== 0)
2690 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
;
2692 aglat
= aglat
->next
)
2693 if (aglat
->is_single_const ())
2695 struct ipa_agg_jf_item item
;
2696 item
.offset
= aglat
->offset
;
2697 item
.value
= aglat
->values
->value
;
2698 vec_safe_push (res
, item
);
2703 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
2704 populate them with values of parameters that are known independent of the
2705 context. INFO describes the function. If REMOVABLE_PARAMS_COST is
2706 non-NULL, the movement cost of all removable parameters will be stored in
2710 gather_context_independent_values (struct ipa_node_params
*info
,
2711 vec
<tree
> *known_csts
,
2712 vec
<ipa_polymorphic_call_context
>
2714 vec
<ipa_agg_jump_function
> *known_aggs
,
2715 int *removable_params_cost
)
2717 int i
, count
= ipa_get_param_count (info
);
2720 known_csts
->create (0);
2721 known_contexts
->create (0);
2722 known_csts
->safe_grow_cleared (count
);
2723 known_contexts
->safe_grow_cleared (count
);
2726 known_aggs
->create (0);
2727 known_aggs
->safe_grow_cleared (count
);
2730 if (removable_params_cost
)
2731 *removable_params_cost
= 0;
2733 for (i
= 0; i
< count
; i
++)
2735 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2736 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
2738 if (lat
->is_single_const ())
2740 ipcp_value
<tree
> *val
= lat
->values
;
2741 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
2742 (*known_csts
)[i
] = val
->value
;
2743 if (removable_params_cost
)
2744 *removable_params_cost
2745 += estimate_move_cost (TREE_TYPE (val
->value
), false);
2748 else if (removable_params_cost
2749 && !ipa_is_param_used (info
, i
))
2750 *removable_params_cost
2751 += ipa_get_param_move_cost (info
, i
);
2753 if (!ipa_is_param_used (info
, i
))
2756 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
2757 /* Do not account known context as reason for cloning. We can see
2758 if it permits devirtualization. */
2759 if (ctxlat
->is_single_const ())
2760 (*known_contexts
)[i
] = ctxlat
->values
->value
;
2764 vec
<ipa_agg_jf_item
, va_gc
> *agg_items
;
2765 struct ipa_agg_jump_function
*ajf
;
2767 agg_items
= context_independent_aggregate_values (plats
);
2768 ajf
= &(*known_aggs
)[i
];
2769 ajf
->items
= agg_items
;
2770 ajf
->by_ref
= plats
->aggs_by_ref
;
2771 ret
|= agg_items
!= NULL
;
2778 /* The current interface in ipa-inline-analysis requires a pointer vector.
2781 FIXME: That interface should be re-worked, this is slightly silly. Still,
2782 I'd like to discuss how to change it first and this demonstrates the
2785 static vec
<ipa_agg_jump_function_p
>
2786 agg_jmp_p_vec_for_t_vec (vec
<ipa_agg_jump_function
> known_aggs
)
2788 vec
<ipa_agg_jump_function_p
> ret
;
2789 struct ipa_agg_jump_function
*ajf
;
2792 ret
.create (known_aggs
.length ());
2793 FOR_EACH_VEC_ELT (known_aggs
, i
, ajf
)
2794 ret
.quick_push (ajf
);
2798 /* Perform time and size measurement of NODE with the context given in
2799 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
2800 given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
2801 all context-independent removable parameters and EST_MOVE_COST of estimated
2802 movement of the considered parameter and store it into VAL. */
2805 perform_estimation_of_a_value (cgraph_node
*node
, vec
<tree
> known_csts
,
2806 vec
<ipa_polymorphic_call_context
> known_contexts
,
2807 vec
<ipa_agg_jump_function_p
> known_aggs_ptrs
,
2808 int removable_params_cost
,
2809 int est_move_cost
, ipcp_value_base
*val
)
2811 int size
, time_benefit
;
2812 sreal time
, base_time
;
2815 estimate_ipcp_clone_size_and_time (node
, known_csts
, known_contexts
,
2816 known_aggs_ptrs
, &size
, &time
,
2817 &base_time
, &hints
);
2819 if (base_time
> 65535)
2821 time_benefit
= base_time
.to_int ()
2822 + devirtualization_time_bonus (node
, known_csts
, known_contexts
,
2824 + hint_time_bonus (hints
)
2825 + removable_params_cost
+ est_move_cost
;
2827 gcc_checking_assert (size
>=0);
2828 /* The inliner-heuristics based estimates may think that in certain
2829 contexts some functions do not have any size at all but we want
2830 all specializations to have at least a tiny cost, not least not to
2835 val
->local_time_benefit
= time_benefit
;
2836 val
->local_size_cost
= size
;
2839 /* Iterate over known values of parameters of NODE and estimate the local
2840 effects in terms of time and size they have. */
2843 estimate_local_effects (struct cgraph_node
*node
)
2845 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2846 int i
, count
= ipa_get_param_count (info
);
2847 vec
<tree
> known_csts
;
2848 vec
<ipa_polymorphic_call_context
> known_contexts
;
2849 vec
<ipa_agg_jump_function
> known_aggs
;
2850 vec
<ipa_agg_jump_function_p
> known_aggs_ptrs
;
2852 int removable_params_cost
;
2854 if (!count
|| !ipcp_versionable_function_p (node
))
2857 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2858 fprintf (dump_file
, "\nEstimating effects for %s.\n", node
->dump_name ());
2860 always_const
= gather_context_independent_values (info
, &known_csts
,
2861 &known_contexts
, &known_aggs
,
2862 &removable_params_cost
);
2863 known_aggs_ptrs
= agg_jmp_p_vec_for_t_vec (known_aggs
);
2864 int devirt_bonus
= devirtualization_time_bonus (node
, known_csts
,
2865 known_contexts
, known_aggs_ptrs
);
2866 if (always_const
|| devirt_bonus
2867 || (removable_params_cost
&& node
->local
.can_change_signature
))
2869 struct caller_statistics stats
;
2871 sreal time
, base_time
;
2874 init_caller_stats (&stats
);
2875 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
2877 estimate_ipcp_clone_size_and_time (node
, known_csts
, known_contexts
,
2878 known_aggs_ptrs
, &size
, &time
,
2879 &base_time
, &hints
);
2880 time
-= devirt_bonus
;
2881 time
-= hint_time_bonus (hints
);
2882 time
-= removable_params_cost
;
2883 size
-= stats
.n_calls
* removable_params_cost
;
2886 fprintf (dump_file
, " - context independent values, size: %i, "
2887 "time_benefit: %f\n", size
, (base_time
- time
).to_double ());
2889 if (size
<= 0 || node
->local
.local
)
2891 info
->do_clone_for_all_contexts
= true;
2894 fprintf (dump_file
, " Decided to specialize for all "
2895 "known contexts, code not going to grow.\n");
2897 else if (good_cloning_opportunity_p (node
,
2898 MIN ((base_time
- time
).to_int (),
2900 stats
.freq_sum
, stats
.count_sum
,
2903 if (size
+ overall_size
<= max_new_size
)
2905 info
->do_clone_for_all_contexts
= true;
2906 overall_size
+= size
;
2909 fprintf (dump_file
, " Decided to specialize for all "
2910 "known contexts, growth deemed beneficial.\n");
2912 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2913 fprintf (dump_file
, " Not cloning for all contexts because "
2914 "max_new_size would be reached with %li.\n",
2915 size
+ overall_size
);
2917 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2918 fprintf (dump_file
, " Not cloning for all contexts because "
2919 "!good_cloning_opportunity_p.\n");
2923 for (i
= 0; i
< count
; i
++)
2925 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2926 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
2927 ipcp_value
<tree
> *val
;
2934 for (val
= lat
->values
; val
; val
= val
->next
)
2936 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
2937 known_csts
[i
] = val
->value
;
2939 int emc
= estimate_move_cost (TREE_TYPE (val
->value
), true);
2940 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2942 removable_params_cost
, emc
, val
);
2944 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2946 fprintf (dump_file
, " - estimates for value ");
2947 print_ipcp_constant_value (dump_file
, val
->value
);
2948 fprintf (dump_file
, " for ");
2949 ipa_dump_param (dump_file
, info
, i
);
2950 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2951 val
->local_time_benefit
, val
->local_size_cost
);
2954 known_csts
[i
] = NULL_TREE
;
2957 for (i
= 0; i
< count
; i
++)
2959 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2961 if (!plats
->virt_call
)
2964 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
2965 ipcp_value
<ipa_polymorphic_call_context
> *val
;
2969 || !known_contexts
[i
].useless_p ())
2972 for (val
= ctxlat
->values
; val
; val
= val
->next
)
2974 known_contexts
[i
] = val
->value
;
2975 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2977 removable_params_cost
, 0, val
);
2979 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2981 fprintf (dump_file
, " - estimates for polymorphic context ");
2982 print_ipcp_constant_value (dump_file
, val
->value
);
2983 fprintf (dump_file
, " for ");
2984 ipa_dump_param (dump_file
, info
, i
);
2985 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2986 val
->local_time_benefit
, val
->local_size_cost
);
2989 known_contexts
[i
] = ipa_polymorphic_call_context ();
2992 for (i
= 0; i
< count
; i
++)
2994 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2995 struct ipa_agg_jump_function
*ajf
;
2996 struct ipcp_agg_lattice
*aglat
;
2998 if (plats
->aggs_bottom
|| !plats
->aggs
)
3001 ajf
= &known_aggs
[i
];
3002 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3004 ipcp_value
<tree
> *val
;
3005 if (aglat
->bottom
|| !aglat
->values
3006 /* If the following is true, the one value is in known_aggs. */
3007 || (!plats
->aggs_contain_variable
3008 && aglat
->is_single_const ()))
3011 for (val
= aglat
->values
; val
; val
= val
->next
)
3013 struct ipa_agg_jf_item item
;
3015 item
.offset
= aglat
->offset
;
3016 item
.value
= val
->value
;
3017 vec_safe_push (ajf
->items
, item
);
3019 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
3021 removable_params_cost
, 0, val
);
3023 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3025 fprintf (dump_file
, " - estimates for value ");
3026 print_ipcp_constant_value (dump_file
, val
->value
);
3027 fprintf (dump_file
, " for ");
3028 ipa_dump_param (dump_file
, info
, i
);
3029 fprintf (dump_file
, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3030 "]: time_benefit: %i, size: %i\n",
3031 plats
->aggs_by_ref
? "ref " : "",
3033 val
->local_time_benefit
, val
->local_size_cost
);
3041 for (i
= 0; i
< count
; i
++)
3042 vec_free (known_aggs
[i
].items
);
3044 known_csts
.release ();
3045 known_contexts
.release ();
3046 known_aggs
.release ();
3047 known_aggs_ptrs
.release ();
3051 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3052 topological sort of values. */
3054 template <typename valtype
>
3056 value_topo_info
<valtype
>::add_val (ipcp_value
<valtype
> *cur_val
)
3058 ipcp_value_source
<valtype
> *src
;
3064 cur_val
->dfs
= dfs_counter
;
3065 cur_val
->low_link
= dfs_counter
;
3067 cur_val
->topo_next
= stack
;
3069 cur_val
->on_stack
= true;
3071 for (src
= cur_val
->sources
; src
; src
= src
->next
)
3074 if (src
->val
->dfs
== 0)
3077 if (src
->val
->low_link
< cur_val
->low_link
)
3078 cur_val
->low_link
= src
->val
->low_link
;
3080 else if (src
->val
->on_stack
3081 && src
->val
->dfs
< cur_val
->low_link
)
3082 cur_val
->low_link
= src
->val
->dfs
;
3085 if (cur_val
->dfs
== cur_val
->low_link
)
3087 ipcp_value
<valtype
> *v
, *scc_list
= NULL
;
3092 stack
= v
->topo_next
;
3093 v
->on_stack
= false;
3095 v
->scc_next
= scc_list
;
3098 while (v
!= cur_val
);
3100 cur_val
->topo_next
= values_topo
;
3101 values_topo
= cur_val
;
3105 /* Add all values in lattices associated with NODE to the topological sort if
3106 they are not there yet. */
3109 add_all_node_vals_to_toposort (cgraph_node
*node
, ipa_topo_info
*topo
)
3111 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3112 int i
, count
= ipa_get_param_count (info
);
3114 for (i
= 0; i
< count
; i
++)
3116 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3117 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3118 struct ipcp_agg_lattice
*aglat
;
3122 ipcp_value
<tree
> *val
;
3123 for (val
= lat
->values
; val
; val
= val
->next
)
3124 topo
->constants
.add_val (val
);
3127 if (!plats
->aggs_bottom
)
3128 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3131 ipcp_value
<tree
> *val
;
3132 for (val
= aglat
->values
; val
; val
= val
->next
)
3133 topo
->constants
.add_val (val
);
3136 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3137 if (!ctxlat
->bottom
)
3139 ipcp_value
<ipa_polymorphic_call_context
> *ctxval
;
3140 for (ctxval
= ctxlat
->values
; ctxval
; ctxval
= ctxval
->next
)
3141 topo
->contexts
.add_val (ctxval
);
3146 /* One pass of constants propagation along the call graph edges, from callers
3147 to callees (requires topological ordering in TOPO), iterate over strongly
3148 connected components. */
3151 propagate_constants_topo (struct ipa_topo_info
*topo
)
3155 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
3158 struct cgraph_node
*v
, *node
= topo
->order
[i
];
3159 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
3161 /* First, iteratively propagate within the strongly connected component
3162 until all lattices stabilize. */
3163 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3164 if (v
->has_gimple_body_p ())
3165 push_node_to_stack (topo
, v
);
3167 v
= pop_node_from_stack (topo
);
3170 struct cgraph_edge
*cs
;
3172 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3173 if (ipa_edge_within_scc (cs
))
3175 IPA_NODE_REF (v
)->node_within_scc
= true;
3176 if (propagate_constants_across_call (cs
))
3177 push_node_to_stack (topo
, cs
->callee
->function_symbol ());
3179 v
= pop_node_from_stack (topo
);
3182 /* Afterwards, propagate along edges leading out of the SCC, calculates
3183 the local effects of the discovered constants and all valid values to
3184 their topological sort. */
3185 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3186 if (v
->has_gimple_body_p ())
3188 struct cgraph_edge
*cs
;
3190 estimate_local_effects (v
);
3191 add_all_node_vals_to_toposort (v
, topo
);
3192 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3193 if (!ipa_edge_within_scc (cs
))
3194 propagate_constants_across_call (cs
);
3196 cycle_nodes
.release ();
3201 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3202 the bigger one if otherwise. */
3205 safe_add (int a
, int b
)
3207 if (a
> INT_MAX
/2 || b
> INT_MAX
/2)
3208 return a
> b
? a
: b
;
3214 /* Propagate the estimated effects of individual values along the topological
3215 from the dependent values to those they depend on. */
3217 template <typename valtype
>
3219 value_topo_info
<valtype
>::propagate_effects ()
3221 ipcp_value
<valtype
> *base
;
3223 for (base
= values_topo
; base
; base
= base
->topo_next
)
3225 ipcp_value_source
<valtype
> *src
;
3226 ipcp_value
<valtype
> *val
;
3227 int time
= 0, size
= 0;
3229 for (val
= base
; val
; val
= val
->scc_next
)
3231 time
= safe_add (time
,
3232 val
->local_time_benefit
+ val
->prop_time_benefit
);
3233 size
= safe_add (size
, val
->local_size_cost
+ val
->prop_size_cost
);
3236 for (val
= base
; val
; val
= val
->scc_next
)
3237 for (src
= val
->sources
; src
; src
= src
->next
)
3239 && src
->cs
->maybe_hot_p ())
3241 src
->val
->prop_time_benefit
= safe_add (time
,
3242 src
->val
->prop_time_benefit
);
3243 src
->val
->prop_size_cost
= safe_add (size
,
3244 src
->val
->prop_size_cost
);
3250 /* Propagate constants, polymorphic contexts and their effects from the
3251 summaries interprocedurally. */
3254 ipcp_propagate_stage (struct ipa_topo_info
*topo
)
3256 struct cgraph_node
*node
;
3259 fprintf (dump_file
, "\n Propagating constants:\n\n");
3261 max_count
= profile_count::uninitialized ();
3263 FOR_EACH_DEFINED_FUNCTION (node
)
3265 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3267 determine_versionability (node
, info
);
3268 if (node
->has_gimple_body_p ())
3270 info
->lattices
= XCNEWVEC (struct ipcp_param_lattices
,
3271 ipa_get_param_count (info
));
3272 initialize_node_lattices (node
);
3274 ipa_fn_summary
*s
= ipa_fn_summaries
->get (node
);
3275 if (node
->definition
&& !node
->alias
&& s
!= NULL
)
3276 overall_size
+= s
->self_size
;
3277 max_count
= max_count
.max (node
->count
.ipa ());
3280 max_new_size
= overall_size
;
3281 if (max_new_size
< PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
))
3282 max_new_size
= PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
);
3283 max_new_size
+= max_new_size
* PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH
) / 100 + 1;
3286 fprintf (dump_file
, "\noverall_size: %li, max_new_size: %li\n",
3287 overall_size
, max_new_size
);
3289 propagate_constants_topo (topo
);
3291 ipcp_verify_propagated_values ();
3292 topo
->constants
.propagate_effects ();
3293 topo
->contexts
.propagate_effects ();
3297 fprintf (dump_file
, "\nIPA lattices after all propagation:\n");
3298 print_all_lattices (dump_file
, (dump_flags
& TDF_DETAILS
), true);
3302 /* Discover newly direct outgoing edges from NODE which is a new clone with
3303 known KNOWN_CSTS and make them direct. */
3306 ipcp_discover_new_direct_edges (struct cgraph_node
*node
,
3307 vec
<tree
> known_csts
,
3308 vec
<ipa_polymorphic_call_context
>
3310 struct ipa_agg_replacement_value
*aggvals
)
3312 struct cgraph_edge
*ie
, *next_ie
;
3315 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3320 next_ie
= ie
->next_callee
;
3321 target
= ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
3322 vNULL
, aggvals
, &speculative
);
3325 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3326 bool polymorphic
= ie
->indirect_info
->polymorphic
;
3327 int param_index
= ie
->indirect_info
->param_index
;
3328 struct cgraph_edge
*cs
= ipa_make_edge_direct_to_target (ie
, target
,
3332 if (cs
&& !agg_contents
&& !polymorphic
)
3334 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3335 int c
= ipa_get_controlled_uses (info
, param_index
);
3336 if (c
!= IPA_UNDESCRIBED_USE
)
3338 struct ipa_ref
*to_del
;
3341 ipa_set_controlled_uses (info
, param_index
, c
);
3342 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3343 fprintf (dump_file
, " controlled uses count of param "
3344 "%i bumped down to %i\n", param_index
, c
);
3346 && (to_del
= node
->find_reference (cs
->callee
, NULL
, 0)))
3348 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3349 fprintf (dump_file
, " and even removing its "
3350 "cloning-created reference\n");
3351 to_del
->remove_reference ();
3357 /* Turning calls to direct calls will improve overall summary. */
3359 ipa_update_overall_fn_summary (node
);
3362 class edge_clone_summary
;
3363 static call_summary
<edge_clone_summary
*> *edge_clone_summaries
= NULL
;
3365 /* Edge clone summary. */
3367 struct edge_clone_summary
3369 /* Default constructor. */
3370 edge_clone_summary (): prev_clone (NULL
), next_clone (NULL
) {}
3372 /* Default destructor. */
3373 ~edge_clone_summary ()
3376 edge_clone_summaries
->get (prev_clone
)->next_clone
= next_clone
;
3378 edge_clone_summaries
->get (next_clone
)->prev_clone
= prev_clone
;
3381 cgraph_edge
*prev_clone
;
3382 cgraph_edge
*next_clone
;
3385 class edge_clone_summary_t
:
3386 public call_summary
<edge_clone_summary
*>
3389 edge_clone_summary_t (symbol_table
*symtab
):
3390 call_summary
<edge_clone_summary
*> (symtab
)
3392 m_initialize_when_cloning
= true;
3395 virtual void duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
3396 edge_clone_summary
*src_data
,
3397 edge_clone_summary
*dst_data
);
3400 /* Edge duplication hook. */
3403 edge_clone_summary_t::duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
3404 edge_clone_summary
*src_data
,
3405 edge_clone_summary
*dst_data
)
3407 if (src_data
->next_clone
)
3408 edge_clone_summaries
->get (src_data
->next_clone
)->prev_clone
= dst_edge
;
3409 dst_data
->prev_clone
= src_edge
;
3410 dst_data
->next_clone
= src_data
->next_clone
;
3411 src_data
->next_clone
= dst_edge
;
3414 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3415 parameter with the given INDEX. */
3418 get_clone_agg_value (struct cgraph_node
*node
, HOST_WIDE_INT offset
,
3421 struct ipa_agg_replacement_value
*aggval
;
3423 aggval
= ipa_get_agg_replacements_for_node (node
);
3426 if (aggval
->offset
== offset
3427 && aggval
->index
== index
)
3428 return aggval
->value
;
3429 aggval
= aggval
->next
;
3434 /* Return true is NODE is DEST or its clone for all contexts. */
3437 same_node_or_its_all_contexts_clone_p (cgraph_node
*node
, cgraph_node
*dest
)
3442 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3443 return info
->is_all_contexts_clone
&& info
->ipcp_orig_node
== dest
;
3446 /* Return true if edge CS does bring about the value described by SRC to
3447 DEST_VAL of node DEST or its clone for all contexts. */
3450 cgraph_edge_brings_value_p (cgraph_edge
*cs
, ipcp_value_source
<tree
> *src
,
3451 cgraph_node
*dest
, ipcp_value
<tree
> *dest_val
)
3453 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3454 enum availability availability
;
3455 cgraph_node
*real_dest
= cs
->callee
->function_symbol (&availability
);
3457 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3458 || availability
<= AVAIL_INTERPOSABLE
3459 || caller_info
->node_dead
)
3465 if (caller_info
->ipcp_orig_node
)
3468 if (src
->offset
== -1)
3469 t
= caller_info
->known_csts
[src
->index
];
3471 t
= get_clone_agg_value (cs
->caller
, src
->offset
, src
->index
);
3472 return (t
!= NULL_TREE
3473 && values_equal_for_ipcp_p (src
->val
->value
, t
));
3477 /* At the moment we do not propagate over arithmetic jump functions in
3478 SCCs, so it is safe to detect self-feeding recursive calls in this
3480 if (src
->val
== dest_val
)
3483 struct ipcp_agg_lattice
*aglat
;
3484 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3486 if (src
->offset
== -1)
3487 return (plats
->itself
.is_single_const ()
3488 && values_equal_for_ipcp_p (src
->val
->value
,
3489 plats
->itself
.values
->value
));
3492 if (plats
->aggs_bottom
|| plats
->aggs_contain_variable
)
3494 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3495 if (aglat
->offset
== src
->offset
)
3496 return (aglat
->is_single_const ()
3497 && values_equal_for_ipcp_p (src
->val
->value
,
3498 aglat
->values
->value
));
3504 /* Return true if edge CS does bring about the value described by SRC to
3505 DST_VAL of node DEST or its clone for all contexts. */
3508 cgraph_edge_brings_value_p (cgraph_edge
*cs
,
3509 ipcp_value_source
<ipa_polymorphic_call_context
> *src
,
3511 ipcp_value
<ipa_polymorphic_call_context
> *)
3513 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3514 cgraph_node
*real_dest
= cs
->callee
->function_symbol ();
3516 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3517 || caller_info
->node_dead
)
3522 if (caller_info
->ipcp_orig_node
)
3523 return (caller_info
->known_contexts
.length () > (unsigned) src
->index
)
3524 && values_equal_for_ipcp_p (src
->val
->value
,
3525 caller_info
->known_contexts
[src
->index
]);
3527 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3529 return plats
->ctxlat
.is_single_const ()
3530 && values_equal_for_ipcp_p (src
->val
->value
,
3531 plats
->ctxlat
.values
->value
);
3534 /* Get the next clone in the linked list of clones of an edge. */
3536 static inline struct cgraph_edge
*
3537 get_next_cgraph_edge_clone (struct cgraph_edge
*cs
)
3539 edge_clone_summary
*s
= edge_clone_summaries
->get (cs
);
3540 return s
!= NULL
? s
->next_clone
: NULL
;
3543 /* Given VAL that is intended for DEST, iterate over all its sources and if any
3544 of them is viable and hot, return true. In that case, for those that still
3545 hold, add their edge frequency and their number into *FREQUENCY and
3546 *CALLER_COUNT respectively. */
3548 template <typename valtype
>
3550 get_info_about_necessary_edges (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3552 profile_count
*count_sum
, int *caller_count
)
3554 ipcp_value_source
<valtype
> *src
;
3555 int freq
= 0, count
= 0;
3556 profile_count cnt
= profile_count::zero ();
3558 bool non_self_recursive
= false;
3560 for (src
= val
->sources
; src
; src
= src
->next
)
3562 struct cgraph_edge
*cs
= src
->cs
;
3565 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
3568 freq
+= cs
->frequency ();
3569 if (cs
->count
.ipa ().initialized_p ())
3570 cnt
+= cs
->count
.ipa ();
3571 hot
|= cs
->maybe_hot_p ();
3572 if (cs
->caller
!= dest
)
3573 non_self_recursive
= true;
3575 cs
= get_next_cgraph_edge_clone (cs
);
3579 /* If the only edges bringing a value are self-recursive ones, do not bother
3581 if (!non_self_recursive
)
3586 *caller_count
= count
;
3590 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
3591 is assumed their number is known and equal to CALLER_COUNT. */
3593 template <typename valtype
>
3594 static vec
<cgraph_edge
*>
3595 gather_edges_for_value (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3598 ipcp_value_source
<valtype
> *src
;
3599 vec
<cgraph_edge
*> ret
;
3601 ret
.create (caller_count
);
3602 for (src
= val
->sources
; src
; src
= src
->next
)
3604 struct cgraph_edge
*cs
= src
->cs
;
3607 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
3608 ret
.quick_push (cs
);
3609 cs
= get_next_cgraph_edge_clone (cs
);
3616 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3617 Return it or NULL if for some reason it cannot be created. */
3619 static struct ipa_replace_map
*
3620 get_replacement_map (struct ipa_node_params
*info
, tree value
, int parm_num
)
3622 struct ipa_replace_map
*replace_map
;
3625 replace_map
= ggc_alloc
<ipa_replace_map
> ();
3628 fprintf (dump_file
, " replacing ");
3629 ipa_dump_param (dump_file
, info
, parm_num
);
3631 fprintf (dump_file
, " with const ");
3632 print_generic_expr (dump_file
, value
);
3633 fprintf (dump_file
, "\n");
3635 replace_map
->old_tree
= NULL
;
3636 replace_map
->parm_num
= parm_num
;
3637 replace_map
->new_tree
= value
;
3638 replace_map
->replace_p
= true;
3639 replace_map
->ref_p
= false;
3644 /* Dump new profiling counts */
3647 dump_profile_updates (struct cgraph_node
*orig_node
,
3648 struct cgraph_node
*new_node
)
3650 struct cgraph_edge
*cs
;
3652 fprintf (dump_file
, " setting count of the specialized node to ");
3653 new_node
->count
.dump (dump_file
);
3654 fprintf (dump_file
, "\n");
3655 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3657 fprintf (dump_file
, " edge to %s has count ",
3658 cs
->callee
->name ());
3659 cs
->count
.dump (dump_file
);
3660 fprintf (dump_file
, "\n");
3663 fprintf (dump_file
, " setting count of the original node to ");
3664 orig_node
->count
.dump (dump_file
);
3665 fprintf (dump_file
, "\n");
3666 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3668 fprintf (dump_file
, " edge to %s is left with ",
3669 cs
->callee
->name ());
3670 cs
->count
.dump (dump_file
);
3671 fprintf (dump_file
, "\n");
3675 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
3676 their profile information to reflect this. */
3679 update_profiling_info (struct cgraph_node
*orig_node
,
3680 struct cgraph_node
*new_node
)
3682 struct cgraph_edge
*cs
;
3683 struct caller_statistics stats
;
3684 profile_count new_sum
, orig_sum
;
3685 profile_count remainder
, orig_node_count
= orig_node
->count
;
3687 if (!(orig_node_count
.ipa () > profile_count::zero ()))
3690 init_caller_stats (&stats
);
3691 orig_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3693 orig_sum
= stats
.count_sum
;
3694 init_caller_stats (&stats
);
3695 new_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3697 new_sum
= stats
.count_sum
;
3699 if (orig_node_count
< orig_sum
+ new_sum
)
3703 fprintf (dump_file
, " Problem: node %s has too low count ",
3704 orig_node
->dump_name ());
3705 orig_node_count
.dump (dump_file
);
3706 fprintf (dump_file
, "while the sum of incoming count is ");
3707 (orig_sum
+ new_sum
).dump (dump_file
);
3708 fprintf (dump_file
, "\n");
3711 orig_node_count
= (orig_sum
+ new_sum
).apply_scale (12, 10);
3714 fprintf (dump_file
, " proceeding by pretending it was ");
3715 orig_node_count
.dump (dump_file
);
3716 fprintf (dump_file
, "\n");
3720 remainder
= orig_node_count
.combine_with_ipa_count (orig_node_count
.ipa ()
3722 new_sum
= orig_node_count
.combine_with_ipa_count (new_sum
);
3723 orig_node
->count
= remainder
;
3725 profile_count::adjust_for_ipa_scaling (&new_sum
, &orig_node_count
);
3726 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3727 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_node_count
);
3729 profile_count::adjust_for_ipa_scaling (&remainder
, &orig_node_count
);
3730 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3731 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
3734 dump_profile_updates (orig_node
, new_node
);
3737 /* Update the respective profile of specialized NEW_NODE and the original
3738 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
3739 have been redirected to the specialized version. */
3742 update_specialized_profile (struct cgraph_node
*new_node
,
3743 struct cgraph_node
*orig_node
,
3744 profile_count redirected_sum
)
3746 struct cgraph_edge
*cs
;
3747 profile_count new_node_count
, orig_node_count
= orig_node
->count
;
3751 fprintf (dump_file
, " the sum of counts of redirected edges is ");
3752 redirected_sum
.dump (dump_file
);
3753 fprintf (dump_file
, "\n");
3755 if (!(orig_node_count
> profile_count::zero ()))
3758 gcc_assert (orig_node_count
>= redirected_sum
);
3760 new_node_count
= new_node
->count
;
3761 new_node
->count
+= redirected_sum
;
3762 orig_node
->count
-= redirected_sum
;
3764 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3765 cs
->count
+= cs
->count
.apply_scale (redirected_sum
, new_node_count
);
3767 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3769 profile_count dec
= cs
->count
.apply_scale (redirected_sum
,
3775 dump_profile_updates (orig_node
, new_node
);
3778 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3779 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3780 redirect all edges in CALLERS to it. */
3782 static struct cgraph_node
*
3783 create_specialized_node (struct cgraph_node
*node
,
3784 vec
<tree
> known_csts
,
3785 vec
<ipa_polymorphic_call_context
> known_contexts
,
3786 struct ipa_agg_replacement_value
*aggvals
,
3787 vec
<cgraph_edge
*> callers
)
3789 struct ipa_node_params
*new_info
, *info
= IPA_NODE_REF (node
);
3790 vec
<ipa_replace_map
*, va_gc
> *replace_trees
= NULL
;
3791 struct ipa_agg_replacement_value
*av
;
3792 struct cgraph_node
*new_node
;
3793 int i
, count
= ipa_get_param_count (info
);
3794 bitmap args_to_skip
;
3796 gcc_assert (!info
->ipcp_orig_node
);
3798 if (node
->local
.can_change_signature
)
3800 args_to_skip
= BITMAP_GGC_ALLOC ();
3801 for (i
= 0; i
< count
; i
++)
3803 tree t
= known_csts
[i
];
3805 if (t
|| !ipa_is_param_used (info
, i
))
3806 bitmap_set_bit (args_to_skip
, i
);
3811 args_to_skip
= NULL
;
3812 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3813 fprintf (dump_file
, " cannot change function signature\n");
3816 for (i
= 0; i
< count
; i
++)
3818 tree t
= known_csts
[i
];
3821 struct ipa_replace_map
*replace_map
;
3823 gcc_checking_assert (TREE_CODE (t
) != TREE_BINFO
);
3824 replace_map
= get_replacement_map (info
, t
, i
);
3826 vec_safe_push (replace_trees
, replace_map
);
3829 auto_vec
<cgraph_edge
*, 2> self_recursive_calls
;
3830 for (i
= callers
.length () - 1; i
>= 0; i
--)
3832 cgraph_edge
*cs
= callers
[i
];
3833 if (cs
->caller
== node
)
3835 self_recursive_calls
.safe_push (cs
);
3836 callers
.unordered_remove (i
);
3840 unsigned &suffix_counter
= clone_num_suffixes
->get_or_insert (
3841 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
3843 new_node
= node
->create_virtual_clone (callers
, replace_trees
,
3844 args_to_skip
, "constprop",
3848 bool have_self_recursive_calls
= !self_recursive_calls
.is_empty ();
3849 for (unsigned j
= 0; j
< self_recursive_calls
.length (); j
++)
3851 cgraph_edge
*cs
= get_next_cgraph_edge_clone (self_recursive_calls
[j
]);
3852 /* Cloned edges can disappear during cloning as speculation can be
3853 resolved, check that we have one and that it comes from the last
3855 if (cs
&& cs
->caller
== new_node
)
3856 cs
->redirect_callee_duplicating_thunks (new_node
);
3857 /* Any future code that would make more than one clone of an outgoing
3858 edge would confuse this mechanism, so let's check that does not
3860 gcc_checking_assert (!cs
3861 || !get_next_cgraph_edge_clone (cs
)
3862 || get_next_cgraph_edge_clone (cs
)->caller
!= new_node
);
3864 if (have_self_recursive_calls
)
3865 new_node
->expand_all_artificial_thunks ();
3867 ipa_set_node_agg_value_chain (new_node
, aggvals
);
3868 for (av
= aggvals
; av
; av
= av
->next
)
3869 new_node
->maybe_create_reference (av
->value
, NULL
);
3871 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3873 fprintf (dump_file
, " the new node is %s.\n", new_node
->dump_name ());
3874 if (known_contexts
.exists ())
3876 for (i
= 0; i
< count
; i
++)
3877 if (!known_contexts
[i
].useless_p ())
3879 fprintf (dump_file
, " known ctx %i is ", i
);
3880 known_contexts
[i
].dump (dump_file
);
3884 ipa_dump_agg_replacement_values (dump_file
, aggvals
);
3886 ipa_check_create_node_params ();
3887 update_profiling_info (node
, new_node
);
3888 new_info
= IPA_NODE_REF (new_node
);
3889 new_info
->ipcp_orig_node
= node
;
3890 new_info
->known_csts
= known_csts
;
3891 new_info
->known_contexts
= known_contexts
;
3893 ipcp_discover_new_direct_edges (new_node
, known_csts
, known_contexts
, aggvals
);
3899 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
3900 simple no-operation pass-through function to itself. */
3903 self_recursive_pass_through_p (cgraph_edge
*cs
, ipa_jump_func
*jfunc
, int i
)
3905 enum availability availability
;
3906 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
3907 && availability
> AVAIL_INTERPOSABLE
3908 && jfunc
->type
== IPA_JF_PASS_THROUGH
3909 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
3910 && ipa_get_jf_pass_through_formal_id (jfunc
) == i
)
3915 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3916 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
3919 find_more_scalar_values_for_callers_subset (struct cgraph_node
*node
,
3920 vec
<tree
> known_csts
,
3921 vec
<cgraph_edge
*> callers
)
3923 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3924 int i
, count
= ipa_get_param_count (info
);
3926 for (i
= 0; i
< count
; i
++)
3928 struct cgraph_edge
*cs
;
3929 tree newval
= NULL_TREE
;
3932 tree type
= ipa_get_type (info
, i
);
3934 if (ipa_get_scalar_lat (info
, i
)->bottom
|| known_csts
[i
])
3937 FOR_EACH_VEC_ELT (callers
, j
, cs
)
3939 struct ipa_jump_func
*jump_func
;
3942 if (IPA_NODE_REF (cs
->caller
)->node_dead
)
3945 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
))
3947 && call_passes_through_thunk_p (cs
)))
3952 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
3953 if (self_recursive_pass_through_p (cs
, jump_func
, i
))
3956 t
= ipa_value_from_jfunc (IPA_NODE_REF (cs
->caller
), jump_func
, type
);
3959 && !values_equal_for_ipcp_p (t
, newval
))
3960 || (!first
&& !newval
))
3972 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3974 fprintf (dump_file
, " adding an extra known scalar value ");
3975 print_ipcp_constant_value (dump_file
, newval
);
3976 fprintf (dump_file
, " for ");
3977 ipa_dump_param (dump_file
, info
, i
);
3978 fprintf (dump_file
, "\n");
3981 known_csts
[i
] = newval
;
3986 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
3987 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
3991 find_more_contexts_for_caller_subset (cgraph_node
*node
,
3992 vec
<ipa_polymorphic_call_context
>
3994 vec
<cgraph_edge
*> callers
)
3996 ipa_node_params
*info
= IPA_NODE_REF (node
);
3997 int i
, count
= ipa_get_param_count (info
);
3999 for (i
= 0; i
< count
; i
++)
4003 if (ipa_get_poly_ctx_lat (info
, i
)->bottom
4004 || (known_contexts
->exists ()
4005 && !(*known_contexts
)[i
].useless_p ()))
4008 ipa_polymorphic_call_context newval
;
4012 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4014 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
)))
4016 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
),
4018 ipa_polymorphic_call_context ctx
;
4019 ctx
= ipa_context_from_jfunc (IPA_NODE_REF (cs
->caller
), cs
, i
,
4027 newval
.meet_with (ctx
);
4028 if (newval
.useless_p ())
4032 if (!newval
.useless_p ())
4034 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4036 fprintf (dump_file
, " adding an extra known polymorphic "
4038 print_ipcp_constant_value (dump_file
, newval
);
4039 fprintf (dump_file
, " for ");
4040 ipa_dump_param (dump_file
, info
, i
);
4041 fprintf (dump_file
, "\n");
4044 if (!known_contexts
->exists ())
4045 known_contexts
->safe_grow_cleared (ipa_get_param_count (info
));
4046 (*known_contexts
)[i
] = newval
;
4052 /* Go through PLATS and create a vector of values consisting of values and
4053 offsets (minus OFFSET) of lattices that contain only a single value. */
4055 static vec
<ipa_agg_jf_item
>
4056 copy_plats_to_inter (struct ipcp_param_lattices
*plats
, HOST_WIDE_INT offset
)
4058 vec
<ipa_agg_jf_item
> res
= vNULL
;
4060 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4063 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4064 if (aglat
->is_single_const ())
4066 struct ipa_agg_jf_item ti
;
4067 ti
.offset
= aglat
->offset
- offset
;
4068 ti
.value
= aglat
->values
->value
;
4074 /* Intersect all values in INTER with single value lattices in PLATS (while
4075 subtracting OFFSET). */
4078 intersect_with_plats (struct ipcp_param_lattices
*plats
,
4079 vec
<ipa_agg_jf_item
> *inter
,
4080 HOST_WIDE_INT offset
)
4082 struct ipcp_agg_lattice
*aglat
;
4083 struct ipa_agg_jf_item
*item
;
4086 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4092 aglat
= plats
->aggs
;
4093 FOR_EACH_VEC_ELT (*inter
, k
, item
)
4100 if (aglat
->offset
- offset
> item
->offset
)
4102 if (aglat
->offset
- offset
== item
->offset
)
4104 gcc_checking_assert (item
->value
);
4105 if (aglat
->is_single_const ()
4106 && values_equal_for_ipcp_p (item
->value
,
4107 aglat
->values
->value
))
4111 aglat
= aglat
->next
;
4114 item
->value
= NULL_TREE
;
4118 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4119 vector result while subtracting OFFSET from the individual value offsets. */
4121 static vec
<ipa_agg_jf_item
>
4122 agg_replacements_to_vector (struct cgraph_node
*node
, int index
,
4123 HOST_WIDE_INT offset
)
4125 struct ipa_agg_replacement_value
*av
;
4126 vec
<ipa_agg_jf_item
> res
= vNULL
;
4128 for (av
= ipa_get_agg_replacements_for_node (node
); av
; av
= av
->next
)
4129 if (av
->index
== index
4130 && (av
->offset
- offset
) >= 0)
4132 struct ipa_agg_jf_item item
;
4133 gcc_checking_assert (av
->value
);
4134 item
.offset
= av
->offset
- offset
;
4135 item
.value
= av
->value
;
4136 res
.safe_push (item
);
4142 /* Intersect all values in INTER with those that we have already scheduled to
4143 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4144 (while subtracting OFFSET). */
4147 intersect_with_agg_replacements (struct cgraph_node
*node
, int index
,
4148 vec
<ipa_agg_jf_item
> *inter
,
4149 HOST_WIDE_INT offset
)
4151 struct ipa_agg_replacement_value
*srcvals
;
4152 struct ipa_agg_jf_item
*item
;
4155 srcvals
= ipa_get_agg_replacements_for_node (node
);
4162 FOR_EACH_VEC_ELT (*inter
, i
, item
)
4164 struct ipa_agg_replacement_value
*av
;
4168 for (av
= srcvals
; av
; av
= av
->next
)
4170 gcc_checking_assert (av
->value
);
4171 if (av
->index
== index
4172 && av
->offset
- offset
== item
->offset
)
4174 if (values_equal_for_ipcp_p (item
->value
, av
->value
))
4180 item
->value
= NULL_TREE
;
4184 /* Intersect values in INTER with aggregate values that come along edge CS to
4185 parameter number INDEX and return it. If INTER does not actually exist yet,
4186 copy all incoming values to it. If we determine we ended up with no values
4187 whatsoever, return a released vector. */
4189 static vec
<ipa_agg_jf_item
>
4190 intersect_aggregates_with_edge (struct cgraph_edge
*cs
, int index
,
4191 vec
<ipa_agg_jf_item
> inter
)
4193 struct ipa_jump_func
*jfunc
;
4194 jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), index
);
4195 if (jfunc
->type
== IPA_JF_PASS_THROUGH
4196 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4198 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4199 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
4201 if (caller_info
->ipcp_orig_node
)
4203 struct cgraph_node
*orig_node
= caller_info
->ipcp_orig_node
;
4204 struct ipcp_param_lattices
*orig_plats
;
4205 orig_plats
= ipa_get_parm_lattices (IPA_NODE_REF (orig_node
),
4207 if (agg_pass_through_permissible_p (orig_plats
, jfunc
))
4209 if (!inter
.exists ())
4210 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, 0);
4212 intersect_with_agg_replacements (cs
->caller
, src_idx
,
4223 struct ipcp_param_lattices
*src_plats
;
4224 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4225 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
4227 /* Currently we do not produce clobber aggregate jump
4228 functions, adjust when we do. */
4229 gcc_checking_assert (!jfunc
->agg
.items
);
4230 if (!inter
.exists ())
4231 inter
= copy_plats_to_inter (src_plats
, 0);
4233 intersect_with_plats (src_plats
, &inter
, 0);
4242 else if (jfunc
->type
== IPA_JF_ANCESTOR
4243 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
4245 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4246 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
4247 struct ipcp_param_lattices
*src_plats
;
4248 HOST_WIDE_INT delta
= ipa_get_jf_ancestor_offset (jfunc
);
4250 if (caller_info
->ipcp_orig_node
)
4252 if (!inter
.exists ())
4253 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, delta
);
4255 intersect_with_agg_replacements (cs
->caller
, src_idx
, &inter
,
4260 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4261 /* Currently we do not produce clobber aggregate jump
4262 functions, adjust when we do. */
4263 gcc_checking_assert (!src_plats
->aggs
|| !jfunc
->agg
.items
);
4264 if (!inter
.exists ())
4265 inter
= copy_plats_to_inter (src_plats
, delta
);
4267 intersect_with_plats (src_plats
, &inter
, delta
);
4270 else if (jfunc
->agg
.items
)
4272 struct ipa_agg_jf_item
*item
;
4275 if (!inter
.exists ())
4276 for (unsigned i
= 0; i
< jfunc
->agg
.items
->length (); i
++)
4277 inter
.safe_push ((*jfunc
->agg
.items
)[i
]);
4279 FOR_EACH_VEC_ELT (inter
, k
, item
)
4287 while ((unsigned) l
< jfunc
->agg
.items
->length ())
4289 struct ipa_agg_jf_item
*ti
;
4290 ti
= &(*jfunc
->agg
.items
)[l
];
4291 if (ti
->offset
> item
->offset
)
4293 if (ti
->offset
== item
->offset
)
4295 gcc_checking_assert (ti
->value
);
4296 if (values_equal_for_ipcp_p (item
->value
,
4310 return vec
<ipa_agg_jf_item
>();
4315 /* Look at edges in CALLERS and collect all known aggregate values that arrive
4316 from all of them. */
4318 static struct ipa_agg_replacement_value
*
4319 find_aggregate_values_for_callers_subset (struct cgraph_node
*node
,
4320 vec
<cgraph_edge
*> callers
)
4322 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4323 struct ipa_agg_replacement_value
*res
;
4324 struct ipa_agg_replacement_value
**tail
= &res
;
4325 struct cgraph_edge
*cs
;
4326 int i
, j
, count
= ipa_get_param_count (dest_info
);
4328 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4330 int c
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4335 for (i
= 0; i
< count
; i
++)
4337 struct cgraph_edge
*cs
;
4338 vec
<ipa_agg_jf_item
> inter
= vNULL
;
4339 struct ipa_agg_jf_item
*item
;
4340 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (dest_info
, i
);
4343 /* Among other things, the following check should deal with all by_ref
4345 if (plats
->aggs_bottom
)
4348 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4350 struct ipa_jump_func
*jfunc
4351 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
4352 if (self_recursive_pass_through_p (cs
, jfunc
, i
)
4353 && (!plats
->aggs_by_ref
4354 || ipa_get_jf_pass_through_agg_preserved (jfunc
)))
4356 inter
= intersect_aggregates_with_edge (cs
, i
, inter
);
4358 if (!inter
.exists ())
4362 FOR_EACH_VEC_ELT (inter
, j
, item
)
4364 struct ipa_agg_replacement_value
*v
;
4369 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
4371 v
->offset
= item
->offset
;
4372 v
->value
= item
->value
;
4373 v
->by_ref
= plats
->aggs_by_ref
;
4379 if (inter
.exists ())
4386 /* Determine whether CS also brings all scalar values that the NODE is
4390 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge
*cs
,
4391 struct cgraph_node
*node
)
4393 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4394 int count
= ipa_get_param_count (dest_info
);
4395 struct ipa_node_params
*caller_info
;
4396 struct ipa_edge_args
*args
;
4399 caller_info
= IPA_NODE_REF (cs
->caller
);
4400 args
= IPA_EDGE_REF (cs
);
4401 for (i
= 0; i
< count
; i
++)
4403 struct ipa_jump_func
*jump_func
;
4406 val
= dest_info
->known_csts
[i
];
4410 if (i
>= ipa_get_cs_argument_count (args
))
4412 jump_func
= ipa_get_ith_jump_func (args
, i
);
4413 t
= ipa_value_from_jfunc (caller_info
, jump_func
,
4414 ipa_get_type (dest_info
, i
));
4415 if (!t
|| !values_equal_for_ipcp_p (val
, t
))
4421 /* Determine whether CS also brings all aggregate values that NODE is
4424 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge
*cs
,
4425 struct cgraph_node
*node
)
4427 struct ipa_node_params
*orig_caller_info
= IPA_NODE_REF (cs
->caller
);
4428 struct ipa_node_params
*orig_node_info
;
4429 struct ipa_agg_replacement_value
*aggval
;
4432 aggval
= ipa_get_agg_replacements_for_node (node
);
4436 count
= ipa_get_param_count (IPA_NODE_REF (node
));
4437 ec
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4439 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4440 if (aggval
->index
>= ec
)
4443 orig_node_info
= IPA_NODE_REF (IPA_NODE_REF (node
)->ipcp_orig_node
);
4444 if (orig_caller_info
->ipcp_orig_node
)
4445 orig_caller_info
= IPA_NODE_REF (orig_caller_info
->ipcp_orig_node
);
4447 for (i
= 0; i
< count
; i
++)
4449 static vec
<ipa_agg_jf_item
> values
= vec
<ipa_agg_jf_item
>();
4450 struct ipcp_param_lattices
*plats
;
4451 bool interesting
= false;
4452 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4453 if (aggval
->index
== i
)
4461 plats
= ipa_get_parm_lattices (orig_node_info
, aggval
->index
);
4462 if (plats
->aggs_bottom
)
4465 values
= intersect_aggregates_with_edge (cs
, i
, values
);
4466 if (!values
.exists ())
4469 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4470 if (aggval
->index
== i
)
4472 struct ipa_agg_jf_item
*item
;
4475 FOR_EACH_VEC_ELT (values
, j
, item
)
4477 && item
->offset
== av
->offset
4478 && values_equal_for_ipcp_p (item
->value
, av
->value
))
4493 /* Given an original NODE and a VAL for which we have already created a
4494 specialized clone, look whether there are incoming edges that still lead
4495 into the old node but now also bring the requested value and also conform to
4496 all other criteria such that they can be redirected the special node.
4497 This function can therefore redirect the final edge in a SCC. */
4499 template <typename valtype
>
4501 perhaps_add_new_callers (cgraph_node
*node
, ipcp_value
<valtype
> *val
)
4503 ipcp_value_source
<valtype
> *src
;
4504 profile_count redirected_sum
= profile_count::zero ();
4506 for (src
= val
->sources
; src
; src
= src
->next
)
4508 struct cgraph_edge
*cs
= src
->cs
;
4511 if (cgraph_edge_brings_value_p (cs
, src
, node
, val
)
4512 && cgraph_edge_brings_all_scalars_for_node (cs
, val
->spec_node
)
4513 && cgraph_edge_brings_all_agg_vals_for_node (cs
, val
->spec_node
))
4516 fprintf (dump_file
, " - adding an extra caller %s of %s\n",
4517 cs
->caller
->dump_name (),
4518 val
->spec_node
->dump_name ());
4520 cs
->redirect_callee_duplicating_thunks (val
->spec_node
);
4521 val
->spec_node
->expand_all_artificial_thunks ();
4522 if (cs
->count
.ipa ().initialized_p ())
4523 redirected_sum
= redirected_sum
+ cs
->count
.ipa ();
4525 cs
= get_next_cgraph_edge_clone (cs
);
4529 if (redirected_sum
.nonzero_p ())
4530 update_specialized_profile (val
->spec_node
, node
, redirected_sum
);
4533 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
4536 known_contexts_useful_p (vec
<ipa_polymorphic_call_context
> known_contexts
)
4538 ipa_polymorphic_call_context
*ctx
;
4541 FOR_EACH_VEC_ELT (known_contexts
, i
, ctx
)
4542 if (!ctx
->useless_p ())
4547 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
4549 static vec
<ipa_polymorphic_call_context
>
4550 copy_useful_known_contexts (vec
<ipa_polymorphic_call_context
> known_contexts
)
4552 if (known_contexts_useful_p (known_contexts
))
4553 return known_contexts
.copy ();
4558 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX. If
4559 non-empty, replace KNOWN_CONTEXTS with its copy too. */
4562 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4563 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4564 ipcp_value
<tree
> *val
,
4567 *known_csts
= known_csts
->copy ();
4568 *known_contexts
= copy_useful_known_contexts (*known_contexts
);
4569 (*known_csts
)[index
] = val
->value
;
4572 /* Replace KNOWN_CSTS with its copy. Also copy KNOWN_CONTEXTS and modify the
4573 copy according to VAL and INDEX. */
4576 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4577 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4578 ipcp_value
<ipa_polymorphic_call_context
> *val
,
4581 *known_csts
= known_csts
->copy ();
4582 *known_contexts
= known_contexts
->copy ();
4583 (*known_contexts
)[index
] = val
->value
;
4586 /* Return true if OFFSET indicates this was not an aggregate value or there is
4587 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
4591 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*aggvals
,
4592 int index
, HOST_WIDE_INT offset
, tree value
)
4599 if (aggvals
->index
== index
4600 && aggvals
->offset
== offset
4601 && values_equal_for_ipcp_p (aggvals
->value
, value
))
4603 aggvals
= aggvals
->next
;
4608 /* Return true if offset is minus one because source of a polymorphic context
4609 cannot be an aggregate value. */
4612 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*,
4613 int , HOST_WIDE_INT offset
,
4614 ipa_polymorphic_call_context
)
4616 return offset
== -1;
4619 /* Decide whether to create a special version of NODE for value VAL of parameter
4620 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
4621 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
4622 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
4624 template <typename valtype
>
4626 decide_about_value (struct cgraph_node
*node
, int index
, HOST_WIDE_INT offset
,
4627 ipcp_value
<valtype
> *val
, vec
<tree
> known_csts
,
4628 vec
<ipa_polymorphic_call_context
> known_contexts
)
4630 struct ipa_agg_replacement_value
*aggvals
;
4631 int freq_sum
, caller_count
;
4632 profile_count count_sum
;
4633 vec
<cgraph_edge
*> callers
;
4637 perhaps_add_new_callers (node
, val
);
4640 else if (val
->local_size_cost
+ overall_size
> max_new_size
)
4642 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4643 fprintf (dump_file
, " Ignoring candidate value because "
4644 "max_new_size would be reached with %li.\n",
4645 val
->local_size_cost
+ overall_size
);
4648 else if (!get_info_about_necessary_edges (val
, node
, &freq_sum
, &count_sum
,
4652 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4654 fprintf (dump_file
, " - considering value ");
4655 print_ipcp_constant_value (dump_file
, val
->value
);
4656 fprintf (dump_file
, " for ");
4657 ipa_dump_param (dump_file
, IPA_NODE_REF (node
), index
);
4659 fprintf (dump_file
, ", offset: " HOST_WIDE_INT_PRINT_DEC
, offset
);
4660 fprintf (dump_file
, " (caller_count: %i)\n", caller_count
);
4663 if (!good_cloning_opportunity_p (node
, val
->local_time_benefit
,
4664 freq_sum
, count_sum
,
4665 val
->local_size_cost
)
4666 && !good_cloning_opportunity_p (node
,
4667 val
->local_time_benefit
4668 + val
->prop_time_benefit
,
4669 freq_sum
, count_sum
,
4670 val
->local_size_cost
4671 + val
->prop_size_cost
))
4675 fprintf (dump_file
, " Creating a specialized node of %s.\n",
4676 node
->dump_name ());
4678 callers
= gather_edges_for_value (val
, node
, caller_count
);
4680 modify_known_vectors_with_val (&known_csts
, &known_contexts
, val
, index
);
4683 known_csts
= known_csts
.copy ();
4684 known_contexts
= copy_useful_known_contexts (known_contexts
);
4686 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
4687 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
4688 aggvals
= find_aggregate_values_for_callers_subset (node
, callers
);
4689 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals
, index
,
4690 offset
, val
->value
));
4691 val
->spec_node
= create_specialized_node (node
, known_csts
, known_contexts
,
4693 overall_size
+= val
->local_size_cost
;
4695 /* TODO: If for some lattice there is only one other known value
4696 left, make a special node for it too. */
4701 /* Decide whether and what specialized clones of NODE should be created. */
4704 decide_whether_version_node (struct cgraph_node
*node
)
4706 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4707 int i
, count
= ipa_get_param_count (info
);
4708 vec
<tree
> known_csts
;
4709 vec
<ipa_polymorphic_call_context
> known_contexts
;
4710 vec
<ipa_agg_jump_function
> known_aggs
= vNULL
;
4716 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4717 fprintf (dump_file
, "\nEvaluating opportunities for %s.\n",
4718 node
->dump_name ());
4720 gather_context_independent_values (info
, &known_csts
, &known_contexts
,
4721 info
->do_clone_for_all_contexts
? &known_aggs
4724 for (i
= 0; i
< count
;i
++)
4726 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4727 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
4728 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
4733 ipcp_value
<tree
> *val
;
4734 for (val
= lat
->values
; val
; val
= val
->next
)
4735 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4739 if (!plats
->aggs_bottom
)
4741 struct ipcp_agg_lattice
*aglat
;
4742 ipcp_value
<tree
> *val
;
4743 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4744 if (!aglat
->bottom
&& aglat
->values
4745 /* If the following is false, the one value is in
4747 && (plats
->aggs_contain_variable
4748 || !aglat
->is_single_const ()))
4749 for (val
= aglat
->values
; val
; val
= val
->next
)
4750 ret
|= decide_about_value (node
, i
, aglat
->offset
, val
,
4751 known_csts
, known_contexts
);
4755 && known_contexts
[i
].useless_p ())
4757 ipcp_value
<ipa_polymorphic_call_context
> *val
;
4758 for (val
= ctxlat
->values
; val
; val
= val
->next
)
4759 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4763 info
= IPA_NODE_REF (node
);
4766 if (info
->do_clone_for_all_contexts
)
4768 struct cgraph_node
*clone
;
4769 vec
<cgraph_edge
*> callers
;
4772 fprintf (dump_file
, " - Creating a specialized node of %s "
4773 "for all known contexts.\n", node
->dump_name ());
4775 callers
= node
->collect_callers ();
4776 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
4777 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
4778 ipa_agg_replacement_value
*aggvals
4779 = find_aggregate_values_for_callers_subset (node
, callers
);
4781 if (!known_contexts_useful_p (known_contexts
))
4783 known_contexts
.release ();
4784 known_contexts
= vNULL
;
4786 clone
= create_specialized_node (node
, known_csts
, known_contexts
,
4788 info
= IPA_NODE_REF (node
);
4789 info
->do_clone_for_all_contexts
= false;
4790 IPA_NODE_REF (clone
)->is_all_contexts_clone
= true;
4791 for (i
= 0; i
< count
; i
++)
4792 vec_free (known_aggs
[i
].items
);
4793 known_aggs
.release ();
4798 known_csts
.release ();
4799 known_contexts
.release ();
4805 /* Transitively mark all callees of NODE within the same SCC as not dead. */
4808 spread_undeadness (struct cgraph_node
*node
)
4810 struct cgraph_edge
*cs
;
4812 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
4813 if (ipa_edge_within_scc (cs
))
4815 struct cgraph_node
*callee
;
4816 struct ipa_node_params
*info
;
4818 callee
= cs
->callee
->function_symbol (NULL
);
4819 info
= IPA_NODE_REF (callee
);
4821 if (info
->node_dead
)
4823 info
->node_dead
= 0;
4824 spread_undeadness (callee
);
4829 /* Return true if NODE has a caller from outside of its SCC that is not
4830 dead. Worker callback for cgraph_for_node_and_aliases. */
4833 has_undead_caller_from_outside_scc_p (struct cgraph_node
*node
,
4834 void *data ATTRIBUTE_UNUSED
)
4836 struct cgraph_edge
*cs
;
4838 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4839 if (cs
->caller
->thunk
.thunk_p
4840 && cs
->caller
->call_for_symbol_thunks_and_aliases
4841 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4843 else if (!ipa_edge_within_scc (cs
)
4844 && !IPA_NODE_REF (cs
->caller
)->node_dead
)
4850 /* Identify nodes within the same SCC as NODE which are no longer needed
4851 because of new clones and will be removed as unreachable. */
4854 identify_dead_nodes (struct cgraph_node
*node
)
4856 struct cgraph_node
*v
;
4857 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4859 && !v
->call_for_symbol_thunks_and_aliases
4860 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4861 IPA_NODE_REF (v
)->node_dead
= 1;
4863 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4864 if (!IPA_NODE_REF (v
)->node_dead
)
4865 spread_undeadness (v
);
4867 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4869 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4870 if (IPA_NODE_REF (v
)->node_dead
)
4871 fprintf (dump_file
, " Marking node as dead: %s.\n", v
->dump_name ());
4875 /* The decision stage. Iterate over the topological order of call graph nodes
4876 TOPO and make specialized clones if deemed beneficial. */
4879 ipcp_decision_stage (struct ipa_topo_info
*topo
)
4884 fprintf (dump_file
, "\nIPA decision stage:\n\n");
4886 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
4888 struct cgraph_node
*node
= topo
->order
[i
];
4889 bool change
= false, iterate
= true;
4893 struct cgraph_node
*v
;
4895 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4896 if (v
->has_gimple_body_p ()
4897 && ipcp_versionable_function_p (v
))
4898 iterate
|= decide_whether_version_node (v
);
4903 identify_dead_nodes (node
);
4907 /* Look up all the bits information that we have discovered and copy it over
4908 to the transformation summary. */
4911 ipcp_store_bits_results (void)
4915 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4917 ipa_node_params
*info
= IPA_NODE_REF (node
);
4918 bool dumped_sth
= false;
4919 bool found_useful_result
= false;
4921 if (!opt_for_fn (node
->decl
, flag_ipa_bit_cp
))
4924 fprintf (dump_file
, "Not considering %s for ipa bitwise propagation "
4925 "; -fipa-bit-cp: disabled.\n",
4930 if (info
->ipcp_orig_node
)
4931 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
4933 unsigned count
= ipa_get_param_count (info
);
4934 for (unsigned i
= 0; i
< count
; i
++)
4936 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4937 if (plats
->bits_lattice
.constant_p ())
4939 found_useful_result
= true;
4944 if (!found_useful_result
)
4947 ipcp_transformation_initialize ();
4948 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
4949 vec_safe_reserve_exact (ts
->bits
, count
);
4951 for (unsigned i
= 0; i
< count
; i
++)
4953 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4956 if (plats
->bits_lattice
.constant_p ())
4958 = ipa_get_ipa_bits_for_value (plats
->bits_lattice
.get_value (),
4959 plats
->bits_lattice
.get_mask ());
4963 ts
->bits
->quick_push (jfbits
);
4964 if (!dump_file
|| !jfbits
)
4968 fprintf (dump_file
, "Propagated bits info for function %s:\n",
4969 node
->dump_name ());
4972 fprintf (dump_file
, " param %i: value = ", i
);
4973 print_hex (jfbits
->value
, dump_file
);
4974 fprintf (dump_file
, ", mask = ");
4975 print_hex (jfbits
->mask
, dump_file
);
4976 fprintf (dump_file
, "\n");
4981 /* Look up all VR information that we have discovered and copy it over
4982 to the transformation summary. */
4985 ipcp_store_vr_results (void)
4989 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4991 ipa_node_params
*info
= IPA_NODE_REF (node
);
4992 bool found_useful_result
= false;
4994 if (!opt_for_fn (node
->decl
, flag_ipa_vrp
))
4997 fprintf (dump_file
, "Not considering %s for VR discovery "
4998 "and propagate; -fipa-ipa-vrp: disabled.\n",
5003 if (info
->ipcp_orig_node
)
5004 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
5006 unsigned count
= ipa_get_param_count (info
);
5007 for (unsigned i
= 0; i
< count
; i
++)
5009 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5010 if (!plats
->m_value_range
.bottom_p ()
5011 && !plats
->m_value_range
.top_p ())
5013 found_useful_result
= true;
5017 if (!found_useful_result
)
5020 ipcp_transformation_initialize ();
5021 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5022 vec_safe_reserve_exact (ts
->m_vr
, count
);
5024 for (unsigned i
= 0; i
< count
; i
++)
5026 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5029 if (!plats
->m_value_range
.bottom_p ()
5030 && !plats
->m_value_range
.top_p ())
5033 vr
.type
= plats
->m_value_range
.m_vr
.kind ();
5034 vr
.min
= wi::to_wide (plats
->m_value_range
.m_vr
.min ());
5035 vr
.max
= wi::to_wide (plats
->m_value_range
.m_vr
.max ());
5040 vr
.type
= VR_VARYING
;
5041 vr
.min
= vr
.max
= wi::zero (INT_TYPE_SIZE
);
5043 ts
->m_vr
->quick_push (vr
);
5048 /* The IPCP driver. */
5053 struct ipa_topo_info topo
;
5055 if (edge_clone_summaries
== NULL
)
5056 edge_clone_summaries
= new edge_clone_summary_t (symtab
);
5058 ipa_check_create_node_params ();
5059 ipa_check_create_edge_args ();
5060 clone_num_suffixes
= new hash_map
<const char *, unsigned>;
5064 fprintf (dump_file
, "\nIPA structures before propagation:\n");
5065 if (dump_flags
& TDF_DETAILS
)
5066 ipa_print_all_params (dump_file
);
5067 ipa_print_all_jump_functions (dump_file
);
5070 /* Topological sort. */
5071 build_toporder_info (&topo
);
5072 /* Do the interprocedural propagation. */
5073 ipcp_propagate_stage (&topo
);
5074 /* Decide what constant propagation and cloning should be performed. */
5075 ipcp_decision_stage (&topo
);
5076 /* Store results of bits propagation. */
5077 ipcp_store_bits_results ();
5078 /* Store results of value range propagation. */
5079 ipcp_store_vr_results ();
5081 /* Free all IPCP structures. */
5082 delete clone_num_suffixes
;
5083 free_toporder_info (&topo
);
5084 delete edge_clone_summaries
;
5085 edge_clone_summaries
= NULL
;
5086 ipa_free_all_structures_after_ipa_cp ();
5088 fprintf (dump_file
, "\nIPA constant propagation end\n");
5092 /* Initialization and computation of IPCP data structures. This is the initial
5093 intraprocedural analysis of functions, which gathers information to be
5094 propagated later on. */
5097 ipcp_generate_summary (void)
5099 struct cgraph_node
*node
;
5102 fprintf (dump_file
, "\nIPA constant propagation start:\n");
5103 ipa_register_cgraph_hooks ();
5105 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5106 ipa_analyze_node (node
);
5109 /* Write ipcp summary for nodes in SET. */
5112 ipcp_write_summary (void)
5114 ipa_prop_write_jump_functions ();
5117 /* Read ipcp summary. */
5120 ipcp_read_summary (void)
5122 ipa_prop_read_jump_functions ();
5127 const pass_data pass_data_ipa_cp
=
5129 IPA_PASS
, /* type */
5131 OPTGROUP_NONE
, /* optinfo_flags */
5132 TV_IPA_CONSTANT_PROP
, /* tv_id */
5133 0, /* properties_required */
5134 0, /* properties_provided */
5135 0, /* properties_destroyed */
5136 0, /* todo_flags_start */
5137 ( TODO_dump_symtab
| TODO_remove_functions
), /* todo_flags_finish */
5140 class pass_ipa_cp
: public ipa_opt_pass_d
5143 pass_ipa_cp (gcc::context
*ctxt
)
5144 : ipa_opt_pass_d (pass_data_ipa_cp
, ctxt
,
5145 ipcp_generate_summary
, /* generate_summary */
5146 ipcp_write_summary
, /* write_summary */
5147 ipcp_read_summary
, /* read_summary */
5148 ipcp_write_transformation_summaries
, /*
5149 write_optimization_summary */
5150 ipcp_read_transformation_summaries
, /*
5151 read_optimization_summary */
5152 NULL
, /* stmt_fixup */
5153 0, /* function_transform_todo_flags_start */
5154 ipcp_transform_function
, /* function_transform */
5155 NULL
) /* variable_transform */
5158 /* opt_pass methods: */
5159 virtual bool gate (function
*)
5161 /* FIXME: We should remove the optimize check after we ensure we never run
5162 IPA passes when not optimizing. */
5163 return (flag_ipa_cp
&& optimize
) || in_lto_p
;
5166 virtual unsigned int execute (function
*) { return ipcp_driver (); }
5168 }; // class pass_ipa_cp
5173 make_pass_ipa_cp (gcc::context
*ctxt
)
5175 return new pass_ipa_cp (ctxt
);
5178 /* Reset all state within ipa-cp.c so that we can rerun the compiler
5179 within the same process. For use by toplev::finalize. */
5182 ipa_cp_c_finalize (void)
5184 max_count
= profile_count::uninitialized ();