1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2019 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, 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 cannot
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)
2822 /* Extern inline functions have no cloning local time benefits because they
2823 will be inlined anyway. The only reason to clone them is if it enables
2824 optimization in any of the functions they call. */
2825 if (DECL_EXTERNAL (node
->decl
) && DECL_DECLARED_INLINE_P (node
->decl
))
2828 time_benefit
= base_time
.to_int ()
2829 + devirtualization_time_bonus (node
, known_csts
, known_contexts
,
2831 + hint_time_bonus (hints
)
2832 + removable_params_cost
+ est_move_cost
;
2834 gcc_checking_assert (size
>=0);
2835 /* The inliner-heuristics based estimates may think that in certain
2836 contexts some functions do not have any size at all but we want
2837 all specializations to have at least a tiny cost, not least not to
2842 val
->local_time_benefit
= time_benefit
;
2843 val
->local_size_cost
= size
;
2846 /* Iterate over known values of parameters of NODE and estimate the local
2847 effects in terms of time and size they have. */
2850 estimate_local_effects (struct cgraph_node
*node
)
2852 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2853 int i
, count
= ipa_get_param_count (info
);
2854 vec
<tree
> known_csts
;
2855 vec
<ipa_polymorphic_call_context
> known_contexts
;
2856 vec
<ipa_agg_jump_function
> known_aggs
;
2857 vec
<ipa_agg_jump_function_p
> known_aggs_ptrs
;
2859 int removable_params_cost
;
2861 if (!count
|| !ipcp_versionable_function_p (node
))
2864 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2865 fprintf (dump_file
, "\nEstimating effects for %s.\n", node
->dump_name ());
2867 always_const
= gather_context_independent_values (info
, &known_csts
,
2868 &known_contexts
, &known_aggs
,
2869 &removable_params_cost
);
2870 known_aggs_ptrs
= agg_jmp_p_vec_for_t_vec (known_aggs
);
2871 int devirt_bonus
= devirtualization_time_bonus (node
, known_csts
,
2872 known_contexts
, known_aggs_ptrs
);
2873 if (always_const
|| devirt_bonus
2874 || (removable_params_cost
&& node
->local
.can_change_signature
))
2876 struct caller_statistics stats
;
2878 sreal time
, base_time
;
2881 init_caller_stats (&stats
);
2882 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
2884 estimate_ipcp_clone_size_and_time (node
, known_csts
, known_contexts
,
2885 known_aggs_ptrs
, &size
, &time
,
2886 &base_time
, &hints
);
2887 time
-= devirt_bonus
;
2888 time
-= hint_time_bonus (hints
);
2889 time
-= removable_params_cost
;
2890 size
-= stats
.n_calls
* removable_params_cost
;
2893 fprintf (dump_file
, " - context independent values, size: %i, "
2894 "time_benefit: %f\n", size
, (base_time
- time
).to_double ());
2896 if (size
<= 0 || node
->local
.local
)
2898 info
->do_clone_for_all_contexts
= true;
2901 fprintf (dump_file
, " Decided to specialize for all "
2902 "known contexts, code not going to grow.\n");
2904 else if (good_cloning_opportunity_p (node
,
2905 MIN ((base_time
- time
).to_int (),
2907 stats
.freq_sum
, stats
.count_sum
,
2910 if (size
+ overall_size
<= max_new_size
)
2912 info
->do_clone_for_all_contexts
= true;
2913 overall_size
+= size
;
2916 fprintf (dump_file
, " Decided to specialize for all "
2917 "known contexts, growth deemed beneficial.\n");
2919 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2920 fprintf (dump_file
, " Not cloning for all contexts because "
2921 "max_new_size would be reached with %li.\n",
2922 size
+ overall_size
);
2924 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2925 fprintf (dump_file
, " Not cloning for all contexts because "
2926 "!good_cloning_opportunity_p.\n");
2930 for (i
= 0; i
< count
; i
++)
2932 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2933 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
2934 ipcp_value
<tree
> *val
;
2941 for (val
= lat
->values
; val
; val
= val
->next
)
2943 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
2944 known_csts
[i
] = val
->value
;
2946 int emc
= estimate_move_cost (TREE_TYPE (val
->value
), true);
2947 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2949 removable_params_cost
, emc
, val
);
2951 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2953 fprintf (dump_file
, " - estimates for value ");
2954 print_ipcp_constant_value (dump_file
, val
->value
);
2955 fprintf (dump_file
, " for ");
2956 ipa_dump_param (dump_file
, info
, i
);
2957 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2958 val
->local_time_benefit
, val
->local_size_cost
);
2961 known_csts
[i
] = NULL_TREE
;
2964 for (i
= 0; i
< count
; i
++)
2966 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2968 if (!plats
->virt_call
)
2971 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
2972 ipcp_value
<ipa_polymorphic_call_context
> *val
;
2976 || !known_contexts
[i
].useless_p ())
2979 for (val
= ctxlat
->values
; val
; val
= val
->next
)
2981 known_contexts
[i
] = val
->value
;
2982 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2984 removable_params_cost
, 0, val
);
2986 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2988 fprintf (dump_file
, " - estimates for polymorphic context ");
2989 print_ipcp_constant_value (dump_file
, val
->value
);
2990 fprintf (dump_file
, " for ");
2991 ipa_dump_param (dump_file
, info
, i
);
2992 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2993 val
->local_time_benefit
, val
->local_size_cost
);
2996 known_contexts
[i
] = ipa_polymorphic_call_context ();
2999 for (i
= 0; i
< count
; i
++)
3001 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3002 struct ipa_agg_jump_function
*ajf
;
3003 struct ipcp_agg_lattice
*aglat
;
3005 if (plats
->aggs_bottom
|| !plats
->aggs
)
3008 ajf
= &known_aggs
[i
];
3009 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3011 ipcp_value
<tree
> *val
;
3012 if (aglat
->bottom
|| !aglat
->values
3013 /* If the following is true, the one value is in known_aggs. */
3014 || (!plats
->aggs_contain_variable
3015 && aglat
->is_single_const ()))
3018 for (val
= aglat
->values
; val
; val
= val
->next
)
3020 struct ipa_agg_jf_item item
;
3022 item
.offset
= aglat
->offset
;
3023 item
.value
= val
->value
;
3024 vec_safe_push (ajf
->items
, item
);
3026 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
3028 removable_params_cost
, 0, val
);
3030 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3032 fprintf (dump_file
, " - estimates for value ");
3033 print_ipcp_constant_value (dump_file
, val
->value
);
3034 fprintf (dump_file
, " for ");
3035 ipa_dump_param (dump_file
, info
, i
);
3036 fprintf (dump_file
, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3037 "]: time_benefit: %i, size: %i\n",
3038 plats
->aggs_by_ref
? "ref " : "",
3040 val
->local_time_benefit
, val
->local_size_cost
);
3048 for (i
= 0; i
< count
; i
++)
3049 vec_free (known_aggs
[i
].items
);
3051 known_csts
.release ();
3052 known_contexts
.release ();
3053 known_aggs
.release ();
3054 known_aggs_ptrs
.release ();
3058 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3059 topological sort of values. */
3061 template <typename valtype
>
3063 value_topo_info
<valtype
>::add_val (ipcp_value
<valtype
> *cur_val
)
3065 ipcp_value_source
<valtype
> *src
;
3071 cur_val
->dfs
= dfs_counter
;
3072 cur_val
->low_link
= dfs_counter
;
3074 cur_val
->topo_next
= stack
;
3076 cur_val
->on_stack
= true;
3078 for (src
= cur_val
->sources
; src
; src
= src
->next
)
3081 if (src
->val
->dfs
== 0)
3084 if (src
->val
->low_link
< cur_val
->low_link
)
3085 cur_val
->low_link
= src
->val
->low_link
;
3087 else if (src
->val
->on_stack
3088 && src
->val
->dfs
< cur_val
->low_link
)
3089 cur_val
->low_link
= src
->val
->dfs
;
3092 if (cur_val
->dfs
== cur_val
->low_link
)
3094 ipcp_value
<valtype
> *v
, *scc_list
= NULL
;
3099 stack
= v
->topo_next
;
3100 v
->on_stack
= false;
3102 v
->scc_next
= scc_list
;
3105 while (v
!= cur_val
);
3107 cur_val
->topo_next
= values_topo
;
3108 values_topo
= cur_val
;
3112 /* Add all values in lattices associated with NODE to the topological sort if
3113 they are not there yet. */
3116 add_all_node_vals_to_toposort (cgraph_node
*node
, ipa_topo_info
*topo
)
3118 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3119 int i
, count
= ipa_get_param_count (info
);
3121 for (i
= 0; i
< count
; i
++)
3123 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3124 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3125 struct ipcp_agg_lattice
*aglat
;
3129 ipcp_value
<tree
> *val
;
3130 for (val
= lat
->values
; val
; val
= val
->next
)
3131 topo
->constants
.add_val (val
);
3134 if (!plats
->aggs_bottom
)
3135 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3138 ipcp_value
<tree
> *val
;
3139 for (val
= aglat
->values
; val
; val
= val
->next
)
3140 topo
->constants
.add_val (val
);
3143 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3144 if (!ctxlat
->bottom
)
3146 ipcp_value
<ipa_polymorphic_call_context
> *ctxval
;
3147 for (ctxval
= ctxlat
->values
; ctxval
; ctxval
= ctxval
->next
)
3148 topo
->contexts
.add_val (ctxval
);
3153 /* One pass of constants propagation along the call graph edges, from callers
3154 to callees (requires topological ordering in TOPO), iterate over strongly
3155 connected components. */
3158 propagate_constants_topo (struct ipa_topo_info
*topo
)
3162 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
3165 struct cgraph_node
*v
, *node
= topo
->order
[i
];
3166 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
3168 /* First, iteratively propagate within the strongly connected component
3169 until all lattices stabilize. */
3170 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3171 if (v
->has_gimple_body_p ())
3172 push_node_to_stack (topo
, v
);
3174 v
= pop_node_from_stack (topo
);
3177 struct cgraph_edge
*cs
;
3179 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3180 if (ipa_edge_within_scc (cs
))
3182 IPA_NODE_REF (v
)->node_within_scc
= true;
3183 if (propagate_constants_across_call (cs
))
3184 push_node_to_stack (topo
, cs
->callee
->function_symbol ());
3186 v
= pop_node_from_stack (topo
);
3189 /* Afterwards, propagate along edges leading out of the SCC, calculates
3190 the local effects of the discovered constants and all valid values to
3191 their topological sort. */
3192 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3193 if (v
->has_gimple_body_p ())
3195 struct cgraph_edge
*cs
;
3197 estimate_local_effects (v
);
3198 add_all_node_vals_to_toposort (v
, topo
);
3199 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3200 if (!ipa_edge_within_scc (cs
))
3201 propagate_constants_across_call (cs
);
3203 cycle_nodes
.release ();
3208 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3209 the bigger one if otherwise. */
3212 safe_add (int a
, int b
)
3214 if (a
> INT_MAX
/2 || b
> INT_MAX
/2)
3215 return a
> b
? a
: b
;
3221 /* Propagate the estimated effects of individual values along the topological
3222 from the dependent values to those they depend on. */
3224 template <typename valtype
>
3226 value_topo_info
<valtype
>::propagate_effects ()
3228 ipcp_value
<valtype
> *base
;
3230 for (base
= values_topo
; base
; base
= base
->topo_next
)
3232 ipcp_value_source
<valtype
> *src
;
3233 ipcp_value
<valtype
> *val
;
3234 int time
= 0, size
= 0;
3236 for (val
= base
; val
; val
= val
->scc_next
)
3238 time
= safe_add (time
,
3239 val
->local_time_benefit
+ val
->prop_time_benefit
);
3240 size
= safe_add (size
, val
->local_size_cost
+ val
->prop_size_cost
);
3243 for (val
= base
; val
; val
= val
->scc_next
)
3244 for (src
= val
->sources
; src
; src
= src
->next
)
3246 && src
->cs
->maybe_hot_p ())
3248 src
->val
->prop_time_benefit
= safe_add (time
,
3249 src
->val
->prop_time_benefit
);
3250 src
->val
->prop_size_cost
= safe_add (size
,
3251 src
->val
->prop_size_cost
);
3257 /* Propagate constants, polymorphic contexts and their effects from the
3258 summaries interprocedurally. */
3261 ipcp_propagate_stage (struct ipa_topo_info
*topo
)
3263 struct cgraph_node
*node
;
3266 fprintf (dump_file
, "\n Propagating constants:\n\n");
3268 max_count
= profile_count::uninitialized ();
3270 FOR_EACH_DEFINED_FUNCTION (node
)
3272 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3274 determine_versionability (node
, info
);
3275 if (node
->has_gimple_body_p ())
3277 info
->lattices
= XCNEWVEC (struct ipcp_param_lattices
,
3278 ipa_get_param_count (info
));
3279 initialize_node_lattices (node
);
3281 ipa_fn_summary
*s
= ipa_fn_summaries
->get (node
);
3282 if (node
->definition
&& !node
->alias
&& s
!= NULL
)
3283 overall_size
+= s
->self_size
;
3284 max_count
= max_count
.max (node
->count
.ipa ());
3287 max_new_size
= overall_size
;
3288 if (max_new_size
< PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
))
3289 max_new_size
= PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
);
3290 max_new_size
+= max_new_size
* PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH
) / 100 + 1;
3293 fprintf (dump_file
, "\noverall_size: %li, max_new_size: %li\n",
3294 overall_size
, max_new_size
);
3296 propagate_constants_topo (topo
);
3298 ipcp_verify_propagated_values ();
3299 topo
->constants
.propagate_effects ();
3300 topo
->contexts
.propagate_effects ();
3304 fprintf (dump_file
, "\nIPA lattices after all propagation:\n");
3305 print_all_lattices (dump_file
, (dump_flags
& TDF_DETAILS
), true);
3309 /* Discover newly direct outgoing edges from NODE which is a new clone with
3310 known KNOWN_CSTS and make them direct. */
3313 ipcp_discover_new_direct_edges (struct cgraph_node
*node
,
3314 vec
<tree
> known_csts
,
3315 vec
<ipa_polymorphic_call_context
>
3317 struct ipa_agg_replacement_value
*aggvals
)
3319 struct cgraph_edge
*ie
, *next_ie
;
3322 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3327 next_ie
= ie
->next_callee
;
3328 target
= ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
3329 vNULL
, aggvals
, &speculative
);
3332 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3333 bool polymorphic
= ie
->indirect_info
->polymorphic
;
3334 int param_index
= ie
->indirect_info
->param_index
;
3335 struct cgraph_edge
*cs
= ipa_make_edge_direct_to_target (ie
, target
,
3339 if (cs
&& !agg_contents
&& !polymorphic
)
3341 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3342 int c
= ipa_get_controlled_uses (info
, param_index
);
3343 if (c
!= IPA_UNDESCRIBED_USE
)
3345 struct ipa_ref
*to_del
;
3348 ipa_set_controlled_uses (info
, param_index
, c
);
3349 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3350 fprintf (dump_file
, " controlled uses count of param "
3351 "%i bumped down to %i\n", param_index
, c
);
3353 && (to_del
= node
->find_reference (cs
->callee
, NULL
, 0)))
3355 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3356 fprintf (dump_file
, " and even removing its "
3357 "cloning-created reference\n");
3358 to_del
->remove_reference ();
3364 /* Turning calls to direct calls will improve overall summary. */
3366 ipa_update_overall_fn_summary (node
);
3369 class edge_clone_summary
;
3370 static call_summary
<edge_clone_summary
*> *edge_clone_summaries
= NULL
;
3372 /* Edge clone summary. */
3374 struct edge_clone_summary
3376 /* Default constructor. */
3377 edge_clone_summary (): prev_clone (NULL
), next_clone (NULL
) {}
3379 /* Default destructor. */
3380 ~edge_clone_summary ()
3383 edge_clone_summaries
->get (prev_clone
)->next_clone
= next_clone
;
3385 edge_clone_summaries
->get (next_clone
)->prev_clone
= prev_clone
;
3388 cgraph_edge
*prev_clone
;
3389 cgraph_edge
*next_clone
;
3392 class edge_clone_summary_t
:
3393 public call_summary
<edge_clone_summary
*>
3396 edge_clone_summary_t (symbol_table
*symtab
):
3397 call_summary
<edge_clone_summary
*> (symtab
)
3399 m_initialize_when_cloning
= true;
3402 virtual void duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
3403 edge_clone_summary
*src_data
,
3404 edge_clone_summary
*dst_data
);
3407 /* Edge duplication hook. */
3410 edge_clone_summary_t::duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
3411 edge_clone_summary
*src_data
,
3412 edge_clone_summary
*dst_data
)
3414 if (src_data
->next_clone
)
3415 edge_clone_summaries
->get (src_data
->next_clone
)->prev_clone
= dst_edge
;
3416 dst_data
->prev_clone
= src_edge
;
3417 dst_data
->next_clone
= src_data
->next_clone
;
3418 src_data
->next_clone
= dst_edge
;
3421 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3422 parameter with the given INDEX. */
3425 get_clone_agg_value (struct cgraph_node
*node
, HOST_WIDE_INT offset
,
3428 struct ipa_agg_replacement_value
*aggval
;
3430 aggval
= ipa_get_agg_replacements_for_node (node
);
3433 if (aggval
->offset
== offset
3434 && aggval
->index
== index
)
3435 return aggval
->value
;
3436 aggval
= aggval
->next
;
3441 /* Return true is NODE is DEST or its clone for all contexts. */
3444 same_node_or_its_all_contexts_clone_p (cgraph_node
*node
, cgraph_node
*dest
)
3449 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3450 return info
->is_all_contexts_clone
&& info
->ipcp_orig_node
== dest
;
3453 /* Return true if edge CS does bring about the value described by SRC to
3454 DEST_VAL of node DEST or its clone for all contexts. */
3457 cgraph_edge_brings_value_p (cgraph_edge
*cs
, ipcp_value_source
<tree
> *src
,
3458 cgraph_node
*dest
, ipcp_value
<tree
> *dest_val
)
3460 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3461 enum availability availability
;
3462 cgraph_node
*real_dest
= cs
->callee
->function_symbol (&availability
);
3464 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3465 || availability
<= AVAIL_INTERPOSABLE
3466 || caller_info
->node_dead
)
3472 if (caller_info
->ipcp_orig_node
)
3475 if (src
->offset
== -1)
3476 t
= caller_info
->known_csts
[src
->index
];
3478 t
= get_clone_agg_value (cs
->caller
, src
->offset
, src
->index
);
3479 return (t
!= NULL_TREE
3480 && values_equal_for_ipcp_p (src
->val
->value
, t
));
3484 /* At the moment we do not propagate over arithmetic jump functions in
3485 SCCs, so it is safe to detect self-feeding recursive calls in this
3487 if (src
->val
== dest_val
)
3490 struct ipcp_agg_lattice
*aglat
;
3491 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3493 if (src
->offset
== -1)
3494 return (plats
->itself
.is_single_const ()
3495 && values_equal_for_ipcp_p (src
->val
->value
,
3496 plats
->itself
.values
->value
));
3499 if (plats
->aggs_bottom
|| plats
->aggs_contain_variable
)
3501 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3502 if (aglat
->offset
== src
->offset
)
3503 return (aglat
->is_single_const ()
3504 && values_equal_for_ipcp_p (src
->val
->value
,
3505 aglat
->values
->value
));
3511 /* Return true if edge CS does bring about the value described by SRC to
3512 DST_VAL of node DEST or its clone for all contexts. */
3515 cgraph_edge_brings_value_p (cgraph_edge
*cs
,
3516 ipcp_value_source
<ipa_polymorphic_call_context
> *src
,
3518 ipcp_value
<ipa_polymorphic_call_context
> *)
3520 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3521 cgraph_node
*real_dest
= cs
->callee
->function_symbol ();
3523 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3524 || caller_info
->node_dead
)
3529 if (caller_info
->ipcp_orig_node
)
3530 return (caller_info
->known_contexts
.length () > (unsigned) src
->index
)
3531 && values_equal_for_ipcp_p (src
->val
->value
,
3532 caller_info
->known_contexts
[src
->index
]);
3534 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3536 return plats
->ctxlat
.is_single_const ()
3537 && values_equal_for_ipcp_p (src
->val
->value
,
3538 plats
->ctxlat
.values
->value
);
3541 /* Get the next clone in the linked list of clones of an edge. */
3543 static inline struct cgraph_edge
*
3544 get_next_cgraph_edge_clone (struct cgraph_edge
*cs
)
3546 edge_clone_summary
*s
= edge_clone_summaries
->get (cs
);
3547 return s
!= NULL
? s
->next_clone
: NULL
;
3550 /* Given VAL that is intended for DEST, iterate over all its sources and if any
3551 of them is viable and hot, return true. In that case, for those that still
3552 hold, add their edge frequency and their number into *FREQUENCY and
3553 *CALLER_COUNT respectively. */
3555 template <typename valtype
>
3557 get_info_about_necessary_edges (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3559 profile_count
*count_sum
, int *caller_count
)
3561 ipcp_value_source
<valtype
> *src
;
3562 int freq
= 0, count
= 0;
3563 profile_count cnt
= profile_count::zero ();
3565 bool non_self_recursive
= false;
3567 for (src
= val
->sources
; src
; src
= src
->next
)
3569 struct cgraph_edge
*cs
= src
->cs
;
3572 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
3575 freq
+= cs
->frequency ();
3576 if (cs
->count
.ipa ().initialized_p ())
3577 cnt
+= cs
->count
.ipa ();
3578 hot
|= cs
->maybe_hot_p ();
3579 if (cs
->caller
!= dest
)
3580 non_self_recursive
= true;
3582 cs
= get_next_cgraph_edge_clone (cs
);
3586 /* If the only edges bringing a value are self-recursive ones, do not bother
3588 if (!non_self_recursive
)
3593 *caller_count
= count
;
3597 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
3598 is assumed their number is known and equal to CALLER_COUNT. */
3600 template <typename valtype
>
3601 static vec
<cgraph_edge
*>
3602 gather_edges_for_value (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3605 ipcp_value_source
<valtype
> *src
;
3606 vec
<cgraph_edge
*> ret
;
3608 ret
.create (caller_count
);
3609 for (src
= val
->sources
; src
; src
= src
->next
)
3611 struct cgraph_edge
*cs
= src
->cs
;
3614 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
3615 ret
.quick_push (cs
);
3616 cs
= get_next_cgraph_edge_clone (cs
);
3623 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3624 Return it or NULL if for some reason it cannot be created. */
3626 static struct ipa_replace_map
*
3627 get_replacement_map (struct ipa_node_params
*info
, tree value
, int parm_num
)
3629 struct ipa_replace_map
*replace_map
;
3632 replace_map
= ggc_alloc
<ipa_replace_map
> ();
3635 fprintf (dump_file
, " replacing ");
3636 ipa_dump_param (dump_file
, info
, parm_num
);
3638 fprintf (dump_file
, " with const ");
3639 print_generic_expr (dump_file
, value
);
3640 fprintf (dump_file
, "\n");
3642 replace_map
->old_tree
= NULL
;
3643 replace_map
->parm_num
= parm_num
;
3644 replace_map
->new_tree
= value
;
3645 replace_map
->replace_p
= true;
3646 replace_map
->ref_p
= false;
3651 /* Dump new profiling counts */
3654 dump_profile_updates (struct cgraph_node
*orig_node
,
3655 struct cgraph_node
*new_node
)
3657 struct cgraph_edge
*cs
;
3659 fprintf (dump_file
, " setting count of the specialized node to ");
3660 new_node
->count
.dump (dump_file
);
3661 fprintf (dump_file
, "\n");
3662 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3664 fprintf (dump_file
, " edge to %s has count ",
3665 cs
->callee
->name ());
3666 cs
->count
.dump (dump_file
);
3667 fprintf (dump_file
, "\n");
3670 fprintf (dump_file
, " setting count of the original node to ");
3671 orig_node
->count
.dump (dump_file
);
3672 fprintf (dump_file
, "\n");
3673 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3675 fprintf (dump_file
, " edge to %s is left with ",
3676 cs
->callee
->name ());
3677 cs
->count
.dump (dump_file
);
3678 fprintf (dump_file
, "\n");
3682 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
3683 their profile information to reflect this. */
3686 update_profiling_info (struct cgraph_node
*orig_node
,
3687 struct cgraph_node
*new_node
)
3689 struct cgraph_edge
*cs
;
3690 struct caller_statistics stats
;
3691 profile_count new_sum
, orig_sum
;
3692 profile_count remainder
, orig_node_count
= orig_node
->count
;
3694 if (!(orig_node_count
.ipa () > profile_count::zero ()))
3697 init_caller_stats (&stats
);
3698 orig_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3700 orig_sum
= stats
.count_sum
;
3701 init_caller_stats (&stats
);
3702 new_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3704 new_sum
= stats
.count_sum
;
3706 if (orig_node_count
< orig_sum
+ new_sum
)
3710 fprintf (dump_file
, " Problem: node %s has too low count ",
3711 orig_node
->dump_name ());
3712 orig_node_count
.dump (dump_file
);
3713 fprintf (dump_file
, "while the sum of incoming count is ");
3714 (orig_sum
+ new_sum
).dump (dump_file
);
3715 fprintf (dump_file
, "\n");
3718 orig_node_count
= (orig_sum
+ new_sum
).apply_scale (12, 10);
3721 fprintf (dump_file
, " proceeding by pretending it was ");
3722 orig_node_count
.dump (dump_file
);
3723 fprintf (dump_file
, "\n");
3727 remainder
= orig_node_count
.combine_with_ipa_count (orig_node_count
.ipa ()
3729 new_sum
= orig_node_count
.combine_with_ipa_count (new_sum
);
3730 orig_node
->count
= remainder
;
3732 profile_count::adjust_for_ipa_scaling (&new_sum
, &orig_node_count
);
3733 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3734 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_node_count
);
3736 profile_count::adjust_for_ipa_scaling (&remainder
, &orig_node_count
);
3737 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3738 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
3741 dump_profile_updates (orig_node
, new_node
);
3744 /* Update the respective profile of specialized NEW_NODE and the original
3745 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
3746 have been redirected to the specialized version. */
3749 update_specialized_profile (struct cgraph_node
*new_node
,
3750 struct cgraph_node
*orig_node
,
3751 profile_count redirected_sum
)
3753 struct cgraph_edge
*cs
;
3754 profile_count new_node_count
, orig_node_count
= orig_node
->count
;
3758 fprintf (dump_file
, " the sum of counts of redirected edges is ");
3759 redirected_sum
.dump (dump_file
);
3760 fprintf (dump_file
, "\n");
3762 if (!(orig_node_count
> profile_count::zero ()))
3765 gcc_assert (orig_node_count
>= redirected_sum
);
3767 new_node_count
= new_node
->count
;
3768 new_node
->count
+= redirected_sum
;
3769 orig_node
->count
-= redirected_sum
;
3771 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3772 cs
->count
+= cs
->count
.apply_scale (redirected_sum
, new_node_count
);
3774 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3776 profile_count dec
= cs
->count
.apply_scale (redirected_sum
,
3782 dump_profile_updates (orig_node
, new_node
);
3785 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3786 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3787 redirect all edges in CALLERS to it. */
3789 static struct cgraph_node
*
3790 create_specialized_node (struct cgraph_node
*node
,
3791 vec
<tree
> known_csts
,
3792 vec
<ipa_polymorphic_call_context
> known_contexts
,
3793 struct ipa_agg_replacement_value
*aggvals
,
3794 vec
<cgraph_edge
*> callers
)
3796 struct ipa_node_params
*new_info
, *info
= IPA_NODE_REF (node
);
3797 vec
<ipa_replace_map
*, va_gc
> *replace_trees
= NULL
;
3798 struct ipa_agg_replacement_value
*av
;
3799 struct cgraph_node
*new_node
;
3800 int i
, count
= ipa_get_param_count (info
);
3801 bitmap args_to_skip
;
3803 gcc_assert (!info
->ipcp_orig_node
);
3805 if (node
->local
.can_change_signature
)
3807 args_to_skip
= BITMAP_GGC_ALLOC ();
3808 for (i
= 0; i
< count
; i
++)
3810 tree t
= known_csts
[i
];
3812 if (t
|| !ipa_is_param_used (info
, i
))
3813 bitmap_set_bit (args_to_skip
, i
);
3818 args_to_skip
= NULL
;
3819 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3820 fprintf (dump_file
, " cannot change function signature\n");
3823 for (i
= 0; i
< count
; i
++)
3825 tree t
= known_csts
[i
];
3828 struct ipa_replace_map
*replace_map
;
3830 gcc_checking_assert (TREE_CODE (t
) != TREE_BINFO
);
3831 replace_map
= get_replacement_map (info
, t
, i
);
3833 vec_safe_push (replace_trees
, replace_map
);
3836 auto_vec
<cgraph_edge
*, 2> self_recursive_calls
;
3837 for (i
= callers
.length () - 1; i
>= 0; i
--)
3839 cgraph_edge
*cs
= callers
[i
];
3840 if (cs
->caller
== node
)
3842 self_recursive_calls
.safe_push (cs
);
3843 callers
.unordered_remove (i
);
3847 unsigned &suffix_counter
= clone_num_suffixes
->get_or_insert (
3848 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
3850 new_node
= node
->create_virtual_clone (callers
, replace_trees
,
3851 args_to_skip
, "constprop",
3855 bool have_self_recursive_calls
= !self_recursive_calls
.is_empty ();
3856 for (unsigned j
= 0; j
< self_recursive_calls
.length (); j
++)
3858 cgraph_edge
*cs
= get_next_cgraph_edge_clone (self_recursive_calls
[j
]);
3859 /* Cloned edges can disappear during cloning as speculation can be
3860 resolved, check that we have one and that it comes from the last
3862 if (cs
&& cs
->caller
== new_node
)
3863 cs
->redirect_callee_duplicating_thunks (new_node
);
3864 /* Any future code that would make more than one clone of an outgoing
3865 edge would confuse this mechanism, so let's check that does not
3867 gcc_checking_assert (!cs
3868 || !get_next_cgraph_edge_clone (cs
)
3869 || get_next_cgraph_edge_clone (cs
)->caller
!= new_node
);
3871 if (have_self_recursive_calls
)
3872 new_node
->expand_all_artificial_thunks ();
3874 ipa_set_node_agg_value_chain (new_node
, aggvals
);
3875 for (av
= aggvals
; av
; av
= av
->next
)
3876 new_node
->maybe_create_reference (av
->value
, NULL
);
3878 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3880 fprintf (dump_file
, " the new node is %s.\n", new_node
->dump_name ());
3881 if (known_contexts
.exists ())
3883 for (i
= 0; i
< count
; i
++)
3884 if (!known_contexts
[i
].useless_p ())
3886 fprintf (dump_file
, " known ctx %i is ", i
);
3887 known_contexts
[i
].dump (dump_file
);
3891 ipa_dump_agg_replacement_values (dump_file
, aggvals
);
3893 ipa_check_create_node_params ();
3894 update_profiling_info (node
, new_node
);
3895 new_info
= IPA_NODE_REF (new_node
);
3896 new_info
->ipcp_orig_node
= node
;
3897 new_info
->known_csts
= known_csts
;
3898 new_info
->known_contexts
= known_contexts
;
3900 ipcp_discover_new_direct_edges (new_node
, known_csts
, known_contexts
, aggvals
);
3906 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
3907 simple no-operation pass-through function to itself. */
3910 self_recursive_pass_through_p (cgraph_edge
*cs
, ipa_jump_func
*jfunc
, int i
)
3912 enum availability availability
;
3913 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
3914 && availability
> AVAIL_INTERPOSABLE
3915 && jfunc
->type
== IPA_JF_PASS_THROUGH
3916 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
3917 && ipa_get_jf_pass_through_formal_id (jfunc
) == i
)
3922 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3923 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
3926 find_more_scalar_values_for_callers_subset (struct cgraph_node
*node
,
3927 vec
<tree
> known_csts
,
3928 vec
<cgraph_edge
*> callers
)
3930 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3931 int i
, count
= ipa_get_param_count (info
);
3933 for (i
= 0; i
< count
; i
++)
3935 struct cgraph_edge
*cs
;
3936 tree newval
= NULL_TREE
;
3939 tree type
= ipa_get_type (info
, i
);
3941 if (ipa_get_scalar_lat (info
, i
)->bottom
|| known_csts
[i
])
3944 FOR_EACH_VEC_ELT (callers
, j
, cs
)
3946 struct ipa_jump_func
*jump_func
;
3949 if (IPA_NODE_REF (cs
->caller
)->node_dead
)
3952 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
))
3954 && call_passes_through_thunk_p (cs
)))
3959 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
3960 if (self_recursive_pass_through_p (cs
, jump_func
, i
))
3963 t
= ipa_value_from_jfunc (IPA_NODE_REF (cs
->caller
), jump_func
, type
);
3966 && !values_equal_for_ipcp_p (t
, newval
))
3967 || (!first
&& !newval
))
3979 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3981 fprintf (dump_file
, " adding an extra known scalar value ");
3982 print_ipcp_constant_value (dump_file
, newval
);
3983 fprintf (dump_file
, " for ");
3984 ipa_dump_param (dump_file
, info
, i
);
3985 fprintf (dump_file
, "\n");
3988 known_csts
[i
] = newval
;
3993 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
3994 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
3998 find_more_contexts_for_caller_subset (cgraph_node
*node
,
3999 vec
<ipa_polymorphic_call_context
>
4001 vec
<cgraph_edge
*> callers
)
4003 ipa_node_params
*info
= IPA_NODE_REF (node
);
4004 int i
, count
= ipa_get_param_count (info
);
4006 for (i
= 0; i
< count
; i
++)
4010 if (ipa_get_poly_ctx_lat (info
, i
)->bottom
4011 || (known_contexts
->exists ()
4012 && !(*known_contexts
)[i
].useless_p ()))
4015 ipa_polymorphic_call_context newval
;
4019 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4021 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
)))
4023 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
),
4025 ipa_polymorphic_call_context ctx
;
4026 ctx
= ipa_context_from_jfunc (IPA_NODE_REF (cs
->caller
), cs
, i
,
4034 newval
.meet_with (ctx
);
4035 if (newval
.useless_p ())
4039 if (!newval
.useless_p ())
4041 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4043 fprintf (dump_file
, " adding an extra known polymorphic "
4045 print_ipcp_constant_value (dump_file
, newval
);
4046 fprintf (dump_file
, " for ");
4047 ipa_dump_param (dump_file
, info
, i
);
4048 fprintf (dump_file
, "\n");
4051 if (!known_contexts
->exists ())
4052 known_contexts
->safe_grow_cleared (ipa_get_param_count (info
));
4053 (*known_contexts
)[i
] = newval
;
4059 /* Go through PLATS and create a vector of values consisting of values and
4060 offsets (minus OFFSET) of lattices that contain only a single value. */
4062 static vec
<ipa_agg_jf_item
>
4063 copy_plats_to_inter (struct ipcp_param_lattices
*plats
, HOST_WIDE_INT offset
)
4065 vec
<ipa_agg_jf_item
> res
= vNULL
;
4067 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4070 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4071 if (aglat
->is_single_const ())
4073 struct ipa_agg_jf_item ti
;
4074 ti
.offset
= aglat
->offset
- offset
;
4075 ti
.value
= aglat
->values
->value
;
4081 /* Intersect all values in INTER with single value lattices in PLATS (while
4082 subtracting OFFSET). */
4085 intersect_with_plats (struct ipcp_param_lattices
*plats
,
4086 vec
<ipa_agg_jf_item
> *inter
,
4087 HOST_WIDE_INT offset
)
4089 struct ipcp_agg_lattice
*aglat
;
4090 struct ipa_agg_jf_item
*item
;
4093 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4099 aglat
= plats
->aggs
;
4100 FOR_EACH_VEC_ELT (*inter
, k
, item
)
4107 if (aglat
->offset
- offset
> item
->offset
)
4109 if (aglat
->offset
- offset
== item
->offset
)
4111 gcc_checking_assert (item
->value
);
4112 if (aglat
->is_single_const ()
4113 && values_equal_for_ipcp_p (item
->value
,
4114 aglat
->values
->value
))
4118 aglat
= aglat
->next
;
4121 item
->value
= NULL_TREE
;
4125 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4126 vector result while subtracting OFFSET from the individual value offsets. */
4128 static vec
<ipa_agg_jf_item
>
4129 agg_replacements_to_vector (struct cgraph_node
*node
, int index
,
4130 HOST_WIDE_INT offset
)
4132 struct ipa_agg_replacement_value
*av
;
4133 vec
<ipa_agg_jf_item
> res
= vNULL
;
4135 for (av
= ipa_get_agg_replacements_for_node (node
); av
; av
= av
->next
)
4136 if (av
->index
== index
4137 && (av
->offset
- offset
) >= 0)
4139 struct ipa_agg_jf_item item
;
4140 gcc_checking_assert (av
->value
);
4141 item
.offset
= av
->offset
- offset
;
4142 item
.value
= av
->value
;
4143 res
.safe_push (item
);
4149 /* Intersect all values in INTER with those that we have already scheduled to
4150 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4151 (while subtracting OFFSET). */
4154 intersect_with_agg_replacements (struct cgraph_node
*node
, int index
,
4155 vec
<ipa_agg_jf_item
> *inter
,
4156 HOST_WIDE_INT offset
)
4158 struct ipa_agg_replacement_value
*srcvals
;
4159 struct ipa_agg_jf_item
*item
;
4162 srcvals
= ipa_get_agg_replacements_for_node (node
);
4169 FOR_EACH_VEC_ELT (*inter
, i
, item
)
4171 struct ipa_agg_replacement_value
*av
;
4175 for (av
= srcvals
; av
; av
= av
->next
)
4177 gcc_checking_assert (av
->value
);
4178 if (av
->index
== index
4179 && av
->offset
- offset
== item
->offset
)
4181 if (values_equal_for_ipcp_p (item
->value
, av
->value
))
4187 item
->value
= NULL_TREE
;
4191 /* Intersect values in INTER with aggregate values that come along edge CS to
4192 parameter number INDEX and return it. If INTER does not actually exist yet,
4193 copy all incoming values to it. If we determine we ended up with no values
4194 whatsoever, return a released vector. */
4196 static vec
<ipa_agg_jf_item
>
4197 intersect_aggregates_with_edge (struct cgraph_edge
*cs
, int index
,
4198 vec
<ipa_agg_jf_item
> inter
)
4200 struct ipa_jump_func
*jfunc
;
4201 jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), index
);
4202 if (jfunc
->type
== IPA_JF_PASS_THROUGH
4203 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4205 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4206 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
4208 if (caller_info
->ipcp_orig_node
)
4210 struct cgraph_node
*orig_node
= caller_info
->ipcp_orig_node
;
4211 struct ipcp_param_lattices
*orig_plats
;
4212 orig_plats
= ipa_get_parm_lattices (IPA_NODE_REF (orig_node
),
4214 if (agg_pass_through_permissible_p (orig_plats
, jfunc
))
4216 if (!inter
.exists ())
4217 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, 0);
4219 intersect_with_agg_replacements (cs
->caller
, src_idx
,
4230 struct ipcp_param_lattices
*src_plats
;
4231 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4232 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
4234 /* Currently we do not produce clobber aggregate jump
4235 functions, adjust when we do. */
4236 gcc_checking_assert (!jfunc
->agg
.items
);
4237 if (!inter
.exists ())
4238 inter
= copy_plats_to_inter (src_plats
, 0);
4240 intersect_with_plats (src_plats
, &inter
, 0);
4249 else if (jfunc
->type
== IPA_JF_ANCESTOR
4250 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
4252 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4253 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
4254 struct ipcp_param_lattices
*src_plats
;
4255 HOST_WIDE_INT delta
= ipa_get_jf_ancestor_offset (jfunc
);
4257 if (caller_info
->ipcp_orig_node
)
4259 if (!inter
.exists ())
4260 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, delta
);
4262 intersect_with_agg_replacements (cs
->caller
, src_idx
, &inter
,
4267 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4268 /* Currently we do not produce clobber aggregate jump
4269 functions, adjust when we do. */
4270 gcc_checking_assert (!src_plats
->aggs
|| !jfunc
->agg
.items
);
4271 if (!inter
.exists ())
4272 inter
= copy_plats_to_inter (src_plats
, delta
);
4274 intersect_with_plats (src_plats
, &inter
, delta
);
4277 else if (jfunc
->agg
.items
)
4279 struct ipa_agg_jf_item
*item
;
4282 if (!inter
.exists ())
4283 for (unsigned i
= 0; i
< jfunc
->agg
.items
->length (); i
++)
4284 inter
.safe_push ((*jfunc
->agg
.items
)[i
]);
4286 FOR_EACH_VEC_ELT (inter
, k
, item
)
4294 while ((unsigned) l
< jfunc
->agg
.items
->length ())
4296 struct ipa_agg_jf_item
*ti
;
4297 ti
= &(*jfunc
->agg
.items
)[l
];
4298 if (ti
->offset
> item
->offset
)
4300 if (ti
->offset
== item
->offset
)
4302 gcc_checking_assert (ti
->value
);
4303 if (values_equal_for_ipcp_p (item
->value
,
4317 return vec
<ipa_agg_jf_item
>();
4322 /* Look at edges in CALLERS and collect all known aggregate values that arrive
4323 from all of them. */
4325 static struct ipa_agg_replacement_value
*
4326 find_aggregate_values_for_callers_subset (struct cgraph_node
*node
,
4327 vec
<cgraph_edge
*> callers
)
4329 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4330 struct ipa_agg_replacement_value
*res
;
4331 struct ipa_agg_replacement_value
**tail
= &res
;
4332 struct cgraph_edge
*cs
;
4333 int i
, j
, count
= ipa_get_param_count (dest_info
);
4335 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4337 int c
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4342 for (i
= 0; i
< count
; i
++)
4344 struct cgraph_edge
*cs
;
4345 vec
<ipa_agg_jf_item
> inter
= vNULL
;
4346 struct ipa_agg_jf_item
*item
;
4347 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (dest_info
, i
);
4350 /* Among other things, the following check should deal with all by_ref
4352 if (plats
->aggs_bottom
)
4355 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4357 struct ipa_jump_func
*jfunc
4358 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
4359 if (self_recursive_pass_through_p (cs
, jfunc
, i
)
4360 && (!plats
->aggs_by_ref
4361 || ipa_get_jf_pass_through_agg_preserved (jfunc
)))
4363 inter
= intersect_aggregates_with_edge (cs
, i
, inter
);
4365 if (!inter
.exists ())
4369 FOR_EACH_VEC_ELT (inter
, j
, item
)
4371 struct ipa_agg_replacement_value
*v
;
4376 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
4378 v
->offset
= item
->offset
;
4379 v
->value
= item
->value
;
4380 v
->by_ref
= plats
->aggs_by_ref
;
4386 if (inter
.exists ())
4393 /* Determine whether CS also brings all scalar values that the NODE is
4397 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge
*cs
,
4398 struct cgraph_node
*node
)
4400 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4401 int count
= ipa_get_param_count (dest_info
);
4402 struct ipa_node_params
*caller_info
;
4403 struct ipa_edge_args
*args
;
4406 caller_info
= IPA_NODE_REF (cs
->caller
);
4407 args
= IPA_EDGE_REF (cs
);
4408 for (i
= 0; i
< count
; i
++)
4410 struct ipa_jump_func
*jump_func
;
4413 val
= dest_info
->known_csts
[i
];
4417 if (i
>= ipa_get_cs_argument_count (args
))
4419 jump_func
= ipa_get_ith_jump_func (args
, i
);
4420 t
= ipa_value_from_jfunc (caller_info
, jump_func
,
4421 ipa_get_type (dest_info
, i
));
4422 if (!t
|| !values_equal_for_ipcp_p (val
, t
))
4428 /* Determine whether CS also brings all aggregate values that NODE is
4431 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge
*cs
,
4432 struct cgraph_node
*node
)
4434 struct ipa_node_params
*orig_caller_info
= IPA_NODE_REF (cs
->caller
);
4435 struct ipa_node_params
*orig_node_info
;
4436 struct ipa_agg_replacement_value
*aggval
;
4439 aggval
= ipa_get_agg_replacements_for_node (node
);
4443 count
= ipa_get_param_count (IPA_NODE_REF (node
));
4444 ec
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4446 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4447 if (aggval
->index
>= ec
)
4450 orig_node_info
= IPA_NODE_REF (IPA_NODE_REF (node
)->ipcp_orig_node
);
4451 if (orig_caller_info
->ipcp_orig_node
)
4452 orig_caller_info
= IPA_NODE_REF (orig_caller_info
->ipcp_orig_node
);
4454 for (i
= 0; i
< count
; i
++)
4456 static vec
<ipa_agg_jf_item
> values
= vec
<ipa_agg_jf_item
>();
4457 struct ipcp_param_lattices
*plats
;
4458 bool interesting
= false;
4459 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4460 if (aggval
->index
== i
)
4468 plats
= ipa_get_parm_lattices (orig_node_info
, aggval
->index
);
4469 if (plats
->aggs_bottom
)
4472 values
= intersect_aggregates_with_edge (cs
, i
, values
);
4473 if (!values
.exists ())
4476 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4477 if (aggval
->index
== i
)
4479 struct ipa_agg_jf_item
*item
;
4482 FOR_EACH_VEC_ELT (values
, j
, item
)
4484 && item
->offset
== av
->offset
4485 && values_equal_for_ipcp_p (item
->value
, av
->value
))
4500 /* Given an original NODE and a VAL for which we have already created a
4501 specialized clone, look whether there are incoming edges that still lead
4502 into the old node but now also bring the requested value and also conform to
4503 all other criteria such that they can be redirected the special node.
4504 This function can therefore redirect the final edge in a SCC. */
4506 template <typename valtype
>
4508 perhaps_add_new_callers (cgraph_node
*node
, ipcp_value
<valtype
> *val
)
4510 ipcp_value_source
<valtype
> *src
;
4511 profile_count redirected_sum
= profile_count::zero ();
4513 for (src
= val
->sources
; src
; src
= src
->next
)
4515 struct cgraph_edge
*cs
= src
->cs
;
4518 if (cgraph_edge_brings_value_p (cs
, src
, node
, val
)
4519 && cgraph_edge_brings_all_scalars_for_node (cs
, val
->spec_node
)
4520 && cgraph_edge_brings_all_agg_vals_for_node (cs
, val
->spec_node
))
4523 fprintf (dump_file
, " - adding an extra caller %s of %s\n",
4524 cs
->caller
->dump_name (),
4525 val
->spec_node
->dump_name ());
4527 cs
->redirect_callee_duplicating_thunks (val
->spec_node
);
4528 val
->spec_node
->expand_all_artificial_thunks ();
4529 if (cs
->count
.ipa ().initialized_p ())
4530 redirected_sum
= redirected_sum
+ cs
->count
.ipa ();
4532 cs
= get_next_cgraph_edge_clone (cs
);
4536 if (redirected_sum
.nonzero_p ())
4537 update_specialized_profile (val
->spec_node
, node
, redirected_sum
);
4540 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
4543 known_contexts_useful_p (vec
<ipa_polymorphic_call_context
> known_contexts
)
4545 ipa_polymorphic_call_context
*ctx
;
4548 FOR_EACH_VEC_ELT (known_contexts
, i
, ctx
)
4549 if (!ctx
->useless_p ())
4554 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
4556 static vec
<ipa_polymorphic_call_context
>
4557 copy_useful_known_contexts (vec
<ipa_polymorphic_call_context
> known_contexts
)
4559 if (known_contexts_useful_p (known_contexts
))
4560 return known_contexts
.copy ();
4565 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX. If
4566 non-empty, replace KNOWN_CONTEXTS with its copy too. */
4569 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4570 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4571 ipcp_value
<tree
> *val
,
4574 *known_csts
= known_csts
->copy ();
4575 *known_contexts
= copy_useful_known_contexts (*known_contexts
);
4576 (*known_csts
)[index
] = val
->value
;
4579 /* Replace KNOWN_CSTS with its copy. Also copy KNOWN_CONTEXTS and modify the
4580 copy according to VAL and INDEX. */
4583 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4584 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4585 ipcp_value
<ipa_polymorphic_call_context
> *val
,
4588 *known_csts
= known_csts
->copy ();
4589 *known_contexts
= known_contexts
->copy ();
4590 (*known_contexts
)[index
] = val
->value
;
4593 /* Return true if OFFSET indicates this was not an aggregate value or there is
4594 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
4598 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*aggvals
,
4599 int index
, HOST_WIDE_INT offset
, tree value
)
4606 if (aggvals
->index
== index
4607 && aggvals
->offset
== offset
4608 && values_equal_for_ipcp_p (aggvals
->value
, value
))
4610 aggvals
= aggvals
->next
;
4615 /* Return true if offset is minus one because source of a polymorphic context
4616 cannot be an aggregate value. */
4619 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*,
4620 int , HOST_WIDE_INT offset
,
4621 ipa_polymorphic_call_context
)
4623 return offset
== -1;
4626 /* Decide whether to create a special version of NODE for value VAL of parameter
4627 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
4628 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
4629 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
4631 template <typename valtype
>
4633 decide_about_value (struct cgraph_node
*node
, int index
, HOST_WIDE_INT offset
,
4634 ipcp_value
<valtype
> *val
, vec
<tree
> known_csts
,
4635 vec
<ipa_polymorphic_call_context
> known_contexts
)
4637 struct ipa_agg_replacement_value
*aggvals
;
4638 int freq_sum
, caller_count
;
4639 profile_count count_sum
;
4640 vec
<cgraph_edge
*> callers
;
4644 perhaps_add_new_callers (node
, val
);
4647 else if (val
->local_size_cost
+ overall_size
> max_new_size
)
4649 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4650 fprintf (dump_file
, " Ignoring candidate value because "
4651 "max_new_size would be reached with %li.\n",
4652 val
->local_size_cost
+ overall_size
);
4655 else if (!get_info_about_necessary_edges (val
, node
, &freq_sum
, &count_sum
,
4659 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4661 fprintf (dump_file
, " - considering value ");
4662 print_ipcp_constant_value (dump_file
, val
->value
);
4663 fprintf (dump_file
, " for ");
4664 ipa_dump_param (dump_file
, IPA_NODE_REF (node
), index
);
4666 fprintf (dump_file
, ", offset: " HOST_WIDE_INT_PRINT_DEC
, offset
);
4667 fprintf (dump_file
, " (caller_count: %i)\n", caller_count
);
4670 if (!good_cloning_opportunity_p (node
, val
->local_time_benefit
,
4671 freq_sum
, count_sum
,
4672 val
->local_size_cost
)
4673 && !good_cloning_opportunity_p (node
,
4674 val
->local_time_benefit
4675 + val
->prop_time_benefit
,
4676 freq_sum
, count_sum
,
4677 val
->local_size_cost
4678 + val
->prop_size_cost
))
4682 fprintf (dump_file
, " Creating a specialized node of %s.\n",
4683 node
->dump_name ());
4685 callers
= gather_edges_for_value (val
, node
, caller_count
);
4687 modify_known_vectors_with_val (&known_csts
, &known_contexts
, val
, index
);
4690 known_csts
= known_csts
.copy ();
4691 known_contexts
= copy_useful_known_contexts (known_contexts
);
4693 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
4694 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
4695 aggvals
= find_aggregate_values_for_callers_subset (node
, callers
);
4696 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals
, index
,
4697 offset
, val
->value
));
4698 val
->spec_node
= create_specialized_node (node
, known_csts
, known_contexts
,
4700 overall_size
+= val
->local_size_cost
;
4702 /* TODO: If for some lattice there is only one other known value
4703 left, make a special node for it too. */
4708 /* Decide whether and what specialized clones of NODE should be created. */
4711 decide_whether_version_node (struct cgraph_node
*node
)
4713 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4714 int i
, count
= ipa_get_param_count (info
);
4715 vec
<tree
> known_csts
;
4716 vec
<ipa_polymorphic_call_context
> known_contexts
;
4717 vec
<ipa_agg_jump_function
> known_aggs
= vNULL
;
4723 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4724 fprintf (dump_file
, "\nEvaluating opportunities for %s.\n",
4725 node
->dump_name ());
4727 gather_context_independent_values (info
, &known_csts
, &known_contexts
,
4728 info
->do_clone_for_all_contexts
? &known_aggs
4731 for (i
= 0; i
< count
;i
++)
4733 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4734 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
4735 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
4740 ipcp_value
<tree
> *val
;
4741 for (val
= lat
->values
; val
; val
= val
->next
)
4742 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4746 if (!plats
->aggs_bottom
)
4748 struct ipcp_agg_lattice
*aglat
;
4749 ipcp_value
<tree
> *val
;
4750 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4751 if (!aglat
->bottom
&& aglat
->values
4752 /* If the following is false, the one value is in
4754 && (plats
->aggs_contain_variable
4755 || !aglat
->is_single_const ()))
4756 for (val
= aglat
->values
; val
; val
= val
->next
)
4757 ret
|= decide_about_value (node
, i
, aglat
->offset
, val
,
4758 known_csts
, known_contexts
);
4762 && known_contexts
[i
].useless_p ())
4764 ipcp_value
<ipa_polymorphic_call_context
> *val
;
4765 for (val
= ctxlat
->values
; val
; val
= val
->next
)
4766 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4770 info
= IPA_NODE_REF (node
);
4773 if (info
->do_clone_for_all_contexts
)
4775 struct cgraph_node
*clone
;
4776 vec
<cgraph_edge
*> callers
;
4779 fprintf (dump_file
, " - Creating a specialized node of %s "
4780 "for all known contexts.\n", node
->dump_name ());
4782 callers
= node
->collect_callers ();
4783 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
4784 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
4785 ipa_agg_replacement_value
*aggvals
4786 = find_aggregate_values_for_callers_subset (node
, callers
);
4788 if (!known_contexts_useful_p (known_contexts
))
4790 known_contexts
.release ();
4791 known_contexts
= vNULL
;
4793 clone
= create_specialized_node (node
, known_csts
, known_contexts
,
4795 info
= IPA_NODE_REF (node
);
4796 info
->do_clone_for_all_contexts
= false;
4797 IPA_NODE_REF (clone
)->is_all_contexts_clone
= true;
4798 for (i
= 0; i
< count
; i
++)
4799 vec_free (known_aggs
[i
].items
);
4800 known_aggs
.release ();
4805 known_csts
.release ();
4806 known_contexts
.release ();
4812 /* Transitively mark all callees of NODE within the same SCC as not dead. */
4815 spread_undeadness (struct cgraph_node
*node
)
4817 struct cgraph_edge
*cs
;
4819 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
4820 if (ipa_edge_within_scc (cs
))
4822 struct cgraph_node
*callee
;
4823 struct ipa_node_params
*info
;
4825 callee
= cs
->callee
->function_symbol (NULL
);
4826 info
= IPA_NODE_REF (callee
);
4828 if (info
->node_dead
)
4830 info
->node_dead
= 0;
4831 spread_undeadness (callee
);
4836 /* Return true if NODE has a caller from outside of its SCC that is not
4837 dead. Worker callback for cgraph_for_node_and_aliases. */
4840 has_undead_caller_from_outside_scc_p (struct cgraph_node
*node
,
4841 void *data ATTRIBUTE_UNUSED
)
4843 struct cgraph_edge
*cs
;
4845 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4846 if (cs
->caller
->thunk
.thunk_p
4847 && cs
->caller
->call_for_symbol_thunks_and_aliases
4848 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4850 else if (!ipa_edge_within_scc (cs
)
4851 && !IPA_NODE_REF (cs
->caller
)->node_dead
)
4857 /* Identify nodes within the same SCC as NODE which are no longer needed
4858 because of new clones and will be removed as unreachable. */
4861 identify_dead_nodes (struct cgraph_node
*node
)
4863 struct cgraph_node
*v
;
4864 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4866 && !v
->call_for_symbol_thunks_and_aliases
4867 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4868 IPA_NODE_REF (v
)->node_dead
= 1;
4870 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4871 if (!IPA_NODE_REF (v
)->node_dead
)
4872 spread_undeadness (v
);
4874 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4876 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4877 if (IPA_NODE_REF (v
)->node_dead
)
4878 fprintf (dump_file
, " Marking node as dead: %s.\n", v
->dump_name ());
4882 /* The decision stage. Iterate over the topological order of call graph nodes
4883 TOPO and make specialized clones if deemed beneficial. */
4886 ipcp_decision_stage (struct ipa_topo_info
*topo
)
4891 fprintf (dump_file
, "\nIPA decision stage:\n\n");
4893 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
4895 struct cgraph_node
*node
= topo
->order
[i
];
4896 bool change
= false, iterate
= true;
4900 struct cgraph_node
*v
;
4902 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4903 if (v
->has_gimple_body_p ()
4904 && ipcp_versionable_function_p (v
))
4905 iterate
|= decide_whether_version_node (v
);
4910 identify_dead_nodes (node
);
4914 /* Look up all the bits information that we have discovered and copy it over
4915 to the transformation summary. */
4918 ipcp_store_bits_results (void)
4922 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4924 ipa_node_params
*info
= IPA_NODE_REF (node
);
4925 bool dumped_sth
= false;
4926 bool found_useful_result
= false;
4928 if (!opt_for_fn (node
->decl
, flag_ipa_bit_cp
))
4931 fprintf (dump_file
, "Not considering %s for ipa bitwise propagation "
4932 "; -fipa-bit-cp: disabled.\n",
4937 if (info
->ipcp_orig_node
)
4938 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
4940 unsigned count
= ipa_get_param_count (info
);
4941 for (unsigned i
= 0; i
< count
; i
++)
4943 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4944 if (plats
->bits_lattice
.constant_p ())
4946 found_useful_result
= true;
4951 if (!found_useful_result
)
4954 ipcp_transformation_initialize ();
4955 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
4956 vec_safe_reserve_exact (ts
->bits
, count
);
4958 for (unsigned i
= 0; i
< count
; i
++)
4960 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4963 if (plats
->bits_lattice
.constant_p ())
4965 = ipa_get_ipa_bits_for_value (plats
->bits_lattice
.get_value (),
4966 plats
->bits_lattice
.get_mask ());
4970 ts
->bits
->quick_push (jfbits
);
4971 if (!dump_file
|| !jfbits
)
4975 fprintf (dump_file
, "Propagated bits info for function %s:\n",
4976 node
->dump_name ());
4979 fprintf (dump_file
, " param %i: value = ", i
);
4980 print_hex (jfbits
->value
, dump_file
);
4981 fprintf (dump_file
, ", mask = ");
4982 print_hex (jfbits
->mask
, dump_file
);
4983 fprintf (dump_file
, "\n");
4988 /* Look up all VR information that we have discovered and copy it over
4989 to the transformation summary. */
4992 ipcp_store_vr_results (void)
4996 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4998 ipa_node_params
*info
= IPA_NODE_REF (node
);
4999 bool found_useful_result
= false;
5001 if (!opt_for_fn (node
->decl
, flag_ipa_vrp
))
5004 fprintf (dump_file
, "Not considering %s for VR discovery "
5005 "and propagate; -fipa-ipa-vrp: disabled.\n",
5010 if (info
->ipcp_orig_node
)
5011 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
5013 unsigned count
= ipa_get_param_count (info
);
5014 for (unsigned i
= 0; i
< count
; i
++)
5016 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5017 if (!plats
->m_value_range
.bottom_p ()
5018 && !plats
->m_value_range
.top_p ())
5020 found_useful_result
= true;
5024 if (!found_useful_result
)
5027 ipcp_transformation_initialize ();
5028 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5029 vec_safe_reserve_exact (ts
->m_vr
, count
);
5031 for (unsigned i
= 0; i
< count
; i
++)
5033 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5036 if (!plats
->m_value_range
.bottom_p ()
5037 && !plats
->m_value_range
.top_p ())
5040 vr
.type
= plats
->m_value_range
.m_vr
.kind ();
5041 vr
.min
= wi::to_wide (plats
->m_value_range
.m_vr
.min ());
5042 vr
.max
= wi::to_wide (plats
->m_value_range
.m_vr
.max ());
5047 vr
.type
= VR_VARYING
;
5048 vr
.min
= vr
.max
= wi::zero (INT_TYPE_SIZE
);
5050 ts
->m_vr
->quick_push (vr
);
5055 /* The IPCP driver. */
5060 struct ipa_topo_info topo
;
5062 if (edge_clone_summaries
== NULL
)
5063 edge_clone_summaries
= new edge_clone_summary_t (symtab
);
5065 ipa_check_create_node_params ();
5066 ipa_check_create_edge_args ();
5067 clone_num_suffixes
= new hash_map
<const char *, unsigned>;
5071 fprintf (dump_file
, "\nIPA structures before propagation:\n");
5072 if (dump_flags
& TDF_DETAILS
)
5073 ipa_print_all_params (dump_file
);
5074 ipa_print_all_jump_functions (dump_file
);
5077 /* Topological sort. */
5078 build_toporder_info (&topo
);
5079 /* Do the interprocedural propagation. */
5080 ipcp_propagate_stage (&topo
);
5081 /* Decide what constant propagation and cloning should be performed. */
5082 ipcp_decision_stage (&topo
);
5083 /* Store results of bits propagation. */
5084 ipcp_store_bits_results ();
5085 /* Store results of value range propagation. */
5086 ipcp_store_vr_results ();
5088 /* Free all IPCP structures. */
5089 delete clone_num_suffixes
;
5090 free_toporder_info (&topo
);
5091 delete edge_clone_summaries
;
5092 edge_clone_summaries
= NULL
;
5093 ipa_free_all_structures_after_ipa_cp ();
5095 fprintf (dump_file
, "\nIPA constant propagation end\n");
5099 /* Initialization and computation of IPCP data structures. This is the initial
5100 intraprocedural analysis of functions, which gathers information to be
5101 propagated later on. */
5104 ipcp_generate_summary (void)
5106 struct cgraph_node
*node
;
5109 fprintf (dump_file
, "\nIPA constant propagation start:\n");
5110 ipa_register_cgraph_hooks ();
5112 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5113 ipa_analyze_node (node
);
5116 /* Write ipcp summary for nodes in SET. */
5119 ipcp_write_summary (void)
5121 ipa_prop_write_jump_functions ();
5124 /* Read ipcp summary. */
5127 ipcp_read_summary (void)
5129 ipa_prop_read_jump_functions ();
5134 const pass_data pass_data_ipa_cp
=
5136 IPA_PASS
, /* type */
5138 OPTGROUP_NONE
, /* optinfo_flags */
5139 TV_IPA_CONSTANT_PROP
, /* tv_id */
5140 0, /* properties_required */
5141 0, /* properties_provided */
5142 0, /* properties_destroyed */
5143 0, /* todo_flags_start */
5144 ( TODO_dump_symtab
| TODO_remove_functions
), /* todo_flags_finish */
5147 class pass_ipa_cp
: public ipa_opt_pass_d
5150 pass_ipa_cp (gcc::context
*ctxt
)
5151 : ipa_opt_pass_d (pass_data_ipa_cp
, ctxt
,
5152 ipcp_generate_summary
, /* generate_summary */
5153 ipcp_write_summary
, /* write_summary */
5154 ipcp_read_summary
, /* read_summary */
5155 ipcp_write_transformation_summaries
, /*
5156 write_optimization_summary */
5157 ipcp_read_transformation_summaries
, /*
5158 read_optimization_summary */
5159 NULL
, /* stmt_fixup */
5160 0, /* function_transform_todo_flags_start */
5161 ipcp_transform_function
, /* function_transform */
5162 NULL
) /* variable_transform */
5165 /* opt_pass methods: */
5166 virtual bool gate (function
*)
5168 /* FIXME: We should remove the optimize check after we ensure we never run
5169 IPA passes when not optimizing. */
5170 return (flag_ipa_cp
&& optimize
) || in_lto_p
;
5173 virtual unsigned int execute (function
*) { return ipcp_driver (); }
5175 }; // class pass_ipa_cp
5180 make_pass_ipa_cp (gcc::context
*ctxt
)
5182 return new pass_ipa_cp (ctxt
);
5185 /* Reset all state within ipa-cp.c so that we can rerun the compiler
5186 within the same process. For use by toplev::finalize. */
5189 ipa_cp_c_finalize (void)
5191 max_count
= profile_count::uninitialized ();