1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2021 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"
111 #include "alloc-pool.h"
112 #include "tree-pass.h"
114 #include "diagnostic.h"
115 #include "fold-const.h"
116 #include "gimple-fold.h"
117 #include "symbol-summary.h"
118 #include "tree-vrp.h"
119 #include "ipa-prop.h"
120 #include "tree-pretty-print.h"
121 #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 #include "symtab-clones.h"
130 template <typename valtype
> class ipcp_value
;
132 /* Describes a particular source for an IPA-CP value. */
134 template <typename valtype
>
135 struct ipcp_value_source
138 /* Aggregate offset of the source, negative if the source is scalar value of
139 the argument itself. */
140 HOST_WIDE_INT offset
;
141 /* The incoming edge that brought the value. */
143 /* If the jump function that resulted into his value was a pass-through or an
144 ancestor, this is the ipcp_value of the caller from which the described
145 value has been derived. Otherwise it is NULL. */
146 ipcp_value
<valtype
> *val
;
147 /* Next pointer in a linked list of sources of a value. */
148 ipcp_value_source
*next
;
149 /* If the jump function that resulted into his value was a pass-through or an
150 ancestor, this is the index of the parameter of the caller the jump
151 function references. */
155 /* Common ancestor for all ipcp_value instantiations. */
157 class ipcp_value_base
160 /* Time benefit and that specializing the function for this value would bring
161 about in this function alone. */
162 sreal local_time_benefit
;
163 /* Time benefit that specializing the function for this value can bring about
165 sreal prop_time_benefit
;
166 /* Size cost that specializing the function for this value would bring about
167 in this function alone. */
169 /* Size cost that specializing the function for this value can bring about in
174 : local_time_benefit (0), prop_time_benefit (0),
175 local_size_cost (0), prop_size_cost (0) {}
178 /* Describes one particular value stored in struct ipcp_lattice. */
180 template <typename valtype
>
181 class ipcp_value
: public ipcp_value_base
184 /* The actual value for the given parameter. */
186 /* The list of sources from which this value originates. */
187 ipcp_value_source
<valtype
> *sources
;
188 /* Next pointers in a linked list of all values in a lattice. */
190 /* Next pointers in a linked list of values in a strongly connected component
192 ipcp_value
*scc_next
;
193 /* Next pointers in a linked list of SCCs of values sorted topologically
194 according their sources. */
195 ipcp_value
*topo_next
;
196 /* A specialized node created for this value, NULL if none has been (so far)
198 cgraph_node
*spec_node
;
199 /* Depth first search number and low link for topological sorting of
202 /* True if this value is currently on the topo-sort stack. */
206 : sources (0), next (0), scc_next (0), topo_next (0),
207 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
209 void add_source (cgraph_edge
*cs
, ipcp_value
*src_val
, int src_idx
,
210 HOST_WIDE_INT offset
);
213 /* Lattice describing potential values of a formal parameter of a function, or
214 a part of an aggregate. TOP is represented by a lattice with zero values
215 and with contains_variable and bottom flags cleared. BOTTOM is represented
216 by a lattice with the bottom flag set. In that case, values and
217 contains_variable flag should be disregarded. */
219 template <typename valtype
>
223 /* The list of known values and types in this lattice. Note that values are
224 not deallocated if a lattice is set to bottom because there may be value
225 sources referencing them. */
226 ipcp_value
<valtype
> *values
;
227 /* Number of known values and types in this lattice. */
229 /* The lattice contains a variable component (in addition to values). */
230 bool contains_variable
;
231 /* The value of the lattice is bottom (i.e. variable and unusable for any
235 inline bool is_single_const ();
236 inline bool set_to_bottom ();
237 inline bool set_contains_variable ();
238 bool add_value (valtype newval
, cgraph_edge
*cs
,
239 ipcp_value
<valtype
> *src_val
= NULL
,
240 int src_idx
= 0, HOST_WIDE_INT offset
= -1,
241 ipcp_value
<valtype
> **val_p
= NULL
,
242 bool unlimited
= false);
243 void print (FILE * f
, bool dump_sources
, bool dump_benefits
);
246 /* Lattice of tree values with an offset to describe a part of an
249 struct ipcp_agg_lattice
: public ipcp_lattice
<tree
>
252 /* Offset that is being described by this lattice. */
253 HOST_WIDE_INT offset
;
254 /* Size so that we don't have to re-compute it every time we traverse the
255 list. Must correspond to TYPE_SIZE of all lat values. */
257 /* Next element of the linked list. */
258 struct ipcp_agg_lattice
*next
;
261 /* Lattice of known bits, only capable of holding one value.
262 Bitwise constant propagation propagates which bits of a
278 In the above case, the param 'x' will always have all
279 the bits (except the bits in lsb) set to 0.
280 Hence the mask of 'x' would be 0xff. The mask
281 reflects that the bits in lsb are unknown.
282 The actual propagated value is given by m_value & ~m_mask. */
284 class ipcp_bits_lattice
287 bool bottom_p () { return m_lattice_val
== IPA_BITS_VARYING
; }
288 bool top_p () { return m_lattice_val
== IPA_BITS_UNDEFINED
; }
289 bool constant_p () { return m_lattice_val
== IPA_BITS_CONSTANT
; }
290 bool set_to_bottom ();
291 bool set_to_constant (widest_int
, widest_int
);
293 widest_int
get_value () { return m_value
; }
294 widest_int
get_mask () { return m_mask
; }
296 bool meet_with (ipcp_bits_lattice
& other
, unsigned, signop
,
297 enum tree_code
, tree
);
299 bool meet_with (widest_int
, widest_int
, unsigned);
304 enum { IPA_BITS_UNDEFINED
, IPA_BITS_CONSTANT
, IPA_BITS_VARYING
} m_lattice_val
;
306 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
307 If a bit in mask is set to 0, then the corresponding bit in
308 value is known to be constant. */
309 widest_int m_value
, m_mask
;
311 bool meet_with_1 (widest_int
, widest_int
, unsigned);
312 void get_value_and_mask (tree
, widest_int
*, widest_int
*);
315 /* Lattice of value ranges. */
317 class ipcp_vr_lattice
322 inline bool bottom_p () const;
323 inline bool top_p () const;
324 inline bool set_to_bottom ();
325 bool meet_with (const value_range
*p_vr
);
326 bool meet_with (const ipcp_vr_lattice
&other
);
327 void init () { gcc_assert (m_vr
.undefined_p ()); }
328 void print (FILE * f
);
331 bool meet_with_1 (const value_range
*other_vr
);
334 /* Structure containing lattices for a parameter itself and for pieces of
335 aggregates that are passed in the parameter or by a reference in a parameter
336 plus some other useful flags. */
338 class ipcp_param_lattices
341 /* Lattice describing the value of the parameter itself. */
342 ipcp_lattice
<tree
> itself
;
343 /* Lattice describing the polymorphic contexts of a parameter. */
344 ipcp_lattice
<ipa_polymorphic_call_context
> ctxlat
;
345 /* Lattices describing aggregate parts. */
346 ipcp_agg_lattice
*aggs
;
347 /* Lattice describing known bits. */
348 ipcp_bits_lattice bits_lattice
;
349 /* Lattice describing value range. */
350 ipcp_vr_lattice m_value_range
;
351 /* Number of aggregate lattices */
353 /* True if aggregate data were passed by reference (as opposed to by
356 /* All aggregate lattices contain a variable component (in addition to
358 bool aggs_contain_variable
;
359 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
360 for any propagation). */
363 /* There is a virtual call based on this parameter. */
367 /* Allocation pools for values and their sources in ipa-cp. */
369 object_allocator
<ipcp_value
<tree
> > ipcp_cst_values_pool
370 ("IPA-CP constant values");
372 object_allocator
<ipcp_value
<ipa_polymorphic_call_context
> >
373 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
375 object_allocator
<ipcp_value_source
<tree
> > ipcp_sources_pool
376 ("IPA-CP value sources");
378 object_allocator
<ipcp_agg_lattice
> ipcp_agg_lattice_pool
379 ("IPA_CP aggregate lattices");
381 /* Maximal count found in program. */
383 static profile_count max_count
;
385 /* Original overall size of the program. */
387 static long overall_size
, orig_overall_size
;
389 /* Node name to unique clone suffix number map. */
390 static hash_map
<const char *, unsigned> *clone_num_suffixes
;
392 /* Return the param lattices structure corresponding to the Ith formal
393 parameter of the function described by INFO. */
394 static inline class ipcp_param_lattices
*
395 ipa_get_parm_lattices (class ipa_node_params
*info
, int i
)
397 gcc_assert (i
>= 0 && i
< ipa_get_param_count (info
));
398 gcc_checking_assert (!info
->ipcp_orig_node
);
399 gcc_checking_assert (info
->lattices
);
400 return &(info
->lattices
[i
]);
403 /* Return the lattice corresponding to the scalar value of the Ith formal
404 parameter of the function described by INFO. */
405 static inline ipcp_lattice
<tree
> *
406 ipa_get_scalar_lat (class ipa_node_params
*info
, int i
)
408 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
409 return &plats
->itself
;
412 /* Return the lattice corresponding to the scalar value of the Ith formal
413 parameter of the function described by INFO. */
414 static inline ipcp_lattice
<ipa_polymorphic_call_context
> *
415 ipa_get_poly_ctx_lat (class ipa_node_params
*info
, int i
)
417 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
418 return &plats
->ctxlat
;
421 /* Return whether LAT is a lattice with a single constant and without an
424 template <typename valtype
>
426 ipcp_lattice
<valtype
>::is_single_const ()
428 if (bottom
|| contains_variable
|| values_count
!= 1)
434 /* Print V which is extracted from a value in a lattice to F. */
437 print_ipcp_constant_value (FILE * f
, tree v
)
439 if (TREE_CODE (v
) == ADDR_EXPR
440 && TREE_CODE (TREE_OPERAND (v
, 0)) == CONST_DECL
)
443 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (v
, 0)));
446 print_generic_expr (f
, v
);
449 /* Print V which is extracted from a value in a lattice to F. */
452 print_ipcp_constant_value (FILE * f
, ipa_polymorphic_call_context v
)
457 /* Print a lattice LAT to F. */
459 template <typename valtype
>
461 ipcp_lattice
<valtype
>::print (FILE * f
, bool dump_sources
, bool dump_benefits
)
463 ipcp_value
<valtype
> *val
;
468 fprintf (f
, "BOTTOM\n");
472 if (!values_count
&& !contains_variable
)
474 fprintf (f
, "TOP\n");
478 if (contains_variable
)
480 fprintf (f
, "VARIABLE");
486 for (val
= values
; val
; val
= val
->next
)
488 if (dump_benefits
&& prev
)
490 else if (!dump_benefits
&& prev
)
495 print_ipcp_constant_value (f
, val
->value
);
499 ipcp_value_source
<valtype
> *s
;
501 fprintf (f
, " [from:");
502 for (s
= val
->sources
; s
; s
= s
->next
)
503 fprintf (f
, " %i(%f)", s
->cs
->caller
->order
,
504 s
->cs
->sreal_frequency ().to_double ());
509 fprintf (f
, " [loc_time: %g, loc_size: %i, "
510 "prop_time: %g, prop_size: %i]\n",
511 val
->local_time_benefit
.to_double (), val
->local_size_cost
,
512 val
->prop_time_benefit
.to_double (), val
->prop_size_cost
);
519 ipcp_bits_lattice::print (FILE *f
)
522 fprintf (f
, " Bits unknown (TOP)\n");
523 else if (bottom_p ())
524 fprintf (f
, " Bits unusable (BOTTOM)\n");
527 fprintf (f
, " Bits: value = "); print_hex (get_value (), f
);
528 fprintf (f
, ", mask = "); print_hex (get_mask (), f
);
533 /* Print value range lattice to F. */
536 ipcp_vr_lattice::print (FILE * f
)
538 dump_value_range (f
, &m_vr
);
541 /* Print all ipcp_lattices of all functions to F. */
544 print_all_lattices (FILE * f
, bool dump_sources
, bool dump_benefits
)
546 struct cgraph_node
*node
;
549 fprintf (f
, "\nLattices:\n");
550 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
552 class ipa_node_params
*info
;
554 info
= ipa_node_params_sum
->get (node
);
555 /* Skip unoptimized functions and constprop clones since we don't make
556 lattices for them. */
557 if (!info
|| info
->ipcp_orig_node
)
559 fprintf (f
, " Node: %s:\n", node
->dump_name ());
560 count
= ipa_get_param_count (info
);
561 for (i
= 0; i
< count
; i
++)
563 struct ipcp_agg_lattice
*aglat
;
564 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
565 fprintf (f
, " param [%d]: ", i
);
566 plats
->itself
.print (f
, dump_sources
, dump_benefits
);
567 fprintf (f
, " ctxs: ");
568 plats
->ctxlat
.print (f
, dump_sources
, dump_benefits
);
569 plats
->bits_lattice
.print (f
);
571 plats
->m_value_range
.print (f
);
573 if (plats
->virt_call
)
574 fprintf (f
, " virt_call flag set\n");
576 if (plats
->aggs_bottom
)
578 fprintf (f
, " AGGS BOTTOM\n");
581 if (plats
->aggs_contain_variable
)
582 fprintf (f
, " AGGS VARIABLE\n");
583 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
585 fprintf (f
, " %soffset " HOST_WIDE_INT_PRINT_DEC
": ",
586 plats
->aggs_by_ref
? "ref " : "", aglat
->offset
);
587 aglat
->print (f
, dump_sources
, dump_benefits
);
593 /* Determine whether it is at all technically possible to create clones of NODE
594 and store this information in the ipa_node_params structure associated
598 determine_versionability (struct cgraph_node
*node
,
599 class ipa_node_params
*info
)
601 const char *reason
= NULL
;
603 /* There are a number of generic reasons functions cannot be versioned. We
604 also cannot remove parameters if there are type attributes such as fnspec
606 if (node
->alias
|| node
->thunk
)
607 reason
= "alias or thunk";
608 else if (!node
->versionable
)
609 reason
= "not a tree_versionable_function";
610 else if (node
->get_availability () <= AVAIL_INTERPOSABLE
)
611 reason
= "insufficient body availability";
612 else if (!opt_for_fn (node
->decl
, optimize
)
613 || !opt_for_fn (node
->decl
, flag_ipa_cp
))
614 reason
= "non-optimized function";
615 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node
->decl
)))
617 /* Ideally we should clone the SIMD clones themselves and create
618 vector copies of them, so IPA-cp and SIMD clones can happily
619 coexist, but that may not be worth the effort. */
620 reason
= "function has SIMD clones";
622 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node
->decl
)))
624 /* Ideally we should clone the target clones themselves and create
625 copies of them, so IPA-cp and target clones can happily
626 coexist, but that may not be worth the effort. */
627 reason
= "function target_clones attribute";
629 /* Don't clone decls local to a comdat group; it breaks and for C++
630 decloned constructors, inlining is always better anyway. */
631 else if (node
->comdat_local_p ())
632 reason
= "comdat-local function";
633 else if (node
->calls_comdat_local
)
635 /* TODO: call is versionable if we make sure that all
636 callers are inside of a comdat group. */
637 reason
= "calls comdat-local function";
640 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
641 work only when inlined. Cloning them may still lead to better code
642 because ipa-cp will not give up on cloning further. If the function is
643 external this however leads to wrong code because we may end up producing
644 offline copy of the function. */
645 if (DECL_EXTERNAL (node
->decl
))
646 for (cgraph_edge
*edge
= node
->callees
; !reason
&& edge
;
647 edge
= edge
->next_callee
)
648 if (fndecl_built_in_p (edge
->callee
->decl
, BUILT_IN_NORMAL
))
650 if (DECL_FUNCTION_CODE (edge
->callee
->decl
) == BUILT_IN_VA_ARG_PACK
)
651 reason
= "external function which calls va_arg_pack";
652 if (DECL_FUNCTION_CODE (edge
->callee
->decl
)
653 == BUILT_IN_VA_ARG_PACK_LEN
)
654 reason
= "external function which calls va_arg_pack_len";
657 if (reason
&& dump_file
&& !node
->alias
&& !node
->thunk
)
658 fprintf (dump_file
, "Function %s is not versionable, reason: %s.\n",
659 node
->dump_name (), reason
);
661 info
->versionable
= (reason
== NULL
);
664 /* Return true if it is at all technically possible to create clones of a
668 ipcp_versionable_function_p (struct cgraph_node
*node
)
670 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
671 return info
&& info
->versionable
;
674 /* Structure holding accumulated information about callers of a node. */
676 struct caller_statistics
678 profile_count count_sum
;
680 int n_calls
, n_hot_calls
;
683 /* Initialize fields of STAT to zeroes. */
686 init_caller_stats (struct caller_statistics
*stats
)
688 stats
->count_sum
= profile_count::zero ();
690 stats
->n_hot_calls
= 0;
694 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
695 non-thunk incoming edges to NODE. */
698 gather_caller_stats (struct cgraph_node
*node
, void *data
)
700 struct caller_statistics
*stats
= (struct caller_statistics
*) data
;
701 struct cgraph_edge
*cs
;
703 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
704 if (!cs
->caller
->thunk
)
706 if (cs
->count
.ipa ().initialized_p ())
707 stats
->count_sum
+= cs
->count
.ipa ();
708 stats
->freq_sum
+= cs
->sreal_frequency ();
710 if (cs
->maybe_hot_p ())
711 stats
->n_hot_calls
++;
717 /* Return true if this NODE is viable candidate for cloning. */
720 ipcp_cloning_candidate_p (struct cgraph_node
*node
)
722 struct caller_statistics stats
;
724 gcc_checking_assert (node
->has_gimple_body_p ());
726 if (!opt_for_fn (node
->decl
, flag_ipa_cp_clone
))
729 fprintf (dump_file
, "Not considering %s for cloning; "
730 "-fipa-cp-clone disabled.\n",
735 if (node
->optimize_for_size_p ())
738 fprintf (dump_file
, "Not considering %s for cloning; "
739 "optimizing it for size.\n",
744 init_caller_stats (&stats
);
745 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
, false);
747 if (ipa_size_summaries
->get (node
)->self_size
< stats
.n_calls
)
750 fprintf (dump_file
, "Considering %s for cloning; code might shrink.\n",
755 /* When profile is available and function is hot, propagate into it even if
756 calls seems cold; constant propagation can improve function's speed
758 if (max_count
> profile_count::zero ())
760 if (stats
.count_sum
> node
->count
.ipa ().apply_scale (90, 100))
763 fprintf (dump_file
, "Considering %s for cloning; "
764 "usually called directly.\n",
769 if (!stats
.n_hot_calls
)
772 fprintf (dump_file
, "Not considering %s for cloning; no hot calls.\n",
777 fprintf (dump_file
, "Considering %s for cloning.\n",
782 template <typename valtype
>
783 class value_topo_info
786 /* Head of the linked list of topologically sorted values. */
787 ipcp_value
<valtype
> *values_topo
;
788 /* Stack for creating SCCs, represented by a linked list too. */
789 ipcp_value
<valtype
> *stack
;
790 /* Counter driving the algorithm in add_val_to_toposort. */
793 value_topo_info () : values_topo (NULL
), stack (NULL
), dfs_counter (0)
795 void add_val (ipcp_value
<valtype
> *cur_val
);
796 void propagate_effects ();
799 /* Arrays representing a topological ordering of call graph nodes and a stack
800 of nodes used during constant propagation and also data required to perform
801 topological sort of values and propagation of benefits in the determined
807 /* Array with obtained topological order of cgraph nodes. */
808 struct cgraph_node
**order
;
809 /* Stack of cgraph nodes used during propagation within SCC until all values
810 in the SCC stabilize. */
811 struct cgraph_node
**stack
;
812 int nnodes
, stack_top
;
814 value_topo_info
<tree
> constants
;
815 value_topo_info
<ipa_polymorphic_call_context
> contexts
;
817 ipa_topo_info () : order(NULL
), stack(NULL
), nnodes(0), stack_top(0),
822 /* Skip edges from and to nodes without ipa_cp enabled.
823 Ignore not available symbols. */
826 ignore_edge_p (cgraph_edge
*e
)
828 enum availability avail
;
829 cgraph_node
*ultimate_target
830 = e
->callee
->function_or_virtual_thunk_symbol (&avail
, e
->caller
);
832 return (avail
<= AVAIL_INTERPOSABLE
833 || !opt_for_fn (ultimate_target
->decl
, optimize
)
834 || !opt_for_fn (ultimate_target
->decl
, flag_ipa_cp
));
837 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
840 build_toporder_info (class ipa_topo_info
*topo
)
842 topo
->order
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
843 topo
->stack
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
845 gcc_checking_assert (topo
->stack_top
== 0);
846 topo
->nnodes
= ipa_reduced_postorder (topo
->order
, true,
850 /* Free information about strongly connected components and the arrays in
854 free_toporder_info (class ipa_topo_info
*topo
)
856 ipa_free_postorder_info ();
861 /* Add NODE to the stack in TOPO, unless it is already there. */
864 push_node_to_stack (class ipa_topo_info
*topo
, struct cgraph_node
*node
)
866 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
867 if (info
->node_enqueued
)
869 info
->node_enqueued
= 1;
870 topo
->stack
[topo
->stack_top
++] = node
;
873 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
876 static struct cgraph_node
*
877 pop_node_from_stack (class ipa_topo_info
*topo
)
881 struct cgraph_node
*node
;
883 node
= topo
->stack
[topo
->stack_top
];
884 ipa_node_params_sum
->get (node
)->node_enqueued
= 0;
891 /* Set lattice LAT to bottom and return true if it previously was not set as
894 template <typename valtype
>
896 ipcp_lattice
<valtype
>::set_to_bottom ()
903 /* Mark lattice as containing an unknown value and return true if it previously
904 was not marked as such. */
906 template <typename valtype
>
908 ipcp_lattice
<valtype
>::set_contains_variable ()
910 bool ret
= !contains_variable
;
911 contains_variable
= true;
915 /* Set all aggregate lattices in PLATS to bottom and return true if they were
916 not previously set as such. */
919 set_agg_lats_to_bottom (class ipcp_param_lattices
*plats
)
921 bool ret
= !plats
->aggs_bottom
;
922 plats
->aggs_bottom
= true;
926 /* Mark all aggregate lattices in PLATS as containing an unknown value and
927 return true if they were not previously marked as such. */
930 set_agg_lats_contain_variable (class ipcp_param_lattices
*plats
)
932 bool ret
= !plats
->aggs_contain_variable
;
933 plats
->aggs_contain_variable
= true;
938 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice
&other
)
940 return meet_with_1 (&other
.m_vr
);
943 /* Meet the current value of the lattice with value range described by VR
947 ipcp_vr_lattice::meet_with (const value_range
*p_vr
)
949 return meet_with_1 (p_vr
);
952 /* Meet the current value of the lattice with value range described by
953 OTHER_VR lattice. Return TRUE if anything changed. */
956 ipcp_vr_lattice::meet_with_1 (const value_range
*other_vr
)
961 if (other_vr
->varying_p ())
962 return set_to_bottom ();
964 value_range
save (m_vr
);
965 m_vr
.union_ (other_vr
);
966 return !m_vr
.equal_p (save
);
969 /* Return true if value range information in the lattice is yet unknown. */
972 ipcp_vr_lattice::top_p () const
974 return m_vr
.undefined_p ();
977 /* Return true if value range information in the lattice is known to be
981 ipcp_vr_lattice::bottom_p () const
983 return m_vr
.varying_p ();
986 /* Set value range information in the lattice to bottom. Return true if it
987 previously was in a different state. */
990 ipcp_vr_lattice::set_to_bottom ()
992 if (m_vr
.varying_p ())
994 /* ?? We create all sorts of VARYING ranges for floats, structures,
995 and other types which we cannot handle as ranges. We should
996 probably avoid handling them throughout the pass, but it's easier
997 to create a sensible VARYING here and let the lattice
999 m_vr
.set_varying (integer_type_node
);
1003 /* Set lattice value to bottom, if it already isn't the case. */
1006 ipcp_bits_lattice::set_to_bottom ()
1010 m_lattice_val
= IPA_BITS_VARYING
;
1016 /* Set to constant if it isn't already. Only meant to be called
1017 when switching state from TOP. */
1020 ipcp_bits_lattice::set_to_constant (widest_int value
, widest_int mask
)
1022 gcc_assert (top_p ());
1023 m_lattice_val
= IPA_BITS_CONSTANT
;
1024 m_value
= wi::bit_and (wi::bit_not (mask
), value
);
1029 /* Convert operand to value, mask form. */
1032 ipcp_bits_lattice::get_value_and_mask (tree operand
, widest_int
*valuep
, widest_int
*maskp
)
1034 wide_int
get_nonzero_bits (const_tree
);
1036 if (TREE_CODE (operand
) == INTEGER_CST
)
1038 *valuep
= wi::to_widest (operand
);
1048 /* Meet operation, similar to ccp_lattice_meet, we xor values
1049 if this->value, value have different values at same bit positions, we want
1050 to drop that bit to varying. Return true if mask is changed.
1051 This function assumes that the lattice value is in CONSTANT state */
1054 ipcp_bits_lattice::meet_with_1 (widest_int value
, widest_int mask
,
1057 gcc_assert (constant_p ());
1059 widest_int old_mask
= m_mask
;
1060 m_mask
= (m_mask
| mask
) | (m_value
^ value
);
1063 if (wi::sext (m_mask
, precision
) == -1)
1064 return set_to_bottom ();
1066 return m_mask
!= old_mask
;
1069 /* Meet the bits lattice with operand
1070 described by <value, mask, sgn, precision. */
1073 ipcp_bits_lattice::meet_with (widest_int value
, widest_int mask
,
1081 if (wi::sext (mask
, precision
) == -1)
1082 return set_to_bottom ();
1083 return set_to_constant (value
, mask
);
1086 return meet_with_1 (value
, mask
, precision
);
1089 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1090 if code is binary operation or bit_value_unop (other) if code is unary op.
1091 In the case when code is nop_expr, no adjustment is required. */
1094 ipcp_bits_lattice::meet_with (ipcp_bits_lattice
& other
, unsigned precision
,
1095 signop sgn
, enum tree_code code
, tree operand
)
1097 if (other
.bottom_p ())
1098 return set_to_bottom ();
1100 if (bottom_p () || other
.top_p ())
1103 widest_int adjusted_value
, adjusted_mask
;
1105 if (TREE_CODE_CLASS (code
) == tcc_binary
)
1107 tree type
= TREE_TYPE (operand
);
1108 widest_int o_value
, o_mask
;
1109 get_value_and_mask (operand
, &o_value
, &o_mask
);
1111 bit_value_binop (code
, sgn
, precision
, &adjusted_value
, &adjusted_mask
,
1112 sgn
, precision
, other
.get_value (), other
.get_mask (),
1113 TYPE_SIGN (type
), TYPE_PRECISION (type
), o_value
, o_mask
);
1115 if (wi::sext (adjusted_mask
, precision
) == -1)
1116 return set_to_bottom ();
1119 else if (TREE_CODE_CLASS (code
) == tcc_unary
)
1121 bit_value_unop (code
, sgn
, precision
, &adjusted_value
,
1122 &adjusted_mask
, sgn
, precision
, other
.get_value (),
1125 if (wi::sext (adjusted_mask
, precision
) == -1)
1126 return set_to_bottom ();
1130 return set_to_bottom ();
1134 if (wi::sext (adjusted_mask
, precision
) == -1)
1135 return set_to_bottom ();
1136 return set_to_constant (adjusted_value
, adjusted_mask
);
1139 return meet_with_1 (adjusted_value
, adjusted_mask
, precision
);
1142 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1143 return true is any of them has not been marked as such so far. */
1146 set_all_contains_variable (class ipcp_param_lattices
*plats
)
1149 ret
= plats
->itself
.set_contains_variable ();
1150 ret
|= plats
->ctxlat
.set_contains_variable ();
1151 ret
|= set_agg_lats_contain_variable (plats
);
1152 ret
|= plats
->bits_lattice
.set_to_bottom ();
1153 ret
|= plats
->m_value_range
.set_to_bottom ();
1157 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1158 points to by the number of callers to NODE. */
1161 count_callers (cgraph_node
*node
, void *data
)
1163 int *caller_count
= (int *) data
;
1165 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
1166 /* Local thunks can be handled transparently, but if the thunk cannot
1167 be optimized out, count it as a real use. */
1168 if (!cs
->caller
->thunk
|| !cs
->caller
->local
)
1173 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1174 the one caller of some other node. Set the caller's corresponding flag. */
1177 set_single_call_flag (cgraph_node
*node
, void *)
1179 cgraph_edge
*cs
= node
->callers
;
1180 /* Local thunks can be handled transparently, skip them. */
1181 while (cs
&& cs
->caller
->thunk
&& cs
->caller
->local
)
1182 cs
= cs
->next_caller
;
1184 if (ipa_node_params
* info
= ipa_node_params_sum
->get (cs
->caller
))
1186 info
->node_calling_single_call
= true;
1192 /* Initialize ipcp_lattices. */
1195 initialize_node_lattices (struct cgraph_node
*node
)
1197 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
1198 struct cgraph_edge
*ie
;
1199 bool disable
= false, variable
= false;
1202 gcc_checking_assert (node
->has_gimple_body_p ());
1204 if (!ipa_get_param_count (info
))
1206 else if (node
->local
)
1208 int caller_count
= 0;
1209 node
->call_for_symbol_thunks_and_aliases (count_callers
, &caller_count
,
1211 gcc_checking_assert (caller_count
> 0);
1212 if (caller_count
== 1)
1213 node
->call_for_symbol_thunks_and_aliases (set_single_call_flag
,
1218 /* When cloning is allowed, we can assume that externally visible
1219 functions are not called. We will compensate this by cloning
1221 if (ipcp_versionable_function_p (node
)
1222 && ipcp_cloning_candidate_p (node
))
1228 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1229 && !node
->alias
&& !node
->thunk
)
1231 fprintf (dump_file
, "Initializing lattices of %s\n",
1232 node
->dump_name ());
1233 if (disable
|| variable
)
1234 fprintf (dump_file
, " Marking all lattices as %s\n",
1235 disable
? "BOTTOM" : "VARIABLE");
1238 auto_vec
<bool, 16> surviving_params
;
1239 bool pre_modified
= false;
1241 clone_info
*cinfo
= clone_info::get (node
);
1243 if (!disable
&& cinfo
&& cinfo
->param_adjustments
)
1245 /* At the moment all IPA optimizations should use the number of
1246 parameters of the prevailing decl as the m_always_copy_start.
1247 Handling any other value would complicate the code below, so for the
1248 time bing let's only assert it is so. */
1249 gcc_assert ((cinfo
->param_adjustments
->m_always_copy_start
1250 == ipa_get_param_count (info
))
1251 || cinfo
->param_adjustments
->m_always_copy_start
< 0);
1253 pre_modified
= true;
1254 cinfo
->param_adjustments
->get_surviving_params (&surviving_params
);
1256 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1257 && !node
->alias
&& !node
->thunk
)
1260 for (int j
= 0; j
< ipa_get_param_count (info
); j
++)
1262 if (j
< (int) surviving_params
.length ()
1263 && surviving_params
[j
])
1268 " The following parameters are dead on arrival:");
1271 fprintf (dump_file
, " %u", j
);
1274 fprintf (dump_file
, "\n");
1278 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1280 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1282 || !ipa_get_type (info
, i
)
1283 || (pre_modified
&& (surviving_params
.length () <= (unsigned) i
1284 || !surviving_params
[i
])))
1286 plats
->itself
.set_to_bottom ();
1287 plats
->ctxlat
.set_to_bottom ();
1288 set_agg_lats_to_bottom (plats
);
1289 plats
->bits_lattice
.set_to_bottom ();
1290 plats
->m_value_range
.m_vr
= value_range ();
1291 plats
->m_value_range
.set_to_bottom ();
1295 plats
->m_value_range
.init ();
1297 set_all_contains_variable (plats
);
1301 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
1302 if (ie
->indirect_info
->polymorphic
1303 && ie
->indirect_info
->param_index
>= 0)
1305 gcc_checking_assert (ie
->indirect_info
->param_index
>= 0);
1306 ipa_get_parm_lattices (info
,
1307 ie
->indirect_info
->param_index
)->virt_call
= 1;
1311 /* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
1315 ipacp_value_safe_for_type (tree param_type
, tree value
)
1317 tree val_type
= TREE_TYPE (value
);
1318 if (param_type
== val_type
1319 || useless_type_conversion_p (param_type
, val_type
)
1320 || fold_convertible_p (param_type
, value
))
1326 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1329 values_equal_for_ipcp_p (tree x
, tree y
)
1331 gcc_checking_assert (x
!= NULL_TREE
&& y
!= NULL_TREE
);
1336 if (TREE_CODE (x
) == ADDR_EXPR
1337 && TREE_CODE (y
) == ADDR_EXPR
1338 && TREE_CODE (TREE_OPERAND (x
, 0)) == CONST_DECL
1339 && TREE_CODE (TREE_OPERAND (y
, 0)) == CONST_DECL
)
1340 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x
, 0)),
1341 DECL_INITIAL (TREE_OPERAND (y
, 0)), 0);
1343 return operand_equal_p (x
, y
, 0);
1346 /* Return the result of a (possibly arithmetic) operation on the constant
1347 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1348 the type of the parameter to which the result is passed. Return
1349 NULL_TREE if that cannot be determined or be considered an
1350 interprocedural invariant. */
1353 ipa_get_jf_arith_result (enum tree_code opcode
, tree input
, tree operand
,
1358 if (opcode
== NOP_EXPR
)
1360 if (!is_gimple_ip_invariant (input
))
1363 if (opcode
== ASSERT_EXPR
)
1365 if (values_equal_for_ipcp_p (input
, operand
))
1373 if (TREE_CODE_CLASS (opcode
) == tcc_comparison
)
1374 res_type
= boolean_type_node
;
1375 else if (expr_type_first_operand_type_p (opcode
))
1376 res_type
= TREE_TYPE (input
);
1381 if (TREE_CODE_CLASS (opcode
) == tcc_unary
)
1382 res
= fold_unary (opcode
, res_type
, input
);
1384 res
= fold_binary (opcode
, res_type
, input
, operand
);
1386 if (res
&& !is_gimple_ip_invariant (res
))
1392 /* Return the result of a (possibly arithmetic) pass through jump function
1393 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1394 to which the result is passed. Return NULL_TREE if that cannot be
1395 determined or be considered an interprocedural invariant. */
1398 ipa_get_jf_pass_through_result (struct ipa_jump_func
*jfunc
, tree input
,
1401 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc
),
1403 ipa_get_jf_pass_through_operand (jfunc
),
1407 /* Return the result of an ancestor jump function JFUNC on the constant value
1408 INPUT. Return NULL_TREE if that cannot be determined. */
1411 ipa_get_jf_ancestor_result (struct ipa_jump_func
*jfunc
, tree input
)
1413 gcc_checking_assert (TREE_CODE (input
) != TREE_BINFO
);
1414 if (TREE_CODE (input
) == ADDR_EXPR
)
1416 gcc_checking_assert (is_gimple_ip_invariant_address (input
));
1417 poly_int64 off
= ipa_get_jf_ancestor_offset (jfunc
);
1418 if (known_eq (off
, 0))
1420 poly_int64 byte_offset
= exact_div (off
, BITS_PER_UNIT
);
1421 return build1 (ADDR_EXPR
, TREE_TYPE (input
),
1422 fold_build2 (MEM_REF
, TREE_TYPE (TREE_TYPE (input
)), input
,
1423 build_int_cst (ptr_type_node
, byte_offset
)));
1429 /* Determine whether JFUNC evaluates to a single known constant value and if
1430 so, return it. Otherwise return NULL. INFO describes the caller node or
1431 the one it is inlined to, so that pass-through jump functions can be
1432 evaluated. PARM_TYPE is the type of the parameter to which the result is
1436 ipa_value_from_jfunc (class ipa_node_params
*info
, struct ipa_jump_func
*jfunc
,
1439 if (jfunc
->type
== IPA_JF_CONST
)
1440 return ipa_get_jf_constant (jfunc
);
1441 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1442 || jfunc
->type
== IPA_JF_ANCESTOR
)
1447 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1448 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1450 idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1452 if (info
->ipcp_orig_node
)
1453 input
= info
->known_csts
[idx
];
1456 ipcp_lattice
<tree
> *lat
;
1459 || idx
>= ipa_get_param_count (info
))
1461 lat
= ipa_get_scalar_lat (info
, idx
);
1462 if (!lat
->is_single_const ())
1464 input
= lat
->values
->value
;
1470 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1471 return ipa_get_jf_pass_through_result (jfunc
, input
, parm_type
);
1473 return ipa_get_jf_ancestor_result (jfunc
, input
);
1479 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1480 that INFO describes the caller node or the one it is inlined to, CS is the
1481 call graph edge corresponding to JFUNC and CSIDX index of the described
1484 ipa_polymorphic_call_context
1485 ipa_context_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
, int csidx
,
1486 ipa_jump_func
*jfunc
)
1488 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
1489 ipa_polymorphic_call_context ctx
;
1490 ipa_polymorphic_call_context
*edge_ctx
1491 = cs
? ipa_get_ith_polymorhic_call_context (args
, csidx
) : NULL
;
1493 if (edge_ctx
&& !edge_ctx
->useless_p ())
1496 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1497 || jfunc
->type
== IPA_JF_ANCESTOR
)
1499 ipa_polymorphic_call_context srcctx
;
1501 bool type_preserved
= true;
1502 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1504 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1506 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1507 srcidx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1511 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1512 srcidx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1514 if (info
->ipcp_orig_node
)
1516 if (info
->known_contexts
.exists ())
1517 srcctx
= info
->known_contexts
[srcidx
];
1522 || srcidx
>= ipa_get_param_count (info
))
1524 ipcp_lattice
<ipa_polymorphic_call_context
> *lat
;
1525 lat
= ipa_get_poly_ctx_lat (info
, srcidx
);
1526 if (!lat
->is_single_const ())
1528 srcctx
= lat
->values
->value
;
1530 if (srcctx
.useless_p ())
1532 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1533 srcctx
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1534 if (!type_preserved
)
1535 srcctx
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1536 srcctx
.combine_with (ctx
);
1543 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1544 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1545 the result is a range or an anti-range. */
1548 ipa_vr_operation_and_type_effects (value_range
*dst_vr
,
1549 value_range
*src_vr
,
1550 enum tree_code operation
,
1551 tree dst_type
, tree src_type
)
1553 range_fold_unary_expr (dst_vr
, operation
, dst_type
, src_vr
, src_type
);
1554 if (dst_vr
->varying_p () || dst_vr
->undefined_p ())
1559 /* Determine value_range of JFUNC given that INFO describes the caller node or
1560 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1561 and PARM_TYPE of the parameter. */
1564 ipa_value_range_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
,
1565 ipa_jump_func
*jfunc
, tree parm_type
)
1570 ipa_vr_operation_and_type_effects (&vr
,
1572 NOP_EXPR
, parm_type
,
1573 jfunc
->m_vr
->type ());
1574 if (vr
.singleton_p ())
1576 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1579 ipcp_transformation
*sum
1580 = ipcp_get_transformation_summary (cs
->caller
->inlined_to
1581 ? cs
->caller
->inlined_to
1583 if (!sum
|| !sum
->m_vr
)
1586 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1588 if (!(*sum
->m_vr
)[idx
].known
)
1590 tree vr_type
= ipa_get_type (info
, idx
);
1591 value_range
srcvr (wide_int_to_tree (vr_type
, (*sum
->m_vr
)[idx
].min
),
1592 wide_int_to_tree (vr_type
, (*sum
->m_vr
)[idx
].max
),
1593 (*sum
->m_vr
)[idx
].type
);
1595 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
1597 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
1601 if (ipa_vr_operation_and_type_effects (&res
,
1603 operation
, parm_type
,
1609 value_range op_res
, res
;
1610 tree op
= ipa_get_jf_pass_through_operand (jfunc
);
1611 value_range
op_vr (op
, op
);
1613 range_fold_binary_expr (&op_res
, operation
, vr_type
, &srcvr
, &op_vr
);
1614 if (ipa_vr_operation_and_type_effects (&res
,
1616 NOP_EXPR
, parm_type
,
1624 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1625 parameter with the given INDEX. */
1628 get_clone_agg_value (struct cgraph_node
*node
, HOST_WIDE_INT offset
,
1631 struct ipa_agg_replacement_value
*aggval
;
1633 aggval
= ipa_get_agg_replacements_for_node (node
);
1636 if (aggval
->offset
== offset
1637 && aggval
->index
== index
)
1638 return aggval
->value
;
1639 aggval
= aggval
->next
;
1644 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1645 single known constant value and if so, return it. Otherwise return NULL.
1646 NODE and INFO describes the caller node or the one it is inlined to, and
1647 its related info. */
1650 ipa_agg_value_from_node (class ipa_node_params
*info
,
1651 struct cgraph_node
*node
,
1652 struct ipa_agg_jf_item
*item
)
1654 tree value
= NULL_TREE
;
1657 if (item
->offset
< 0 || item
->jftype
== IPA_JF_UNKNOWN
)
1660 if (item
->jftype
== IPA_JF_CONST
)
1661 return item
->value
.constant
;
1663 gcc_checking_assert (item
->jftype
== IPA_JF_PASS_THROUGH
1664 || item
->jftype
== IPA_JF_LOAD_AGG
);
1666 src_idx
= item
->value
.pass_through
.formal_id
;
1668 if (info
->ipcp_orig_node
)
1670 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
1671 value
= info
->known_csts
[src_idx
];
1673 value
= get_clone_agg_value (node
, item
->value
.load_agg
.offset
,
1676 else if (info
->lattices
)
1678 class ipcp_param_lattices
*src_plats
1679 = ipa_get_parm_lattices (info
, src_idx
);
1681 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
1683 struct ipcp_lattice
<tree
> *lat
= &src_plats
->itself
;
1685 if (!lat
->is_single_const ())
1688 value
= lat
->values
->value
;
1690 else if (src_plats
->aggs
1691 && !src_plats
->aggs_bottom
1692 && !src_plats
->aggs_contain_variable
1693 && src_plats
->aggs_by_ref
== item
->value
.load_agg
.by_ref
)
1695 struct ipcp_agg_lattice
*aglat
;
1697 for (aglat
= src_plats
->aggs
; aglat
; aglat
= aglat
->next
)
1699 if (aglat
->offset
> item
->value
.load_agg
.offset
)
1702 if (aglat
->offset
== item
->value
.load_agg
.offset
)
1704 if (aglat
->is_single_const ())
1705 value
= aglat
->values
->value
;
1715 if (item
->jftype
== IPA_JF_LOAD_AGG
)
1717 tree load_type
= item
->value
.load_agg
.type
;
1718 tree value_type
= TREE_TYPE (value
);
1720 /* Ensure value type is compatible with load type. */
1721 if (!useless_type_conversion_p (load_type
, value_type
))
1725 return ipa_get_jf_arith_result (item
->value
.pass_through
.operation
,
1727 item
->value
.pass_through
.operand
,
1731 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1732 an aggregate and if so, return it. Otherwise return an empty set. NODE
1733 and INFO describes the caller node or the one it is inlined to, and its
1736 struct ipa_agg_value_set
1737 ipa_agg_value_set_from_jfunc (class ipa_node_params
*info
, cgraph_node
*node
,
1738 struct ipa_agg_jump_function
*agg_jfunc
)
1740 struct ipa_agg_value_set agg
;
1741 struct ipa_agg_jf_item
*item
;
1745 agg
.by_ref
= agg_jfunc
->by_ref
;
1747 FOR_EACH_VEC_SAFE_ELT (agg_jfunc
->items
, i
, item
)
1749 tree value
= ipa_agg_value_from_node (info
, node
, item
);
1753 struct ipa_agg_value value_item
;
1755 value_item
.offset
= item
->offset
;
1756 value_item
.value
= value
;
1758 agg
.items
.safe_push (value_item
);
1764 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1765 bottom, not containing a variable component and without any known value at
1769 ipcp_verify_propagated_values (void)
1771 struct cgraph_node
*node
;
1773 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1775 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
1776 if (!opt_for_fn (node
->decl
, flag_ipa_cp
)
1777 || !opt_for_fn (node
->decl
, optimize
))
1779 int i
, count
= ipa_get_param_count (info
);
1781 for (i
= 0; i
< count
; i
++)
1783 ipcp_lattice
<tree
> *lat
= ipa_get_scalar_lat (info
, i
);
1786 && !lat
->contains_variable
1787 && lat
->values_count
== 0)
1791 symtab
->dump (dump_file
);
1792 fprintf (dump_file
, "\nIPA lattices after constant "
1793 "propagation, before gcc_unreachable:\n");
1794 print_all_lattices (dump_file
, true, false);
1803 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1806 values_equal_for_ipcp_p (ipa_polymorphic_call_context x
,
1807 ipa_polymorphic_call_context y
)
1809 return x
.equal_to (y
);
1813 /* Add a new value source to the value represented by THIS, marking that a
1814 value comes from edge CS and (if the underlying jump function is a
1815 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1816 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1817 scalar value of the parameter itself or the offset within an aggregate. */
1819 template <typename valtype
>
1821 ipcp_value
<valtype
>::add_source (cgraph_edge
*cs
, ipcp_value
*src_val
,
1822 int src_idx
, HOST_WIDE_INT offset
)
1824 ipcp_value_source
<valtype
> *src
;
1826 src
= new (ipcp_sources_pool
.allocate ()) ipcp_value_source
<valtype
>;
1827 src
->offset
= offset
;
1830 src
->index
= src_idx
;
1832 src
->next
= sources
;
1836 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1837 SOURCE and clear all other fields. */
1839 static ipcp_value
<tree
> *
1840 allocate_and_init_ipcp_value (tree source
)
1842 ipcp_value
<tree
> *val
;
1844 val
= new (ipcp_cst_values_pool
.allocate ()) ipcp_value
<tree
>();
1845 val
->value
= source
;
1849 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1850 value to SOURCE and clear all other fields. */
1852 static ipcp_value
<ipa_polymorphic_call_context
> *
1853 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source
)
1855 ipcp_value
<ipa_polymorphic_call_context
> *val
;
1858 val
= new (ipcp_poly_ctx_values_pool
.allocate ())
1859 ipcp_value
<ipa_polymorphic_call_context
>();
1860 val
->value
= source
;
1864 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1865 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1866 meaning. OFFSET -1 means the source is scalar and not a part of an
1867 aggregate. If non-NULL, VAL_P records address of existing or newly added
1868 ipcp_value. UNLIMITED means whether value count should not exceed the limit
1869 given by PARAM_IPA_CP_VALUE_LIST_SIZE. */
1871 template <typename valtype
>
1873 ipcp_lattice
<valtype
>::add_value (valtype newval
, cgraph_edge
*cs
,
1874 ipcp_value
<valtype
> *src_val
,
1875 int src_idx
, HOST_WIDE_INT offset
,
1876 ipcp_value
<valtype
> **val_p
,
1879 ipcp_value
<valtype
> *val
, *last_val
= NULL
;
1887 for (val
= values
; val
; last_val
= val
, val
= val
->next
)
1888 if (values_equal_for_ipcp_p (val
->value
, newval
))
1893 if (ipa_edge_within_scc (cs
))
1895 ipcp_value_source
<valtype
> *s
;
1896 for (s
= val
->sources
; s
; s
= s
->next
)
1897 if (s
->cs
== cs
&& s
->val
== src_val
)
1903 val
->add_source (cs
, src_val
, src_idx
, offset
);
1907 if (!unlimited
&& values_count
== opt_for_fn (cs
->caller
->decl
,
1908 param_ipa_cp_value_list_size
))
1910 /* We can only free sources, not the values themselves, because sources
1911 of other values in this SCC might point to them. */
1912 for (val
= values
; val
; val
= val
->next
)
1914 while (val
->sources
)
1916 ipcp_value_source
<valtype
> *src
= val
->sources
;
1917 val
->sources
= src
->next
;
1918 ipcp_sources_pool
.remove ((ipcp_value_source
<tree
>*)src
);
1922 return set_to_bottom ();
1926 val
= allocate_and_init_ipcp_value (newval
);
1927 val
->add_source (cs
, src_val
, src_idx
, offset
);
1930 /* Add the new value to end of value list, which can reduce iterations
1931 of propagation stage for recursive function. */
1933 last_val
->next
= val
;
1943 /* Return true, if a ipcp_value VAL is orginated from parameter value of
1944 self-feeding recursive function via some kind of pass-through jump
1948 self_recursively_generated_p (ipcp_value
<tree
> *val
)
1950 class ipa_node_params
*info
= NULL
;
1952 for (ipcp_value_source
<tree
> *src
= val
->sources
; src
; src
= src
->next
)
1954 cgraph_edge
*cs
= src
->cs
;
1956 if (!src
->val
|| cs
->caller
!= cs
->callee
->function_symbol ())
1959 if (src
->val
== val
)
1963 info
= ipa_node_params_sum
->get (cs
->caller
);
1965 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
,
1967 ipcp_lattice
<tree
> *src_lat
;
1968 ipcp_value
<tree
> *src_val
;
1970 if (src
->offset
== -1)
1971 src_lat
= &plats
->itself
;
1974 struct ipcp_agg_lattice
*src_aglat
;
1976 for (src_aglat
= plats
->aggs
; src_aglat
; src_aglat
= src_aglat
->next
)
1977 if (src_aglat
->offset
== src
->offset
)
1983 src_lat
= src_aglat
;
1986 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1997 /* A helper function that returns result of operation specified by OPCODE on
1998 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1999 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
2000 acting as its second operand. If non-NULL, RES_TYPE is expected type of
2004 get_val_across_arith_op (enum tree_code opcode
,
2007 ipcp_value
<tree
> *src_val
,
2010 tree opnd1
= src_val
->value
;
2012 /* Skip source values that is incompatible with specified type. */
2014 && !useless_type_conversion_p (opnd1_type
, TREE_TYPE (opnd1
)))
2017 return ipa_get_jf_arith_result (opcode
, opnd1
, opnd2
, res_type
);
2020 /* Propagate values through an arithmetic transformation described by a jump
2021 function associated with edge CS, taking values from SRC_LAT and putting
2022 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
2023 OPND2 is a constant value if transformation is a binary operation.
2024 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
2025 a part of the aggregate. SRC_IDX is the index of the source parameter.
2026 RES_TYPE is the value type of result being propagated into. Return true if
2027 DEST_LAT changed. */
2030 propagate_vals_across_arith_jfunc (cgraph_edge
*cs
,
2031 enum tree_code opcode
,
2034 ipcp_lattice
<tree
> *src_lat
,
2035 ipcp_lattice
<tree
> *dest_lat
,
2036 HOST_WIDE_INT src_offset
,
2040 ipcp_value
<tree
> *src_val
;
2043 /* Due to circular dependencies, propagating within an SCC through arithmetic
2044 transformation would create infinite number of values. But for
2045 self-feeding recursive function, we could allow propagation in a limited
2046 count, and this can enable a simple kind of recursive function versioning.
2047 For other scenario, we would just make lattices bottom. */
2048 if (opcode
!= NOP_EXPR
&& ipa_edge_within_scc (cs
))
2052 int max_recursive_depth
= opt_for_fn(cs
->caller
->decl
,
2053 param_ipa_cp_max_recursive_depth
);
2054 if (src_lat
!= dest_lat
|| max_recursive_depth
< 1)
2055 return dest_lat
->set_contains_variable ();
2057 /* No benefit if recursive execution is in low probability. */
2058 if (cs
->sreal_frequency () * 100
2059 <= ((sreal
) 1) * opt_for_fn (cs
->caller
->decl
,
2060 param_ipa_cp_min_recursive_probability
))
2061 return dest_lat
->set_contains_variable ();
2063 auto_vec
<ipcp_value
<tree
> *, 8> val_seeds
;
2065 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2067 /* Now we do not use self-recursively generated value as propagation
2068 source, this is absolutely conservative, but could avoid explosion
2069 of lattice's value space, especially when one recursive function
2070 calls another recursive. */
2071 if (self_recursively_generated_p (src_val
))
2073 ipcp_value_source
<tree
> *s
;
2075 /* If the lattice has already been propagated for the call site,
2076 no need to do that again. */
2077 for (s
= src_val
->sources
; s
; s
= s
->next
)
2079 return dest_lat
->set_contains_variable ();
2082 val_seeds
.safe_push (src_val
);
2085 gcc_assert ((int) val_seeds
.length () <= param_ipa_cp_value_list_size
);
2087 /* Recursively generate lattice values with a limited count. */
2088 FOR_EACH_VEC_ELT (val_seeds
, i
, src_val
)
2090 for (int j
= 1; j
< max_recursive_depth
; j
++)
2092 tree cstval
= get_val_across_arith_op (opcode
, opnd1_type
, opnd2
,
2095 || !ipacp_value_safe_for_type (res_type
, cstval
))
2098 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
,
2099 src_offset
, &src_val
, true);
2100 gcc_checking_assert (src_val
);
2103 ret
|= dest_lat
->set_contains_variable ();
2106 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2108 /* Now we do not use self-recursively generated value as propagation
2109 source, otherwise it is easy to make value space of normal lattice
2111 if (self_recursively_generated_p (src_val
))
2113 ret
|= dest_lat
->set_contains_variable ();
2117 tree cstval
= get_val_across_arith_op (opcode
, opnd1_type
, opnd2
,
2120 && ipacp_value_safe_for_type (res_type
, cstval
))
2121 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
,
2124 ret
|= dest_lat
->set_contains_variable ();
2130 /* Propagate values through a pass-through jump function JFUNC associated with
2131 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2132 is the index of the source parameter. PARM_TYPE is the type of the
2133 parameter to which the result is passed. */
2136 propagate_vals_across_pass_through (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
2137 ipcp_lattice
<tree
> *src_lat
,
2138 ipcp_lattice
<tree
> *dest_lat
, int src_idx
,
2141 return propagate_vals_across_arith_jfunc (cs
,
2142 ipa_get_jf_pass_through_operation (jfunc
),
2144 ipa_get_jf_pass_through_operand (jfunc
),
2145 src_lat
, dest_lat
, -1, src_idx
, parm_type
);
2148 /* Propagate values through an ancestor jump function JFUNC associated with
2149 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2150 is the index of the source parameter. */
2153 propagate_vals_across_ancestor (struct cgraph_edge
*cs
,
2154 struct ipa_jump_func
*jfunc
,
2155 ipcp_lattice
<tree
> *src_lat
,
2156 ipcp_lattice
<tree
> *dest_lat
, int src_idx
,
2159 ipcp_value
<tree
> *src_val
;
2162 if (ipa_edge_within_scc (cs
))
2163 return dest_lat
->set_contains_variable ();
2165 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2167 tree t
= ipa_get_jf_ancestor_result (jfunc
, src_val
->value
);
2169 if (t
&& ipacp_value_safe_for_type (param_type
, t
))
2170 ret
|= dest_lat
->add_value (t
, cs
, src_val
, src_idx
);
2172 ret
|= dest_lat
->set_contains_variable ();
2178 /* Propagate scalar values across jump function JFUNC that is associated with
2179 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2180 parameter to which the result is passed. */
2183 propagate_scalar_across_jump_function (struct cgraph_edge
*cs
,
2184 struct ipa_jump_func
*jfunc
,
2185 ipcp_lattice
<tree
> *dest_lat
,
2188 if (dest_lat
->bottom
)
2191 if (jfunc
->type
== IPA_JF_CONST
)
2193 tree val
= ipa_get_jf_constant (jfunc
);
2194 if (ipacp_value_safe_for_type (param_type
, val
))
2195 return dest_lat
->add_value (val
, cs
, NULL
, 0);
2197 return dest_lat
->set_contains_variable ();
2199 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
2200 || jfunc
->type
== IPA_JF_ANCESTOR
)
2202 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2203 ipcp_lattice
<tree
> *src_lat
;
2207 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2208 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2210 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2212 src_lat
= ipa_get_scalar_lat (caller_info
, src_idx
);
2213 if (src_lat
->bottom
)
2214 return dest_lat
->set_contains_variable ();
2216 /* If we would need to clone the caller and cannot, do not propagate. */
2217 if (!ipcp_versionable_function_p (cs
->caller
)
2218 && (src_lat
->contains_variable
2219 || (src_lat
->values_count
> 1)))
2220 return dest_lat
->set_contains_variable ();
2222 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2223 ret
= propagate_vals_across_pass_through (cs
, jfunc
, src_lat
,
2227 ret
= propagate_vals_across_ancestor (cs
, jfunc
, src_lat
, dest_lat
,
2228 src_idx
, param_type
);
2230 if (src_lat
->contains_variable
)
2231 ret
|= dest_lat
->set_contains_variable ();
2236 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2237 use it for indirect inlining), we should propagate them too. */
2238 return dest_lat
->set_contains_variable ();
2241 /* Propagate scalar values across jump function JFUNC that is associated with
2242 edge CS and describes argument IDX and put the values into DEST_LAT. */
2245 propagate_context_across_jump_function (cgraph_edge
*cs
,
2246 ipa_jump_func
*jfunc
, int idx
,
2247 ipcp_lattice
<ipa_polymorphic_call_context
> *dest_lat
)
2249 if (dest_lat
->bottom
)
2251 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
2253 bool added_sth
= false;
2254 bool type_preserved
= true;
2256 ipa_polymorphic_call_context edge_ctx
, *edge_ctx_ptr
2257 = ipa_get_ith_polymorhic_call_context (args
, idx
);
2260 edge_ctx
= *edge_ctx_ptr
;
2262 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2263 || jfunc
->type
== IPA_JF_ANCESTOR
)
2265 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2267 ipcp_lattice
<ipa_polymorphic_call_context
> *src_lat
;
2269 /* TODO: Once we figure out how to propagate speculations, it will
2270 probably be a good idea to switch to speculation if type_preserved is
2271 not set instead of punting. */
2272 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2274 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
2276 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
2277 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2281 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
2282 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2285 src_lat
= ipa_get_poly_ctx_lat (caller_info
, src_idx
);
2286 /* If we would need to clone the caller and cannot, do not propagate. */
2287 if (!ipcp_versionable_function_p (cs
->caller
)
2288 && (src_lat
->contains_variable
2289 || (src_lat
->values_count
> 1)))
2292 ipcp_value
<ipa_polymorphic_call_context
> *src_val
;
2293 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2295 ipa_polymorphic_call_context cur
= src_val
->value
;
2297 if (!type_preserved
)
2298 cur
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
2299 if (jfunc
->type
== IPA_JF_ANCESTOR
)
2300 cur
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
2301 /* TODO: In cases we know how the context is going to be used,
2302 we can improve the result by passing proper OTR_TYPE. */
2303 cur
.combine_with (edge_ctx
);
2304 if (!cur
.useless_p ())
2306 if (src_lat
->contains_variable
2307 && !edge_ctx
.equal_to (cur
))
2308 ret
|= dest_lat
->set_contains_variable ();
2309 ret
|= dest_lat
->add_value (cur
, cs
, src_val
, src_idx
);
2318 if (!edge_ctx
.useless_p ())
2319 ret
|= dest_lat
->add_value (edge_ctx
, cs
);
2321 ret
|= dest_lat
->set_contains_variable ();
2327 /* Propagate bits across jfunc that is associated with
2328 edge cs and update dest_lattice accordingly. */
2331 propagate_bits_across_jump_function (cgraph_edge
*cs
, int idx
,
2332 ipa_jump_func
*jfunc
,
2333 ipcp_bits_lattice
*dest_lattice
)
2335 if (dest_lattice
->bottom_p ())
2338 enum availability availability
;
2339 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
2340 ipa_node_params
*callee_info
= ipa_node_params_sum
->get (callee
);
2341 tree parm_type
= ipa_get_type (callee_info
, idx
);
2343 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2344 transform for these cases. Similarly, we can have bad type mismatches
2345 with LTO, avoid doing anything with those too. */
2347 || (!INTEGRAL_TYPE_P (parm_type
) && !POINTER_TYPE_P (parm_type
)))
2349 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2350 fprintf (dump_file
, "Setting dest_lattice to bottom, because type of "
2351 "param %i of %s is NULL or unsuitable for bits propagation\n",
2352 idx
, cs
->callee
->dump_name ());
2354 return dest_lattice
->set_to_bottom ();
2357 unsigned precision
= TYPE_PRECISION (parm_type
);
2358 signop sgn
= TYPE_SIGN (parm_type
);
2360 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2361 || jfunc
->type
== IPA_JF_ANCESTOR
)
2363 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2364 tree operand
= NULL_TREE
;
2365 enum tree_code code
;
2368 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2370 code
= ipa_get_jf_pass_through_operation (jfunc
);
2371 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2372 if (code
!= NOP_EXPR
)
2373 operand
= ipa_get_jf_pass_through_operand (jfunc
);
2377 code
= POINTER_PLUS_EXPR
;
2378 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2379 unsigned HOST_WIDE_INT offset
= ipa_get_jf_ancestor_offset (jfunc
) / BITS_PER_UNIT
;
2380 operand
= build_int_cstu (size_type_node
, offset
);
2383 class ipcp_param_lattices
*src_lats
2384 = ipa_get_parm_lattices (caller_info
, src_idx
);
2386 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2392 Assume lattice for x is bottom, however we can still propagate
2393 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2394 and we store it in jump function during analysis stage. */
2396 if (src_lats
->bits_lattice
.bottom_p ()
2398 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
2401 return dest_lattice
->meet_with (src_lats
->bits_lattice
, precision
, sgn
,
2405 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
2406 return dest_lattice
->set_to_bottom ();
2407 else if (jfunc
->bits
)
2408 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
2411 return dest_lattice
->set_to_bottom ();
2414 /* Propagate value range across jump function JFUNC that is associated with
2415 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2419 propagate_vr_across_jump_function (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
2420 class ipcp_param_lattices
*dest_plats
,
2423 ipcp_vr_lattice
*dest_lat
= &dest_plats
->m_value_range
;
2425 if (dest_lat
->bottom_p ())
2429 || (!INTEGRAL_TYPE_P (param_type
)
2430 && !POINTER_TYPE_P (param_type
)))
2431 return dest_lat
->set_to_bottom ();
2433 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2435 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
2436 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2437 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2438 class ipcp_param_lattices
*src_lats
2439 = ipa_get_parm_lattices (caller_info
, src_idx
);
2440 tree operand_type
= ipa_get_type (caller_info
, src_idx
);
2442 if (src_lats
->m_value_range
.bottom_p ())
2443 return dest_lat
->set_to_bottom ();
2446 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
2447 ipa_vr_operation_and_type_effects (&vr
,
2448 &src_lats
->m_value_range
.m_vr
,
2449 operation
, param_type
,
2451 /* A crude way to prevent unbounded number of value range updates
2452 in SCC components. We should allow limited number of updates within
2454 else if (!ipa_edge_within_scc (cs
))
2456 tree op
= ipa_get_jf_pass_through_operand (jfunc
);
2457 value_range
op_vr (op
, op
);
2458 value_range op_res
,res
;
2460 range_fold_binary_expr (&op_res
, operation
, operand_type
,
2461 &src_lats
->m_value_range
.m_vr
, &op_vr
);
2462 ipa_vr_operation_and_type_effects (&vr
,
2464 NOP_EXPR
, param_type
,
2467 if (!vr
.undefined_p () && !vr
.varying_p ())
2472 if (ipa_vr_operation_and_type_effects (&jvr
, jfunc
->m_vr
,
2475 jfunc
->m_vr
->type ()))
2478 return dest_lat
->meet_with (&vr
);
2481 else if (jfunc
->type
== IPA_JF_CONST
)
2483 tree val
= ipa_get_jf_constant (jfunc
);
2484 if (TREE_CODE (val
) == INTEGER_CST
)
2486 val
= fold_convert (param_type
, val
);
2487 if (TREE_OVERFLOW_P (val
))
2488 val
= drop_tree_overflow (val
);
2490 value_range
tmpvr (val
, val
);
2491 return dest_lat
->meet_with (&tmpvr
);
2497 && ipa_vr_operation_and_type_effects (&vr
, jfunc
->m_vr
, NOP_EXPR
,
2499 jfunc
->m_vr
->type ()))
2500 return dest_lat
->meet_with (&vr
);
2502 return dest_lat
->set_to_bottom ();
2505 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2506 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2507 other cases, return false). If there are no aggregate items, set
2508 aggs_by_ref to NEW_AGGS_BY_REF. */
2511 set_check_aggs_by_ref (class ipcp_param_lattices
*dest_plats
,
2512 bool new_aggs_by_ref
)
2514 if (dest_plats
->aggs
)
2516 if (dest_plats
->aggs_by_ref
!= new_aggs_by_ref
)
2518 set_agg_lats_to_bottom (dest_plats
);
2523 dest_plats
->aggs_by_ref
= new_aggs_by_ref
;
2527 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2528 already existing lattice for the given OFFSET and SIZE, marking all skipped
2529 lattices as containing variable and checking for overlaps. If there is no
2530 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2531 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2532 unless there are too many already. If there are two many, return false. If
2533 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2534 skipped lattices were newly marked as containing variable, set *CHANGE to
2535 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2538 merge_agg_lats_step (class ipcp_param_lattices
*dest_plats
,
2539 HOST_WIDE_INT offset
, HOST_WIDE_INT val_size
,
2540 struct ipcp_agg_lattice
***aglat
,
2541 bool pre_existing
, bool *change
, int max_agg_items
)
2543 gcc_checking_assert (offset
>= 0);
2545 while (**aglat
&& (**aglat
)->offset
< offset
)
2547 if ((**aglat
)->offset
+ (**aglat
)->size
> offset
)
2549 set_agg_lats_to_bottom (dest_plats
);
2552 *change
|= (**aglat
)->set_contains_variable ();
2553 *aglat
= &(**aglat
)->next
;
2556 if (**aglat
&& (**aglat
)->offset
== offset
)
2558 if ((**aglat
)->size
!= val_size
)
2560 set_agg_lats_to_bottom (dest_plats
);
2563 gcc_assert (!(**aglat
)->next
2564 || (**aglat
)->next
->offset
>= offset
+ val_size
);
2569 struct ipcp_agg_lattice
*new_al
;
2571 if (**aglat
&& (**aglat
)->offset
< offset
+ val_size
)
2573 set_agg_lats_to_bottom (dest_plats
);
2576 if (dest_plats
->aggs_count
== max_agg_items
)
2578 dest_plats
->aggs_count
++;
2579 new_al
= ipcp_agg_lattice_pool
.allocate ();
2580 memset (new_al
, 0, sizeof (*new_al
));
2582 new_al
->offset
= offset
;
2583 new_al
->size
= val_size
;
2584 new_al
->contains_variable
= pre_existing
;
2586 new_al
->next
= **aglat
;
2592 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2593 containing an unknown value. */
2596 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice
*aglat
)
2601 ret
|= aglat
->set_contains_variable ();
2602 aglat
= aglat
->next
;
2607 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2608 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2609 parameter used for lattice value sources. Return true if DEST_PLATS changed
2613 merge_aggregate_lattices (struct cgraph_edge
*cs
,
2614 class ipcp_param_lattices
*dest_plats
,
2615 class ipcp_param_lattices
*src_plats
,
2616 int src_idx
, HOST_WIDE_INT offset_delta
)
2618 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2619 struct ipcp_agg_lattice
**dst_aglat
;
2622 if (set_check_aggs_by_ref (dest_plats
, src_plats
->aggs_by_ref
))
2624 if (src_plats
->aggs_bottom
)
2625 return set_agg_lats_contain_variable (dest_plats
);
2626 if (src_plats
->aggs_contain_variable
)
2627 ret
|= set_agg_lats_contain_variable (dest_plats
);
2628 dst_aglat
= &dest_plats
->aggs
;
2630 int max_agg_items
= opt_for_fn (cs
->callee
->function_symbol ()->decl
,
2631 param_ipa_max_agg_items
);
2632 for (struct ipcp_agg_lattice
*src_aglat
= src_plats
->aggs
;
2634 src_aglat
= src_aglat
->next
)
2636 HOST_WIDE_INT new_offset
= src_aglat
->offset
- offset_delta
;
2640 if (merge_agg_lats_step (dest_plats
, new_offset
, src_aglat
->size
,
2641 &dst_aglat
, pre_existing
, &ret
, max_agg_items
))
2643 struct ipcp_agg_lattice
*new_al
= *dst_aglat
;
2645 dst_aglat
= &(*dst_aglat
)->next
;
2646 if (src_aglat
->bottom
)
2648 ret
|= new_al
->set_contains_variable ();
2651 if (src_aglat
->contains_variable
)
2652 ret
|= new_al
->set_contains_variable ();
2653 for (ipcp_value
<tree
> *val
= src_aglat
->values
;
2656 ret
|= new_al
->add_value (val
->value
, cs
, val
, src_idx
,
2659 else if (dest_plats
->aggs_bottom
)
2662 ret
|= set_chain_of_aglats_contains_variable (*dst_aglat
);
2666 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2667 pass-through JFUNC and if so, whether it has conform and conforms to the
2668 rules about propagating values passed by reference. */
2671 agg_pass_through_permissible_p (class ipcp_param_lattices
*src_plats
,
2672 struct ipa_jump_func
*jfunc
)
2674 return src_plats
->aggs
2675 && (!src_plats
->aggs_by_ref
2676 || ipa_get_jf_pass_through_agg_preserved (jfunc
));
2679 /* Propagate values through ITEM, jump function for a part of an aggregate,
2680 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2681 associated with the jump function. Return true if AGLAT changed in any
2685 propagate_aggregate_lattice (struct cgraph_edge
*cs
,
2686 struct ipa_agg_jf_item
*item
,
2687 struct ipcp_agg_lattice
*aglat
)
2689 class ipa_node_params
*caller_info
;
2690 class ipcp_param_lattices
*src_plats
;
2691 struct ipcp_lattice
<tree
> *src_lat
;
2692 HOST_WIDE_INT src_offset
;
2697 if (item
->jftype
== IPA_JF_CONST
)
2699 tree value
= item
->value
.constant
;
2701 gcc_checking_assert (is_gimple_ip_invariant (value
));
2702 return aglat
->add_value (value
, cs
, NULL
, 0);
2705 gcc_checking_assert (item
->jftype
== IPA_JF_PASS_THROUGH
2706 || item
->jftype
== IPA_JF_LOAD_AGG
);
2708 caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2709 src_idx
= item
->value
.pass_through
.formal_id
;
2710 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2712 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
2714 load_type
= NULL_TREE
;
2715 src_lat
= &src_plats
->itself
;
2720 HOST_WIDE_INT load_offset
= item
->value
.load_agg
.offset
;
2721 struct ipcp_agg_lattice
*src_aglat
;
2723 for (src_aglat
= src_plats
->aggs
; src_aglat
; src_aglat
= src_aglat
->next
)
2724 if (src_aglat
->offset
>= load_offset
)
2727 load_type
= item
->value
.load_agg
.type
;
2729 || src_aglat
->offset
> load_offset
2730 || src_aglat
->size
!= tree_to_shwi (TYPE_SIZE (load_type
))
2731 || src_plats
->aggs_by_ref
!= item
->value
.load_agg
.by_ref
)
2732 return aglat
->set_contains_variable ();
2734 src_lat
= src_aglat
;
2735 src_offset
= load_offset
;
2739 || (!ipcp_versionable_function_p (cs
->caller
)
2740 && !src_lat
->is_single_const ()))
2741 return aglat
->set_contains_variable ();
2743 ret
= propagate_vals_across_arith_jfunc (cs
,
2744 item
->value
.pass_through
.operation
,
2746 item
->value
.pass_through
.operand
,
2752 if (src_lat
->contains_variable
)
2753 ret
|= aglat
->set_contains_variable ();
2758 /* Propagate scalar values across jump function JFUNC that is associated with
2759 edge CS and put the values into DEST_LAT. */
2762 propagate_aggs_across_jump_function (struct cgraph_edge
*cs
,
2763 struct ipa_jump_func
*jfunc
,
2764 class ipcp_param_lattices
*dest_plats
)
2768 if (dest_plats
->aggs_bottom
)
2771 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2772 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
2774 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2775 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2776 class ipcp_param_lattices
*src_plats
;
2778 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2779 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
2781 /* Currently we do not produce clobber aggregate jump
2782 functions, replace with merging when we do. */
2783 gcc_assert (!jfunc
->agg
.items
);
2784 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
,
2789 else if (jfunc
->type
== IPA_JF_ANCESTOR
2790 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
2792 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
2793 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2794 class ipcp_param_lattices
*src_plats
;
2796 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2797 if (src_plats
->aggs
&& src_plats
->aggs_by_ref
)
2799 /* Currently we do not produce clobber aggregate jump
2800 functions, replace with merging when we do. */
2801 gcc_assert (!jfunc
->agg
.items
);
2802 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
, src_idx
,
2803 ipa_get_jf_ancestor_offset (jfunc
));
2805 else if (!src_plats
->aggs_by_ref
)
2806 ret
|= set_agg_lats_to_bottom (dest_plats
);
2808 ret
|= set_agg_lats_contain_variable (dest_plats
);
2812 if (jfunc
->agg
.items
)
2814 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2815 struct ipcp_agg_lattice
**aglat
= &dest_plats
->aggs
;
2816 struct ipa_agg_jf_item
*item
;
2819 if (set_check_aggs_by_ref (dest_plats
, jfunc
->agg
.by_ref
))
2822 int max_agg_items
= opt_for_fn (cs
->callee
->function_symbol ()->decl
,
2823 param_ipa_max_agg_items
);
2824 FOR_EACH_VEC_ELT (*jfunc
->agg
.items
, i
, item
)
2826 HOST_WIDE_INT val_size
;
2828 if (item
->offset
< 0 || item
->jftype
== IPA_JF_UNKNOWN
)
2830 val_size
= tree_to_shwi (TYPE_SIZE (item
->type
));
2832 if (merge_agg_lats_step (dest_plats
, item
->offset
, val_size
,
2833 &aglat
, pre_existing
, &ret
, max_agg_items
))
2835 ret
|= propagate_aggregate_lattice (cs
, item
, *aglat
);
2836 aglat
= &(*aglat
)->next
;
2838 else if (dest_plats
->aggs_bottom
)
2842 ret
|= set_chain_of_aglats_contains_variable (*aglat
);
2845 ret
|= set_agg_lats_contain_variable (dest_plats
);
2850 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2851 non-thunk) destination, the call passes through a thunk. */
2854 call_passes_through_thunk (cgraph_edge
*cs
)
2856 cgraph_node
*alias_or_thunk
= cs
->callee
;
2857 while (alias_or_thunk
->alias
)
2858 alias_or_thunk
= alias_or_thunk
->get_alias_target ();
2859 return alias_or_thunk
->thunk
;
2862 /* Propagate constants from the caller to the callee of CS. INFO describes the
2866 propagate_constants_across_call (struct cgraph_edge
*cs
)
2868 class ipa_node_params
*callee_info
;
2869 enum availability availability
;
2870 cgraph_node
*callee
;
2871 class ipa_edge_args
*args
;
2873 int i
, args_count
, parms_count
;
2875 callee
= cs
->callee
->function_symbol (&availability
);
2876 if (!callee
->definition
)
2878 gcc_checking_assert (callee
->has_gimple_body_p ());
2879 callee_info
= ipa_node_params_sum
->get (callee
);
2883 args
= ipa_edge_args_sum
->get (cs
);
2884 parms_count
= ipa_get_param_count (callee_info
);
2885 if (parms_count
== 0)
2888 || !opt_for_fn (cs
->caller
->decl
, flag_ipa_cp
)
2889 || !opt_for_fn (cs
->caller
->decl
, optimize
))
2891 for (i
= 0; i
< parms_count
; i
++)
2892 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2896 args_count
= ipa_get_cs_argument_count (args
);
2898 /* If this call goes through a thunk we must not propagate to the first (0th)
2899 parameter. However, we might need to uncover a thunk from below a series
2900 of aliases first. */
2901 if (call_passes_through_thunk (cs
))
2903 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2910 for (; (i
< args_count
) && (i
< parms_count
); i
++)
2912 struct ipa_jump_func
*jump_func
= ipa_get_ith_jump_func (args
, i
);
2913 class ipcp_param_lattices
*dest_plats
;
2914 tree param_type
= ipa_get_type (callee_info
, i
);
2916 dest_plats
= ipa_get_parm_lattices (callee_info
, i
);
2917 if (availability
== AVAIL_INTERPOSABLE
)
2918 ret
|= set_all_contains_variable (dest_plats
);
2921 ret
|= propagate_scalar_across_jump_function (cs
, jump_func
,
2922 &dest_plats
->itself
,
2924 ret
|= propagate_context_across_jump_function (cs
, jump_func
, i
,
2925 &dest_plats
->ctxlat
);
2927 |= propagate_bits_across_jump_function (cs
, i
, jump_func
,
2928 &dest_plats
->bits_lattice
);
2929 ret
|= propagate_aggs_across_jump_function (cs
, jump_func
,
2931 if (opt_for_fn (callee
->decl
, flag_ipa_vrp
))
2932 ret
|= propagate_vr_across_jump_function (cs
, jump_func
,
2933 dest_plats
, param_type
);
2935 ret
|= dest_plats
->m_value_range
.set_to_bottom ();
2938 for (; i
< parms_count
; i
++)
2939 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
, i
));
2944 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2945 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2946 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2949 ipa_get_indirect_edge_target_1 (struct cgraph_edge
*ie
,
2950 const vec
<tree
> &known_csts
,
2951 const vec
<ipa_polymorphic_call_context
> &known_contexts
,
2952 const vec
<ipa_agg_value_set
> &known_aggs
,
2953 struct ipa_agg_replacement_value
*agg_reps
,
2956 int param_index
= ie
->indirect_info
->param_index
;
2957 HOST_WIDE_INT anc_offset
;
2961 *speculative
= false;
2963 if (param_index
== -1)
2966 if (!ie
->indirect_info
->polymorphic
)
2970 if (ie
->indirect_info
->agg_contents
)
2973 if (agg_reps
&& ie
->indirect_info
->guaranteed_unmodified
)
2977 if (agg_reps
->index
== param_index
2978 && agg_reps
->offset
== ie
->indirect_info
->offset
2979 && agg_reps
->by_ref
== ie
->indirect_info
->by_ref
)
2981 t
= agg_reps
->value
;
2984 agg_reps
= agg_reps
->next
;
2989 const ipa_agg_value_set
*agg
;
2990 if (known_aggs
.length () > (unsigned int) param_index
)
2991 agg
= &known_aggs
[param_index
];
2994 bool from_global_constant
;
2995 t
= ipa_find_agg_cst_for_param (agg
,
2996 (unsigned) param_index
2997 < known_csts
.length ()
2998 ? known_csts
[param_index
]
3000 ie
->indirect_info
->offset
,
3001 ie
->indirect_info
->by_ref
,
3002 &from_global_constant
);
3004 && !from_global_constant
3005 && !ie
->indirect_info
->guaranteed_unmodified
)
3009 else if ((unsigned) param_index
< known_csts
.length ())
3010 t
= known_csts
[param_index
];
3013 && TREE_CODE (t
) == ADDR_EXPR
3014 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
)
3015 return TREE_OPERAND (t
, 0);
3020 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
3023 gcc_assert (!ie
->indirect_info
->agg_contents
);
3024 anc_offset
= ie
->indirect_info
->offset
;
3028 /* Try to work out value of virtual table pointer value in replacements. */
3029 if (!t
&& agg_reps
&& !ie
->indirect_info
->by_ref
)
3033 if (agg_reps
->index
== param_index
3034 && agg_reps
->offset
== ie
->indirect_info
->offset
3035 && agg_reps
->by_ref
)
3037 t
= agg_reps
->value
;
3040 agg_reps
= agg_reps
->next
;
3044 /* Try to work out value of virtual table pointer value in known
3045 aggregate values. */
3046 if (!t
&& known_aggs
.length () > (unsigned int) param_index
3047 && !ie
->indirect_info
->by_ref
)
3049 const ipa_agg_value_set
*agg
= &known_aggs
[param_index
];
3050 t
= ipa_find_agg_cst_for_param (agg
,
3051 (unsigned) param_index
3052 < known_csts
.length ()
3053 ? known_csts
[param_index
] : NULL
,
3054 ie
->indirect_info
->offset
, true);
3057 /* If we found the virtual table pointer, lookup the target. */
3061 unsigned HOST_WIDE_INT offset
;
3062 if (vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3065 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3066 vtable
, offset
, &can_refer
);
3070 || fndecl_built_in_p (target
, BUILT_IN_UNREACHABLE
)
3071 || !possible_polymorphic_call_target_p
3072 (ie
, cgraph_node::get (target
)))
3074 /* Do not speculate builtin_unreachable, it is stupid! */
3075 if (ie
->indirect_info
->vptr_changed
)
3077 target
= ipa_impossible_devirt_target (ie
, target
);
3079 *speculative
= ie
->indirect_info
->vptr_changed
;
3086 /* Do we know the constant value of pointer? */
3087 if (!t
&& (unsigned) param_index
< known_csts
.length ())
3088 t
= known_csts
[param_index
];
3090 gcc_checking_assert (!t
|| TREE_CODE (t
) != TREE_BINFO
);
3092 ipa_polymorphic_call_context context
;
3093 if (known_contexts
.length () > (unsigned int) param_index
)
3095 context
= known_contexts
[param_index
];
3096 context
.offset_by (anc_offset
);
3097 if (ie
->indirect_info
->vptr_changed
)
3098 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3099 ie
->indirect_info
->otr_type
);
3102 ipa_polymorphic_call_context ctx2
= ipa_polymorphic_call_context
3103 (t
, ie
->indirect_info
->otr_type
, anc_offset
);
3104 if (!ctx2
.useless_p ())
3105 context
.combine_with (ctx2
, ie
->indirect_info
->otr_type
);
3110 context
= ipa_polymorphic_call_context (t
, ie
->indirect_info
->otr_type
,
3112 if (ie
->indirect_info
->vptr_changed
)
3113 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3114 ie
->indirect_info
->otr_type
);
3119 vec
<cgraph_node
*>targets
;
3122 targets
= possible_polymorphic_call_targets
3123 (ie
->indirect_info
->otr_type
,
3124 ie
->indirect_info
->otr_token
,
3126 if (!final
|| targets
.length () > 1)
3128 struct cgraph_node
*node
;
3131 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
3132 || ie
->speculative
|| !ie
->maybe_hot_p ())
3134 node
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
3135 ie
->indirect_info
->otr_token
,
3139 *speculative
= true;
3140 target
= node
->decl
;
3147 *speculative
= false;
3148 if (targets
.length () == 1)
3149 target
= targets
[0]->decl
;
3151 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3154 if (target
&& !possible_polymorphic_call_target_p (ie
,
3155 cgraph_node::get (target
)))
3159 target
= ipa_impossible_devirt_target (ie
, target
);
3165 /* If an indirect edge IE can be turned into a direct one based on data in
3166 AVALS, return the destination. Store into *SPECULATIVE a boolean determinig
3167 whether the discovered target is only speculative guess. */
3170 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
3171 ipa_call_arg_values
*avals
,
3174 return ipa_get_indirect_edge_target_1 (ie
, avals
->m_known_vals
,
3175 avals
->m_known_contexts
,
3176 avals
->m_known_aggs
,
3180 /* The same functionality as above overloaded for ipa_auto_call_arg_values. */
3183 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
3184 ipa_auto_call_arg_values
*avals
,
3187 return ipa_get_indirect_edge_target_1 (ie
, avals
->m_known_vals
,
3188 avals
->m_known_contexts
,
3189 avals
->m_known_aggs
,
3193 /* Calculate devirtualization time bonus for NODE, assuming we know information
3194 about arguments stored in AVALS. */
3197 devirtualization_time_bonus (struct cgraph_node
*node
,
3198 ipa_auto_call_arg_values
*avals
)
3200 struct cgraph_edge
*ie
;
3203 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
3205 struct cgraph_node
*callee
;
3206 class ipa_fn_summary
*isummary
;
3207 enum availability avail
;
3211 target
= ipa_get_indirect_edge_target (ie
, avals
, &speculative
);
3215 /* Only bare minimum benefit for clearly un-inlineable targets. */
3217 callee
= cgraph_node::get (target
);
3218 if (!callee
|| !callee
->definition
)
3220 callee
= callee
->function_symbol (&avail
);
3221 if (avail
< AVAIL_AVAILABLE
)
3223 isummary
= ipa_fn_summaries
->get (callee
);
3224 if (!isummary
|| !isummary
->inlinable
)
3227 int size
= ipa_size_summaries
->get (callee
)->size
;
3228 /* FIXME: The values below need re-considering and perhaps also
3229 integrating into the cost metrics, at lest in some very basic way. */
3230 int max_inline_insns_auto
3231 = opt_for_fn (callee
->decl
, param_max_inline_insns_auto
);
3232 if (size
<= max_inline_insns_auto
/ 4)
3233 res
+= 31 / ((int)speculative
+ 1);
3234 else if (size
<= max_inline_insns_auto
/ 2)
3235 res
+= 15 / ((int)speculative
+ 1);
3236 else if (size
<= max_inline_insns_auto
3237 || DECL_DECLARED_INLINE_P (callee
->decl
))
3238 res
+= 7 / ((int)speculative
+ 1);
3244 /* Return time bonus incurred because of hints stored in ESTIMATES. */
3247 hint_time_bonus (cgraph_node
*node
, const ipa_call_estimates
&estimates
)
3250 ipa_hints hints
= estimates
.hints
;
3251 if (hints
& (INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride
))
3252 result
+= opt_for_fn (node
->decl
, param_ipa_cp_loop_hint_bonus
);
3254 sreal bonus_for_one
= opt_for_fn (node
->decl
, param_ipa_cp_loop_hint_bonus
);
3256 if (hints
& INLINE_HINT_loop_iterations
)
3257 result
+= (estimates
.loops_with_known_iterations
* bonus_for_one
).to_int ();
3259 if (hints
& INLINE_HINT_loop_stride
)
3260 result
+= (estimates
.loops_with_known_strides
* bonus_for_one
).to_int ();
3265 /* If there is a reason to penalize the function described by INFO in the
3266 cloning goodness evaluation, do so. */
3269 incorporate_penalties (cgraph_node
*node
, ipa_node_params
*info
,
3272 if (info
->node_within_scc
&& !info
->node_is_self_scc
)
3273 evaluation
= (evaluation
3274 * (100 - opt_for_fn (node
->decl
,
3275 param_ipa_cp_recursion_penalty
))) / 100;
3277 if (info
->node_calling_single_call
)
3278 evaluation
= (evaluation
3279 * (100 - opt_for_fn (node
->decl
,
3280 param_ipa_cp_single_call_penalty
)))
3286 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3287 and SIZE_COST and with the sum of frequencies of incoming edges to the
3288 potential new clone in FREQUENCIES. */
3291 good_cloning_opportunity_p (struct cgraph_node
*node
, sreal time_benefit
,
3292 sreal freq_sum
, profile_count count_sum
,
3295 if (time_benefit
== 0
3296 || !opt_for_fn (node
->decl
, flag_ipa_cp_clone
)
3297 || node
->optimize_for_size_p ())
3300 gcc_assert (size_cost
> 0);
3302 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
3303 int eval_threshold
= opt_for_fn (node
->decl
, param_ipa_cp_eval_threshold
);
3304 if (max_count
> profile_count::zero ())
3307 sreal factor
= count_sum
.probability_in (max_count
).to_sreal ();
3308 sreal evaluation
= (time_benefit
* factor
) / size_cost
;
3309 evaluation
= incorporate_penalties (node
, info
, evaluation
);
3312 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3314 fprintf (dump_file
, " good_cloning_opportunity_p (time: %g, "
3315 "size: %i, count_sum: ", time_benefit
.to_double (),
3317 count_sum
.dump (dump_file
);
3318 fprintf (dump_file
, "%s%s) -> evaluation: %.2f, threshold: %i\n",
3319 info
->node_within_scc
3320 ? (info
->node_is_self_scc
? ", self_scc" : ", scc") : "",
3321 info
->node_calling_single_call
? ", single_call" : "",
3322 evaluation
.to_double (), eval_threshold
);
3325 return evaluation
.to_int () >= eval_threshold
;
3329 sreal evaluation
= (time_benefit
* freq_sum
) / size_cost
;
3330 evaluation
= incorporate_penalties (node
, info
, evaluation
);
3333 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3334 fprintf (dump_file
, " good_cloning_opportunity_p (time: %g, "
3335 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
3337 time_benefit
.to_double (), size_cost
, freq_sum
.to_double (),
3338 info
->node_within_scc
3339 ? (info
->node_is_self_scc
? ", self_scc" : ", scc") : "",
3340 info
->node_calling_single_call
? ", single_call" : "",
3341 evaluation
.to_double (), eval_threshold
);
3343 return evaluation
.to_int () >= eval_threshold
;
3347 /* Return all context independent values from aggregate lattices in PLATS in a
3348 vector. Return NULL if there are none. */
3350 static vec
<ipa_agg_value
>
3351 context_independent_aggregate_values (class ipcp_param_lattices
*plats
)
3353 vec
<ipa_agg_value
> res
= vNULL
;
3355 if (plats
->aggs_bottom
3356 || plats
->aggs_contain_variable
3357 || plats
->aggs_count
== 0)
3360 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
;
3362 aglat
= aglat
->next
)
3363 if (aglat
->is_single_const ())
3365 struct ipa_agg_value item
;
3366 item
.offset
= aglat
->offset
;
3367 item
.value
= aglat
->values
->value
;
3368 res
.safe_push (item
);
3373 /* Grow vectors in AVALS and fill them with information about values of
3374 parameters that are known to be independent of the context. Only calculate
3375 m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If
3376 REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
3377 parameters will be stored in it.
3379 TODO: Also grow context independent value range vectors. */
3382 gather_context_independent_values (class ipa_node_params
*info
,
3383 ipa_auto_call_arg_values
*avals
,
3384 bool calculate_aggs
,
3385 int *removable_params_cost
)
3387 int i
, count
= ipa_get_param_count (info
);
3390 avals
->m_known_vals
.safe_grow_cleared (count
, true);
3391 avals
->m_known_contexts
.safe_grow_cleared (count
, true);
3393 avals
->m_known_aggs
.safe_grow_cleared (count
, true);
3395 if (removable_params_cost
)
3396 *removable_params_cost
= 0;
3398 for (i
= 0; i
< count
; i
++)
3400 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3401 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3403 if (lat
->is_single_const ())
3405 ipcp_value
<tree
> *val
= lat
->values
;
3406 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
3407 avals
->m_known_vals
[i
] = val
->value
;
3408 if (removable_params_cost
)
3409 *removable_params_cost
3410 += estimate_move_cost (TREE_TYPE (val
->value
), false);
3413 else if (removable_params_cost
3414 && !ipa_is_param_used (info
, i
))
3415 *removable_params_cost
3416 += ipa_get_param_move_cost (info
, i
);
3418 if (!ipa_is_param_used (info
, i
))
3421 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3422 /* Do not account known context as reason for cloning. We can see
3423 if it permits devirtualization. */
3424 if (ctxlat
->is_single_const ())
3425 avals
->m_known_contexts
[i
] = ctxlat
->values
->value
;
3429 vec
<ipa_agg_value
> agg_items
;
3430 struct ipa_agg_value_set
*agg
;
3432 agg_items
= context_independent_aggregate_values (plats
);
3433 agg
= &avals
->m_known_aggs
[i
];
3434 agg
->items
= agg_items
;
3435 agg
->by_ref
= plats
->aggs_by_ref
;
3436 ret
|= !agg_items
.is_empty ();
3443 /* Perform time and size measurement of NODE with the context given in AVALS,
3444 calculate the benefit compared to the node without specialization and store
3445 it into VAL. Take into account REMOVABLE_PARAMS_COST of all
3446 context-independent or unused removable parameters and EST_MOVE_COST, the
3447 estimated movement of the considered parameter. */
3450 perform_estimation_of_a_value (cgraph_node
*node
,
3451 ipa_auto_call_arg_values
*avals
,
3452 int removable_params_cost
, int est_move_cost
,
3453 ipcp_value_base
*val
)
3456 ipa_call_estimates estimates
;
3458 estimate_ipcp_clone_size_and_time (node
, avals
, &estimates
);
3460 /* Extern inline functions have no cloning local time benefits because they
3461 will be inlined anyway. The only reason to clone them is if it enables
3462 optimization in any of the functions they call. */
3463 if (DECL_EXTERNAL (node
->decl
) && DECL_DECLARED_INLINE_P (node
->decl
))
3466 time_benefit
= (estimates
.nonspecialized_time
- estimates
.time
)
3467 + (devirtualization_time_bonus (node
, avals
)
3468 + hint_time_bonus (node
, estimates
)
3469 + removable_params_cost
+ est_move_cost
);
3471 int size
= estimates
.size
;
3472 gcc_checking_assert (size
>=0);
3473 /* The inliner-heuristics based estimates may think that in certain
3474 contexts some functions do not have any size at all but we want
3475 all specializations to have at least a tiny cost, not least not to
3480 val
->local_time_benefit
= time_benefit
;
3481 val
->local_size_cost
= size
;
3484 /* Get the overall limit oof growth based on parameters extracted from growth.
3485 it does not really make sense to mix functions with different overall growth
3486 limits but it is possible and if it happens, we do not want to select one
3490 get_max_overall_size (cgraph_node
*node
)
3492 long max_new_size
= orig_overall_size
;
3493 long large_unit
= opt_for_fn (node
->decl
, param_ipa_cp_large_unit_insns
);
3494 if (max_new_size
< large_unit
)
3495 max_new_size
= large_unit
;
3496 int unit_growth
= opt_for_fn (node
->decl
, param_ipa_cp_unit_growth
);
3497 max_new_size
+= max_new_size
* unit_growth
/ 100 + 1;
3498 return max_new_size
;
3501 /* Iterate over known values of parameters of NODE and estimate the local
3502 effects in terms of time and size they have. */
3505 estimate_local_effects (struct cgraph_node
*node
)
3507 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
3508 int i
, count
= ipa_get_param_count (info
);
3510 int removable_params_cost
;
3512 if (!count
|| !ipcp_versionable_function_p (node
))
3515 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3516 fprintf (dump_file
, "\nEstimating effects for %s.\n", node
->dump_name ());
3518 ipa_auto_call_arg_values avals
;
3519 always_const
= gather_context_independent_values (info
, &avals
, true,
3520 &removable_params_cost
);
3521 int devirt_bonus
= devirtualization_time_bonus (node
, &avals
);
3522 if (always_const
|| devirt_bonus
3523 || (removable_params_cost
&& node
->can_change_signature
))
3525 struct caller_statistics stats
;
3526 ipa_call_estimates estimates
;
3528 init_caller_stats (&stats
);
3529 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3531 estimate_ipcp_clone_size_and_time (node
, &avals
, &estimates
);
3532 sreal time
= estimates
.nonspecialized_time
- estimates
.time
;
3533 time
+= devirt_bonus
;
3534 time
+= hint_time_bonus (node
, estimates
);
3535 time
+= removable_params_cost
;
3536 int size
= estimates
.size
- stats
.n_calls
* removable_params_cost
;
3539 fprintf (dump_file
, " - context independent values, size: %i, "
3540 "time_benefit: %f\n", size
, (time
).to_double ());
3542 if (size
<= 0 || node
->local
)
3544 info
->do_clone_for_all_contexts
= true;
3547 fprintf (dump_file
, " Decided to specialize for all "
3548 "known contexts, code not going to grow.\n");
3550 else if (good_cloning_opportunity_p (node
, time
, stats
.freq_sum
,
3551 stats
.count_sum
, size
))
3553 if (size
+ overall_size
<= get_max_overall_size (node
))
3555 info
->do_clone_for_all_contexts
= true;
3556 overall_size
+= size
;
3559 fprintf (dump_file
, " Decided to specialize for all "
3560 "known contexts, growth (to %li) deemed "
3561 "beneficial.\n", overall_size
);
3563 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3564 fprintf (dump_file
, " Not cloning for all contexts because "
3565 "maximum unit size would be reached with %li.\n",
3566 size
+ overall_size
);
3568 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3569 fprintf (dump_file
, " Not cloning for all contexts because "
3570 "!good_cloning_opportunity_p.\n");
3574 for (i
= 0; i
< count
; i
++)
3576 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3577 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3578 ipcp_value
<tree
> *val
;
3582 || avals
.m_known_vals
[i
])
3585 for (val
= lat
->values
; val
; val
= val
->next
)
3587 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
3588 avals
.m_known_vals
[i
] = val
->value
;
3590 int emc
= estimate_move_cost (TREE_TYPE (val
->value
), true);
3591 perform_estimation_of_a_value (node
, &avals
, removable_params_cost
,
3594 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3596 fprintf (dump_file
, " - estimates for value ");
3597 print_ipcp_constant_value (dump_file
, val
->value
);
3598 fprintf (dump_file
, " for ");
3599 ipa_dump_param (dump_file
, info
, i
);
3600 fprintf (dump_file
, ": time_benefit: %g, size: %i\n",
3601 val
->local_time_benefit
.to_double (),
3602 val
->local_size_cost
);
3605 avals
.m_known_vals
[i
] = NULL_TREE
;
3608 for (i
= 0; i
< count
; i
++)
3610 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3612 if (!plats
->virt_call
)
3615 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3616 ipcp_value
<ipa_polymorphic_call_context
> *val
;
3620 || !avals
.m_known_contexts
[i
].useless_p ())
3623 for (val
= ctxlat
->values
; val
; val
= val
->next
)
3625 avals
.m_known_contexts
[i
] = val
->value
;
3626 perform_estimation_of_a_value (node
, &avals
, removable_params_cost
,
3629 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3631 fprintf (dump_file
, " - estimates for polymorphic context ");
3632 print_ipcp_constant_value (dump_file
, val
->value
);
3633 fprintf (dump_file
, " for ");
3634 ipa_dump_param (dump_file
, info
, i
);
3635 fprintf (dump_file
, ": time_benefit: %g, size: %i\n",
3636 val
->local_time_benefit
.to_double (),
3637 val
->local_size_cost
);
3640 avals
.m_known_contexts
[i
] = ipa_polymorphic_call_context ();
3643 for (i
= 0; i
< count
; i
++)
3645 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3647 if (plats
->aggs_bottom
|| !plats
->aggs
)
3650 ipa_agg_value_set
*agg
= &avals
.m_known_aggs
[i
];
3651 for (ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3653 ipcp_value
<tree
> *val
;
3654 if (aglat
->bottom
|| !aglat
->values
3655 /* If the following is true, the one value is in known_aggs. */
3656 || (!plats
->aggs_contain_variable
3657 && aglat
->is_single_const ()))
3660 for (val
= aglat
->values
; val
; val
= val
->next
)
3662 struct ipa_agg_value item
;
3664 item
.offset
= aglat
->offset
;
3665 item
.value
= val
->value
;
3666 agg
->items
.safe_push (item
);
3668 perform_estimation_of_a_value (node
, &avals
,
3669 removable_params_cost
, 0, val
);
3671 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3673 fprintf (dump_file
, " - estimates for value ");
3674 print_ipcp_constant_value (dump_file
, val
->value
);
3675 fprintf (dump_file
, " for ");
3676 ipa_dump_param (dump_file
, info
, i
);
3677 fprintf (dump_file
, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3678 "]: time_benefit: %g, size: %i\n",
3679 plats
->aggs_by_ref
? "ref " : "",
3681 val
->local_time_benefit
.to_double (),
3682 val
->local_size_cost
);
3692 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3693 topological sort of values. */
3695 template <typename valtype
>
3697 value_topo_info
<valtype
>::add_val (ipcp_value
<valtype
> *cur_val
)
3699 ipcp_value_source
<valtype
> *src
;
3705 cur_val
->dfs
= dfs_counter
;
3706 cur_val
->low_link
= dfs_counter
;
3708 cur_val
->topo_next
= stack
;
3710 cur_val
->on_stack
= true;
3712 for (src
= cur_val
->sources
; src
; src
= src
->next
)
3715 if (src
->val
->dfs
== 0)
3718 if (src
->val
->low_link
< cur_val
->low_link
)
3719 cur_val
->low_link
= src
->val
->low_link
;
3721 else if (src
->val
->on_stack
3722 && src
->val
->dfs
< cur_val
->low_link
)
3723 cur_val
->low_link
= src
->val
->dfs
;
3726 if (cur_val
->dfs
== cur_val
->low_link
)
3728 ipcp_value
<valtype
> *v
, *scc_list
= NULL
;
3733 stack
= v
->topo_next
;
3734 v
->on_stack
= false;
3736 v
->scc_next
= scc_list
;
3739 while (v
!= cur_val
);
3741 cur_val
->topo_next
= values_topo
;
3742 values_topo
= cur_val
;
3746 /* Add all values in lattices associated with NODE to the topological sort if
3747 they are not there yet. */
3750 add_all_node_vals_to_toposort (cgraph_node
*node
, ipa_topo_info
*topo
)
3752 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
3753 int i
, count
= ipa_get_param_count (info
);
3755 for (i
= 0; i
< count
; i
++)
3757 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3758 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3759 struct ipcp_agg_lattice
*aglat
;
3763 ipcp_value
<tree
> *val
;
3764 for (val
= lat
->values
; val
; val
= val
->next
)
3765 topo
->constants
.add_val (val
);
3768 if (!plats
->aggs_bottom
)
3769 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3772 ipcp_value
<tree
> *val
;
3773 for (val
= aglat
->values
; val
; val
= val
->next
)
3774 topo
->constants
.add_val (val
);
3777 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3778 if (!ctxlat
->bottom
)
3780 ipcp_value
<ipa_polymorphic_call_context
> *ctxval
;
3781 for (ctxval
= ctxlat
->values
; ctxval
; ctxval
= ctxval
->next
)
3782 topo
->contexts
.add_val (ctxval
);
3787 /* One pass of constants propagation along the call graph edges, from callers
3788 to callees (requires topological ordering in TOPO), iterate over strongly
3789 connected components. */
3792 propagate_constants_topo (class ipa_topo_info
*topo
)
3796 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
3799 struct cgraph_node
*v
, *node
= topo
->order
[i
];
3800 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
3802 /* First, iteratively propagate within the strongly connected component
3803 until all lattices stabilize. */
3804 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3805 if (v
->has_gimple_body_p ())
3807 if (opt_for_fn (v
->decl
, flag_ipa_cp
)
3808 && opt_for_fn (v
->decl
, optimize
))
3809 push_node_to_stack (topo
, v
);
3810 /* When V is not optimized, we can not push it to stack, but
3811 still we need to set all its callees lattices to bottom. */
3814 for (cgraph_edge
*cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3815 propagate_constants_across_call (cs
);
3819 v
= pop_node_from_stack (topo
);
3822 struct cgraph_edge
*cs
;
3823 class ipa_node_params
*info
= NULL
;
3824 bool self_scc
= true;
3826 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3827 if (ipa_edge_within_scc (cs
))
3829 cgraph_node
*callee
= cs
->callee
->function_symbol ();
3836 info
= ipa_node_params_sum
->get (v
);
3837 info
->node_within_scc
= true;
3840 if (propagate_constants_across_call (cs
))
3841 push_node_to_stack (topo
, callee
);
3845 info
->node_is_self_scc
= self_scc
;
3847 v
= pop_node_from_stack (topo
);
3850 /* Afterwards, propagate along edges leading out of the SCC, calculates
3851 the local effects of the discovered constants and all valid values to
3852 their topological sort. */
3853 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3854 if (v
->has_gimple_body_p ()
3855 && opt_for_fn (v
->decl
, flag_ipa_cp
)
3856 && opt_for_fn (v
->decl
, optimize
))
3858 struct cgraph_edge
*cs
;
3860 estimate_local_effects (v
);
3861 add_all_node_vals_to_toposort (v
, topo
);
3862 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3863 if (!ipa_edge_within_scc (cs
))
3864 propagate_constants_across_call (cs
);
3866 cycle_nodes
.release ();
3870 /* Propagate the estimated effects of individual values along the topological
3871 from the dependent values to those they depend on. */
3873 template <typename valtype
>
3875 value_topo_info
<valtype
>::propagate_effects ()
3877 ipcp_value
<valtype
> *base
;
3878 hash_set
<ipcp_value
<valtype
> *> processed_srcvals
;
3880 for (base
= values_topo
; base
; base
= base
->topo_next
)
3882 ipcp_value_source
<valtype
> *src
;
3883 ipcp_value
<valtype
> *val
;
3885 HOST_WIDE_INT size
= 0;
3887 for (val
= base
; val
; val
= val
->scc_next
)
3889 time
= time
+ val
->local_time_benefit
+ val
->prop_time_benefit
;
3890 size
= size
+ val
->local_size_cost
+ val
->prop_size_cost
;
3893 for (val
= base
; val
; val
= val
->scc_next
)
3895 processed_srcvals
.empty ();
3896 for (src
= val
->sources
; src
; src
= src
->next
)
3898 && src
->cs
->maybe_hot_p ())
3900 if (!processed_srcvals
.add (src
->val
))
3902 HOST_WIDE_INT prop_size
= size
+ src
->val
->prop_size_cost
;
3903 if (prop_size
< INT_MAX
)
3904 src
->val
->prop_size_cost
= prop_size
;
3908 src
->val
->prop_time_benefit
3909 += time
* src
->cs
->sreal_frequency ();
3914 val
->prop_time_benefit
= time
;
3915 val
->prop_size_cost
= size
;
3919 val
->prop_time_benefit
= 0;
3920 val
->prop_size_cost
= 0;
3927 /* Propagate constants, polymorphic contexts and their effects from the
3928 summaries interprocedurally. */
3931 ipcp_propagate_stage (class ipa_topo_info
*topo
)
3933 struct cgraph_node
*node
;
3936 fprintf (dump_file
, "\n Propagating constants:\n\n");
3938 max_count
= profile_count::uninitialized ();
3940 FOR_EACH_DEFINED_FUNCTION (node
)
3942 if (node
->has_gimple_body_p ()
3943 && opt_for_fn (node
->decl
, flag_ipa_cp
)
3944 && opt_for_fn (node
->decl
, optimize
))
3946 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
3947 determine_versionability (node
, info
);
3949 unsigned nlattices
= ipa_get_param_count (info
);
3950 void *chunk
= XCNEWVEC (class ipcp_param_lattices
, nlattices
);
3951 info
->lattices
= new (chunk
) ipcp_param_lattices
[nlattices
];
3952 initialize_node_lattices (node
);
3954 ipa_size_summary
*s
= ipa_size_summaries
->get (node
);
3955 if (node
->definition
&& !node
->alias
&& s
!= NULL
)
3956 overall_size
+= s
->self_size
;
3957 max_count
= max_count
.max (node
->count
.ipa ());
3960 orig_overall_size
= overall_size
;
3963 fprintf (dump_file
, "\noverall_size: %li\n", overall_size
);
3965 propagate_constants_topo (topo
);
3967 ipcp_verify_propagated_values ();
3968 topo
->constants
.propagate_effects ();
3969 topo
->contexts
.propagate_effects ();
3973 fprintf (dump_file
, "\nIPA lattices after all propagation:\n");
3974 print_all_lattices (dump_file
, (dump_flags
& TDF_DETAILS
), true);
3978 /* Discover newly direct outgoing edges from NODE which is a new clone with
3979 known KNOWN_CSTS and make them direct. */
3982 ipcp_discover_new_direct_edges (struct cgraph_node
*node
,
3983 vec
<tree
> known_csts
,
3984 vec
<ipa_polymorphic_call_context
>
3986 struct ipa_agg_replacement_value
*aggvals
)
3988 struct cgraph_edge
*ie
, *next_ie
;
3991 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3996 next_ie
= ie
->next_callee
;
3997 target
= ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
3998 vNULL
, aggvals
, &speculative
);
4001 bool agg_contents
= ie
->indirect_info
->agg_contents
;
4002 bool polymorphic
= ie
->indirect_info
->polymorphic
;
4003 int param_index
= ie
->indirect_info
->param_index
;
4004 struct cgraph_edge
*cs
= ipa_make_edge_direct_to_target (ie
, target
,
4008 if (cs
&& !agg_contents
&& !polymorphic
)
4010 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
4011 int c
= ipa_get_controlled_uses (info
, param_index
);
4012 if (c
!= IPA_UNDESCRIBED_USE
4013 && !ipa_get_param_load_dereferenced (info
, param_index
))
4015 struct ipa_ref
*to_del
;
4018 ipa_set_controlled_uses (info
, param_index
, c
);
4019 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4020 fprintf (dump_file
, " controlled uses count of param "
4021 "%i bumped down to %i\n", param_index
, c
);
4023 && (to_del
= node
->find_reference (cs
->callee
, NULL
, 0)))
4025 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4026 fprintf (dump_file
, " and even removing its "
4027 "cloning-created reference\n");
4028 to_del
->remove_reference ();
4034 /* Turning calls to direct calls will improve overall summary. */
4036 ipa_update_overall_fn_summary (node
);
4039 class edge_clone_summary
;
4040 static call_summary
<edge_clone_summary
*> *edge_clone_summaries
= NULL
;
4042 /* Edge clone summary. */
4044 class edge_clone_summary
4047 /* Default constructor. */
4048 edge_clone_summary (): prev_clone (NULL
), next_clone (NULL
) {}
4050 /* Default destructor. */
4051 ~edge_clone_summary ()
4054 edge_clone_summaries
->get (prev_clone
)->next_clone
= next_clone
;
4056 edge_clone_summaries
->get (next_clone
)->prev_clone
= prev_clone
;
4059 cgraph_edge
*prev_clone
;
4060 cgraph_edge
*next_clone
;
4063 class edge_clone_summary_t
:
4064 public call_summary
<edge_clone_summary
*>
4067 edge_clone_summary_t (symbol_table
*symtab
):
4068 call_summary
<edge_clone_summary
*> (symtab
)
4070 m_initialize_when_cloning
= true;
4073 virtual void duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
4074 edge_clone_summary
*src_data
,
4075 edge_clone_summary
*dst_data
);
4078 /* Edge duplication hook. */
4081 edge_clone_summary_t::duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
4082 edge_clone_summary
*src_data
,
4083 edge_clone_summary
*dst_data
)
4085 if (src_data
->next_clone
)
4086 edge_clone_summaries
->get (src_data
->next_clone
)->prev_clone
= dst_edge
;
4087 dst_data
->prev_clone
= src_edge
;
4088 dst_data
->next_clone
= src_data
->next_clone
;
4089 src_data
->next_clone
= dst_edge
;
4092 /* Return true is CS calls DEST or its clone for all contexts. When
4093 ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
4094 edges from/to an all-context clone. */
4097 calls_same_node_or_its_all_contexts_clone_p (cgraph_edge
*cs
, cgraph_node
*dest
,
4098 bool allow_recursion_to_clone
)
4100 enum availability availability
;
4101 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
4103 if (availability
<= AVAIL_INTERPOSABLE
)
4107 if (!allow_recursion_to_clone
&& cs
->caller
== callee
)
4110 ipa_node_params
*info
= ipa_node_params_sum
->get (callee
);
4111 return info
->is_all_contexts_clone
&& info
->ipcp_orig_node
== dest
;
4114 /* Return true if edge CS does bring about the value described by SRC to
4115 DEST_VAL of node DEST or its clone for all contexts. */
4118 cgraph_edge_brings_value_p (cgraph_edge
*cs
, ipcp_value_source
<tree
> *src
,
4119 cgraph_node
*dest
, ipcp_value
<tree
> *dest_val
)
4121 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
4123 if (!calls_same_node_or_its_all_contexts_clone_p (cs
, dest
, !src
->val
)
4124 || caller_info
->node_dead
)
4130 if (caller_info
->ipcp_orig_node
)
4133 if (src
->offset
== -1)
4134 t
= caller_info
->known_csts
[src
->index
];
4136 t
= get_clone_agg_value (cs
->caller
, src
->offset
, src
->index
);
4137 return (t
!= NULL_TREE
4138 && values_equal_for_ipcp_p (src
->val
->value
, t
));
4142 if (src
->val
== dest_val
)
4145 struct ipcp_agg_lattice
*aglat
;
4146 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
4148 if (src
->offset
== -1)
4149 return (plats
->itself
.is_single_const ()
4150 && values_equal_for_ipcp_p (src
->val
->value
,
4151 plats
->itself
.values
->value
));
4154 if (plats
->aggs_bottom
|| plats
->aggs_contain_variable
)
4156 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4157 if (aglat
->offset
== src
->offset
)
4158 return (aglat
->is_single_const ()
4159 && values_equal_for_ipcp_p (src
->val
->value
,
4160 aglat
->values
->value
));
4166 /* Return true if edge CS does bring about the value described by SRC to
4167 DST_VAL of node DEST or its clone for all contexts. */
4170 cgraph_edge_brings_value_p (cgraph_edge
*cs
,
4171 ipcp_value_source
<ipa_polymorphic_call_context
> *src
,
4173 ipcp_value
<ipa_polymorphic_call_context
> *)
4175 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
4177 if (!calls_same_node_or_its_all_contexts_clone_p (cs
, dest
, true)
4178 || caller_info
->node_dead
)
4183 if (caller_info
->ipcp_orig_node
)
4184 return (caller_info
->known_contexts
.length () > (unsigned) src
->index
)
4185 && values_equal_for_ipcp_p (src
->val
->value
,
4186 caller_info
->known_contexts
[src
->index
]);
4188 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
4190 return plats
->ctxlat
.is_single_const ()
4191 && values_equal_for_ipcp_p (src
->val
->value
,
4192 plats
->ctxlat
.values
->value
);
4195 /* Get the next clone in the linked list of clones of an edge. */
4197 static inline struct cgraph_edge
*
4198 get_next_cgraph_edge_clone (struct cgraph_edge
*cs
)
4200 edge_clone_summary
*s
= edge_clone_summaries
->get (cs
);
4201 return s
!= NULL
? s
->next_clone
: NULL
;
4204 /* Given VAL that is intended for DEST, iterate over all its sources and if any
4205 of them is viable and hot, return true. In that case, for those that still
4206 hold, add their edge frequency and their number into *FREQUENCY and
4207 *CALLER_COUNT respectively. */
4209 template <typename valtype
>
4211 get_info_about_necessary_edges (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
4212 sreal
*freq_sum
, profile_count
*count_sum
,
4215 ipcp_value_source
<valtype
> *src
;
4218 profile_count cnt
= profile_count::zero ();
4220 bool non_self_recursive
= false;
4222 for (src
= val
->sources
; src
; src
= src
->next
)
4224 struct cgraph_edge
*cs
= src
->cs
;
4227 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
4230 freq
+= cs
->sreal_frequency ();
4231 if (cs
->count
.ipa ().initialized_p ())
4232 cnt
+= cs
->count
.ipa ();
4233 hot
|= cs
->maybe_hot_p ();
4234 if (cs
->caller
!= dest
)
4235 non_self_recursive
= true;
4237 cs
= get_next_cgraph_edge_clone (cs
);
4241 /* If the only edges bringing a value are self-recursive ones, do not bother
4243 if (!non_self_recursive
)
4248 *caller_count
= count
;
4250 if (!hot
&& ipa_node_params_sum
->get (dest
)->node_within_scc
)
4252 struct cgraph_edge
*cs
;
4254 /* Cold non-SCC source edge could trigger hot recursive execution of
4255 function. Consider the case as hot and rely on following cost model
4256 computation to further select right one. */
4257 for (cs
= dest
->callers
; cs
; cs
= cs
->next_caller
)
4258 if (cs
->caller
== dest
&& cs
->maybe_hot_p ())
4265 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4266 to let a non-self-recursive caller be the first element. Thus, we can
4267 simplify intersecting operations on values that arrive from all of these
4268 callers, especially when there exists self-recursive call. Return true if
4269 this kind of adjustment is possible. */
4272 adjust_callers_for_value_intersection (vec
<cgraph_edge
*> &callers
,
4275 for (unsigned i
= 0; i
< callers
.length (); i
++)
4277 cgraph_edge
*cs
= callers
[i
];
4279 if (cs
->caller
!= node
)
4283 callers
[i
] = callers
[0];
4292 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
4293 is assumed their number is known and equal to CALLER_COUNT. */
4295 template <typename valtype
>
4296 static vec
<cgraph_edge
*>
4297 gather_edges_for_value (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
4300 ipcp_value_source
<valtype
> *src
;
4301 vec
<cgraph_edge
*> ret
;
4303 ret
.create (caller_count
);
4304 for (src
= val
->sources
; src
; src
= src
->next
)
4306 struct cgraph_edge
*cs
= src
->cs
;
4309 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
4310 ret
.quick_push (cs
);
4311 cs
= get_next_cgraph_edge_clone (cs
);
4315 if (caller_count
> 1)
4316 adjust_callers_for_value_intersection (ret
, dest
);
4321 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4322 Return it or NULL if for some reason it cannot be created. FORCE_LOAD_REF
4323 should be set to true when the reference created for the constant should be
4324 a load one and not an address one because the corresponding parameter p is
4327 static struct ipa_replace_map
*
4328 get_replacement_map (class ipa_node_params
*info
, tree value
, int parm_num
,
4329 bool force_load_ref
)
4331 struct ipa_replace_map
*replace_map
;
4333 replace_map
= ggc_alloc
<ipa_replace_map
> ();
4336 fprintf (dump_file
, " replacing ");
4337 ipa_dump_param (dump_file
, info
, parm_num
);
4339 fprintf (dump_file
, " with const ");
4340 print_generic_expr (dump_file
, value
);
4343 fprintf (dump_file
, " - forcing load reference\n");
4345 fprintf (dump_file
, "\n");
4347 replace_map
->parm_num
= parm_num
;
4348 replace_map
->new_tree
= value
;
4349 replace_map
->force_load_ref
= force_load_ref
;
4353 /* Dump new profiling counts */
4356 dump_profile_updates (struct cgraph_node
*orig_node
,
4357 struct cgraph_node
*new_node
)
4359 struct cgraph_edge
*cs
;
4361 fprintf (dump_file
, " setting count of the specialized node to ");
4362 new_node
->count
.dump (dump_file
);
4363 fprintf (dump_file
, "\n");
4364 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4366 fprintf (dump_file
, " edge to %s has count ",
4367 cs
->callee
->dump_name ());
4368 cs
->count
.dump (dump_file
);
4369 fprintf (dump_file
, "\n");
4372 fprintf (dump_file
, " setting count of the original node to ");
4373 orig_node
->count
.dump (dump_file
);
4374 fprintf (dump_file
, "\n");
4375 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4377 fprintf (dump_file
, " edge to %s is left with ",
4378 cs
->callee
->dump_name ());
4379 cs
->count
.dump (dump_file
);
4380 fprintf (dump_file
, "\n");
4384 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4385 their profile information to reflect this. */
4388 update_profiling_info (struct cgraph_node
*orig_node
,
4389 struct cgraph_node
*new_node
)
4391 struct cgraph_edge
*cs
;
4392 struct caller_statistics stats
;
4393 profile_count new_sum
, orig_sum
;
4394 profile_count remainder
, orig_node_count
= orig_node
->count
;
4395 profile_count orig_new_node_count
= new_node
->count
;
4397 if (!(orig_node_count
.ipa () > profile_count::zero ()))
4400 init_caller_stats (&stats
);
4401 orig_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
4403 orig_sum
= stats
.count_sum
;
4404 init_caller_stats (&stats
);
4405 new_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
4407 new_sum
= stats
.count_sum
;
4409 if (orig_node_count
< orig_sum
+ new_sum
)
4413 fprintf (dump_file
, " Problem: node %s has too low count ",
4414 orig_node
->dump_name ());
4415 orig_node_count
.dump (dump_file
);
4416 fprintf (dump_file
, "while the sum of incoming count is ");
4417 (orig_sum
+ new_sum
).dump (dump_file
);
4418 fprintf (dump_file
, "\n");
4421 orig_node_count
= (orig_sum
+ new_sum
).apply_scale (12, 10);
4424 fprintf (dump_file
, " proceeding by pretending it was ");
4425 orig_node_count
.dump (dump_file
);
4426 fprintf (dump_file
, "\n");
4430 remainder
= orig_node_count
.combine_with_ipa_count (orig_node_count
.ipa ()
4433 /* With partial train run we do not want to assume that original's
4434 count is zero whenever we redurect all executed edges to clone.
4435 Simply drop profile to local one in this case. */
4436 if (remainder
.ipa_p () && !remainder
.ipa ().nonzero_p ()
4437 && orig_node
->count
.ipa_p () && orig_node
->count
.ipa ().nonzero_p ()
4438 && flag_profile_partial_training
)
4439 remainder
= remainder
.guessed_local ();
4441 new_sum
= orig_node_count
.combine_with_ipa_count (new_sum
);
4442 new_node
->count
= new_sum
;
4443 orig_node
->count
= remainder
;
4445 profile_count::adjust_for_ipa_scaling (&new_sum
, &orig_new_node_count
);
4446 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4447 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_new_node_count
);
4448 for (cs
= new_node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
4449 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_new_node_count
);
4451 profile_count::adjust_for_ipa_scaling (&remainder
, &orig_node_count
);
4452 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4453 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
4454 for (cs
= orig_node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
4455 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
4458 dump_profile_updates (orig_node
, new_node
);
4461 /* Update the respective profile of specialized NEW_NODE and the original
4462 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4463 have been redirected to the specialized version. */
4466 update_specialized_profile (struct cgraph_node
*new_node
,
4467 struct cgraph_node
*orig_node
,
4468 profile_count redirected_sum
)
4470 struct cgraph_edge
*cs
;
4471 profile_count new_node_count
, orig_node_count
= orig_node
->count
;
4475 fprintf (dump_file
, " the sum of counts of redirected edges is ");
4476 redirected_sum
.dump (dump_file
);
4477 fprintf (dump_file
, "\n");
4479 if (!(orig_node_count
> profile_count::zero ()))
4482 gcc_assert (orig_node_count
>= redirected_sum
);
4484 new_node_count
= new_node
->count
;
4485 new_node
->count
+= redirected_sum
;
4486 orig_node
->count
-= redirected_sum
;
4488 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4489 cs
->count
+= cs
->count
.apply_scale (redirected_sum
, new_node_count
);
4491 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4493 profile_count dec
= cs
->count
.apply_scale (redirected_sum
,
4499 dump_profile_updates (orig_node
, new_node
);
4502 static void adjust_references_in_caller (cgraph_edge
*cs
,
4503 symtab_node
*symbol
, int index
);
4505 /* Simple structure to pass a symbol and index (with same meaning as parameters
4506 of adjust_references_in_caller) through a void* parameter of a
4507 call_for_symbol_thunks_and_aliases callback. */
4508 struct symbol_and_index_together
4510 symtab_node
*symbol
;
4514 /* Worker callback of call_for_symbol_thunks_and_aliases to recursively call
4515 adjust_references_in_caller on edges up in the call-graph, if necessary. */
4517 adjust_refs_in_act_callers (struct cgraph_node
*node
, void *data
)
4519 symbol_and_index_together
*pack
= (symbol_and_index_together
*) data
;
4520 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4521 if (!cs
->caller
->thunk
)
4522 adjust_references_in_caller (cs
, pack
->symbol
, pack
->index
);
4526 /* At INDEX of a function being called by CS there is an ADDR_EXPR of a
4527 variable which is only dereferenced and which is represented by SYMBOL. See
4528 if we can remove ADDR reference in callers assosiated witht the call. */
4531 adjust_references_in_caller (cgraph_edge
*cs
, symtab_node
*symbol
, int index
)
4533 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4534 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, index
);
4535 if (jfunc
->type
== IPA_JF_CONST
)
4537 ipa_ref
*to_del
= cs
->caller
->find_reference (symbol
, cs
->call_stmt
,
4541 to_del
->remove_reference ();
4543 fprintf (dump_file
, " Removed a reference from %s to %s.\n",
4544 cs
->caller
->dump_name (), symbol
->dump_name ());
4548 if (jfunc
->type
!= IPA_JF_PASS_THROUGH
4549 || ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
4552 int fidx
= ipa_get_jf_pass_through_formal_id (jfunc
);
4553 cgraph_node
*caller
= cs
->caller
;
4554 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (caller
);
4555 /* TODO: This consistency check may be too big and not really
4556 that useful. Consider removing it. */
4558 if (caller_info
->ipcp_orig_node
)
4559 cst
= caller_info
->known_csts
[fidx
];
4562 ipcp_lattice
<tree
> *lat
= ipa_get_scalar_lat (caller_info
, fidx
);
4563 gcc_assert (lat
->is_single_const ());
4564 cst
= lat
->values
->value
;
4566 gcc_assert (TREE_CODE (cst
) == ADDR_EXPR
4567 && (symtab_node::get (get_base_address (TREE_OPERAND (cst
, 0)))
4570 int cuses
= ipa_get_controlled_uses (caller_info
, fidx
);
4571 if (cuses
== IPA_UNDESCRIBED_USE
)
4573 gcc_assert (cuses
> 0);
4575 ipa_set_controlled_uses (caller_info
, fidx
, cuses
);
4579 if (caller_info
->ipcp_orig_node
)
4581 /* Cloning machinery has created a reference here, we need to either
4582 remove it or change it to a read one. */
4583 ipa_ref
*to_del
= caller
->find_reference (symbol
, NULL
, 0);
4584 if (to_del
&& to_del
->use
== IPA_REF_ADDR
)
4586 to_del
->remove_reference ();
4588 fprintf (dump_file
, " Removed a reference from %s to %s.\n",
4589 cs
->caller
->dump_name (), symbol
->dump_name ());
4590 if (ipa_get_param_load_dereferenced (caller_info
, fidx
))
4592 caller
->create_reference (symbol
, IPA_REF_LOAD
, NULL
);
4595 " ...and replaced it with LOAD one.\n");
4600 symbol_and_index_together pack
;
4601 pack
.symbol
= symbol
;
4603 if (caller
->can_change_signature
)
4604 caller
->call_for_symbol_thunks_and_aliases (adjust_refs_in_act_callers
,
4609 /* Return true if we would like to remove a parameter from NODE when cloning it
4610 with KNOWN_CSTS scalar constants. */
4613 want_remove_some_param_p (cgraph_node
*node
, vec
<tree
> known_csts
)
4615 auto_vec
<bool, 16> surviving
;
4616 bool filled_vec
= false;
4617 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
4618 int i
, count
= ipa_get_param_count (info
);
4620 for (i
= 0; i
< count
; i
++)
4622 if (!known_csts
[i
] && ipa_is_param_used (info
, i
))
4627 clone_info
*info
= clone_info::get (node
);
4628 if (!info
|| !info
->param_adjustments
)
4630 info
->param_adjustments
->get_surviving_params (&surviving
);
4633 if (surviving
.length() < (unsigned) i
&& surviving
[i
])
4639 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4640 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4641 redirect all edges in CALLERS to it. */
4643 static struct cgraph_node
*
4644 create_specialized_node (struct cgraph_node
*node
,
4645 vec
<tree
> known_csts
,
4646 vec
<ipa_polymorphic_call_context
> known_contexts
,
4647 struct ipa_agg_replacement_value
*aggvals
,
4648 vec
<cgraph_edge
*> &callers
)
4650 ipa_node_params
*new_info
, *info
= ipa_node_params_sum
->get (node
);
4651 vec
<ipa_replace_map
*, va_gc
> *replace_trees
= NULL
;
4652 vec
<ipa_adjusted_param
, va_gc
> *new_params
= NULL
;
4653 struct ipa_agg_replacement_value
*av
;
4654 struct cgraph_node
*new_node
;
4655 int i
, count
= ipa_get_param_count (info
);
4656 clone_info
*cinfo
= clone_info::get (node
);
4657 ipa_param_adjustments
*old_adjustments
= cinfo
4658 ? cinfo
->param_adjustments
: NULL
;
4659 ipa_param_adjustments
*new_adjustments
;
4660 gcc_assert (!info
->ipcp_orig_node
);
4661 gcc_assert (node
->can_change_signature
4662 || !old_adjustments
);
4664 if (old_adjustments
)
4666 /* At the moment all IPA optimizations should use the number of
4667 parameters of the prevailing decl as the m_always_copy_start.
4668 Handling any other value would complicate the code below, so for the
4669 time bing let's only assert it is so. */
4670 gcc_assert (old_adjustments
->m_always_copy_start
== count
4671 || old_adjustments
->m_always_copy_start
< 0);
4672 int old_adj_count
= vec_safe_length (old_adjustments
->m_adj_params
);
4673 for (i
= 0; i
< old_adj_count
; i
++)
4675 ipa_adjusted_param
*old_adj
= &(*old_adjustments
->m_adj_params
)[i
];
4676 if (!node
->can_change_signature
4677 || old_adj
->op
!= IPA_PARAM_OP_COPY
4678 || (!known_csts
[old_adj
->base_index
]
4679 && ipa_is_param_used (info
, old_adj
->base_index
)))
4681 ipa_adjusted_param new_adj
= *old_adj
;
4683 new_adj
.prev_clone_adjustment
= true;
4684 new_adj
.prev_clone_index
= i
;
4685 vec_safe_push (new_params
, new_adj
);
4688 bool skip_return
= old_adjustments
->m_skip_return
;
4689 new_adjustments
= (new (ggc_alloc
<ipa_param_adjustments
> ())
4690 ipa_param_adjustments (new_params
, count
,
4693 else if (node
->can_change_signature
4694 && want_remove_some_param_p (node
, known_csts
))
4696 ipa_adjusted_param adj
;
4697 memset (&adj
, 0, sizeof (adj
));
4698 adj
.op
= IPA_PARAM_OP_COPY
;
4699 for (i
= 0; i
< count
; i
++)
4700 if (!known_csts
[i
] && ipa_is_param_used (info
, i
))
4703 adj
.prev_clone_index
= i
;
4704 vec_safe_push (new_params
, adj
);
4706 new_adjustments
= (new (ggc_alloc
<ipa_param_adjustments
> ())
4707 ipa_param_adjustments (new_params
, count
, false));
4710 new_adjustments
= NULL
;
4712 replace_trees
= cinfo
? vec_safe_copy (cinfo
->tree_map
) : NULL
;
4713 for (i
= 0; i
< count
; i
++)
4715 tree t
= known_csts
[i
];
4719 gcc_checking_assert (TREE_CODE (t
) != TREE_BINFO
);
4721 bool load_ref
= false;
4722 symtab_node
*ref_symbol
;
4723 if (TREE_CODE (t
) == ADDR_EXPR
)
4725 tree base
= get_base_address (TREE_OPERAND (t
, 0));
4726 if (TREE_CODE (base
) == VAR_DECL
4727 && ipa_get_controlled_uses (info
, i
) == 0
4728 && ipa_get_param_load_dereferenced (info
, i
)
4729 && (ref_symbol
= symtab_node::get (base
)))
4732 if (node
->can_change_signature
)
4733 for (cgraph_edge
*caller
: callers
)
4734 adjust_references_in_caller (caller
, ref_symbol
, i
);
4738 ipa_replace_map
*replace_map
= get_replacement_map (info
, t
, i
, load_ref
);
4740 vec_safe_push (replace_trees
, replace_map
);
4742 auto_vec
<cgraph_edge
*, 2> self_recursive_calls
;
4743 for (i
= callers
.length () - 1; i
>= 0; i
--)
4745 cgraph_edge
*cs
= callers
[i
];
4746 if (cs
->caller
== node
)
4748 self_recursive_calls
.safe_push (cs
);
4749 callers
.unordered_remove (i
);
4753 unsigned &suffix_counter
= clone_num_suffixes
->get_or_insert (
4754 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4756 new_node
= node
->create_virtual_clone (callers
, replace_trees
,
4757 new_adjustments
, "constprop",
4761 bool have_self_recursive_calls
= !self_recursive_calls
.is_empty ();
4762 for (unsigned j
= 0; j
< self_recursive_calls
.length (); j
++)
4764 cgraph_edge
*cs
= get_next_cgraph_edge_clone (self_recursive_calls
[j
]);
4765 /* Cloned edges can disappear during cloning as speculation can be
4766 resolved, check that we have one and that it comes from the last
4768 if (cs
&& cs
->caller
== new_node
)
4769 cs
->redirect_callee_duplicating_thunks (new_node
);
4770 /* Any future code that would make more than one clone of an outgoing
4771 edge would confuse this mechanism, so let's check that does not
4773 gcc_checking_assert (!cs
4774 || !get_next_cgraph_edge_clone (cs
)
4775 || get_next_cgraph_edge_clone (cs
)->caller
!= new_node
);
4777 if (have_self_recursive_calls
)
4778 new_node
->expand_all_artificial_thunks ();
4780 ipa_set_node_agg_value_chain (new_node
, aggvals
);
4781 for (av
= aggvals
; av
; av
= av
->next
)
4782 new_node
->maybe_create_reference (av
->value
, NULL
);
4784 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4786 fprintf (dump_file
, " the new node is %s.\n", new_node
->dump_name ());
4787 if (known_contexts
.exists ())
4789 for (i
= 0; i
< count
; i
++)
4790 if (!known_contexts
[i
].useless_p ())
4792 fprintf (dump_file
, " known ctx %i is ", i
);
4793 known_contexts
[i
].dump (dump_file
);
4797 ipa_dump_agg_replacement_values (dump_file
, aggvals
);
4799 ipa_check_create_node_params ();
4800 update_profiling_info (node
, new_node
);
4801 new_info
= ipa_node_params_sum
->get (new_node
);
4802 new_info
->ipcp_orig_node
= node
;
4803 new_node
->ipcp_clone
= true;
4804 new_info
->known_csts
= known_csts
;
4805 new_info
->known_contexts
= known_contexts
;
4807 ipcp_discover_new_direct_edges (new_node
, known_csts
, known_contexts
, aggvals
);
4812 /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
4813 pass-through function to itself when the cgraph_node involved is not an
4814 IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
4815 no-operation pass-through. */
4818 self_recursive_pass_through_p (cgraph_edge
*cs
, ipa_jump_func
*jfunc
, int i
,
4821 enum availability availability
;
4822 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
4823 && availability
> AVAIL_INTERPOSABLE
4824 && jfunc
->type
== IPA_JF_PASS_THROUGH
4825 && (!simple
|| ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4826 && ipa_get_jf_pass_through_formal_id (jfunc
) == i
4827 && ipa_node_params_sum
->get (cs
->caller
)
4828 && !ipa_node_params_sum
->get (cs
->caller
)->ipcp_orig_node
)
4833 /* Return true if JFUNC, which describes a part of an aggregate represented or
4834 pointed to by the i-th parameter of call CS, is a pass-through function to
4835 itself when the cgraph_node involved is not an IPA-CP clone.. When
4836 SIMPLE is true, further check if JFUNC is a simple no-operation
4840 self_recursive_agg_pass_through_p (cgraph_edge
*cs
, ipa_agg_jf_item
*jfunc
,
4841 int i
, bool simple
= true)
4843 enum availability availability
;
4844 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
4845 && availability
> AVAIL_INTERPOSABLE
4846 && jfunc
->jftype
== IPA_JF_LOAD_AGG
4847 && jfunc
->offset
== jfunc
->value
.load_agg
.offset
4848 && (!simple
|| jfunc
->value
.pass_through
.operation
== NOP_EXPR
)
4849 && jfunc
->value
.pass_through
.formal_id
== i
4850 && useless_type_conversion_p (jfunc
->value
.load_agg
.type
, jfunc
->type
)
4851 && ipa_node_params_sum
->get (cs
->caller
)
4852 && !ipa_node_params_sum
->get (cs
->caller
)->ipcp_orig_node
)
4857 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
4858 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
4861 find_more_scalar_values_for_callers_subset (struct cgraph_node
*node
,
4862 vec
<tree
> &known_csts
,
4863 const vec
<cgraph_edge
*> &callers
)
4865 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
4866 int i
, count
= ipa_get_param_count (info
);
4868 for (i
= 0; i
< count
; i
++)
4870 struct cgraph_edge
*cs
;
4871 tree newval
= NULL_TREE
;
4874 tree type
= ipa_get_type (info
, i
);
4876 if (ipa_get_scalar_lat (info
, i
)->bottom
|| known_csts
[i
])
4879 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4881 struct ipa_jump_func
*jump_func
;
4884 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4886 || i
>= ipa_get_cs_argument_count (args
)
4888 && call_passes_through_thunk (cs
)))
4893 jump_func
= ipa_get_ith_jump_func (args
, i
);
4895 /* Besides simple pass-through jump function, arithmetic jump
4896 function could also introduce argument-direct-pass-through for
4897 self-feeding recursive call. For example,
4904 Given that i is 0, recursive propagation via (i & 1) also gets
4906 if (self_recursive_pass_through_p (cs
, jump_func
, i
, false))
4908 gcc_assert (newval
);
4909 t
= ipa_get_jf_arith_result (
4910 ipa_get_jf_pass_through_operation (jump_func
),
4912 ipa_get_jf_pass_through_operand (jump_func
),
4916 t
= ipa_value_from_jfunc (ipa_node_params_sum
->get (cs
->caller
),
4920 && !values_equal_for_ipcp_p (t
, newval
))
4921 || (!first
&& !newval
))
4933 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4935 fprintf (dump_file
, " adding an extra known scalar value ");
4936 print_ipcp_constant_value (dump_file
, newval
);
4937 fprintf (dump_file
, " for ");
4938 ipa_dump_param (dump_file
, info
, i
);
4939 fprintf (dump_file
, "\n");
4942 known_csts
[i
] = newval
;
4947 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4948 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4952 find_more_contexts_for_caller_subset (cgraph_node
*node
,
4953 vec
<ipa_polymorphic_call_context
>
4955 const vec
<cgraph_edge
*> &callers
)
4957 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
4958 int i
, count
= ipa_get_param_count (info
);
4960 for (i
= 0; i
< count
; i
++)
4964 if (ipa_get_poly_ctx_lat (info
, i
)->bottom
4965 || (known_contexts
->exists ()
4966 && !(*known_contexts
)[i
].useless_p ()))
4969 ipa_polymorphic_call_context newval
;
4973 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4975 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
4977 || i
>= ipa_get_cs_argument_count (args
))
4979 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (args
, i
);
4980 ipa_polymorphic_call_context ctx
;
4981 ctx
= ipa_context_from_jfunc (ipa_node_params_sum
->get (cs
->caller
),
4989 newval
.meet_with (ctx
);
4990 if (newval
.useless_p ())
4994 if (!newval
.useless_p ())
4996 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4998 fprintf (dump_file
, " adding an extra known polymorphic "
5000 print_ipcp_constant_value (dump_file
, newval
);
5001 fprintf (dump_file
, " for ");
5002 ipa_dump_param (dump_file
, info
, i
);
5003 fprintf (dump_file
, "\n");
5006 if (!known_contexts
->exists ())
5007 known_contexts
->safe_grow_cleared (ipa_get_param_count (info
),
5009 (*known_contexts
)[i
] = newval
;
5015 /* Go through PLATS and create a vector of values consisting of values and
5016 offsets (minus OFFSET) of lattices that contain only a single value. */
5018 static vec
<ipa_agg_value
>
5019 copy_plats_to_inter (class ipcp_param_lattices
*plats
, HOST_WIDE_INT offset
)
5021 vec
<ipa_agg_value
> res
= vNULL
;
5023 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
5026 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
5027 if (aglat
->is_single_const ())
5029 struct ipa_agg_value ti
;
5030 ti
.offset
= aglat
->offset
- offset
;
5031 ti
.value
= aglat
->values
->value
;
5037 /* Intersect all values in INTER with single value lattices in PLATS (while
5038 subtracting OFFSET). */
5041 intersect_with_plats (class ipcp_param_lattices
*plats
,
5042 vec
<ipa_agg_value
> *inter
,
5043 HOST_WIDE_INT offset
)
5045 struct ipcp_agg_lattice
*aglat
;
5046 struct ipa_agg_value
*item
;
5049 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
5055 aglat
= plats
->aggs
;
5056 FOR_EACH_VEC_ELT (*inter
, k
, item
)
5063 if (aglat
->offset
- offset
> item
->offset
)
5065 if (aglat
->offset
- offset
== item
->offset
)
5067 if (aglat
->is_single_const ())
5069 tree value
= aglat
->values
->value
;
5071 if (values_equal_for_ipcp_p (item
->value
, value
))
5076 aglat
= aglat
->next
;
5079 item
->value
= NULL_TREE
;
5083 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
5084 vector result while subtracting OFFSET from the individual value offsets. */
5086 static vec
<ipa_agg_value
>
5087 agg_replacements_to_vector (struct cgraph_node
*node
, int index
,
5088 HOST_WIDE_INT offset
)
5090 struct ipa_agg_replacement_value
*av
;
5091 vec
<ipa_agg_value
> res
= vNULL
;
5093 for (av
= ipa_get_agg_replacements_for_node (node
); av
; av
= av
->next
)
5094 if (av
->index
== index
5095 && (av
->offset
- offset
) >= 0)
5097 struct ipa_agg_value item
;
5098 gcc_checking_assert (av
->value
);
5099 item
.offset
= av
->offset
- offset
;
5100 item
.value
= av
->value
;
5101 res
.safe_push (item
);
5107 /* Intersect all values in INTER with those that we have already scheduled to
5108 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
5109 (while subtracting OFFSET). */
5112 intersect_with_agg_replacements (struct cgraph_node
*node
, int index
,
5113 vec
<ipa_agg_value
> *inter
,
5114 HOST_WIDE_INT offset
)
5116 struct ipa_agg_replacement_value
*srcvals
;
5117 struct ipa_agg_value
*item
;
5120 srcvals
= ipa_get_agg_replacements_for_node (node
);
5127 FOR_EACH_VEC_ELT (*inter
, i
, item
)
5129 struct ipa_agg_replacement_value
*av
;
5133 for (av
= srcvals
; av
; av
= av
->next
)
5135 gcc_checking_assert (av
->value
);
5136 if (av
->index
== index
5137 && av
->offset
- offset
== item
->offset
)
5139 if (values_equal_for_ipcp_p (item
->value
, av
->value
))
5145 item
->value
= NULL_TREE
;
5149 /* Intersect values in INTER with aggregate values that come along edge CS to
5150 parameter number INDEX and return it. If INTER does not actually exist yet,
5151 copy all incoming values to it. If we determine we ended up with no values
5152 whatsoever, return a released vector. */
5154 static vec
<ipa_agg_value
>
5155 intersect_aggregates_with_edge (struct cgraph_edge
*cs
, int index
,
5156 vec
<ipa_agg_value
> inter
)
5158 struct ipa_jump_func
*jfunc
;
5159 jfunc
= ipa_get_ith_jump_func (ipa_edge_args_sum
->get (cs
), index
);
5160 if (jfunc
->type
== IPA_JF_PASS_THROUGH
5161 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
5163 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5164 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
5166 if (caller_info
->ipcp_orig_node
)
5168 struct cgraph_node
*orig_node
= caller_info
->ipcp_orig_node
;
5169 class ipcp_param_lattices
*orig_plats
;
5170 ipa_node_params
*orig_info
= ipa_node_params_sum
->get (orig_node
);
5171 orig_plats
= ipa_get_parm_lattices (orig_info
, src_idx
);
5172 if (agg_pass_through_permissible_p (orig_plats
, jfunc
))
5174 if (!inter
.exists ())
5175 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, 0);
5177 intersect_with_agg_replacements (cs
->caller
, src_idx
,
5184 class ipcp_param_lattices
*src_plats
;
5185 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
5186 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
5188 /* Currently we do not produce clobber aggregate jump
5189 functions, adjust when we do. */
5190 gcc_checking_assert (!jfunc
->agg
.items
);
5191 if (!inter
.exists ())
5192 inter
= copy_plats_to_inter (src_plats
, 0);
5194 intersect_with_plats (src_plats
, &inter
, 0);
5199 else if (jfunc
->type
== IPA_JF_ANCESTOR
5200 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
5202 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5203 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
5204 class ipcp_param_lattices
*src_plats
;
5205 HOST_WIDE_INT delta
= ipa_get_jf_ancestor_offset (jfunc
);
5207 if (caller_info
->ipcp_orig_node
)
5209 if (!inter
.exists ())
5210 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, delta
);
5212 intersect_with_agg_replacements (cs
->caller
, src_idx
, &inter
,
5217 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
5218 /* Currently we do not produce clobber aggregate jump
5219 functions, adjust when we do. */
5220 gcc_checking_assert (!src_plats
->aggs
|| !jfunc
->agg
.items
);
5221 if (!inter
.exists ())
5222 inter
= copy_plats_to_inter (src_plats
, delta
);
5224 intersect_with_plats (src_plats
, &inter
, delta
);
5229 if (jfunc
->agg
.items
)
5231 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5232 struct ipa_agg_value
*item
;
5235 if (!inter
.exists ())
5236 for (unsigned i
= 0; i
< jfunc
->agg
.items
->length (); i
++)
5238 struct ipa_agg_jf_item
*agg_item
= &(*jfunc
->agg
.items
)[i
];
5239 tree value
= ipa_agg_value_from_node (caller_info
, cs
->caller
,
5243 struct ipa_agg_value agg_value
;
5245 agg_value
.value
= value
;
5246 agg_value
.offset
= agg_item
->offset
;
5247 inter
.safe_push (agg_value
);
5251 FOR_EACH_VEC_ELT (inter
, k
, item
)
5259 while ((unsigned) l
< jfunc
->agg
.items
->length ())
5261 struct ipa_agg_jf_item
*ti
;
5262 ti
= &(*jfunc
->agg
.items
)[l
];
5263 if (ti
->offset
> item
->offset
)
5265 if (ti
->offset
== item
->offset
)
5269 /* Besides simple pass-through aggregate jump function,
5270 arithmetic aggregate jump function could also bring
5271 same aggregate value as parameter passed-in for
5272 self-feeding recursive call. For example,
5280 Given that *i is 0, recursive propagation via (*i & 1)
5282 if (self_recursive_agg_pass_through_p (cs
, ti
, index
,
5284 value
= ipa_get_jf_arith_result (
5285 ti
->value
.pass_through
.operation
,
5287 ti
->value
.pass_through
.operand
,
5290 value
= ipa_agg_value_from_node (caller_info
,
5293 if (value
&& values_equal_for_ipcp_p (item
->value
, value
))
5311 /* Look at edges in CALLERS and collect all known aggregate values that arrive
5312 from all of them. */
5314 static struct ipa_agg_replacement_value
*
5315 find_aggregate_values_for_callers_subset (struct cgraph_node
*node
,
5316 const vec
<cgraph_edge
*> &callers
)
5318 ipa_node_params
*dest_info
= ipa_node_params_sum
->get (node
);
5319 struct ipa_agg_replacement_value
*res
;
5320 struct ipa_agg_replacement_value
**tail
= &res
;
5321 struct cgraph_edge
*cs
;
5322 int i
, j
, count
= ipa_get_param_count (dest_info
);
5324 FOR_EACH_VEC_ELT (callers
, j
, cs
)
5326 ipa_edge_args
*args
= ipa_edge_args_sum
->get (cs
);
5332 int c
= ipa_get_cs_argument_count (args
);
5337 for (i
= 0; i
< count
; i
++)
5339 struct cgraph_edge
*cs
;
5340 vec
<ipa_agg_value
> inter
= vNULL
;
5341 struct ipa_agg_value
*item
;
5342 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (dest_info
, i
);
5345 /* Among other things, the following check should deal with all by_ref
5347 if (plats
->aggs_bottom
)
5350 FOR_EACH_VEC_ELT (callers
, j
, cs
)
5352 struct ipa_jump_func
*jfunc
5353 = ipa_get_ith_jump_func (ipa_edge_args_sum
->get (cs
), i
);
5354 if (self_recursive_pass_through_p (cs
, jfunc
, i
)
5355 && (!plats
->aggs_by_ref
5356 || ipa_get_jf_pass_through_agg_preserved (jfunc
)))
5358 inter
= intersect_aggregates_with_edge (cs
, i
, inter
);
5360 if (!inter
.exists ())
5364 FOR_EACH_VEC_ELT (inter
, j
, item
)
5366 struct ipa_agg_replacement_value
*v
;
5371 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
5373 v
->offset
= item
->offset
;
5374 v
->value
= item
->value
;
5375 v
->by_ref
= plats
->aggs_by_ref
;
5381 if (inter
.exists ())
5388 /* Determine whether CS also brings all scalar values that the NODE is
5392 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge
*cs
,
5393 struct cgraph_node
*node
)
5395 ipa_node_params
*dest_info
= ipa_node_params_sum
->get (node
);
5396 int count
= ipa_get_param_count (dest_info
);
5397 class ipa_node_params
*caller_info
;
5398 class ipa_edge_args
*args
;
5401 caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5402 args
= ipa_edge_args_sum
->get (cs
);
5403 for (i
= 0; i
< count
; i
++)
5405 struct ipa_jump_func
*jump_func
;
5408 val
= dest_info
->known_csts
[i
];
5412 if (i
>= ipa_get_cs_argument_count (args
))
5414 jump_func
= ipa_get_ith_jump_func (args
, i
);
5415 t
= ipa_value_from_jfunc (caller_info
, jump_func
,
5416 ipa_get_type (dest_info
, i
));
5417 if (!t
|| !values_equal_for_ipcp_p (val
, t
))
5423 /* Determine whether CS also brings all aggregate values that NODE is
5426 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge
*cs
,
5427 struct cgraph_node
*node
)
5429 struct ipa_agg_replacement_value
*aggval
;
5432 aggval
= ipa_get_agg_replacements_for_node (node
);
5436 ipa_node_params
*clone_node_info
= ipa_node_params_sum
->get (node
);
5437 count
= ipa_get_param_count (clone_node_info
);
5438 ec
= ipa_get_cs_argument_count (ipa_edge_args_sum
->get (cs
));
5440 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5441 if (aggval
->index
>= ec
)
5444 ipa_node_params
*orig_node_info
5445 = ipa_node_params_sum
->get (clone_node_info
->ipcp_orig_node
);
5447 for (i
= 0; i
< count
; i
++)
5449 class ipcp_param_lattices
*plats
;
5450 bool interesting
= false;
5451 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5452 if (aggval
->index
== i
)
5460 plats
= ipa_get_parm_lattices (orig_node_info
, aggval
->index
);
5461 if (plats
->aggs_bottom
)
5464 vec
<ipa_agg_value
> values
= intersect_aggregates_with_edge (cs
, i
, vNULL
);
5465 if (!values
.exists ())
5468 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5469 if (aggval
->index
== i
)
5471 struct ipa_agg_value
*item
;
5474 FOR_EACH_VEC_ELT (values
, j
, item
)
5476 && item
->offset
== av
->offset
5477 && values_equal_for_ipcp_p (item
->value
, av
->value
))
5493 /* Given an original NODE and a VAL for which we have already created a
5494 specialized clone, look whether there are incoming edges that still lead
5495 into the old node but now also bring the requested value and also conform to
5496 all other criteria such that they can be redirected the special node.
5497 This function can therefore redirect the final edge in a SCC. */
5499 template <typename valtype
>
5501 perhaps_add_new_callers (cgraph_node
*node
, ipcp_value
<valtype
> *val
)
5503 ipcp_value_source
<valtype
> *src
;
5504 profile_count redirected_sum
= profile_count::zero ();
5506 for (src
= val
->sources
; src
; src
= src
->next
)
5508 struct cgraph_edge
*cs
= src
->cs
;
5511 if (cgraph_edge_brings_value_p (cs
, src
, node
, val
)
5512 && cgraph_edge_brings_all_scalars_for_node (cs
, val
->spec_node
)
5513 && cgraph_edge_brings_all_agg_vals_for_node (cs
, val
->spec_node
))
5516 fprintf (dump_file
, " - adding an extra caller %s of %s\n",
5517 cs
->caller
->dump_name (),
5518 val
->spec_node
->dump_name ());
5520 cs
->redirect_callee_duplicating_thunks (val
->spec_node
);
5521 val
->spec_node
->expand_all_artificial_thunks ();
5522 if (cs
->count
.ipa ().initialized_p ())
5523 redirected_sum
= redirected_sum
+ cs
->count
.ipa ();
5525 cs
= get_next_cgraph_edge_clone (cs
);
5529 if (redirected_sum
.nonzero_p ())
5530 update_specialized_profile (val
->spec_node
, node
, redirected_sum
);
5533 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5536 known_contexts_useful_p (vec
<ipa_polymorphic_call_context
> known_contexts
)
5538 ipa_polymorphic_call_context
*ctx
;
5541 FOR_EACH_VEC_ELT (known_contexts
, i
, ctx
)
5542 if (!ctx
->useless_p ())
5547 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5549 static vec
<ipa_polymorphic_call_context
>
5550 copy_useful_known_contexts (const vec
<ipa_polymorphic_call_context
> &known_contexts
)
5552 if (known_contexts_useful_p (known_contexts
))
5553 return known_contexts
.copy ();
5558 /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
5559 according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its
5563 copy_known_vectors_add_val (ipa_auto_call_arg_values
*avals
,
5564 vec
<tree
> *known_csts
,
5565 vec
<ipa_polymorphic_call_context
> *known_contexts
,
5566 ipcp_value
<tree
> *val
, int index
)
5568 *known_csts
= avals
->m_known_vals
.copy ();
5569 *known_contexts
= copy_useful_known_contexts (avals
->m_known_contexts
);
5570 (*known_csts
)[index
] = val
->value
;
5573 /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy
5574 contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
5578 copy_known_vectors_add_val (ipa_auto_call_arg_values
*avals
,
5579 vec
<tree
> *known_csts
,
5580 vec
<ipa_polymorphic_call_context
> *known_contexts
,
5581 ipcp_value
<ipa_polymorphic_call_context
> *val
,
5584 *known_csts
= avals
->m_known_vals
.copy ();
5585 *known_contexts
= avals
->m_known_contexts
.copy ();
5586 (*known_contexts
)[index
] = val
->value
;
5589 /* Return true if OFFSET indicates this was not an aggregate value or there is
5590 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5594 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*aggvals
,
5595 int index
, HOST_WIDE_INT offset
, tree value
)
5602 if (aggvals
->index
== index
5603 && aggvals
->offset
== offset
5604 && values_equal_for_ipcp_p (aggvals
->value
, value
))
5606 aggvals
= aggvals
->next
;
5611 /* Return true if offset is minus one because source of a polymorphic context
5612 cannot be an aggregate value. */
5615 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*,
5616 int , HOST_WIDE_INT offset
,
5617 ipa_polymorphic_call_context
)
5619 return offset
== -1;
5622 /* Decide whether to create a special version of NODE for value VAL of
5623 parameter at the given INDEX. If OFFSET is -1, the value is for the
5624 parameter itself, otherwise it is stored at the given OFFSET of the
5625 parameter. AVALS describes the other already known values. */
5627 template <typename valtype
>
5629 decide_about_value (struct cgraph_node
*node
, int index
, HOST_WIDE_INT offset
,
5630 ipcp_value
<valtype
> *val
, ipa_auto_call_arg_values
*avals
)
5632 struct ipa_agg_replacement_value
*aggvals
;
5635 profile_count count_sum
;
5636 vec
<cgraph_edge
*> callers
;
5640 perhaps_add_new_callers (node
, val
);
5643 else if (val
->local_size_cost
+ overall_size
> get_max_overall_size (node
))
5645 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5646 fprintf (dump_file
, " Ignoring candidate value because "
5647 "maximum unit size would be reached with %li.\n",
5648 val
->local_size_cost
+ overall_size
);
5651 else if (!get_info_about_necessary_edges (val
, node
, &freq_sum
, &count_sum
,
5655 if (!dbg_cnt (ipa_cp_values
))
5658 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5660 fprintf (dump_file
, " - considering value ");
5661 print_ipcp_constant_value (dump_file
, val
->value
);
5662 fprintf (dump_file
, " for ");
5663 ipa_dump_param (dump_file
, ipa_node_params_sum
->get (node
), index
);
5665 fprintf (dump_file
, ", offset: " HOST_WIDE_INT_PRINT_DEC
, offset
);
5666 fprintf (dump_file
, " (caller_count: %i)\n", caller_count
);
5669 if (!good_cloning_opportunity_p (node
, val
->local_time_benefit
,
5670 freq_sum
, count_sum
,
5671 val
->local_size_cost
)
5672 && !good_cloning_opportunity_p (node
, val
->prop_time_benefit
,
5673 freq_sum
, count_sum
, val
->prop_size_cost
))
5677 fprintf (dump_file
, " Creating a specialized node of %s.\n",
5678 node
->dump_name ());
5680 vec
<tree
> known_csts
;
5681 vec
<ipa_polymorphic_call_context
> known_contexts
;
5683 callers
= gather_edges_for_value (val
, node
, caller_count
);
5685 copy_known_vectors_add_val (avals
, &known_csts
, &known_contexts
, val
, index
);
5688 known_csts
= avals
->m_known_vals
.copy ();
5689 known_contexts
= copy_useful_known_contexts (avals
->m_known_contexts
);
5691 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
5692 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
5693 aggvals
= find_aggregate_values_for_callers_subset (node
, callers
);
5694 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals
, index
,
5695 offset
, val
->value
));
5696 val
->spec_node
= create_specialized_node (node
, known_csts
, known_contexts
,
5699 overall_size
+= val
->local_size_cost
;
5700 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5701 fprintf (dump_file
, " overall size reached %li\n",
5704 /* TODO: If for some lattice there is only one other known value
5705 left, make a special node for it too. */
5710 /* Decide whether and what specialized clones of NODE should be created. */
5713 decide_whether_version_node (struct cgraph_node
*node
)
5715 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
5716 int i
, count
= ipa_get_param_count (info
);
5722 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5723 fprintf (dump_file
, "\nEvaluating opportunities for %s.\n",
5724 node
->dump_name ());
5726 ipa_auto_call_arg_values avals
;
5727 gather_context_independent_values (info
, &avals
, false, NULL
);
5729 for (i
= 0; i
< count
;i
++)
5731 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5732 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
5733 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
5736 && !avals
.m_known_vals
[i
])
5738 ipcp_value
<tree
> *val
;
5739 for (val
= lat
->values
; val
; val
= val
->next
)
5740 ret
|= decide_about_value (node
, i
, -1, val
, &avals
);
5743 if (!plats
->aggs_bottom
)
5745 struct ipcp_agg_lattice
*aglat
;
5746 ipcp_value
<tree
> *val
;
5747 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
5748 if (!aglat
->bottom
&& aglat
->values
5749 /* If the following is false, the one value has been considered
5750 for cloning for all contexts. */
5751 && (plats
->aggs_contain_variable
5752 || !aglat
->is_single_const ()))
5753 for (val
= aglat
->values
; val
; val
= val
->next
)
5754 ret
|= decide_about_value (node
, i
, aglat
->offset
, val
, &avals
);
5758 && avals
.m_known_contexts
[i
].useless_p ())
5760 ipcp_value
<ipa_polymorphic_call_context
> *val
;
5761 for (val
= ctxlat
->values
; val
; val
= val
->next
)
5762 ret
|= decide_about_value (node
, i
, -1, val
, &avals
);
5766 if (info
->do_clone_for_all_contexts
)
5768 if (!dbg_cnt (ipa_cp_values
))
5770 info
->do_clone_for_all_contexts
= false;
5774 struct cgraph_node
*clone
;
5775 auto_vec
<cgraph_edge
*> callers
= node
->collect_callers ();
5777 for (int i
= callers
.length () - 1; i
>= 0; i
--)
5779 cgraph_edge
*cs
= callers
[i
];
5780 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5782 if (caller_info
&& caller_info
->node_dead
)
5783 callers
.unordered_remove (i
);
5786 if (!adjust_callers_for_value_intersection (callers
, node
))
5788 /* If node is not called by anyone, or all its caller edges are
5789 self-recursive, the node is not really in use, no need to do
5791 info
->do_clone_for_all_contexts
= false;
5796 fprintf (dump_file
, " - Creating a specialized node of %s "
5797 "for all known contexts.\n", node
->dump_name ());
5799 vec
<tree
> known_csts
= avals
.m_known_vals
.copy ();
5800 vec
<ipa_polymorphic_call_context
> known_contexts
5801 = copy_useful_known_contexts (avals
.m_known_contexts
);
5802 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
5803 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
5804 ipa_agg_replacement_value
*aggvals
5805 = find_aggregate_values_for_callers_subset (node
, callers
);
5807 if (!known_contexts_useful_p (known_contexts
))
5809 known_contexts
.release ();
5810 known_contexts
= vNULL
;
5812 clone
= create_specialized_node (node
, known_csts
, known_contexts
,
5814 info
->do_clone_for_all_contexts
= false;
5815 ipa_node_params_sum
->get (clone
)->is_all_contexts_clone
= true;
5822 /* Transitively mark all callees of NODE within the same SCC as not dead. */
5825 spread_undeadness (struct cgraph_node
*node
)
5827 struct cgraph_edge
*cs
;
5829 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
5830 if (ipa_edge_within_scc (cs
))
5832 struct cgraph_node
*callee
;
5833 class ipa_node_params
*info
;
5835 callee
= cs
->callee
->function_symbol (NULL
);
5836 info
= ipa_node_params_sum
->get (callee
);
5838 if (info
&& info
->node_dead
)
5840 info
->node_dead
= 0;
5841 spread_undeadness (callee
);
5846 /* Return true if NODE has a caller from outside of its SCC that is not
5847 dead. Worker callback for cgraph_for_node_and_aliases. */
5850 has_undead_caller_from_outside_scc_p (struct cgraph_node
*node
,
5851 void *data ATTRIBUTE_UNUSED
)
5853 struct cgraph_edge
*cs
;
5855 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5856 if (cs
->caller
->thunk
5857 && cs
->caller
->call_for_symbol_thunks_and_aliases
5858 (has_undead_caller_from_outside_scc_p
, NULL
, true))
5860 else if (!ipa_edge_within_scc (cs
))
5862 ipa_node_params
*caller_info
= ipa_node_params_sum
->get (cs
->caller
);
5863 if (!caller_info
/* Unoptimized caller are like dead ones. */
5864 || !caller_info
->node_dead
)
5871 /* Identify nodes within the same SCC as NODE which are no longer needed
5872 because of new clones and will be removed as unreachable. */
5875 identify_dead_nodes (struct cgraph_node
*node
)
5877 struct cgraph_node
*v
;
5878 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5881 ipa_node_params
*info
= ipa_node_params_sum
->get (v
);
5883 && !v
->call_for_symbol_thunks_and_aliases
5884 (has_undead_caller_from_outside_scc_p
, NULL
, true))
5885 info
->node_dead
= 1;
5888 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5890 ipa_node_params
*info
= ipa_node_params_sum
->get (v
);
5891 if (info
&& !info
->node_dead
)
5892 spread_undeadness (v
);
5895 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5897 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5898 if (ipa_node_params_sum
->get (v
)
5899 && ipa_node_params_sum
->get (v
)->node_dead
)
5900 fprintf (dump_file
, " Marking node as dead: %s.\n",
5905 /* The decision stage. Iterate over the topological order of call graph nodes
5906 TOPO and make specialized clones if deemed beneficial. */
5909 ipcp_decision_stage (class ipa_topo_info
*topo
)
5914 fprintf (dump_file
, "\nIPA decision stage:\n\n");
5916 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
5918 struct cgraph_node
*node
= topo
->order
[i
];
5919 bool change
= false, iterate
= true;
5923 struct cgraph_node
*v
;
5925 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5926 if (v
->has_gimple_body_p ()
5927 && ipcp_versionable_function_p (v
))
5928 iterate
|= decide_whether_version_node (v
);
5933 identify_dead_nodes (node
);
5937 /* Look up all the bits information that we have discovered and copy it over
5938 to the transformation summary. */
5941 ipcp_store_bits_results (void)
5945 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5947 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
5948 bool dumped_sth
= false;
5949 bool found_useful_result
= false;
5951 if (!opt_for_fn (node
->decl
, flag_ipa_bit_cp
) || !info
)
5954 fprintf (dump_file
, "Not considering %s for ipa bitwise propagation "
5955 "; -fipa-bit-cp: disabled.\n",
5956 node
->dump_name ());
5960 if (info
->ipcp_orig_node
)
5961 info
= ipa_node_params_sum
->get (info
->ipcp_orig_node
);
5962 if (!info
->lattices
)
5963 /* Newly expanded artificial thunks do not have lattices. */
5966 unsigned count
= ipa_get_param_count (info
);
5967 for (unsigned i
= 0; i
< count
; i
++)
5969 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5970 if (plats
->bits_lattice
.constant_p ())
5972 found_useful_result
= true;
5977 if (!found_useful_result
)
5980 ipcp_transformation_initialize ();
5981 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5982 vec_safe_reserve_exact (ts
->bits
, count
);
5984 for (unsigned i
= 0; i
< count
; i
++)
5986 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5989 if (plats
->bits_lattice
.constant_p ())
5992 = ipa_get_ipa_bits_for_value (plats
->bits_lattice
.get_value (),
5993 plats
->bits_lattice
.get_mask ());
5994 if (!dbg_cnt (ipa_cp_bits
))
6000 ts
->bits
->quick_push (jfbits
);
6001 if (!dump_file
|| !jfbits
)
6005 fprintf (dump_file
, "Propagated bits info for function %s:\n",
6006 node
->dump_name ());
6009 fprintf (dump_file
, " param %i: value = ", i
);
6010 print_hex (jfbits
->value
, dump_file
);
6011 fprintf (dump_file
, ", mask = ");
6012 print_hex (jfbits
->mask
, dump_file
);
6013 fprintf (dump_file
, "\n");
6018 /* Look up all VR information that we have discovered and copy it over
6019 to the transformation summary. */
6022 ipcp_store_vr_results (void)
6026 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
6028 ipa_node_params
*info
= ipa_node_params_sum
->get (node
);
6029 bool found_useful_result
= false;
6031 if (!info
|| !opt_for_fn (node
->decl
, flag_ipa_vrp
))
6034 fprintf (dump_file
, "Not considering %s for VR discovery "
6035 "and propagate; -fipa-ipa-vrp: disabled.\n",
6036 node
->dump_name ());
6040 if (info
->ipcp_orig_node
)
6041 info
= ipa_node_params_sum
->get (info
->ipcp_orig_node
);
6042 if (!info
->lattices
)
6043 /* Newly expanded artificial thunks do not have lattices. */
6046 unsigned count
= ipa_get_param_count (info
);
6047 for (unsigned i
= 0; i
< count
; i
++)
6049 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
6050 if (!plats
->m_value_range
.bottom_p ()
6051 && !plats
->m_value_range
.top_p ())
6053 found_useful_result
= true;
6057 if (!found_useful_result
)
6060 ipcp_transformation_initialize ();
6061 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
6062 vec_safe_reserve_exact (ts
->m_vr
, count
);
6064 for (unsigned i
= 0; i
< count
; i
++)
6066 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
6069 if (!plats
->m_value_range
.bottom_p ()
6070 && !plats
->m_value_range
.top_p ()
6071 && dbg_cnt (ipa_cp_vr
))
6074 vr
.type
= plats
->m_value_range
.m_vr
.kind ();
6075 vr
.min
= wi::to_wide (plats
->m_value_range
.m_vr
.min ());
6076 vr
.max
= wi::to_wide (plats
->m_value_range
.m_vr
.max ());
6081 vr
.type
= VR_VARYING
;
6082 vr
.min
= vr
.max
= wi::zero (INT_TYPE_SIZE
);
6084 ts
->m_vr
->quick_push (vr
);
6089 /* The IPCP driver. */
6094 class ipa_topo_info topo
;
6096 if (edge_clone_summaries
== NULL
)
6097 edge_clone_summaries
= new edge_clone_summary_t (symtab
);
6099 ipa_check_create_node_params ();
6100 ipa_check_create_edge_args ();
6101 clone_num_suffixes
= new hash_map
<const char *, unsigned>;
6105 fprintf (dump_file
, "\nIPA structures before propagation:\n");
6106 if (dump_flags
& TDF_DETAILS
)
6107 ipa_print_all_params (dump_file
);
6108 ipa_print_all_jump_functions (dump_file
);
6111 /* Topological sort. */
6112 build_toporder_info (&topo
);
6113 /* Do the interprocedural propagation. */
6114 ipcp_propagate_stage (&topo
);
6115 /* Decide what constant propagation and cloning should be performed. */
6116 ipcp_decision_stage (&topo
);
6117 /* Store results of bits propagation. */
6118 ipcp_store_bits_results ();
6119 /* Store results of value range propagation. */
6120 ipcp_store_vr_results ();
6122 /* Free all IPCP structures. */
6123 delete clone_num_suffixes
;
6124 free_toporder_info (&topo
);
6125 delete edge_clone_summaries
;
6126 edge_clone_summaries
= NULL
;
6127 ipa_free_all_structures_after_ipa_cp ();
6129 fprintf (dump_file
, "\nIPA constant propagation end\n");
6133 /* Initialization and computation of IPCP data structures. This is the initial
6134 intraprocedural analysis of functions, which gathers information to be
6135 propagated later on. */
6138 ipcp_generate_summary (void)
6140 struct cgraph_node
*node
;
6143 fprintf (dump_file
, "\nIPA constant propagation start:\n");
6144 ipa_register_cgraph_hooks ();
6146 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
6147 ipa_analyze_node (node
);
6152 const pass_data pass_data_ipa_cp
=
6154 IPA_PASS
, /* type */
6156 OPTGROUP_NONE
, /* optinfo_flags */
6157 TV_IPA_CONSTANT_PROP
, /* tv_id */
6158 0, /* properties_required */
6159 0, /* properties_provided */
6160 0, /* properties_destroyed */
6161 0, /* todo_flags_start */
6162 ( TODO_dump_symtab
| TODO_remove_functions
), /* todo_flags_finish */
6165 class pass_ipa_cp
: public ipa_opt_pass_d
6168 pass_ipa_cp (gcc::context
*ctxt
)
6169 : ipa_opt_pass_d (pass_data_ipa_cp
, ctxt
,
6170 ipcp_generate_summary
, /* generate_summary */
6171 NULL
, /* write_summary */
6172 NULL
, /* read_summary */
6173 ipcp_write_transformation_summaries
, /*
6174 write_optimization_summary */
6175 ipcp_read_transformation_summaries
, /*
6176 read_optimization_summary */
6177 NULL
, /* stmt_fixup */
6178 0, /* function_transform_todo_flags_start */
6179 ipcp_transform_function
, /* function_transform */
6180 NULL
) /* variable_transform */
6183 /* opt_pass methods: */
6184 virtual bool gate (function
*)
6186 /* FIXME: We should remove the optimize check after we ensure we never run
6187 IPA passes when not optimizing. */
6188 return (flag_ipa_cp
&& optimize
) || in_lto_p
;
6191 virtual unsigned int execute (function
*) { return ipcp_driver (); }
6193 }; // class pass_ipa_cp
6198 make_pass_ipa_cp (gcc::context
*ctxt
)
6200 return new pass_ipa_cp (ctxt
);
6203 /* Reset all state within ipa-cp.c so that we can rerun the compiler
6204 within the same process. For use by toplev::finalize. */
6207 ipa_cp_c_finalize (void)
6209 max_count
= profile_count::uninitialized ();
6211 orig_overall_size
= 0;
6212 ipcp_free_transformation_sum ();