1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* Interprocedural constant propagation (IPA-CP).
25 The goal of this transformation is to
27 1) discover functions which are always invoked with some arguments with the
28 same known constant values and modify the functions so that the
29 subsequent optimizations can take advantage of the knowledge, and
31 2) partial specialization - create specialized versions of functions
32 transformed in this way if some parameters are known constants only in
33 certain contexts but the estimated tradeoff between speedup and cost size
36 The algorithm also propagates types and attempts to perform type based
37 devirtualization. Types are propagated much like constants.
39 The algorithm basically consists of three stages. In the first, functions
40 are analyzed one at a time and jump functions are constructed for all known
41 call-sites. In the second phase, the pass propagates information from the
42 jump functions across the call to reveal what values are available at what
43 call sites, performs estimations of effects of known values on functions and
44 their callees, and finally decides what specialized extra versions should be
45 created. In the third, the special versions materialize and appropriate
48 The algorithm used is to a certain extent based on "Interprocedural Constant
49 Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
50 Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
51 Cooper, Mary W. Hall, and Ken Kennedy.
54 First stage - intraprocedural analysis
55 =======================================
57 This phase computes jump_function and modification flags.
59 A jump function for a call-site represents the values passed as an actual
60 arguments of a given call-site. In principle, there are three types of
63 Pass through - the caller's formal parameter is passed as an actual
64 argument, plus an operation on it can be performed.
65 Constant - a constant is passed as an actual argument.
66 Unknown - neither of the above.
68 All jump function types are described in detail in ipa-prop.h, together with
69 the data structures that represent them and methods of accessing them.
71 ipcp_generate_summary() is the main function of the first stage.
73 Second stage - interprocedural analysis
74 ========================================
76 This stage is itself divided into two phases. In the first, we propagate
77 known values over the call graph, in the second, we make cloning decisions.
78 It uses a different algorithm than the original Callahan's paper.
80 First, we traverse the functions topologically from callers to callees and,
81 for each strongly connected component (SCC), we propagate constants
82 according to previously computed jump functions. We also record what known
83 values depend on other known values and estimate local effects. Finally, we
84 propagate cumulative information about these effects from dependent values
85 to those on which they depend.
87 Second, we again traverse the call graph in the same topological order and
88 make clones for functions which we know are called with the same values in
89 all contexts and decide about extra specialized clones of functions just for
90 some contexts - these decisions are based on both local estimates and
91 cumulative estimates propagated from callees.
93 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
96 Third phase - materialization of clones, call statement updates.
97 ============================================
99 This stage is currently performed by call graph code (mainly in cgraphunit.c
100 and tree-inline.c) according to instructions inserted to the call graph by
105 #include "coretypes.h"
108 #include "gimple-expr.h"
110 #include "alloc-pool.h"
111 #include "tree-pass.h"
113 #include "diagnostic.h"
114 #include "fold-const.h"
115 #include "gimple-fold.h"
116 #include "symbol-summary.h"
117 #include "tree-vrp.h"
118 #include "ipa-prop.h"
119 #include "tree-pretty-print.h"
120 #include "tree-inline.h"
121 #include "ipa-fnsummary.h"
122 #include "ipa-utils.h"
123 #include "tree-ssa-ccp.h"
124 #include "stringpool.h"
127 #include "symtab-clones.h"
129 template <typename valtype
> class ipcp_value
;
131 /* Describes a particular source for an IPA-CP value. */
133 template <typename valtype
>
134 struct ipcp_value_source
137 /* Aggregate offset of the source, negative if the source is scalar value of
138 the argument itself. */
139 HOST_WIDE_INT offset
;
140 /* The incoming edge that brought the value. */
142 /* If the jump function that resulted into his value was a pass-through or an
143 ancestor, this is the ipcp_value of the caller from which the described
144 value has been derived. Otherwise it is NULL. */
145 ipcp_value
<valtype
> *val
;
146 /* Next pointer in a linked list of sources of a value. */
147 ipcp_value_source
*next
;
148 /* If the jump function that resulted into his value was a pass-through or an
149 ancestor, this is the index of the parameter of the caller the jump
150 function references. */
154 /* Common ancestor for all ipcp_value instantiations. */
156 class ipcp_value_base
159 /* Time benefit and that specializing the function for this value would bring
160 about in this function alone. */
161 sreal local_time_benefit
;
162 /* Time benefit that specializing the function for this value can bring about
164 sreal prop_time_benefit
;
165 /* Size cost that specializing the function for this value would bring about
166 in this function alone. */
168 /* Size cost that specializing the function for this value can bring about in
173 : local_time_benefit (0), prop_time_benefit (0),
174 local_size_cost (0), prop_size_cost (0) {}
177 /* Describes one particular value stored in struct ipcp_lattice. */
179 template <typename valtype
>
180 class ipcp_value
: public ipcp_value_base
183 /* The actual value for the given parameter. */
185 /* The list of sources from which this value originates. */
186 ipcp_value_source
<valtype
> *sources
;
187 /* Next pointers in a linked list of all values in a lattice. */
189 /* Next pointers in a linked list of values in a strongly connected component
191 ipcp_value
*scc_next
;
192 /* Next pointers in a linked list of SCCs of values sorted topologically
193 according their sources. */
194 ipcp_value
*topo_next
;
195 /* A specialized node created for this value, NULL if none has been (so far)
197 cgraph_node
*spec_node
;
198 /* Depth first search number and low link for topological sorting of
201 /* True if this value is currently on the topo-sort stack. */
205 : sources (0), next (0), scc_next (0), topo_next (0),
206 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
208 void add_source (cgraph_edge
*cs
, ipcp_value
*src_val
, int src_idx
,
209 HOST_WIDE_INT offset
);
212 /* Lattice describing potential values of a formal parameter of a function, or
213 a part of an aggregate. TOP is represented by a lattice with zero values
214 and with contains_variable and bottom flags cleared. BOTTOM is represented
215 by a lattice with the bottom flag set. In that case, values and
216 contains_variable flag should be disregarded. */
218 template <typename valtype
>
222 /* The list of known values and types in this lattice. Note that values are
223 not deallocated if a lattice is set to bottom because there may be value
224 sources referencing them. */
225 ipcp_value
<valtype
> *values
;
226 /* Number of known values and types in this lattice. */
228 /* The lattice contains a variable component (in addition to values). */
229 bool contains_variable
;
230 /* The value of the lattice is bottom (i.e. variable and unusable for any
234 inline bool is_single_const ();
235 inline bool set_to_bottom ();
236 inline bool set_contains_variable ();
237 bool add_value (valtype newval
, cgraph_edge
*cs
,
238 ipcp_value
<valtype
> *src_val
= NULL
,
239 int src_idx
= 0, HOST_WIDE_INT offset
= -1,
240 ipcp_value
<valtype
> **val_p
= NULL
,
241 bool unlimited
= false);
242 void print (FILE * f
, bool dump_sources
, bool dump_benefits
);
245 /* Lattice of tree values with an offset to describe a part of an
248 struct ipcp_agg_lattice
: public ipcp_lattice
<tree
>
251 /* Offset that is being described by this lattice. */
252 HOST_WIDE_INT offset
;
253 /* Size so that we don't have to re-compute it every time we traverse the
254 list. Must correspond to TYPE_SIZE of all lat values. */
256 /* Next element of the linked list. */
257 struct ipcp_agg_lattice
*next
;
260 /* Lattice of known bits, only capable of holding one value.
261 Bitwise constant propagation propagates which bits of a
277 In the above case, the param 'x' will always have all
278 the bits (except the bits in lsb) set to 0.
279 Hence the mask of 'x' would be 0xff. The mask
280 reflects that the bits in lsb are unknown.
281 The actual propagated value is given by m_value & ~m_mask. */
283 class ipcp_bits_lattice
286 bool bottom_p () { return m_lattice_val
== IPA_BITS_VARYING
; }
287 bool top_p () { return m_lattice_val
== IPA_BITS_UNDEFINED
; }
288 bool constant_p () { return m_lattice_val
== IPA_BITS_CONSTANT
; }
289 bool set_to_bottom ();
290 bool set_to_constant (widest_int
, widest_int
);
292 widest_int
get_value () { return m_value
; }
293 widest_int
get_mask () { return m_mask
; }
295 bool meet_with (ipcp_bits_lattice
& other
, unsigned, signop
,
296 enum tree_code
, tree
);
298 bool meet_with (widest_int
, widest_int
, unsigned);
303 enum { IPA_BITS_UNDEFINED
, IPA_BITS_CONSTANT
, IPA_BITS_VARYING
} m_lattice_val
;
305 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
306 If a bit in mask is set to 0, then the corresponding bit in
307 value is known to be constant. */
308 widest_int m_value
, m_mask
;
310 bool meet_with_1 (widest_int
, widest_int
, unsigned);
311 void get_value_and_mask (tree
, widest_int
*, widest_int
*);
314 /* Lattice of value ranges. */
316 class ipcp_vr_lattice
321 inline bool bottom_p () const;
322 inline bool top_p () const;
323 inline bool set_to_bottom ();
324 bool meet_with (const value_range
*p_vr
);
325 bool meet_with (const ipcp_vr_lattice
&other
);
326 void init () { gcc_assert (m_vr
.undefined_p ()); }
327 void print (FILE * f
);
330 bool meet_with_1 (const value_range
*other_vr
);
333 /* Structure containing lattices for a parameter itself and for pieces of
334 aggregates that are passed in the parameter or by a reference in a parameter
335 plus some other useful flags. */
337 class ipcp_param_lattices
340 /* Lattice describing the value of the parameter itself. */
341 ipcp_lattice
<tree
> itself
;
342 /* Lattice describing the polymorphic contexts of a parameter. */
343 ipcp_lattice
<ipa_polymorphic_call_context
> ctxlat
;
344 /* Lattices describing aggregate parts. */
345 ipcp_agg_lattice
*aggs
;
346 /* Lattice describing known bits. */
347 ipcp_bits_lattice bits_lattice
;
348 /* Lattice describing value range. */
349 ipcp_vr_lattice m_value_range
;
350 /* Number of aggregate lattices */
352 /* True if aggregate data were passed by reference (as opposed to by
355 /* All aggregate lattices contain a variable component (in addition to
357 bool aggs_contain_variable
;
358 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
359 for any propagation). */
362 /* There is a virtual call based on this parameter. */
366 /* Allocation pools for values and their sources in ipa-cp. */
368 object_allocator
<ipcp_value
<tree
> > ipcp_cst_values_pool
369 ("IPA-CP constant values");
371 object_allocator
<ipcp_value
<ipa_polymorphic_call_context
> >
372 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
374 object_allocator
<ipcp_value_source
<tree
> > ipcp_sources_pool
375 ("IPA-CP value sources");
377 object_allocator
<ipcp_agg_lattice
> ipcp_agg_lattice_pool
378 ("IPA_CP aggregate lattices");
380 /* Maximal count found in program. */
382 static profile_count max_count
;
384 /* Original overall size of the program. */
386 static long overall_size
, orig_overall_size
;
388 /* Node name to unique clone suffix number map. */
389 static hash_map
<const char *, unsigned> *clone_num_suffixes
;
391 /* Return the param lattices structure corresponding to the Ith formal
392 parameter of the function described by INFO. */
393 static inline class ipcp_param_lattices
*
394 ipa_get_parm_lattices (class ipa_node_params
*info
, int i
)
396 gcc_assert (i
>= 0 && i
< ipa_get_param_count (info
));
397 gcc_checking_assert (!info
->ipcp_orig_node
);
398 gcc_checking_assert (info
->lattices
);
399 return &(info
->lattices
[i
]);
402 /* Return the lattice corresponding to the scalar value of the Ith formal
403 parameter of the function described by INFO. */
404 static inline ipcp_lattice
<tree
> *
405 ipa_get_scalar_lat (class ipa_node_params
*info
, int i
)
407 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
408 return &plats
->itself
;
411 /* Return the lattice corresponding to the scalar value of the Ith formal
412 parameter of the function described by INFO. */
413 static inline ipcp_lattice
<ipa_polymorphic_call_context
> *
414 ipa_get_poly_ctx_lat (class ipa_node_params
*info
, int i
)
416 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
417 return &plats
->ctxlat
;
420 /* Return whether LAT is a lattice with a single constant and without an
423 template <typename valtype
>
425 ipcp_lattice
<valtype
>::is_single_const ()
427 if (bottom
|| contains_variable
|| values_count
!= 1)
433 /* Print V which is extracted from a value in a lattice to F. */
436 print_ipcp_constant_value (FILE * f
, tree v
)
438 if (TREE_CODE (v
) == ADDR_EXPR
439 && TREE_CODE (TREE_OPERAND (v
, 0)) == CONST_DECL
)
442 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (v
, 0)));
445 print_generic_expr (f
, v
);
448 /* Print V which is extracted from a value in a lattice to F. */
451 print_ipcp_constant_value (FILE * f
, ipa_polymorphic_call_context v
)
456 /* Print a lattice LAT to F. */
458 template <typename valtype
>
460 ipcp_lattice
<valtype
>::print (FILE * f
, bool dump_sources
, bool dump_benefits
)
462 ipcp_value
<valtype
> *val
;
467 fprintf (f
, "BOTTOM\n");
471 if (!values_count
&& !contains_variable
)
473 fprintf (f
, "TOP\n");
477 if (contains_variable
)
479 fprintf (f
, "VARIABLE");
485 for (val
= values
; val
; val
= val
->next
)
487 if (dump_benefits
&& prev
)
489 else if (!dump_benefits
&& prev
)
494 print_ipcp_constant_value (f
, val
->value
);
498 ipcp_value_source
<valtype
> *s
;
500 fprintf (f
, " [from:");
501 for (s
= val
->sources
; s
; s
= s
->next
)
502 fprintf (f
, " %i(%f)", s
->cs
->caller
->order
,
503 s
->cs
->sreal_frequency ().to_double ());
508 fprintf (f
, " [loc_time: %g, loc_size: %i, "
509 "prop_time: %g, prop_size: %i]\n",
510 val
->local_time_benefit
.to_double (), val
->local_size_cost
,
511 val
->prop_time_benefit
.to_double (), val
->prop_size_cost
);
518 ipcp_bits_lattice::print (FILE *f
)
521 fprintf (f
, " Bits unknown (TOP)\n");
522 else if (bottom_p ())
523 fprintf (f
, " Bits unusable (BOTTOM)\n");
526 fprintf (f
, " Bits: value = "); print_hex (get_value (), f
);
527 fprintf (f
, ", mask = "); print_hex (get_mask (), f
);
532 /* Print value range lattice to F. */
535 ipcp_vr_lattice::print (FILE * f
)
537 dump_value_range (f
, &m_vr
);
540 /* Print all ipcp_lattices of all functions to F. */
543 print_all_lattices (FILE * f
, bool dump_sources
, bool dump_benefits
)
545 struct cgraph_node
*node
;
548 fprintf (f
, "\nLattices:\n");
549 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
551 class ipa_node_params
*info
;
553 info
= IPA_NODE_REF (node
);
554 /* Skip unoptimized functions and constprop clones since we don't make
555 lattices for them. */
556 if (!info
|| info
->ipcp_orig_node
)
558 fprintf (f
, " Node: %s:\n", node
->dump_name ());
559 count
= ipa_get_param_count (info
);
560 for (i
= 0; i
< count
; i
++)
562 struct ipcp_agg_lattice
*aglat
;
563 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
564 fprintf (f
, " param [%d]: ", i
);
565 plats
->itself
.print (f
, dump_sources
, dump_benefits
);
566 fprintf (f
, " ctxs: ");
567 plats
->ctxlat
.print (f
, dump_sources
, dump_benefits
);
568 plats
->bits_lattice
.print (f
);
570 plats
->m_value_range
.print (f
);
572 if (plats
->virt_call
)
573 fprintf (f
, " virt_call flag set\n");
575 if (plats
->aggs_bottom
)
577 fprintf (f
, " AGGS BOTTOM\n");
580 if (plats
->aggs_contain_variable
)
581 fprintf (f
, " AGGS VARIABLE\n");
582 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
584 fprintf (f
, " %soffset " HOST_WIDE_INT_PRINT_DEC
": ",
585 plats
->aggs_by_ref
? "ref " : "", aglat
->offset
);
586 aglat
->print (f
, dump_sources
, dump_benefits
);
592 /* Determine whether it is at all technically possible to create clones of NODE
593 and store this information in the ipa_node_params structure associated
597 determine_versionability (struct cgraph_node
*node
,
598 class ipa_node_params
*info
)
600 const char *reason
= NULL
;
602 /* There are a number of generic reasons functions cannot be versioned. We
603 also cannot remove parameters if there are type attributes such as fnspec
605 if (node
->alias
|| node
->thunk
)
606 reason
= "alias or thunk";
607 else if (!node
->versionable
)
608 reason
= "not a tree_versionable_function";
609 else if (node
->get_availability () <= AVAIL_INTERPOSABLE
)
610 reason
= "insufficient body availability";
611 else if (!opt_for_fn (node
->decl
, optimize
)
612 || !opt_for_fn (node
->decl
, flag_ipa_cp
))
613 reason
= "non-optimized function";
614 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node
->decl
)))
616 /* Ideally we should clone the SIMD clones themselves and create
617 vector copies of them, so IPA-cp and SIMD clones can happily
618 coexist, but that may not be worth the effort. */
619 reason
= "function has SIMD clones";
621 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node
->decl
)))
623 /* Ideally we should clone the target clones themselves and create
624 copies of them, so IPA-cp and target clones can happily
625 coexist, but that may not be worth the effort. */
626 reason
= "function target_clones attribute";
628 /* Don't clone decls local to a comdat group; it breaks and for C++
629 decloned constructors, inlining is always better anyway. */
630 else if (node
->comdat_local_p ())
631 reason
= "comdat-local function";
632 else if (node
->calls_comdat_local
)
634 /* TODO: call is versionable if we make sure that all
635 callers are inside of a comdat group. */
636 reason
= "calls comdat-local function";
639 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
640 work only when inlined. Cloning them may still lead to better code
641 because ipa-cp will not give up on cloning further. If the function is
642 external this however leads to wrong code because we may end up producing
643 offline copy of the function. */
644 if (DECL_EXTERNAL (node
->decl
))
645 for (cgraph_edge
*edge
= node
->callees
; !reason
&& edge
;
646 edge
= edge
->next_callee
)
647 if (fndecl_built_in_p (edge
->callee
->decl
, BUILT_IN_NORMAL
))
649 if (DECL_FUNCTION_CODE (edge
->callee
->decl
) == BUILT_IN_VA_ARG_PACK
)
650 reason
= "external function which calls va_arg_pack";
651 if (DECL_FUNCTION_CODE (edge
->callee
->decl
)
652 == BUILT_IN_VA_ARG_PACK_LEN
)
653 reason
= "external function which calls va_arg_pack_len";
656 if (reason
&& dump_file
&& !node
->alias
&& !node
->thunk
)
657 fprintf (dump_file
, "Function %s is not versionable, reason: %s.\n",
658 node
->dump_name (), reason
);
660 info
->versionable
= (reason
== NULL
);
663 /* Return true if it is at all technically possible to create clones of a
667 ipcp_versionable_function_p (struct cgraph_node
*node
)
669 return IPA_NODE_REF (node
) && IPA_NODE_REF (node
)->versionable
;
672 /* Structure holding accumulated information about callers of a node. */
674 struct caller_statistics
676 profile_count count_sum
;
678 int n_calls
, n_hot_calls
;
681 /* Initialize fields of STAT to zeroes. */
684 init_caller_stats (struct caller_statistics
*stats
)
686 stats
->count_sum
= profile_count::zero ();
688 stats
->n_hot_calls
= 0;
692 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
693 non-thunk incoming edges to NODE. */
696 gather_caller_stats (struct cgraph_node
*node
, void *data
)
698 struct caller_statistics
*stats
= (struct caller_statistics
*) data
;
699 struct cgraph_edge
*cs
;
701 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
702 if (!cs
->caller
->thunk
)
704 if (cs
->count
.ipa ().initialized_p ())
705 stats
->count_sum
+= cs
->count
.ipa ();
706 stats
->freq_sum
+= cs
->sreal_frequency ();
708 if (cs
->maybe_hot_p ())
709 stats
->n_hot_calls
++;
715 /* Return true if this NODE is viable candidate for cloning. */
718 ipcp_cloning_candidate_p (struct cgraph_node
*node
)
720 struct caller_statistics stats
;
722 gcc_checking_assert (node
->has_gimple_body_p ());
724 if (!opt_for_fn (node
->decl
, flag_ipa_cp_clone
))
727 fprintf (dump_file
, "Not considering %s for cloning; "
728 "-fipa-cp-clone disabled.\n",
733 if (node
->optimize_for_size_p ())
736 fprintf (dump_file
, "Not considering %s for cloning; "
737 "optimizing it for size.\n",
742 init_caller_stats (&stats
);
743 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
, false);
745 if (ipa_size_summaries
->get (node
)->self_size
< stats
.n_calls
)
748 fprintf (dump_file
, "Considering %s for cloning; code might shrink.\n",
753 /* When profile is available and function is hot, propagate into it even if
754 calls seems cold; constant propagation can improve function's speed
756 if (max_count
> profile_count::zero ())
758 if (stats
.count_sum
> node
->count
.ipa ().apply_scale (90, 100))
761 fprintf (dump_file
, "Considering %s for cloning; "
762 "usually called directly.\n",
767 if (!stats
.n_hot_calls
)
770 fprintf (dump_file
, "Not considering %s for cloning; no hot calls.\n",
775 fprintf (dump_file
, "Considering %s for cloning.\n",
780 template <typename valtype
>
781 class value_topo_info
784 /* Head of the linked list of topologically sorted values. */
785 ipcp_value
<valtype
> *values_topo
;
786 /* Stack for creating SCCs, represented by a linked list too. */
787 ipcp_value
<valtype
> *stack
;
788 /* Counter driving the algorithm in add_val_to_toposort. */
791 value_topo_info () : values_topo (NULL
), stack (NULL
), dfs_counter (0)
793 void add_val (ipcp_value
<valtype
> *cur_val
);
794 void propagate_effects ();
797 /* Arrays representing a topological ordering of call graph nodes and a stack
798 of nodes used during constant propagation and also data required to perform
799 topological sort of values and propagation of benefits in the determined
805 /* Array with obtained topological order of cgraph nodes. */
806 struct cgraph_node
**order
;
807 /* Stack of cgraph nodes used during propagation within SCC until all values
808 in the SCC stabilize. */
809 struct cgraph_node
**stack
;
810 int nnodes
, stack_top
;
812 value_topo_info
<tree
> constants
;
813 value_topo_info
<ipa_polymorphic_call_context
> contexts
;
815 ipa_topo_info () : order(NULL
), stack(NULL
), nnodes(0), stack_top(0),
820 /* Skip edges from and to nodes without ipa_cp enabled.
821 Ignore not available symbols. */
824 ignore_edge_p (cgraph_edge
*e
)
826 enum availability avail
;
827 cgraph_node
*ultimate_target
828 = e
->callee
->function_or_virtual_thunk_symbol (&avail
, e
->caller
);
830 return (avail
<= AVAIL_INTERPOSABLE
831 || !opt_for_fn (ultimate_target
->decl
, optimize
)
832 || !opt_for_fn (ultimate_target
->decl
, flag_ipa_cp
));
835 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
838 build_toporder_info (class ipa_topo_info
*topo
)
840 topo
->order
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
841 topo
->stack
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
843 gcc_checking_assert (topo
->stack_top
== 0);
844 topo
->nnodes
= ipa_reduced_postorder (topo
->order
, true,
848 /* Free information about strongly connected components and the arrays in
852 free_toporder_info (class ipa_topo_info
*topo
)
854 ipa_free_postorder_info ();
859 /* Add NODE to the stack in TOPO, unless it is already there. */
862 push_node_to_stack (class ipa_topo_info
*topo
, struct cgraph_node
*node
)
864 class ipa_node_params
*info
= IPA_NODE_REF (node
);
865 if (info
->node_enqueued
)
867 info
->node_enqueued
= 1;
868 topo
->stack
[topo
->stack_top
++] = node
;
871 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
874 static struct cgraph_node
*
875 pop_node_from_stack (class ipa_topo_info
*topo
)
879 struct cgraph_node
*node
;
881 node
= topo
->stack
[topo
->stack_top
];
882 IPA_NODE_REF (node
)->node_enqueued
= 0;
889 /* Set lattice LAT to bottom and return true if it previously was not set as
892 template <typename valtype
>
894 ipcp_lattice
<valtype
>::set_to_bottom ()
901 /* Mark lattice as containing an unknown value and return true if it previously
902 was not marked as such. */
904 template <typename valtype
>
906 ipcp_lattice
<valtype
>::set_contains_variable ()
908 bool ret
= !contains_variable
;
909 contains_variable
= true;
913 /* Set all aggregate lattices in PLATS to bottom and return true if they were
914 not previously set as such. */
917 set_agg_lats_to_bottom (class ipcp_param_lattices
*plats
)
919 bool ret
= !plats
->aggs_bottom
;
920 plats
->aggs_bottom
= true;
924 /* Mark all aggregate lattices in PLATS as containing an unknown value and
925 return true if they were not previously marked as such. */
928 set_agg_lats_contain_variable (class ipcp_param_lattices
*plats
)
930 bool ret
= !plats
->aggs_contain_variable
;
931 plats
->aggs_contain_variable
= true;
936 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice
&other
)
938 return meet_with_1 (&other
.m_vr
);
941 /* Meet the current value of the lattice with value range described by VR
945 ipcp_vr_lattice::meet_with (const value_range
*p_vr
)
947 return meet_with_1 (p_vr
);
950 /* Meet the current value of the lattice with value range described by
951 OTHER_VR lattice. Return TRUE if anything changed. */
954 ipcp_vr_lattice::meet_with_1 (const value_range
*other_vr
)
959 if (other_vr
->varying_p ())
960 return set_to_bottom ();
962 value_range
save (m_vr
);
963 m_vr
.union_ (other_vr
);
964 return !m_vr
.equal_p (save
);
967 /* Return true if value range information in the lattice is yet unknown. */
970 ipcp_vr_lattice::top_p () const
972 return m_vr
.undefined_p ();
975 /* Return true if value range information in the lattice is known to be
979 ipcp_vr_lattice::bottom_p () const
981 return m_vr
.varying_p ();
984 /* Set value range information in the lattice to bottom. Return true if it
985 previously was in a different state. */
988 ipcp_vr_lattice::set_to_bottom ()
990 if (m_vr
.varying_p ())
992 /* ?? We create all sorts of VARYING ranges for floats, structures,
993 and other types which we cannot handle as ranges. We should
994 probably avoid handling them throughout the pass, but it's easier
995 to create a sensible VARYING here and let the lattice
997 m_vr
.set_varying (integer_type_node
);
1001 /* Set lattice value to bottom, if it already isn't the case. */
1004 ipcp_bits_lattice::set_to_bottom ()
1008 m_lattice_val
= IPA_BITS_VARYING
;
1014 /* Set to constant if it isn't already. Only meant to be called
1015 when switching state from TOP. */
1018 ipcp_bits_lattice::set_to_constant (widest_int value
, widest_int mask
)
1020 gcc_assert (top_p ());
1021 m_lattice_val
= IPA_BITS_CONSTANT
;
1022 m_value
= wi::bit_and (wi::bit_not (mask
), value
);
1027 /* Convert operand to value, mask form. */
1030 ipcp_bits_lattice::get_value_and_mask (tree operand
, widest_int
*valuep
, widest_int
*maskp
)
1032 wide_int
get_nonzero_bits (const_tree
);
1034 if (TREE_CODE (operand
) == INTEGER_CST
)
1036 *valuep
= wi::to_widest (operand
);
1046 /* Meet operation, similar to ccp_lattice_meet, we xor values
1047 if this->value, value have different values at same bit positions, we want
1048 to drop that bit to varying. Return true if mask is changed.
1049 This function assumes that the lattice value is in CONSTANT state */
1052 ipcp_bits_lattice::meet_with_1 (widest_int value
, widest_int mask
,
1055 gcc_assert (constant_p ());
1057 widest_int old_mask
= m_mask
;
1058 m_mask
= (m_mask
| mask
) | (m_value
^ value
);
1061 if (wi::sext (m_mask
, precision
) == -1)
1062 return set_to_bottom ();
1064 return m_mask
!= old_mask
;
1067 /* Meet the bits lattice with operand
1068 described by <value, mask, sgn, precision. */
1071 ipcp_bits_lattice::meet_with (widest_int value
, widest_int mask
,
1079 if (wi::sext (mask
, precision
) == -1)
1080 return set_to_bottom ();
1081 return set_to_constant (value
, mask
);
1084 return meet_with_1 (value
, mask
, precision
);
1087 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1088 if code is binary operation or bit_value_unop (other) if code is unary op.
1089 In the case when code is nop_expr, no adjustment is required. */
1092 ipcp_bits_lattice::meet_with (ipcp_bits_lattice
& other
, unsigned precision
,
1093 signop sgn
, enum tree_code code
, tree operand
)
1095 if (other
.bottom_p ())
1096 return set_to_bottom ();
1098 if (bottom_p () || other
.top_p ())
1101 widest_int adjusted_value
, adjusted_mask
;
1103 if (TREE_CODE_CLASS (code
) == tcc_binary
)
1105 tree type
= TREE_TYPE (operand
);
1106 widest_int o_value
, o_mask
;
1107 get_value_and_mask (operand
, &o_value
, &o_mask
);
1109 bit_value_binop (code
, sgn
, precision
, &adjusted_value
, &adjusted_mask
,
1110 sgn
, precision
, other
.get_value (), other
.get_mask (),
1111 TYPE_SIGN (type
), TYPE_PRECISION (type
), o_value
, o_mask
);
1113 if (wi::sext (adjusted_mask
, precision
) == -1)
1114 return set_to_bottom ();
1117 else if (TREE_CODE_CLASS (code
) == tcc_unary
)
1119 bit_value_unop (code
, sgn
, precision
, &adjusted_value
,
1120 &adjusted_mask
, sgn
, precision
, other
.get_value (),
1123 if (wi::sext (adjusted_mask
, precision
) == -1)
1124 return set_to_bottom ();
1128 return set_to_bottom ();
1132 if (wi::sext (adjusted_mask
, precision
) == -1)
1133 return set_to_bottom ();
1134 return set_to_constant (adjusted_value
, adjusted_mask
);
1137 return meet_with_1 (adjusted_value
, adjusted_mask
, precision
);
1140 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1141 return true is any of them has not been marked as such so far. */
1144 set_all_contains_variable (class ipcp_param_lattices
*plats
)
1147 ret
= plats
->itself
.set_contains_variable ();
1148 ret
|= plats
->ctxlat
.set_contains_variable ();
1149 ret
|= set_agg_lats_contain_variable (plats
);
1150 ret
|= plats
->bits_lattice
.set_to_bottom ();
1151 ret
|= plats
->m_value_range
.set_to_bottom ();
1155 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1156 points to by the number of callers to NODE. */
1159 count_callers (cgraph_node
*node
, void *data
)
1161 int *caller_count
= (int *) data
;
1163 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
1164 /* Local thunks can be handled transparently, but if the thunk cannot
1165 be optimized out, count it as a real use. */
1166 if (!cs
->caller
->thunk
|| !cs
->caller
->local
)
1171 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1172 the one caller of some other node. Set the caller's corresponding flag. */
1175 set_single_call_flag (cgraph_node
*node
, void *)
1177 cgraph_edge
*cs
= node
->callers
;
1178 /* Local thunks can be handled transparently, skip them. */
1179 while (cs
&& cs
->caller
->thunk
&& cs
->caller
->local
)
1180 cs
= cs
->next_caller
;
1181 if (cs
&& IPA_NODE_REF (cs
->caller
))
1183 IPA_NODE_REF (cs
->caller
)->node_calling_single_call
= true;
1189 /* Initialize ipcp_lattices. */
1192 initialize_node_lattices (struct cgraph_node
*node
)
1194 class ipa_node_params
*info
= IPA_NODE_REF (node
);
1195 struct cgraph_edge
*ie
;
1196 bool disable
= false, variable
= false;
1199 gcc_checking_assert (node
->has_gimple_body_p ());
1201 if (!ipa_get_param_count (info
))
1203 else if (node
->local
)
1205 int caller_count
= 0;
1206 node
->call_for_symbol_thunks_and_aliases (count_callers
, &caller_count
,
1208 gcc_checking_assert (caller_count
> 0);
1209 if (caller_count
== 1)
1210 node
->call_for_symbol_thunks_and_aliases (set_single_call_flag
,
1215 /* When cloning is allowed, we can assume that externally visible
1216 functions are not called. We will compensate this by cloning
1218 if (ipcp_versionable_function_p (node
)
1219 && ipcp_cloning_candidate_p (node
))
1225 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1226 && !node
->alias
&& !node
->thunk
)
1228 fprintf (dump_file
, "Initializing lattices of %s\n",
1229 node
->dump_name ());
1230 if (disable
|| variable
)
1231 fprintf (dump_file
, " Marking all lattices as %s\n",
1232 disable
? "BOTTOM" : "VARIABLE");
1235 auto_vec
<bool, 16> surviving_params
;
1236 bool pre_modified
= false;
1238 clone_info
*cinfo
= clone_info::get (node
);
1240 if (!disable
&& cinfo
&& cinfo
->param_adjustments
)
1242 /* At the moment all IPA optimizations should use the number of
1243 parameters of the prevailing decl as the m_always_copy_start.
1244 Handling any other value would complicate the code below, so for the
1245 time bing let's only assert it is so. */
1246 gcc_assert ((cinfo
->param_adjustments
->m_always_copy_start
1247 == ipa_get_param_count (info
))
1248 || cinfo
->param_adjustments
->m_always_copy_start
< 0);
1250 pre_modified
= true;
1251 cinfo
->param_adjustments
->get_surviving_params (&surviving_params
);
1253 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1254 && !node
->alias
&& !node
->thunk
)
1257 for (int j
= 0; j
< ipa_get_param_count (info
); j
++)
1259 if (j
< (int) surviving_params
.length ()
1260 && surviving_params
[j
])
1265 " The following parameters are dead on arrival:");
1268 fprintf (dump_file
, " %u", j
);
1271 fprintf (dump_file
, "\n");
1275 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1277 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1279 || (pre_modified
&& (surviving_params
.length () <= (unsigned) i
1280 || !surviving_params
[i
])))
1282 plats
->itself
.set_to_bottom ();
1283 plats
->ctxlat
.set_to_bottom ();
1284 set_agg_lats_to_bottom (plats
);
1285 plats
->bits_lattice
.set_to_bottom ();
1286 plats
->m_value_range
.m_vr
= value_range ();
1287 plats
->m_value_range
.set_to_bottom ();
1291 plats
->m_value_range
.init ();
1293 set_all_contains_variable (plats
);
1297 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
1298 if (ie
->indirect_info
->polymorphic
1299 && ie
->indirect_info
->param_index
>= 0)
1301 gcc_checking_assert (ie
->indirect_info
->param_index
>= 0);
1302 ipa_get_parm_lattices (info
,
1303 ie
->indirect_info
->param_index
)->virt_call
= 1;
1307 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1310 values_equal_for_ipcp_p (tree x
, tree y
)
1312 gcc_checking_assert (x
!= NULL_TREE
&& y
!= NULL_TREE
);
1317 if (TREE_CODE (x
) == ADDR_EXPR
1318 && TREE_CODE (y
) == ADDR_EXPR
1319 && TREE_CODE (TREE_OPERAND (x
, 0)) == CONST_DECL
1320 && TREE_CODE (TREE_OPERAND (y
, 0)) == CONST_DECL
)
1321 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x
, 0)),
1322 DECL_INITIAL (TREE_OPERAND (y
, 0)), 0);
1324 return operand_equal_p (x
, y
, 0);
1327 /* Return the result of a (possibly arithmetic) operation on the constant
1328 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1329 the type of the parameter to which the result is passed. Return
1330 NULL_TREE if that cannot be determined or be considered an
1331 interprocedural invariant. */
1334 ipa_get_jf_arith_result (enum tree_code opcode
, tree input
, tree operand
,
1339 if (opcode
== NOP_EXPR
)
1341 if (!is_gimple_ip_invariant (input
))
1344 if (opcode
== ASSERT_EXPR
)
1346 if (values_equal_for_ipcp_p (input
, operand
))
1354 if (TREE_CODE_CLASS (opcode
) == tcc_comparison
)
1355 res_type
= boolean_type_node
;
1356 else if (expr_type_first_operand_type_p (opcode
))
1357 res_type
= TREE_TYPE (input
);
1362 if (TREE_CODE_CLASS (opcode
) == tcc_unary
)
1363 res
= fold_unary (opcode
, res_type
, input
);
1365 res
= fold_binary (opcode
, res_type
, input
, operand
);
1367 if (res
&& !is_gimple_ip_invariant (res
))
1373 /* Return the result of a (possibly arithmetic) pass through jump function
1374 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1375 to which the result is passed. Return NULL_TREE if that cannot be
1376 determined or be considered an interprocedural invariant. */
1379 ipa_get_jf_pass_through_result (struct ipa_jump_func
*jfunc
, tree input
,
1382 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc
),
1384 ipa_get_jf_pass_through_operand (jfunc
),
1388 /* Return the result of an ancestor jump function JFUNC on the constant value
1389 INPUT. Return NULL_TREE if that cannot be determined. */
1392 ipa_get_jf_ancestor_result (struct ipa_jump_func
*jfunc
, tree input
)
1394 gcc_checking_assert (TREE_CODE (input
) != TREE_BINFO
);
1395 if (TREE_CODE (input
) == ADDR_EXPR
)
1397 gcc_checking_assert (is_gimple_ip_invariant_address (input
));
1398 poly_int64 off
= ipa_get_jf_ancestor_offset (jfunc
);
1399 if (known_eq (off
, 0))
1401 poly_int64 byte_offset
= exact_div (off
, BITS_PER_UNIT
);
1402 return build1 (ADDR_EXPR
, TREE_TYPE (input
),
1403 fold_build2 (MEM_REF
, TREE_TYPE (TREE_TYPE (input
)), input
,
1404 build_int_cst (ptr_type_node
, byte_offset
)));
1410 /* Determine whether JFUNC evaluates to a single known constant value and if
1411 so, return it. Otherwise return NULL. INFO describes the caller node or
1412 the one it is inlined to, so that pass-through jump functions can be
1413 evaluated. PARM_TYPE is the type of the parameter to which the result is
1417 ipa_value_from_jfunc (class ipa_node_params
*info
, struct ipa_jump_func
*jfunc
,
1420 if (jfunc
->type
== IPA_JF_CONST
)
1421 return ipa_get_jf_constant (jfunc
);
1422 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1423 || jfunc
->type
== IPA_JF_ANCESTOR
)
1428 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1429 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1431 idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1433 if (info
->ipcp_orig_node
)
1434 input
= info
->known_csts
[idx
];
1437 ipcp_lattice
<tree
> *lat
;
1440 || idx
>= ipa_get_param_count (info
))
1442 lat
= ipa_get_scalar_lat (info
, idx
);
1443 if (!lat
->is_single_const ())
1445 input
= lat
->values
->value
;
1451 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1452 return ipa_get_jf_pass_through_result (jfunc
, input
, parm_type
);
1454 return ipa_get_jf_ancestor_result (jfunc
, input
);
1460 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1461 that INFO describes the caller node or the one it is inlined to, CS is the
1462 call graph edge corresponding to JFUNC and CSIDX index of the described
1465 ipa_polymorphic_call_context
1466 ipa_context_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
, int csidx
,
1467 ipa_jump_func
*jfunc
)
1469 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1470 ipa_polymorphic_call_context ctx
;
1471 ipa_polymorphic_call_context
*edge_ctx
1472 = cs
? ipa_get_ith_polymorhic_call_context (args
, csidx
) : NULL
;
1474 if (edge_ctx
&& !edge_ctx
->useless_p ())
1477 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1478 || jfunc
->type
== IPA_JF_ANCESTOR
)
1480 ipa_polymorphic_call_context srcctx
;
1482 bool type_preserved
= true;
1483 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1485 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1487 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1488 srcidx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1492 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1493 srcidx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1495 if (info
->ipcp_orig_node
)
1497 if (info
->known_contexts
.exists ())
1498 srcctx
= info
->known_contexts
[srcidx
];
1503 || srcidx
>= ipa_get_param_count (info
))
1505 ipcp_lattice
<ipa_polymorphic_call_context
> *lat
;
1506 lat
= ipa_get_poly_ctx_lat (info
, srcidx
);
1507 if (!lat
->is_single_const ())
1509 srcctx
= lat
->values
->value
;
1511 if (srcctx
.useless_p ())
1513 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1514 srcctx
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1515 if (!type_preserved
)
1516 srcctx
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1517 srcctx
.combine_with (ctx
);
1524 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1525 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1526 the result is a range or an anti-range. */
1529 ipa_vr_operation_and_type_effects (value_range
*dst_vr
,
1530 value_range
*src_vr
,
1531 enum tree_code operation
,
1532 tree dst_type
, tree src_type
)
1534 range_fold_unary_expr (dst_vr
, operation
, dst_type
, src_vr
, src_type
);
1535 if (dst_vr
->varying_p () || dst_vr
->undefined_p ())
1540 /* Determine value_range of JFUNC given that INFO describes the caller node or
1541 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1542 and PARM_TYPE of the parameter. */
1545 ipa_value_range_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
,
1546 ipa_jump_func
*jfunc
, tree parm_type
)
1551 ipa_vr_operation_and_type_effects (&vr
,
1553 NOP_EXPR
, parm_type
,
1554 jfunc
->m_vr
->type ());
1555 if (vr
.singleton_p ())
1557 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1560 ipcp_transformation
*sum
1561 = ipcp_get_transformation_summary (cs
->caller
->inlined_to
1562 ? cs
->caller
->inlined_to
1564 if (!sum
|| !sum
->m_vr
)
1567 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1569 if (!(*sum
->m_vr
)[idx
].known
)
1571 tree vr_type
= ipa_get_type (info
, idx
);
1572 value_range
srcvr (wide_int_to_tree (vr_type
, (*sum
->m_vr
)[idx
].min
),
1573 wide_int_to_tree (vr_type
, (*sum
->m_vr
)[idx
].max
),
1574 (*sum
->m_vr
)[idx
].type
);
1576 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
1578 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
1582 if (ipa_vr_operation_and_type_effects (&res
,
1584 operation
, parm_type
,
1590 value_range op_res
, res
;
1591 tree op
= ipa_get_jf_pass_through_operand (jfunc
);
1592 value_range
op_vr (op
, op
);
1594 range_fold_binary_expr (&op_res
, operation
, vr_type
, &srcvr
, &op_vr
);
1595 if (ipa_vr_operation_and_type_effects (&res
,
1597 NOP_EXPR
, parm_type
,
1605 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1606 parameter with the given INDEX. */
1609 get_clone_agg_value (struct cgraph_node
*node
, HOST_WIDE_INT offset
,
1612 struct ipa_agg_replacement_value
*aggval
;
1614 aggval
= ipa_get_agg_replacements_for_node (node
);
1617 if (aggval
->offset
== offset
1618 && aggval
->index
== index
)
1619 return aggval
->value
;
1620 aggval
= aggval
->next
;
1625 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1626 single known constant value and if so, return it. Otherwise return NULL.
1627 NODE and INFO describes the caller node or the one it is inlined to, and
1628 its related info. */
1631 ipa_agg_value_from_node (class ipa_node_params
*info
,
1632 struct cgraph_node
*node
,
1633 struct ipa_agg_jf_item
*item
)
1635 tree value
= NULL_TREE
;
1638 if (item
->offset
< 0 || item
->jftype
== IPA_JF_UNKNOWN
)
1641 if (item
->jftype
== IPA_JF_CONST
)
1642 return item
->value
.constant
;
1644 gcc_checking_assert (item
->jftype
== IPA_JF_PASS_THROUGH
1645 || item
->jftype
== IPA_JF_LOAD_AGG
);
1647 src_idx
= item
->value
.pass_through
.formal_id
;
1649 if (info
->ipcp_orig_node
)
1651 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
1652 value
= info
->known_csts
[src_idx
];
1654 value
= get_clone_agg_value (node
, item
->value
.load_agg
.offset
,
1657 else if (info
->lattices
)
1659 class ipcp_param_lattices
*src_plats
1660 = ipa_get_parm_lattices (info
, src_idx
);
1662 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
1664 struct ipcp_lattice
<tree
> *lat
= &src_plats
->itself
;
1666 if (!lat
->is_single_const ())
1669 value
= lat
->values
->value
;
1671 else if (src_plats
->aggs
1672 && !src_plats
->aggs_bottom
1673 && !src_plats
->aggs_contain_variable
1674 && src_plats
->aggs_by_ref
== item
->value
.load_agg
.by_ref
)
1676 struct ipcp_agg_lattice
*aglat
;
1678 for (aglat
= src_plats
->aggs
; aglat
; aglat
= aglat
->next
)
1680 if (aglat
->offset
> item
->value
.load_agg
.offset
)
1683 if (aglat
->offset
== item
->value
.load_agg
.offset
)
1685 if (aglat
->is_single_const ())
1686 value
= aglat
->values
->value
;
1696 if (item
->jftype
== IPA_JF_LOAD_AGG
)
1698 tree load_type
= item
->value
.load_agg
.type
;
1699 tree value_type
= TREE_TYPE (value
);
1701 /* Ensure value type is compatible with load type. */
1702 if (!useless_type_conversion_p (load_type
, value_type
))
1706 return ipa_get_jf_arith_result (item
->value
.pass_through
.operation
,
1708 item
->value
.pass_through
.operand
,
1712 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1713 an aggregate and if so, return it. Otherwise return an empty set. NODE
1714 and INFO describes the caller node or the one it is inlined to, and its
1717 struct ipa_agg_value_set
1718 ipa_agg_value_set_from_jfunc (class ipa_node_params
*info
, cgraph_node
*node
,
1719 struct ipa_agg_jump_function
*agg_jfunc
)
1721 struct ipa_agg_value_set agg
;
1722 struct ipa_agg_jf_item
*item
;
1726 agg
.by_ref
= agg_jfunc
->by_ref
;
1728 FOR_EACH_VEC_SAFE_ELT (agg_jfunc
->items
, i
, item
)
1730 tree value
= ipa_agg_value_from_node (info
, node
, item
);
1734 struct ipa_agg_value value_item
;
1736 value_item
.offset
= item
->offset
;
1737 value_item
.value
= value
;
1739 agg
.items
.safe_push (value_item
);
1745 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1746 bottom, not containing a variable component and without any known value at
1750 ipcp_verify_propagated_values (void)
1752 struct cgraph_node
*node
;
1754 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1756 class ipa_node_params
*info
= IPA_NODE_REF (node
);
1757 if (!opt_for_fn (node
->decl
, flag_ipa_cp
)
1758 || !opt_for_fn (node
->decl
, optimize
))
1760 int i
, count
= ipa_get_param_count (info
);
1762 for (i
= 0; i
< count
; i
++)
1764 ipcp_lattice
<tree
> *lat
= ipa_get_scalar_lat (info
, i
);
1767 && !lat
->contains_variable
1768 && lat
->values_count
== 0)
1772 symtab
->dump (dump_file
);
1773 fprintf (dump_file
, "\nIPA lattices after constant "
1774 "propagation, before gcc_unreachable:\n");
1775 print_all_lattices (dump_file
, true, false);
1784 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1787 values_equal_for_ipcp_p (ipa_polymorphic_call_context x
,
1788 ipa_polymorphic_call_context y
)
1790 return x
.equal_to (y
);
1794 /* Add a new value source to the value represented by THIS, marking that a
1795 value comes from edge CS and (if the underlying jump function is a
1796 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1797 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1798 scalar value of the parameter itself or the offset within an aggregate. */
1800 template <typename valtype
>
1802 ipcp_value
<valtype
>::add_source (cgraph_edge
*cs
, ipcp_value
*src_val
,
1803 int src_idx
, HOST_WIDE_INT offset
)
1805 ipcp_value_source
<valtype
> *src
;
1807 src
= new (ipcp_sources_pool
.allocate ()) ipcp_value_source
<valtype
>;
1808 src
->offset
= offset
;
1811 src
->index
= src_idx
;
1813 src
->next
= sources
;
1817 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1818 SOURCE and clear all other fields. */
1820 static ipcp_value
<tree
> *
1821 allocate_and_init_ipcp_value (tree source
)
1823 ipcp_value
<tree
> *val
;
1825 val
= new (ipcp_cst_values_pool
.allocate ()) ipcp_value
<tree
>();
1826 val
->value
= source
;
1830 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1831 value to SOURCE and clear all other fields. */
1833 static ipcp_value
<ipa_polymorphic_call_context
> *
1834 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source
)
1836 ipcp_value
<ipa_polymorphic_call_context
> *val
;
1839 val
= new (ipcp_poly_ctx_values_pool
.allocate ())
1840 ipcp_value
<ipa_polymorphic_call_context
>();
1841 val
->value
= source
;
1845 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1846 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1847 meaning. OFFSET -1 means the source is scalar and not a part of an
1848 aggregate. If non-NULL, VAL_P records address of existing or newly added
1849 ipcp_value. UNLIMITED means whether value count should not exceed the limit
1850 given by PARAM_IPA_CP_VALUE_LIST_SIZE. */
1852 template <typename valtype
>
1854 ipcp_lattice
<valtype
>::add_value (valtype newval
, cgraph_edge
*cs
,
1855 ipcp_value
<valtype
> *src_val
,
1856 int src_idx
, HOST_WIDE_INT offset
,
1857 ipcp_value
<valtype
> **val_p
,
1860 ipcp_value
<valtype
> *val
, *last_val
= NULL
;
1868 for (val
= values
; val
; last_val
= val
, val
= val
->next
)
1869 if (values_equal_for_ipcp_p (val
->value
, newval
))
1874 if (ipa_edge_within_scc (cs
))
1876 ipcp_value_source
<valtype
> *s
;
1877 for (s
= val
->sources
; s
; s
= s
->next
)
1878 if (s
->cs
== cs
&& s
->val
== src_val
)
1884 val
->add_source (cs
, src_val
, src_idx
, offset
);
1888 if (!unlimited
&& values_count
== opt_for_fn (cs
->caller
->decl
,
1889 param_ipa_cp_value_list_size
))
1891 /* We can only free sources, not the values themselves, because sources
1892 of other values in this SCC might point to them. */
1893 for (val
= values
; val
; val
= val
->next
)
1895 while (val
->sources
)
1897 ipcp_value_source
<valtype
> *src
= val
->sources
;
1898 val
->sources
= src
->next
;
1899 ipcp_sources_pool
.remove ((ipcp_value_source
<tree
>*)src
);
1903 return set_to_bottom ();
1907 val
= allocate_and_init_ipcp_value (newval
);
1908 val
->add_source (cs
, src_val
, src_idx
, offset
);
1911 /* Add the new value to end of value list, which can reduce iterations
1912 of propagation stage for recursive function. */
1914 last_val
->next
= val
;
1924 /* Return true, if a ipcp_value VAL is orginated from parameter value of
1925 self-feeding recursive function via some kind of pass-through jump
1929 self_recursively_generated_p (ipcp_value
<tree
> *val
)
1931 class ipa_node_params
*info
= NULL
;
1933 for (ipcp_value_source
<tree
> *src
= val
->sources
; src
; src
= src
->next
)
1935 cgraph_edge
*cs
= src
->cs
;
1937 if (!src
->val
|| cs
->caller
!= cs
->callee
->function_symbol ())
1940 if (src
->val
== val
)
1944 info
= IPA_NODE_REF (cs
->caller
);
1946 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
,
1948 ipcp_lattice
<tree
> *src_lat
;
1949 ipcp_value
<tree
> *src_val
;
1951 if (src
->offset
== -1)
1952 src_lat
= &plats
->itself
;
1955 struct ipcp_agg_lattice
*src_aglat
;
1957 for (src_aglat
= plats
->aggs
; src_aglat
; src_aglat
= src_aglat
->next
)
1958 if (src_aglat
->offset
== src
->offset
)
1964 src_lat
= src_aglat
;
1967 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1978 /* A helper function that returns result of operation specified by OPCODE on
1979 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1980 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
1981 acting as its second operand. If non-NULL, RES_TYPE is expected type of
1985 get_val_across_arith_op (enum tree_code opcode
,
1988 ipcp_value
<tree
> *src_val
,
1991 tree opnd1
= src_val
->value
;
1993 /* Skip source values that is incompatible with specified type. */
1995 && !useless_type_conversion_p (opnd1_type
, TREE_TYPE (opnd1
)))
1998 return ipa_get_jf_arith_result (opcode
, opnd1
, opnd2
, res_type
);
2001 /* Propagate values through an arithmetic transformation described by a jump
2002 function associated with edge CS, taking values from SRC_LAT and putting
2003 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
2004 OPND2 is a constant value if transformation is a binary operation.
2005 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
2006 a part of the aggregate. SRC_IDX is the index of the source parameter.
2007 RES_TYPE is the value type of result being propagated into. Return true if
2008 DEST_LAT changed. */
2011 propagate_vals_across_arith_jfunc (cgraph_edge
*cs
,
2012 enum tree_code opcode
,
2015 ipcp_lattice
<tree
> *src_lat
,
2016 ipcp_lattice
<tree
> *dest_lat
,
2017 HOST_WIDE_INT src_offset
,
2021 ipcp_value
<tree
> *src_val
;
2024 /* Due to circular dependencies, propagating within an SCC through arithmetic
2025 transformation would create infinite number of values. But for
2026 self-feeding recursive function, we could allow propagation in a limited
2027 count, and this can enable a simple kind of recursive function versioning.
2028 For other scenario, we would just make lattices bottom. */
2029 if (opcode
!= NOP_EXPR
&& ipa_edge_within_scc (cs
))
2033 int max_recursive_depth
= opt_for_fn(cs
->caller
->decl
,
2034 param_ipa_cp_max_recursive_depth
);
2035 if (src_lat
!= dest_lat
|| max_recursive_depth
< 1)
2036 return dest_lat
->set_contains_variable ();
2038 /* No benefit if recursive execution is in low probability. */
2039 if (cs
->sreal_frequency () * 100
2040 <= ((sreal
) 1) * opt_for_fn (cs
->caller
->decl
,
2041 param_ipa_cp_min_recursive_probability
))
2042 return dest_lat
->set_contains_variable ();
2044 auto_vec
<ipcp_value
<tree
> *, 8> val_seeds
;
2046 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2048 /* Now we do not use self-recursively generated value as propagation
2049 source, this is absolutely conservative, but could avoid explosion
2050 of lattice's value space, especially when one recursive function
2051 calls another recursive. */
2052 if (self_recursively_generated_p (src_val
))
2054 ipcp_value_source
<tree
> *s
;
2056 /* If the lattice has already been propagated for the call site,
2057 no need to do that again. */
2058 for (s
= src_val
->sources
; s
; s
= s
->next
)
2060 return dest_lat
->set_contains_variable ();
2063 val_seeds
.safe_push (src_val
);
2066 gcc_assert ((int) val_seeds
.length () <= param_ipa_cp_value_list_size
);
2068 /* Recursively generate lattice values with a limited count. */
2069 FOR_EACH_VEC_ELT (val_seeds
, i
, src_val
)
2071 for (int j
= 1; j
< max_recursive_depth
; j
++)
2073 tree cstval
= get_val_across_arith_op (opcode
, opnd1_type
, opnd2
,
2078 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
,
2079 src_offset
, &src_val
, true);
2080 gcc_checking_assert (src_val
);
2083 ret
|= dest_lat
->set_contains_variable ();
2086 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2088 /* Now we do not use self-recursively generated value as propagation
2089 source, otherwise it is easy to make value space of normal lattice
2091 if (self_recursively_generated_p (src_val
))
2093 ret
|= dest_lat
->set_contains_variable ();
2097 tree cstval
= get_val_across_arith_op (opcode
, opnd1_type
, opnd2
,
2100 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
,
2103 ret
|= dest_lat
->set_contains_variable ();
2109 /* Propagate values through a pass-through jump function JFUNC associated with
2110 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2111 is the index of the source parameter. PARM_TYPE is the type of the
2112 parameter to which the result is passed. */
2115 propagate_vals_across_pass_through (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
2116 ipcp_lattice
<tree
> *src_lat
,
2117 ipcp_lattice
<tree
> *dest_lat
, int src_idx
,
2120 return propagate_vals_across_arith_jfunc (cs
,
2121 ipa_get_jf_pass_through_operation (jfunc
),
2123 ipa_get_jf_pass_through_operand (jfunc
),
2124 src_lat
, dest_lat
, -1, src_idx
, parm_type
);
2127 /* Propagate values through an ancestor jump function JFUNC associated with
2128 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2129 is the index of the source parameter. */
2132 propagate_vals_across_ancestor (struct cgraph_edge
*cs
,
2133 struct ipa_jump_func
*jfunc
,
2134 ipcp_lattice
<tree
> *src_lat
,
2135 ipcp_lattice
<tree
> *dest_lat
, int src_idx
)
2137 ipcp_value
<tree
> *src_val
;
2140 if (ipa_edge_within_scc (cs
))
2141 return dest_lat
->set_contains_variable ();
2143 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2145 tree t
= ipa_get_jf_ancestor_result (jfunc
, src_val
->value
);
2148 ret
|= dest_lat
->add_value (t
, cs
, src_val
, src_idx
);
2150 ret
|= dest_lat
->set_contains_variable ();
2156 /* Propagate scalar values across jump function JFUNC that is associated with
2157 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2158 parameter to which the result is passed. */
2161 propagate_scalar_across_jump_function (struct cgraph_edge
*cs
,
2162 struct ipa_jump_func
*jfunc
,
2163 ipcp_lattice
<tree
> *dest_lat
,
2166 if (dest_lat
->bottom
)
2169 if (jfunc
->type
== IPA_JF_CONST
)
2171 tree val
= ipa_get_jf_constant (jfunc
);
2172 return dest_lat
->add_value (val
, cs
, NULL
, 0);
2174 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
2175 || jfunc
->type
== IPA_JF_ANCESTOR
)
2177 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2178 ipcp_lattice
<tree
> *src_lat
;
2182 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2183 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2185 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2187 src_lat
= ipa_get_scalar_lat (caller_info
, src_idx
);
2188 if (src_lat
->bottom
)
2189 return dest_lat
->set_contains_variable ();
2191 /* If we would need to clone the caller and cannot, do not propagate. */
2192 if (!ipcp_versionable_function_p (cs
->caller
)
2193 && (src_lat
->contains_variable
2194 || (src_lat
->values_count
> 1)))
2195 return dest_lat
->set_contains_variable ();
2197 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2198 ret
= propagate_vals_across_pass_through (cs
, jfunc
, src_lat
,
2199 dest_lat
, src_idx
, param_type
);
2201 ret
= propagate_vals_across_ancestor (cs
, jfunc
, src_lat
, dest_lat
,
2204 if (src_lat
->contains_variable
)
2205 ret
|= dest_lat
->set_contains_variable ();
2210 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2211 use it for indirect inlining), we should propagate them too. */
2212 return dest_lat
->set_contains_variable ();
2215 /* Propagate scalar values across jump function JFUNC that is associated with
2216 edge CS and describes argument IDX and put the values into DEST_LAT. */
2219 propagate_context_across_jump_function (cgraph_edge
*cs
,
2220 ipa_jump_func
*jfunc
, int idx
,
2221 ipcp_lattice
<ipa_polymorphic_call_context
> *dest_lat
)
2223 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
2224 if (dest_lat
->bottom
)
2227 bool added_sth
= false;
2228 bool type_preserved
= true;
2230 ipa_polymorphic_call_context edge_ctx
, *edge_ctx_ptr
2231 = ipa_get_ith_polymorhic_call_context (args
, idx
);
2234 edge_ctx
= *edge_ctx_ptr
;
2236 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2237 || jfunc
->type
== IPA_JF_ANCESTOR
)
2239 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2241 ipcp_lattice
<ipa_polymorphic_call_context
> *src_lat
;
2243 /* TODO: Once we figure out how to propagate speculations, it will
2244 probably be a good idea to switch to speculation if type_preserved is
2245 not set instead of punting. */
2246 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2248 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
2250 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
2251 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2255 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
2256 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2259 src_lat
= ipa_get_poly_ctx_lat (caller_info
, src_idx
);
2260 /* If we would need to clone the caller and cannot, do not propagate. */
2261 if (!ipcp_versionable_function_p (cs
->caller
)
2262 && (src_lat
->contains_variable
2263 || (src_lat
->values_count
> 1)))
2266 ipcp_value
<ipa_polymorphic_call_context
> *src_val
;
2267 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
2269 ipa_polymorphic_call_context cur
= src_val
->value
;
2271 if (!type_preserved
)
2272 cur
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
2273 if (jfunc
->type
== IPA_JF_ANCESTOR
)
2274 cur
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
2275 /* TODO: In cases we know how the context is going to be used,
2276 we can improve the result by passing proper OTR_TYPE. */
2277 cur
.combine_with (edge_ctx
);
2278 if (!cur
.useless_p ())
2280 if (src_lat
->contains_variable
2281 && !edge_ctx
.equal_to (cur
))
2282 ret
|= dest_lat
->set_contains_variable ();
2283 ret
|= dest_lat
->add_value (cur
, cs
, src_val
, src_idx
);
2292 if (!edge_ctx
.useless_p ())
2293 ret
|= dest_lat
->add_value (edge_ctx
, cs
);
2295 ret
|= dest_lat
->set_contains_variable ();
2301 /* Propagate bits across jfunc that is associated with
2302 edge cs and update dest_lattice accordingly. */
2305 propagate_bits_across_jump_function (cgraph_edge
*cs
, int idx
,
2306 ipa_jump_func
*jfunc
,
2307 ipcp_bits_lattice
*dest_lattice
)
2309 if (dest_lattice
->bottom_p ())
2312 enum availability availability
;
2313 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
2314 class ipa_node_params
*callee_info
= IPA_NODE_REF (callee
);
2315 tree parm_type
= ipa_get_type (callee_info
, idx
);
2317 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2318 transform for these cases. Similarly, we can have bad type mismatches
2319 with LTO, avoid doing anything with those too. */
2321 || (!INTEGRAL_TYPE_P (parm_type
) && !POINTER_TYPE_P (parm_type
)))
2323 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2324 fprintf (dump_file
, "Setting dest_lattice to bottom, because type of "
2325 "param %i of %s is NULL or unsuitable for bits propagation\n",
2326 idx
, cs
->callee
->dump_name ());
2328 return dest_lattice
->set_to_bottom ();
2331 unsigned precision
= TYPE_PRECISION (parm_type
);
2332 signop sgn
= TYPE_SIGN (parm_type
);
2334 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2335 || jfunc
->type
== IPA_JF_ANCESTOR
)
2337 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2338 tree operand
= NULL_TREE
;
2339 enum tree_code code
;
2342 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2344 code
= ipa_get_jf_pass_through_operation (jfunc
);
2345 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2346 if (code
!= NOP_EXPR
)
2347 operand
= ipa_get_jf_pass_through_operand (jfunc
);
2351 code
= POINTER_PLUS_EXPR
;
2352 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2353 unsigned HOST_WIDE_INT offset
= ipa_get_jf_ancestor_offset (jfunc
) / BITS_PER_UNIT
;
2354 operand
= build_int_cstu (size_type_node
, offset
);
2357 class ipcp_param_lattices
*src_lats
2358 = ipa_get_parm_lattices (caller_info
, src_idx
);
2360 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2366 Assume lattice for x is bottom, however we can still propagate
2367 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2368 and we store it in jump function during analysis stage. */
2370 if (src_lats
->bits_lattice
.bottom_p ()
2372 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
2375 return dest_lattice
->meet_with (src_lats
->bits_lattice
, precision
, sgn
,
2379 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
2380 return dest_lattice
->set_to_bottom ();
2381 else if (jfunc
->bits
)
2382 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
2385 return dest_lattice
->set_to_bottom ();
2388 /* Propagate value range across jump function JFUNC that is associated with
2389 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2393 propagate_vr_across_jump_function (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
2394 class ipcp_param_lattices
*dest_plats
,
2397 ipcp_vr_lattice
*dest_lat
= &dest_plats
->m_value_range
;
2399 if (dest_lat
->bottom_p ())
2403 || (!INTEGRAL_TYPE_P (param_type
)
2404 && !POINTER_TYPE_P (param_type
)))
2405 return dest_lat
->set_to_bottom ();
2407 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
2409 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
2410 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2411 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2412 class ipcp_param_lattices
*src_lats
2413 = ipa_get_parm_lattices (caller_info
, src_idx
);
2414 tree operand_type
= ipa_get_type (caller_info
, src_idx
);
2416 if (src_lats
->m_value_range
.bottom_p ())
2417 return dest_lat
->set_to_bottom ();
2420 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
2421 ipa_vr_operation_and_type_effects (&vr
,
2422 &src_lats
->m_value_range
.m_vr
,
2423 operation
, param_type
,
2425 /* A crude way to prevent unbounded number of value range updates
2426 in SCC components. We should allow limited number of updates within
2428 else if (!ipa_edge_within_scc (cs
))
2430 tree op
= ipa_get_jf_pass_through_operand (jfunc
);
2431 value_range
op_vr (op
, op
);
2432 value_range op_res
,res
;
2434 range_fold_binary_expr (&op_res
, operation
, operand_type
,
2435 &src_lats
->m_value_range
.m_vr
, &op_vr
);
2436 ipa_vr_operation_and_type_effects (&vr
,
2438 NOP_EXPR
, param_type
,
2441 if (!vr
.undefined_p () && !vr
.varying_p ())
2446 if (ipa_vr_operation_and_type_effects (&jvr
, jfunc
->m_vr
,
2449 jfunc
->m_vr
->type ()))
2452 return dest_lat
->meet_with (&vr
);
2455 else if (jfunc
->type
== IPA_JF_CONST
)
2457 tree val
= ipa_get_jf_constant (jfunc
);
2458 if (TREE_CODE (val
) == INTEGER_CST
)
2460 val
= fold_convert (param_type
, val
);
2461 if (TREE_OVERFLOW_P (val
))
2462 val
= drop_tree_overflow (val
);
2464 value_range
tmpvr (val
, val
);
2465 return dest_lat
->meet_with (&tmpvr
);
2471 && ipa_vr_operation_and_type_effects (&vr
, jfunc
->m_vr
, NOP_EXPR
,
2473 jfunc
->m_vr
->type ()))
2474 return dest_lat
->meet_with (&vr
);
2476 return dest_lat
->set_to_bottom ();
2479 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2480 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2481 other cases, return false). If there are no aggregate items, set
2482 aggs_by_ref to NEW_AGGS_BY_REF. */
2485 set_check_aggs_by_ref (class ipcp_param_lattices
*dest_plats
,
2486 bool new_aggs_by_ref
)
2488 if (dest_plats
->aggs
)
2490 if (dest_plats
->aggs_by_ref
!= new_aggs_by_ref
)
2492 set_agg_lats_to_bottom (dest_plats
);
2497 dest_plats
->aggs_by_ref
= new_aggs_by_ref
;
2501 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2502 already existing lattice for the given OFFSET and SIZE, marking all skipped
2503 lattices as containing variable and checking for overlaps. If there is no
2504 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2505 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2506 unless there are too many already. If there are two many, return false. If
2507 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2508 skipped lattices were newly marked as containing variable, set *CHANGE to
2509 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2512 merge_agg_lats_step (class ipcp_param_lattices
*dest_plats
,
2513 HOST_WIDE_INT offset
, HOST_WIDE_INT val_size
,
2514 struct ipcp_agg_lattice
***aglat
,
2515 bool pre_existing
, bool *change
, int max_agg_items
)
2517 gcc_checking_assert (offset
>= 0);
2519 while (**aglat
&& (**aglat
)->offset
< offset
)
2521 if ((**aglat
)->offset
+ (**aglat
)->size
> offset
)
2523 set_agg_lats_to_bottom (dest_plats
);
2526 *change
|= (**aglat
)->set_contains_variable ();
2527 *aglat
= &(**aglat
)->next
;
2530 if (**aglat
&& (**aglat
)->offset
== offset
)
2532 if ((**aglat
)->size
!= val_size
)
2534 set_agg_lats_to_bottom (dest_plats
);
2537 gcc_assert (!(**aglat
)->next
2538 || (**aglat
)->next
->offset
>= offset
+ val_size
);
2543 struct ipcp_agg_lattice
*new_al
;
2545 if (**aglat
&& (**aglat
)->offset
< offset
+ val_size
)
2547 set_agg_lats_to_bottom (dest_plats
);
2550 if (dest_plats
->aggs_count
== max_agg_items
)
2552 dest_plats
->aggs_count
++;
2553 new_al
= ipcp_agg_lattice_pool
.allocate ();
2554 memset (new_al
, 0, sizeof (*new_al
));
2556 new_al
->offset
= offset
;
2557 new_al
->size
= val_size
;
2558 new_al
->contains_variable
= pre_existing
;
2560 new_al
->next
= **aglat
;
2566 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2567 containing an unknown value. */
2570 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice
*aglat
)
2575 ret
|= aglat
->set_contains_variable ();
2576 aglat
= aglat
->next
;
2581 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2582 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2583 parameter used for lattice value sources. Return true if DEST_PLATS changed
2587 merge_aggregate_lattices (struct cgraph_edge
*cs
,
2588 class ipcp_param_lattices
*dest_plats
,
2589 class ipcp_param_lattices
*src_plats
,
2590 int src_idx
, HOST_WIDE_INT offset_delta
)
2592 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2593 struct ipcp_agg_lattice
**dst_aglat
;
2596 if (set_check_aggs_by_ref (dest_plats
, src_plats
->aggs_by_ref
))
2598 if (src_plats
->aggs_bottom
)
2599 return set_agg_lats_contain_variable (dest_plats
);
2600 if (src_plats
->aggs_contain_variable
)
2601 ret
|= set_agg_lats_contain_variable (dest_plats
);
2602 dst_aglat
= &dest_plats
->aggs
;
2604 int max_agg_items
= opt_for_fn (cs
->callee
->function_symbol ()->decl
,
2605 param_ipa_max_agg_items
);
2606 for (struct ipcp_agg_lattice
*src_aglat
= src_plats
->aggs
;
2608 src_aglat
= src_aglat
->next
)
2610 HOST_WIDE_INT new_offset
= src_aglat
->offset
- offset_delta
;
2614 if (merge_agg_lats_step (dest_plats
, new_offset
, src_aglat
->size
,
2615 &dst_aglat
, pre_existing
, &ret
, max_agg_items
))
2617 struct ipcp_agg_lattice
*new_al
= *dst_aglat
;
2619 dst_aglat
= &(*dst_aglat
)->next
;
2620 if (src_aglat
->bottom
)
2622 ret
|= new_al
->set_contains_variable ();
2625 if (src_aglat
->contains_variable
)
2626 ret
|= new_al
->set_contains_variable ();
2627 for (ipcp_value
<tree
> *val
= src_aglat
->values
;
2630 ret
|= new_al
->add_value (val
->value
, cs
, val
, src_idx
,
2633 else if (dest_plats
->aggs_bottom
)
2636 ret
|= set_chain_of_aglats_contains_variable (*dst_aglat
);
2640 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2641 pass-through JFUNC and if so, whether it has conform and conforms to the
2642 rules about propagating values passed by reference. */
2645 agg_pass_through_permissible_p (class ipcp_param_lattices
*src_plats
,
2646 struct ipa_jump_func
*jfunc
)
2648 return src_plats
->aggs
2649 && (!src_plats
->aggs_by_ref
2650 || ipa_get_jf_pass_through_agg_preserved (jfunc
));
2653 /* Propagate values through ITEM, jump function for a part of an aggregate,
2654 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2655 associated with the jump function. Return true if AGLAT changed in any
2659 propagate_aggregate_lattice (struct cgraph_edge
*cs
,
2660 struct ipa_agg_jf_item
*item
,
2661 struct ipcp_agg_lattice
*aglat
)
2663 class ipa_node_params
*caller_info
;
2664 class ipcp_param_lattices
*src_plats
;
2665 struct ipcp_lattice
<tree
> *src_lat
;
2666 HOST_WIDE_INT src_offset
;
2671 if (item
->jftype
== IPA_JF_CONST
)
2673 tree value
= item
->value
.constant
;
2675 gcc_checking_assert (is_gimple_ip_invariant (value
));
2676 return aglat
->add_value (value
, cs
, NULL
, 0);
2679 gcc_checking_assert (item
->jftype
== IPA_JF_PASS_THROUGH
2680 || item
->jftype
== IPA_JF_LOAD_AGG
);
2682 caller_info
= IPA_NODE_REF (cs
->caller
);
2683 src_idx
= item
->value
.pass_through
.formal_id
;
2684 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2686 if (item
->jftype
== IPA_JF_PASS_THROUGH
)
2688 load_type
= NULL_TREE
;
2689 src_lat
= &src_plats
->itself
;
2694 HOST_WIDE_INT load_offset
= item
->value
.load_agg
.offset
;
2695 struct ipcp_agg_lattice
*src_aglat
;
2697 for (src_aglat
= src_plats
->aggs
; src_aglat
; src_aglat
= src_aglat
->next
)
2698 if (src_aglat
->offset
>= load_offset
)
2701 load_type
= item
->value
.load_agg
.type
;
2703 || src_aglat
->offset
> load_offset
2704 || src_aglat
->size
!= tree_to_shwi (TYPE_SIZE (load_type
))
2705 || src_plats
->aggs_by_ref
!= item
->value
.load_agg
.by_ref
)
2706 return aglat
->set_contains_variable ();
2708 src_lat
= src_aglat
;
2709 src_offset
= load_offset
;
2713 || (!ipcp_versionable_function_p (cs
->caller
)
2714 && !src_lat
->is_single_const ()))
2715 return aglat
->set_contains_variable ();
2717 ret
= propagate_vals_across_arith_jfunc (cs
,
2718 item
->value
.pass_through
.operation
,
2720 item
->value
.pass_through
.operand
,
2726 if (src_lat
->contains_variable
)
2727 ret
|= aglat
->set_contains_variable ();
2732 /* Propagate scalar values across jump function JFUNC that is associated with
2733 edge CS and put the values into DEST_LAT. */
2736 propagate_aggs_across_jump_function (struct cgraph_edge
*cs
,
2737 struct ipa_jump_func
*jfunc
,
2738 class ipcp_param_lattices
*dest_plats
)
2742 if (dest_plats
->aggs_bottom
)
2745 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2746 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
2748 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2749 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2750 class ipcp_param_lattices
*src_plats
;
2752 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2753 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
2755 /* Currently we do not produce clobber aggregate jump
2756 functions, replace with merging when we do. */
2757 gcc_assert (!jfunc
->agg
.items
);
2758 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
,
2763 else if (jfunc
->type
== IPA_JF_ANCESTOR
2764 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
2766 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2767 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2768 class ipcp_param_lattices
*src_plats
;
2770 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2771 if (src_plats
->aggs
&& src_plats
->aggs_by_ref
)
2773 /* Currently we do not produce clobber aggregate jump
2774 functions, replace with merging when we do. */
2775 gcc_assert (!jfunc
->agg
.items
);
2776 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
, src_idx
,
2777 ipa_get_jf_ancestor_offset (jfunc
));
2779 else if (!src_plats
->aggs_by_ref
)
2780 ret
|= set_agg_lats_to_bottom (dest_plats
);
2782 ret
|= set_agg_lats_contain_variable (dest_plats
);
2786 if (jfunc
->agg
.items
)
2788 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2789 struct ipcp_agg_lattice
**aglat
= &dest_plats
->aggs
;
2790 struct ipa_agg_jf_item
*item
;
2793 if (set_check_aggs_by_ref (dest_plats
, jfunc
->agg
.by_ref
))
2796 int max_agg_items
= opt_for_fn (cs
->callee
->function_symbol ()->decl
,
2797 param_ipa_max_agg_items
);
2798 FOR_EACH_VEC_ELT (*jfunc
->agg
.items
, i
, item
)
2800 HOST_WIDE_INT val_size
;
2802 if (item
->offset
< 0 || item
->jftype
== IPA_JF_UNKNOWN
)
2804 val_size
= tree_to_shwi (TYPE_SIZE (item
->type
));
2806 if (merge_agg_lats_step (dest_plats
, item
->offset
, val_size
,
2807 &aglat
, pre_existing
, &ret
, max_agg_items
))
2809 ret
|= propagate_aggregate_lattice (cs
, item
, *aglat
);
2810 aglat
= &(*aglat
)->next
;
2812 else if (dest_plats
->aggs_bottom
)
2816 ret
|= set_chain_of_aglats_contains_variable (*aglat
);
2819 ret
|= set_agg_lats_contain_variable (dest_plats
);
2824 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2825 non-thunk) destination, the call passes through a thunk. */
2828 call_passes_through_thunk (cgraph_edge
*cs
)
2830 cgraph_node
*alias_or_thunk
= cs
->callee
;
2831 while (alias_or_thunk
->alias
)
2832 alias_or_thunk
= alias_or_thunk
->get_alias_target ();
2833 return alias_or_thunk
->thunk
;
2836 /* Propagate constants from the caller to the callee of CS. INFO describes the
2840 propagate_constants_across_call (struct cgraph_edge
*cs
)
2842 class ipa_node_params
*callee_info
;
2843 enum availability availability
;
2844 cgraph_node
*callee
;
2845 class ipa_edge_args
*args
;
2847 int i
, args_count
, parms_count
;
2849 callee
= cs
->callee
->function_symbol (&availability
);
2850 if (!callee
->definition
)
2852 gcc_checking_assert (callee
->has_gimple_body_p ());
2853 callee_info
= IPA_NODE_REF (callee
);
2857 args
= IPA_EDGE_REF (cs
);
2858 parms_count
= ipa_get_param_count (callee_info
);
2859 if (parms_count
== 0)
2862 || !opt_for_fn (cs
->caller
->decl
, flag_ipa_cp
)
2863 || !opt_for_fn (cs
->caller
->decl
, optimize
))
2865 for (i
= 0; i
< parms_count
; i
++)
2866 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2870 args_count
= ipa_get_cs_argument_count (args
);
2872 /* If this call goes through a thunk we must not propagate to the first (0th)
2873 parameter. However, we might need to uncover a thunk from below a series
2874 of aliases first. */
2875 if (call_passes_through_thunk (cs
))
2877 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2884 for (; (i
< args_count
) && (i
< parms_count
); i
++)
2886 struct ipa_jump_func
*jump_func
= ipa_get_ith_jump_func (args
, i
);
2887 class ipcp_param_lattices
*dest_plats
;
2888 tree param_type
= ipa_get_type (callee_info
, i
);
2890 dest_plats
= ipa_get_parm_lattices (callee_info
, i
);
2891 if (availability
== AVAIL_INTERPOSABLE
)
2892 ret
|= set_all_contains_variable (dest_plats
);
2895 ret
|= propagate_scalar_across_jump_function (cs
, jump_func
,
2896 &dest_plats
->itself
,
2898 ret
|= propagate_context_across_jump_function (cs
, jump_func
, i
,
2899 &dest_plats
->ctxlat
);
2901 |= propagate_bits_across_jump_function (cs
, i
, jump_func
,
2902 &dest_plats
->bits_lattice
);
2903 ret
|= propagate_aggs_across_jump_function (cs
, jump_func
,
2905 if (opt_for_fn (callee
->decl
, flag_ipa_vrp
))
2906 ret
|= propagate_vr_across_jump_function (cs
, jump_func
,
2907 dest_plats
, param_type
);
2909 ret
|= dest_plats
->m_value_range
.set_to_bottom ();
2912 for (; i
< parms_count
; i
++)
2913 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
, i
));
2918 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2919 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2920 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2923 ipa_get_indirect_edge_target_1 (struct cgraph_edge
*ie
,
2924 vec
<tree
> known_csts
,
2925 vec
<ipa_polymorphic_call_context
> known_contexts
,
2926 vec
<ipa_agg_value_set
> known_aggs
,
2927 struct ipa_agg_replacement_value
*agg_reps
,
2930 int param_index
= ie
->indirect_info
->param_index
;
2931 HOST_WIDE_INT anc_offset
;
2935 *speculative
= false;
2937 if (param_index
== -1)
2940 if (!ie
->indirect_info
->polymorphic
)
2944 if (ie
->indirect_info
->agg_contents
)
2947 if (agg_reps
&& ie
->indirect_info
->guaranteed_unmodified
)
2951 if (agg_reps
->index
== param_index
2952 && agg_reps
->offset
== ie
->indirect_info
->offset
2953 && agg_reps
->by_ref
== ie
->indirect_info
->by_ref
)
2955 t
= agg_reps
->value
;
2958 agg_reps
= agg_reps
->next
;
2963 struct ipa_agg_value_set
*agg
;
2964 if (known_aggs
.length () > (unsigned int) param_index
)
2965 agg
= &known_aggs
[param_index
];
2968 bool from_global_constant
;
2969 t
= ipa_find_agg_cst_for_param (agg
,
2970 (unsigned) param_index
2971 < known_csts
.length ()
2972 ? known_csts
[param_index
]
2974 ie
->indirect_info
->offset
,
2975 ie
->indirect_info
->by_ref
,
2976 &from_global_constant
);
2978 && !from_global_constant
2979 && !ie
->indirect_info
->guaranteed_unmodified
)
2983 else if ((unsigned) param_index
< known_csts
.length ())
2984 t
= known_csts
[param_index
];
2987 && TREE_CODE (t
) == ADDR_EXPR
2988 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
)
2989 return TREE_OPERAND (t
, 0);
2994 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
2997 gcc_assert (!ie
->indirect_info
->agg_contents
);
2998 anc_offset
= ie
->indirect_info
->offset
;
3002 /* Try to work out value of virtual table pointer value in replacements. */
3003 if (!t
&& agg_reps
&& !ie
->indirect_info
->by_ref
)
3007 if (agg_reps
->index
== param_index
3008 && agg_reps
->offset
== ie
->indirect_info
->offset
3009 && agg_reps
->by_ref
)
3011 t
= agg_reps
->value
;
3014 agg_reps
= agg_reps
->next
;
3018 /* Try to work out value of virtual table pointer value in known
3019 aggregate values. */
3020 if (!t
&& known_aggs
.length () > (unsigned int) param_index
3021 && !ie
->indirect_info
->by_ref
)
3023 struct ipa_agg_value_set
*agg
= &known_aggs
[param_index
];
3024 t
= ipa_find_agg_cst_for_param (agg
,
3025 (unsigned) param_index
3026 < known_csts
.length ()
3027 ? known_csts
[param_index
] : NULL
,
3028 ie
->indirect_info
->offset
, true);
3031 /* If we found the virtual table pointer, lookup the target. */
3035 unsigned HOST_WIDE_INT offset
;
3036 if (vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
3039 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
3040 vtable
, offset
, &can_refer
);
3044 || fndecl_built_in_p (target
, BUILT_IN_UNREACHABLE
)
3045 || !possible_polymorphic_call_target_p
3046 (ie
, cgraph_node::get (target
)))
3048 /* Do not speculate builtin_unreachable, it is stupid! */
3049 if (ie
->indirect_info
->vptr_changed
)
3051 target
= ipa_impossible_devirt_target (ie
, target
);
3053 *speculative
= ie
->indirect_info
->vptr_changed
;
3060 /* Do we know the constant value of pointer? */
3061 if (!t
&& (unsigned) param_index
< known_csts
.length ())
3062 t
= known_csts
[param_index
];
3064 gcc_checking_assert (!t
|| TREE_CODE (t
) != TREE_BINFO
);
3066 ipa_polymorphic_call_context context
;
3067 if (known_contexts
.length () > (unsigned int) param_index
)
3069 context
= known_contexts
[param_index
];
3070 context
.offset_by (anc_offset
);
3071 if (ie
->indirect_info
->vptr_changed
)
3072 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3073 ie
->indirect_info
->otr_type
);
3076 ipa_polymorphic_call_context ctx2
= ipa_polymorphic_call_context
3077 (t
, ie
->indirect_info
->otr_type
, anc_offset
);
3078 if (!ctx2
.useless_p ())
3079 context
.combine_with (ctx2
, ie
->indirect_info
->otr_type
);
3084 context
= ipa_polymorphic_call_context (t
, ie
->indirect_info
->otr_type
,
3086 if (ie
->indirect_info
->vptr_changed
)
3087 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
3088 ie
->indirect_info
->otr_type
);
3093 vec
<cgraph_node
*>targets
;
3096 targets
= possible_polymorphic_call_targets
3097 (ie
->indirect_info
->otr_type
,
3098 ie
->indirect_info
->otr_token
,
3100 if (!final
|| targets
.length () > 1)
3102 struct cgraph_node
*node
;
3105 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
3106 || ie
->speculative
|| !ie
->maybe_hot_p ())
3108 node
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
3109 ie
->indirect_info
->otr_token
,
3113 *speculative
= true;
3114 target
= node
->decl
;
3121 *speculative
= false;
3122 if (targets
.length () == 1)
3123 target
= targets
[0]->decl
;
3125 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
3128 if (target
&& !possible_polymorphic_call_target_p (ie
,
3129 cgraph_node::get (target
)))
3133 target
= ipa_impossible_devirt_target (ie
, target
);
3139 /* If an indirect edge IE can be turned into a direct one based on data in
3140 AVALS, return the destination. Store into *SPECULATIVE a boolean determinig
3141 whether the discovered target is only speculative guess. */
3144 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
3145 ipa_call_arg_values
*avals
,
3148 return ipa_get_indirect_edge_target_1 (ie
, avals
->m_known_vals
,
3149 avals
->m_known_contexts
,
3150 avals
->m_known_aggs
,
3154 /* The same functionality as above overloaded for ipa_auto_call_arg_values. */
3157 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
3158 ipa_auto_call_arg_values
*avals
,
3161 return ipa_get_indirect_edge_target_1 (ie
, avals
->m_known_vals
,
3162 avals
->m_known_contexts
,
3163 avals
->m_known_aggs
,
3167 /* Calculate devirtualization time bonus for NODE, assuming we know information
3168 about arguments stored in AVALS. */
3171 devirtualization_time_bonus (struct cgraph_node
*node
,
3172 ipa_auto_call_arg_values
*avals
)
3174 struct cgraph_edge
*ie
;
3177 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
3179 struct cgraph_node
*callee
;
3180 class ipa_fn_summary
*isummary
;
3181 enum availability avail
;
3185 target
= ipa_get_indirect_edge_target (ie
, avals
, &speculative
);
3189 /* Only bare minimum benefit for clearly un-inlineable targets. */
3191 callee
= cgraph_node::get (target
);
3192 if (!callee
|| !callee
->definition
)
3194 callee
= callee
->function_symbol (&avail
);
3195 if (avail
< AVAIL_AVAILABLE
)
3197 isummary
= ipa_fn_summaries
->get (callee
);
3198 if (!isummary
|| !isummary
->inlinable
)
3201 int size
= ipa_size_summaries
->get (callee
)->size
;
3202 /* FIXME: The values below need re-considering and perhaps also
3203 integrating into the cost metrics, at lest in some very basic way. */
3204 int max_inline_insns_auto
3205 = opt_for_fn (callee
->decl
, param_max_inline_insns_auto
);
3206 if (size
<= max_inline_insns_auto
/ 4)
3207 res
+= 31 / ((int)speculative
+ 1);
3208 else if (size
<= max_inline_insns_auto
/ 2)
3209 res
+= 15 / ((int)speculative
+ 1);
3210 else if (size
<= max_inline_insns_auto
3211 || DECL_DECLARED_INLINE_P (callee
->decl
))
3212 res
+= 7 / ((int)speculative
+ 1);
3218 /* Return time bonus incurred because of hints stored in ESTIMATES. */
3221 hint_time_bonus (cgraph_node
*node
, const ipa_call_estimates
&estimates
)
3224 ipa_hints hints
= estimates
.hints
;
3225 if (hints
& (INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride
))
3226 result
+= opt_for_fn (node
->decl
, param_ipa_cp_loop_hint_bonus
);
3228 sreal bonus_for_one
= opt_for_fn (node
->decl
, param_ipa_cp_loop_hint_bonus
);
3230 if (hints
& INLINE_HINT_loop_iterations
)
3231 result
+= (estimates
.loops_with_known_iterations
* bonus_for_one
).to_int ();
3233 if (hints
& INLINE_HINT_loop_stride
)
3234 result
+= (estimates
.loops_with_known_strides
* bonus_for_one
).to_int ();
3239 /* If there is a reason to penalize the function described by INFO in the
3240 cloning goodness evaluation, do so. */
3243 incorporate_penalties (cgraph_node
*node
, ipa_node_params
*info
,
3246 if (info
->node_within_scc
&& !info
->node_is_self_scc
)
3247 evaluation
= (evaluation
3248 * (100 - opt_for_fn (node
->decl
,
3249 param_ipa_cp_recursion_penalty
))) / 100;
3251 if (info
->node_calling_single_call
)
3252 evaluation
= (evaluation
3253 * (100 - opt_for_fn (node
->decl
,
3254 param_ipa_cp_single_call_penalty
)))
3260 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3261 and SIZE_COST and with the sum of frequencies of incoming edges to the
3262 potential new clone in FREQUENCIES. */
3265 good_cloning_opportunity_p (struct cgraph_node
*node
, sreal time_benefit
,
3266 sreal freq_sum
, profile_count count_sum
,
3269 if (time_benefit
== 0
3270 || !opt_for_fn (node
->decl
, flag_ipa_cp_clone
)
3271 || node
->optimize_for_size_p ())
3274 gcc_assert (size_cost
> 0);
3275 if (size_cost
== INT_MAX
)
3277 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3278 fprintf (dump_file
, " good_cloning_opportunity_p returning "
3279 "false because of size overflow.\n");
3283 class ipa_node_params
*info
= IPA_NODE_REF (node
);
3284 int eval_threshold
= opt_for_fn (node
->decl
, param_ipa_cp_eval_threshold
);
3285 if (max_count
> profile_count::zero ())
3288 sreal factor
= count_sum
.probability_in (max_count
).to_sreal ();
3289 sreal evaluation
= (time_benefit
* factor
) / size_cost
;
3290 evaluation
= incorporate_penalties (node
, info
, evaluation
);
3293 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3295 fprintf (dump_file
, " good_cloning_opportunity_p (time: %g, "
3296 "size: %i, count_sum: ", time_benefit
.to_double (),
3298 count_sum
.dump (dump_file
);
3299 fprintf (dump_file
, "%s%s) -> evaluation: %.2f, threshold: %i\n",
3300 info
->node_within_scc
3301 ? (info
->node_is_self_scc
? ", self_scc" : ", scc") : "",
3302 info
->node_calling_single_call
? ", single_call" : "",
3303 evaluation
.to_double (), eval_threshold
);
3306 return evaluation
.to_int () >= eval_threshold
;
3310 sreal evaluation
= (time_benefit
* freq_sum
) / size_cost
;
3311 evaluation
= incorporate_penalties (node
, info
, evaluation
);
3314 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3315 fprintf (dump_file
, " good_cloning_opportunity_p (time: %g, "
3316 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
3318 time_benefit
.to_double (), size_cost
, freq_sum
.to_double (),
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
);
3324 return evaluation
.to_int () >= eval_threshold
;
3328 /* Return all context independent values from aggregate lattices in PLATS in a
3329 vector. Return NULL if there are none. */
3331 static vec
<ipa_agg_value
>
3332 context_independent_aggregate_values (class ipcp_param_lattices
*plats
)
3334 vec
<ipa_agg_value
> res
= vNULL
;
3336 if (plats
->aggs_bottom
3337 || plats
->aggs_contain_variable
3338 || plats
->aggs_count
== 0)
3341 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
;
3343 aglat
= aglat
->next
)
3344 if (aglat
->is_single_const ())
3346 struct ipa_agg_value item
;
3347 item
.offset
= aglat
->offset
;
3348 item
.value
= aglat
->values
->value
;
3349 res
.safe_push (item
);
3354 /* Grow vectors in AVALS and fill them with information about values of
3355 parameters that are known to be independent of the context. Only calculate
3356 m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If
3357 REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
3358 parameters will be stored in it.
3360 TODO: Also grow context independent value range vectors. */
3363 gather_context_independent_values (class ipa_node_params
*info
,
3364 ipa_auto_call_arg_values
*avals
,
3365 bool calculate_aggs
,
3366 int *removable_params_cost
)
3368 int i
, count
= ipa_get_param_count (info
);
3371 avals
->m_known_vals
.safe_grow_cleared (count
, true);
3372 avals
->m_known_contexts
.safe_grow_cleared (count
, true);
3374 avals
->m_known_aggs
.safe_grow_cleared (count
, true);
3376 if (removable_params_cost
)
3377 *removable_params_cost
= 0;
3379 for (i
= 0; i
< count
; i
++)
3381 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3382 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3384 if (lat
->is_single_const ())
3386 ipcp_value
<tree
> *val
= lat
->values
;
3387 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
3388 avals
->m_known_vals
[i
] = val
->value
;
3389 if (removable_params_cost
)
3390 *removable_params_cost
3391 += estimate_move_cost (TREE_TYPE (val
->value
), false);
3394 else if (removable_params_cost
3395 && !ipa_is_param_used (info
, i
))
3396 *removable_params_cost
3397 += ipa_get_param_move_cost (info
, i
);
3399 if (!ipa_is_param_used (info
, i
))
3402 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3403 /* Do not account known context as reason for cloning. We can see
3404 if it permits devirtualization. */
3405 if (ctxlat
->is_single_const ())
3406 avals
->m_known_contexts
[i
] = ctxlat
->values
->value
;
3410 vec
<ipa_agg_value
> agg_items
;
3411 struct ipa_agg_value_set
*agg
;
3413 agg_items
= context_independent_aggregate_values (plats
);
3414 agg
= &avals
->m_known_aggs
[i
];
3415 agg
->items
= agg_items
;
3416 agg
->by_ref
= plats
->aggs_by_ref
;
3417 ret
|= !agg_items
.is_empty ();
3424 /* Perform time and size measurement of NODE with the context given in AVALS,
3425 calculate the benefit compared to the node without specialization and store
3426 it into VAL. Take into account REMOVABLE_PARAMS_COST of all
3427 context-independent or unused removable parameters and EST_MOVE_COST, the
3428 estimated movement of the considered parameter. */
3431 perform_estimation_of_a_value (cgraph_node
*node
,
3432 ipa_auto_call_arg_values
*avals
,
3433 int removable_params_cost
, int est_move_cost
,
3434 ipcp_value_base
*val
)
3437 ipa_call_estimates estimates
;
3439 estimate_ipcp_clone_size_and_time (node
, avals
, &estimates
);
3441 /* Extern inline functions have no cloning local time benefits because they
3442 will be inlined anyway. The only reason to clone them is if it enables
3443 optimization in any of the functions they call. */
3444 if (DECL_EXTERNAL (node
->decl
) && DECL_DECLARED_INLINE_P (node
->decl
))
3447 time_benefit
= (estimates
.nonspecialized_time
- estimates
.time
)
3448 + (devirtualization_time_bonus (node
, avals
)
3449 + hint_time_bonus (node
, estimates
)
3450 + removable_params_cost
+ est_move_cost
);
3452 int size
= estimates
.size
;
3453 gcc_checking_assert (size
>=0);
3454 /* The inliner-heuristics based estimates may think that in certain
3455 contexts some functions do not have any size at all but we want
3456 all specializations to have at least a tiny cost, not least not to
3461 val
->local_time_benefit
= time_benefit
;
3462 val
->local_size_cost
= size
;
3465 /* Get the overall limit oof growth based on parameters extracted from growth.
3466 it does not really make sense to mix functions with different overall growth
3467 limits but it is possible and if it happens, we do not want to select one
3471 get_max_overall_size (cgraph_node
*node
)
3473 long max_new_size
= orig_overall_size
;
3474 long large_unit
= opt_for_fn (node
->decl
, param_ipa_cp_large_unit_insns
);
3475 if (max_new_size
< large_unit
)
3476 max_new_size
= large_unit
;
3477 int unit_growth
= opt_for_fn (node
->decl
, param_ipa_cp_unit_growth
);
3478 max_new_size
+= max_new_size
* unit_growth
/ 100 + 1;
3479 return max_new_size
;
3482 /* Iterate over known values of parameters of NODE and estimate the local
3483 effects in terms of time and size they have. */
3486 estimate_local_effects (struct cgraph_node
*node
)
3488 class ipa_node_params
*info
= IPA_NODE_REF (node
);
3489 int i
, count
= ipa_get_param_count (info
);
3491 int removable_params_cost
;
3493 if (!count
|| !ipcp_versionable_function_p (node
))
3496 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3497 fprintf (dump_file
, "\nEstimating effects for %s.\n", node
->dump_name ());
3499 ipa_auto_call_arg_values avals
;
3500 always_const
= gather_context_independent_values (info
, &avals
, true,
3501 &removable_params_cost
);
3502 int devirt_bonus
= devirtualization_time_bonus (node
, &avals
);
3503 if (always_const
|| devirt_bonus
3504 || (removable_params_cost
&& node
->can_change_signature
))
3506 struct caller_statistics stats
;
3507 ipa_call_estimates estimates
;
3509 init_caller_stats (&stats
);
3510 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3512 estimate_ipcp_clone_size_and_time (node
, &avals
, &estimates
);
3513 sreal time
= estimates
.nonspecialized_time
- estimates
.time
;
3514 time
+= devirt_bonus
;
3515 time
+= hint_time_bonus (node
, estimates
);
3516 time
+= removable_params_cost
;
3517 int size
= estimates
.size
- stats
.n_calls
* removable_params_cost
;
3520 fprintf (dump_file
, " - context independent values, size: %i, "
3521 "time_benefit: %f\n", size
, (time
).to_double ());
3523 if (size
<= 0 || node
->local
)
3525 info
->do_clone_for_all_contexts
= true;
3528 fprintf (dump_file
, " Decided to specialize for all "
3529 "known contexts, code not going to grow.\n");
3531 else if (good_cloning_opportunity_p (node
, time
, stats
.freq_sum
,
3532 stats
.count_sum
, size
))
3534 if (size
+ overall_size
<= get_max_overall_size (node
))
3536 info
->do_clone_for_all_contexts
= true;
3537 overall_size
+= size
;
3540 fprintf (dump_file
, " Decided to specialize for all "
3541 "known contexts, growth (to %li) deemed "
3542 "beneficial.\n", overall_size
);
3544 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3545 fprintf (dump_file
, " Not cloning for all contexts because "
3546 "maximum unit size would be reached with %li.\n",
3547 size
+ overall_size
);
3549 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3550 fprintf (dump_file
, " Not cloning for all contexts because "
3551 "!good_cloning_opportunity_p.\n");
3555 for (i
= 0; i
< count
; i
++)
3557 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3558 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3559 ipcp_value
<tree
> *val
;
3563 || avals
.m_known_vals
[i
])
3566 for (val
= lat
->values
; val
; val
= val
->next
)
3568 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
3569 avals
.m_known_vals
[i
] = val
->value
;
3571 int emc
= estimate_move_cost (TREE_TYPE (val
->value
), true);
3572 perform_estimation_of_a_value (node
, &avals
, removable_params_cost
,
3575 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3577 fprintf (dump_file
, " - estimates for value ");
3578 print_ipcp_constant_value (dump_file
, val
->value
);
3579 fprintf (dump_file
, " for ");
3580 ipa_dump_param (dump_file
, info
, i
);
3581 fprintf (dump_file
, ": time_benefit: %g, size: %i\n",
3582 val
->local_time_benefit
.to_double (),
3583 val
->local_size_cost
);
3586 avals
.m_known_vals
[i
] = NULL_TREE
;
3589 for (i
= 0; i
< count
; i
++)
3591 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3593 if (!plats
->virt_call
)
3596 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3597 ipcp_value
<ipa_polymorphic_call_context
> *val
;
3601 || !avals
.m_known_contexts
[i
].useless_p ())
3604 for (val
= ctxlat
->values
; val
; val
= val
->next
)
3606 avals
.m_known_contexts
[i
] = val
->value
;
3607 perform_estimation_of_a_value (node
, &avals
, removable_params_cost
,
3610 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3612 fprintf (dump_file
, " - estimates for polymorphic context ");
3613 print_ipcp_constant_value (dump_file
, val
->value
);
3614 fprintf (dump_file
, " for ");
3615 ipa_dump_param (dump_file
, info
, i
);
3616 fprintf (dump_file
, ": time_benefit: %g, size: %i\n",
3617 val
->local_time_benefit
.to_double (),
3618 val
->local_size_cost
);
3621 avals
.m_known_contexts
[i
] = ipa_polymorphic_call_context ();
3624 for (i
= 0; i
< count
; i
++)
3626 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3628 if (plats
->aggs_bottom
|| !plats
->aggs
)
3631 ipa_agg_value_set
*agg
= &avals
.m_known_aggs
[i
];
3632 for (ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3634 ipcp_value
<tree
> *val
;
3635 if (aglat
->bottom
|| !aglat
->values
3636 /* If the following is true, the one value is in known_aggs. */
3637 || (!plats
->aggs_contain_variable
3638 && aglat
->is_single_const ()))
3641 for (val
= aglat
->values
; val
; val
= val
->next
)
3643 struct ipa_agg_value item
;
3645 item
.offset
= aglat
->offset
;
3646 item
.value
= val
->value
;
3647 agg
->items
.safe_push (item
);
3649 perform_estimation_of_a_value (node
, &avals
,
3650 removable_params_cost
, 0, val
);
3652 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3654 fprintf (dump_file
, " - estimates for value ");
3655 print_ipcp_constant_value (dump_file
, val
->value
);
3656 fprintf (dump_file
, " for ");
3657 ipa_dump_param (dump_file
, info
, i
);
3658 fprintf (dump_file
, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3659 "]: time_benefit: %g, size: %i\n",
3660 plats
->aggs_by_ref
? "ref " : "",
3662 val
->local_time_benefit
.to_double (),
3663 val
->local_size_cost
);
3673 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3674 topological sort of values. */
3676 template <typename valtype
>
3678 value_topo_info
<valtype
>::add_val (ipcp_value
<valtype
> *cur_val
)
3680 ipcp_value_source
<valtype
> *src
;
3686 cur_val
->dfs
= dfs_counter
;
3687 cur_val
->low_link
= dfs_counter
;
3689 cur_val
->topo_next
= stack
;
3691 cur_val
->on_stack
= true;
3693 for (src
= cur_val
->sources
; src
; src
= src
->next
)
3696 if (src
->val
->dfs
== 0)
3699 if (src
->val
->low_link
< cur_val
->low_link
)
3700 cur_val
->low_link
= src
->val
->low_link
;
3702 else if (src
->val
->on_stack
3703 && src
->val
->dfs
< cur_val
->low_link
)
3704 cur_val
->low_link
= src
->val
->dfs
;
3707 if (cur_val
->dfs
== cur_val
->low_link
)
3709 ipcp_value
<valtype
> *v
, *scc_list
= NULL
;
3714 stack
= v
->topo_next
;
3715 v
->on_stack
= false;
3717 v
->scc_next
= scc_list
;
3720 while (v
!= cur_val
);
3722 cur_val
->topo_next
= values_topo
;
3723 values_topo
= cur_val
;
3727 /* Add all values in lattices associated with NODE to the topological sort if
3728 they are not there yet. */
3731 add_all_node_vals_to_toposort (cgraph_node
*node
, ipa_topo_info
*topo
)
3733 class ipa_node_params
*info
= IPA_NODE_REF (node
);
3734 int i
, count
= ipa_get_param_count (info
);
3736 for (i
= 0; i
< count
; i
++)
3738 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3739 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3740 struct ipcp_agg_lattice
*aglat
;
3744 ipcp_value
<tree
> *val
;
3745 for (val
= lat
->values
; val
; val
= val
->next
)
3746 topo
->constants
.add_val (val
);
3749 if (!plats
->aggs_bottom
)
3750 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3753 ipcp_value
<tree
> *val
;
3754 for (val
= aglat
->values
; val
; val
= val
->next
)
3755 topo
->constants
.add_val (val
);
3758 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3759 if (!ctxlat
->bottom
)
3761 ipcp_value
<ipa_polymorphic_call_context
> *ctxval
;
3762 for (ctxval
= ctxlat
->values
; ctxval
; ctxval
= ctxval
->next
)
3763 topo
->contexts
.add_val (ctxval
);
3768 /* One pass of constants propagation along the call graph edges, from callers
3769 to callees (requires topological ordering in TOPO), iterate over strongly
3770 connected components. */
3773 propagate_constants_topo (class ipa_topo_info
*topo
)
3777 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
3780 struct cgraph_node
*v
, *node
= topo
->order
[i
];
3781 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
3783 /* First, iteratively propagate within the strongly connected component
3784 until all lattices stabilize. */
3785 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3786 if (v
->has_gimple_body_p ())
3788 if (opt_for_fn (v
->decl
, flag_ipa_cp
)
3789 && opt_for_fn (v
->decl
, optimize
))
3790 push_node_to_stack (topo
, v
);
3791 /* When V is not optimized, we can not push it to stack, but
3792 still we need to set all its callees lattices to bottom. */
3795 for (cgraph_edge
*cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3796 propagate_constants_across_call (cs
);
3800 v
= pop_node_from_stack (topo
);
3803 struct cgraph_edge
*cs
;
3804 class ipa_node_params
*info
= NULL
;
3805 bool self_scc
= true;
3807 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3808 if (ipa_edge_within_scc (cs
))
3810 cgraph_node
*callee
= cs
->callee
->function_symbol ();
3817 info
= IPA_NODE_REF (v
);
3818 info
->node_within_scc
= true;
3821 if (propagate_constants_across_call (cs
))
3822 push_node_to_stack (topo
, callee
);
3826 info
->node_is_self_scc
= self_scc
;
3828 v
= pop_node_from_stack (topo
);
3831 /* Afterwards, propagate along edges leading out of the SCC, calculates
3832 the local effects of the discovered constants and all valid values to
3833 their topological sort. */
3834 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3835 if (v
->has_gimple_body_p ()
3836 && opt_for_fn (v
->decl
, flag_ipa_cp
)
3837 && opt_for_fn (v
->decl
, optimize
))
3839 struct cgraph_edge
*cs
;
3841 estimate_local_effects (v
);
3842 add_all_node_vals_to_toposort (v
, topo
);
3843 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3844 if (!ipa_edge_within_scc (cs
))
3845 propagate_constants_across_call (cs
);
3847 cycle_nodes
.release ();
3852 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3856 safe_add (int a
, int b
)
3858 if (a
> INT_MAX
/2 || b
> INT_MAX
/2)
3865 /* Propagate the estimated effects of individual values along the topological
3866 from the dependent values to those they depend on. */
3868 template <typename valtype
>
3870 value_topo_info
<valtype
>::propagate_effects ()
3872 ipcp_value
<valtype
> *base
;
3874 for (base
= values_topo
; base
; base
= base
->topo_next
)
3876 ipcp_value_source
<valtype
> *src
;
3877 ipcp_value
<valtype
> *val
;
3881 for (val
= base
; val
; val
= val
->scc_next
)
3883 time
= time
+ val
->local_time_benefit
+ val
->prop_time_benefit
;
3884 size
= safe_add (size
, safe_add (val
->local_size_cost
,
3885 val
->prop_size_cost
));
3888 for (val
= base
; val
; val
= val
->scc_next
)
3889 for (src
= val
->sources
; src
; src
= src
->next
)
3891 && src
->cs
->maybe_hot_p ())
3893 src
->val
->prop_time_benefit
= time
+ src
->val
->prop_time_benefit
;
3894 src
->val
->prop_size_cost
= safe_add (size
,
3895 src
->val
->prop_size_cost
);
3901 /* Propagate constants, polymorphic contexts and their effects from the
3902 summaries interprocedurally. */
3905 ipcp_propagate_stage (class ipa_topo_info
*topo
)
3907 struct cgraph_node
*node
;
3910 fprintf (dump_file
, "\n Propagating constants:\n\n");
3912 max_count
= profile_count::uninitialized ();
3914 FOR_EACH_DEFINED_FUNCTION (node
)
3916 if (node
->has_gimple_body_p ()
3917 && opt_for_fn (node
->decl
, flag_ipa_cp
)
3918 && opt_for_fn (node
->decl
, optimize
))
3920 class ipa_node_params
*info
= IPA_NODE_REF (node
);
3921 determine_versionability (node
, info
);
3923 unsigned nlattices
= ipa_get_param_count (info
);
3924 void *chunk
= XCNEWVEC (class ipcp_param_lattices
, nlattices
);
3925 info
->lattices
= new (chunk
) ipcp_param_lattices
[nlattices
];
3926 initialize_node_lattices (node
);
3928 ipa_size_summary
*s
= ipa_size_summaries
->get (node
);
3929 if (node
->definition
&& !node
->alias
&& s
!= NULL
)
3930 overall_size
+= s
->self_size
;
3931 max_count
= max_count
.max (node
->count
.ipa ());
3934 orig_overall_size
= overall_size
;
3937 fprintf (dump_file
, "\noverall_size: %li\n", overall_size
);
3939 propagate_constants_topo (topo
);
3941 ipcp_verify_propagated_values ();
3942 topo
->constants
.propagate_effects ();
3943 topo
->contexts
.propagate_effects ();
3947 fprintf (dump_file
, "\nIPA lattices after all propagation:\n");
3948 print_all_lattices (dump_file
, (dump_flags
& TDF_DETAILS
), true);
3952 /* Discover newly direct outgoing edges from NODE which is a new clone with
3953 known KNOWN_CSTS and make them direct. */
3956 ipcp_discover_new_direct_edges (struct cgraph_node
*node
,
3957 vec
<tree
> known_csts
,
3958 vec
<ipa_polymorphic_call_context
>
3960 struct ipa_agg_replacement_value
*aggvals
)
3962 struct cgraph_edge
*ie
, *next_ie
;
3965 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3970 next_ie
= ie
->next_callee
;
3971 target
= ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
3972 vNULL
, aggvals
, &speculative
);
3975 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3976 bool polymorphic
= ie
->indirect_info
->polymorphic
;
3977 int param_index
= ie
->indirect_info
->param_index
;
3978 struct cgraph_edge
*cs
= ipa_make_edge_direct_to_target (ie
, target
,
3982 if (cs
&& !agg_contents
&& !polymorphic
)
3984 class ipa_node_params
*info
= IPA_NODE_REF (node
);
3985 int c
= ipa_get_controlled_uses (info
, param_index
);
3986 if (c
!= IPA_UNDESCRIBED_USE
)
3988 struct ipa_ref
*to_del
;
3991 ipa_set_controlled_uses (info
, param_index
, c
);
3992 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3993 fprintf (dump_file
, " controlled uses count of param "
3994 "%i bumped down to %i\n", param_index
, c
);
3996 && (to_del
= node
->find_reference (cs
->callee
, NULL
, 0)))
3998 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3999 fprintf (dump_file
, " and even removing its "
4000 "cloning-created reference\n");
4001 to_del
->remove_reference ();
4007 /* Turning calls to direct calls will improve overall summary. */
4009 ipa_update_overall_fn_summary (node
);
4012 class edge_clone_summary
;
4013 static call_summary
<edge_clone_summary
*> *edge_clone_summaries
= NULL
;
4015 /* Edge clone summary. */
4017 class edge_clone_summary
4020 /* Default constructor. */
4021 edge_clone_summary (): prev_clone (NULL
), next_clone (NULL
) {}
4023 /* Default destructor. */
4024 ~edge_clone_summary ()
4027 edge_clone_summaries
->get (prev_clone
)->next_clone
= next_clone
;
4029 edge_clone_summaries
->get (next_clone
)->prev_clone
= prev_clone
;
4032 cgraph_edge
*prev_clone
;
4033 cgraph_edge
*next_clone
;
4036 class edge_clone_summary_t
:
4037 public call_summary
<edge_clone_summary
*>
4040 edge_clone_summary_t (symbol_table
*symtab
):
4041 call_summary
<edge_clone_summary
*> (symtab
)
4043 m_initialize_when_cloning
= true;
4046 virtual void duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
4047 edge_clone_summary
*src_data
,
4048 edge_clone_summary
*dst_data
);
4051 /* Edge duplication hook. */
4054 edge_clone_summary_t::duplicate (cgraph_edge
*src_edge
, cgraph_edge
*dst_edge
,
4055 edge_clone_summary
*src_data
,
4056 edge_clone_summary
*dst_data
)
4058 if (src_data
->next_clone
)
4059 edge_clone_summaries
->get (src_data
->next_clone
)->prev_clone
= dst_edge
;
4060 dst_data
->prev_clone
= src_edge
;
4061 dst_data
->next_clone
= src_data
->next_clone
;
4062 src_data
->next_clone
= dst_edge
;
4065 /* Return true is CS calls DEST or its clone for all contexts. When
4066 ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
4067 edges from/to an all-context clone. */
4070 calls_same_node_or_its_all_contexts_clone_p (cgraph_edge
*cs
, cgraph_node
*dest
,
4071 bool allow_recursion_to_clone
)
4073 enum availability availability
;
4074 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
4076 if (availability
<= AVAIL_INTERPOSABLE
)
4080 if (!allow_recursion_to_clone
&& cs
->caller
== callee
)
4083 class ipa_node_params
*info
= IPA_NODE_REF (callee
);
4084 return info
->is_all_contexts_clone
&& info
->ipcp_orig_node
== dest
;
4087 /* Return true if edge CS does bring about the value described by SRC to
4088 DEST_VAL of node DEST or its clone for all contexts. */
4091 cgraph_edge_brings_value_p (cgraph_edge
*cs
, ipcp_value_source
<tree
> *src
,
4092 cgraph_node
*dest
, ipcp_value
<tree
> *dest_val
)
4094 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4096 if (!calls_same_node_or_its_all_contexts_clone_p (cs
, dest
, !src
->val
)
4097 || caller_info
->node_dead
)
4103 if (caller_info
->ipcp_orig_node
)
4106 if (src
->offset
== -1)
4107 t
= caller_info
->known_csts
[src
->index
];
4109 t
= get_clone_agg_value (cs
->caller
, src
->offset
, src
->index
);
4110 return (t
!= NULL_TREE
4111 && values_equal_for_ipcp_p (src
->val
->value
, t
));
4115 if (src
->val
== dest_val
)
4118 struct ipcp_agg_lattice
*aglat
;
4119 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
4121 if (src
->offset
== -1)
4122 return (plats
->itself
.is_single_const ()
4123 && values_equal_for_ipcp_p (src
->val
->value
,
4124 plats
->itself
.values
->value
));
4127 if (plats
->aggs_bottom
|| plats
->aggs_contain_variable
)
4129 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4130 if (aglat
->offset
== src
->offset
)
4131 return (aglat
->is_single_const ()
4132 && values_equal_for_ipcp_p (src
->val
->value
,
4133 aglat
->values
->value
));
4139 /* Return true if edge CS does bring about the value described by SRC to
4140 DST_VAL of node DEST or its clone for all contexts. */
4143 cgraph_edge_brings_value_p (cgraph_edge
*cs
,
4144 ipcp_value_source
<ipa_polymorphic_call_context
> *src
,
4146 ipcp_value
<ipa_polymorphic_call_context
> *)
4148 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4150 if (!calls_same_node_or_its_all_contexts_clone_p (cs
, dest
, true)
4151 || caller_info
->node_dead
)
4156 if (caller_info
->ipcp_orig_node
)
4157 return (caller_info
->known_contexts
.length () > (unsigned) src
->index
)
4158 && values_equal_for_ipcp_p (src
->val
->value
,
4159 caller_info
->known_contexts
[src
->index
]);
4161 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
4163 return plats
->ctxlat
.is_single_const ()
4164 && values_equal_for_ipcp_p (src
->val
->value
,
4165 plats
->ctxlat
.values
->value
);
4168 /* Get the next clone in the linked list of clones of an edge. */
4170 static inline struct cgraph_edge
*
4171 get_next_cgraph_edge_clone (struct cgraph_edge
*cs
)
4173 edge_clone_summary
*s
= edge_clone_summaries
->get (cs
);
4174 return s
!= NULL
? s
->next_clone
: NULL
;
4177 /* Given VAL that is intended for DEST, iterate over all its sources and if any
4178 of them is viable and hot, return true. In that case, for those that still
4179 hold, add their edge frequency and their number into *FREQUENCY and
4180 *CALLER_COUNT respectively. */
4182 template <typename valtype
>
4184 get_info_about_necessary_edges (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
4185 sreal
*freq_sum
, profile_count
*count_sum
,
4188 ipcp_value_source
<valtype
> *src
;
4191 profile_count cnt
= profile_count::zero ();
4193 bool non_self_recursive
= false;
4195 for (src
= val
->sources
; src
; src
= src
->next
)
4197 struct cgraph_edge
*cs
= src
->cs
;
4200 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
4203 freq
+= cs
->sreal_frequency ();
4204 if (cs
->count
.ipa ().initialized_p ())
4205 cnt
+= cs
->count
.ipa ();
4206 hot
|= cs
->maybe_hot_p ();
4207 if (cs
->caller
!= dest
)
4208 non_self_recursive
= true;
4210 cs
= get_next_cgraph_edge_clone (cs
);
4214 /* If the only edges bringing a value are self-recursive ones, do not bother
4216 if (!non_self_recursive
)
4221 *caller_count
= count
;
4223 if (!hot
&& IPA_NODE_REF (dest
)->node_within_scc
)
4225 struct cgraph_edge
*cs
;
4227 /* Cold non-SCC source edge could trigger hot recursive execution of
4228 function. Consider the case as hot and rely on following cost model
4229 computation to further select right one. */
4230 for (cs
= dest
->callers
; cs
; cs
= cs
->next_caller
)
4231 if (cs
->caller
== dest
&& cs
->maybe_hot_p ())
4238 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4239 to let a non-self-recursive caller be the first element. Thus, we can
4240 simplify intersecting operations on values that arrive from all of these
4241 callers, especially when there exists self-recursive call. Return true if
4242 this kind of adjustment is possible. */
4245 adjust_callers_for_value_intersection (vec
<cgraph_edge
*> callers
,
4248 for (unsigned i
= 0; i
< callers
.length (); i
++)
4250 cgraph_edge
*cs
= callers
[i
];
4252 if (cs
->caller
!= node
)
4256 callers
[i
] = callers
[0];
4265 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
4266 is assumed their number is known and equal to CALLER_COUNT. */
4268 template <typename valtype
>
4269 static vec
<cgraph_edge
*>
4270 gather_edges_for_value (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
4273 ipcp_value_source
<valtype
> *src
;
4274 vec
<cgraph_edge
*> ret
;
4276 ret
.create (caller_count
);
4277 for (src
= val
->sources
; src
; src
= src
->next
)
4279 struct cgraph_edge
*cs
= src
->cs
;
4282 if (cgraph_edge_brings_value_p (cs
, src
, dest
, val
))
4283 ret
.quick_push (cs
);
4284 cs
= get_next_cgraph_edge_clone (cs
);
4288 if (caller_count
> 1)
4289 adjust_callers_for_value_intersection (ret
, dest
);
4294 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4295 Return it or NULL if for some reason it cannot be created. */
4297 static struct ipa_replace_map
*
4298 get_replacement_map (class ipa_node_params
*info
, tree value
, int parm_num
)
4300 struct ipa_replace_map
*replace_map
;
4302 replace_map
= ggc_alloc
<ipa_replace_map
> ();
4305 fprintf (dump_file
, " replacing ");
4306 ipa_dump_param (dump_file
, info
, parm_num
);
4308 fprintf (dump_file
, " with const ");
4309 print_generic_expr (dump_file
, value
);
4310 fprintf (dump_file
, "\n");
4312 replace_map
->parm_num
= parm_num
;
4313 replace_map
->new_tree
= value
;
4317 /* Dump new profiling counts */
4320 dump_profile_updates (struct cgraph_node
*orig_node
,
4321 struct cgraph_node
*new_node
)
4323 struct cgraph_edge
*cs
;
4325 fprintf (dump_file
, " setting count of the specialized node to ");
4326 new_node
->count
.dump (dump_file
);
4327 fprintf (dump_file
, "\n");
4328 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4330 fprintf (dump_file
, " edge to %s has count ",
4331 cs
->callee
->dump_name ());
4332 cs
->count
.dump (dump_file
);
4333 fprintf (dump_file
, "\n");
4336 fprintf (dump_file
, " setting count of the original node to ");
4337 orig_node
->count
.dump (dump_file
);
4338 fprintf (dump_file
, "\n");
4339 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4341 fprintf (dump_file
, " edge to %s is left with ",
4342 cs
->callee
->dump_name ());
4343 cs
->count
.dump (dump_file
);
4344 fprintf (dump_file
, "\n");
4348 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4349 their profile information to reflect this. */
4352 update_profiling_info (struct cgraph_node
*orig_node
,
4353 struct cgraph_node
*new_node
)
4355 struct cgraph_edge
*cs
;
4356 struct caller_statistics stats
;
4357 profile_count new_sum
, orig_sum
;
4358 profile_count remainder
, orig_node_count
= orig_node
->count
;
4359 profile_count orig_new_node_count
= new_node
->count
;
4361 if (!(orig_node_count
.ipa () > profile_count::zero ()))
4364 init_caller_stats (&stats
);
4365 orig_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
4367 orig_sum
= stats
.count_sum
;
4368 init_caller_stats (&stats
);
4369 new_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
4371 new_sum
= stats
.count_sum
;
4373 if (orig_node_count
< orig_sum
+ new_sum
)
4377 fprintf (dump_file
, " Problem: node %s has too low count ",
4378 orig_node
->dump_name ());
4379 orig_node_count
.dump (dump_file
);
4380 fprintf (dump_file
, "while the sum of incoming count is ");
4381 (orig_sum
+ new_sum
).dump (dump_file
);
4382 fprintf (dump_file
, "\n");
4385 orig_node_count
= (orig_sum
+ new_sum
).apply_scale (12, 10);
4388 fprintf (dump_file
, " proceeding by pretending it was ");
4389 orig_node_count
.dump (dump_file
);
4390 fprintf (dump_file
, "\n");
4394 remainder
= orig_node_count
.combine_with_ipa_count (orig_node_count
.ipa ()
4397 /* With partial train run we do not want to assume that original's
4398 count is zero whenever we redurect all executed edges to clone.
4399 Simply drop profile to local one in this case. */
4400 if (remainder
.ipa_p () && !remainder
.ipa ().nonzero_p ()
4401 && orig_node
->count
.ipa_p () && orig_node
->count
.ipa ().nonzero_p ()
4402 && flag_profile_partial_training
)
4403 remainder
= remainder
.guessed_local ();
4405 new_sum
= orig_node_count
.combine_with_ipa_count (new_sum
);
4406 new_node
->count
= new_sum
;
4407 orig_node
->count
= remainder
;
4409 profile_count::adjust_for_ipa_scaling (&new_sum
, &orig_new_node_count
);
4410 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4411 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_new_node_count
);
4412 for (cs
= new_node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
4413 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_new_node_count
);
4415 profile_count::adjust_for_ipa_scaling (&remainder
, &orig_node_count
);
4416 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4417 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
4418 for (cs
= orig_node
->indirect_calls
; cs
; cs
= cs
->next_callee
)
4419 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
4422 dump_profile_updates (orig_node
, new_node
);
4425 /* Update the respective profile of specialized NEW_NODE and the original
4426 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4427 have been redirected to the specialized version. */
4430 update_specialized_profile (struct cgraph_node
*new_node
,
4431 struct cgraph_node
*orig_node
,
4432 profile_count redirected_sum
)
4434 struct cgraph_edge
*cs
;
4435 profile_count new_node_count
, orig_node_count
= orig_node
->count
;
4439 fprintf (dump_file
, " the sum of counts of redirected edges is ");
4440 redirected_sum
.dump (dump_file
);
4441 fprintf (dump_file
, "\n");
4443 if (!(orig_node_count
> profile_count::zero ()))
4446 gcc_assert (orig_node_count
>= redirected_sum
);
4448 new_node_count
= new_node
->count
;
4449 new_node
->count
+= redirected_sum
;
4450 orig_node
->count
-= redirected_sum
;
4452 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
4453 cs
->count
+= cs
->count
.apply_scale (redirected_sum
, new_node_count
);
4455 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
4457 profile_count dec
= cs
->count
.apply_scale (redirected_sum
,
4463 dump_profile_updates (orig_node
, new_node
);
4466 /* Return true if we would like to remove a parameter from NODE when cloning it
4467 with KNOWN_CSTS scalar constants. */
4470 want_remove_some_param_p (cgraph_node
*node
, vec
<tree
> known_csts
)
4472 auto_vec
<bool, 16> surviving
;
4473 bool filled_vec
= false;
4474 ipa_node_params
*info
= IPA_NODE_REF (node
);
4475 int i
, count
= ipa_get_param_count (info
);
4477 for (i
= 0; i
< count
; i
++)
4479 if (!known_csts
[i
] && ipa_is_param_used (info
, i
))
4484 clone_info
*info
= clone_info::get (node
);
4485 if (!info
|| !info
->param_adjustments
)
4487 info
->param_adjustments
->get_surviving_params (&surviving
);
4490 if (surviving
.length() < (unsigned) i
&& surviving
[i
])
4496 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4497 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4498 redirect all edges in CALLERS to it. */
4500 static struct cgraph_node
*
4501 create_specialized_node (struct cgraph_node
*node
,
4502 vec
<tree
> known_csts
,
4503 vec
<ipa_polymorphic_call_context
> known_contexts
,
4504 struct ipa_agg_replacement_value
*aggvals
,
4505 vec
<cgraph_edge
*> callers
)
4507 class ipa_node_params
*new_info
, *info
= IPA_NODE_REF (node
);
4508 vec
<ipa_replace_map
*, va_gc
> *replace_trees
= NULL
;
4509 vec
<ipa_adjusted_param
, va_gc
> *new_params
= NULL
;
4510 struct ipa_agg_replacement_value
*av
;
4511 struct cgraph_node
*new_node
;
4512 int i
, count
= ipa_get_param_count (info
);
4513 clone_info
*cinfo
= clone_info::get (node
);
4514 ipa_param_adjustments
*old_adjustments
= cinfo
4515 ? cinfo
->param_adjustments
: NULL
;
4516 ipa_param_adjustments
*new_adjustments
;
4517 gcc_assert (!info
->ipcp_orig_node
);
4518 gcc_assert (node
->can_change_signature
4519 || !old_adjustments
);
4521 if (old_adjustments
)
4523 /* At the moment all IPA optimizations should use the number of
4524 parameters of the prevailing decl as the m_always_copy_start.
4525 Handling any other value would complicate the code below, so for the
4526 time bing let's only assert it is so. */
4527 gcc_assert (old_adjustments
->m_always_copy_start
== count
4528 || old_adjustments
->m_always_copy_start
< 0);
4529 int old_adj_count
= vec_safe_length (old_adjustments
->m_adj_params
);
4530 for (i
= 0; i
< old_adj_count
; i
++)
4532 ipa_adjusted_param
*old_adj
= &(*old_adjustments
->m_adj_params
)[i
];
4533 if (!node
->can_change_signature
4534 || old_adj
->op
!= IPA_PARAM_OP_COPY
4535 || (!known_csts
[old_adj
->base_index
]
4536 && ipa_is_param_used (info
, old_adj
->base_index
)))
4538 ipa_adjusted_param new_adj
= *old_adj
;
4540 new_adj
.prev_clone_adjustment
= true;
4541 new_adj
.prev_clone_index
= i
;
4542 vec_safe_push (new_params
, new_adj
);
4545 bool skip_return
= old_adjustments
->m_skip_return
;
4546 new_adjustments
= (new (ggc_alloc
<ipa_param_adjustments
> ())
4547 ipa_param_adjustments (new_params
, count
,
4550 else if (node
->can_change_signature
4551 && want_remove_some_param_p (node
, known_csts
))
4553 ipa_adjusted_param adj
;
4554 memset (&adj
, 0, sizeof (adj
));
4555 adj
.op
= IPA_PARAM_OP_COPY
;
4556 for (i
= 0; i
< count
; i
++)
4557 if (!known_csts
[i
] && ipa_is_param_used (info
, i
))
4560 adj
.prev_clone_index
= i
;
4561 vec_safe_push (new_params
, adj
);
4563 new_adjustments
= (new (ggc_alloc
<ipa_param_adjustments
> ())
4564 ipa_param_adjustments (new_params
, count
, false));
4567 new_adjustments
= NULL
;
4569 replace_trees
= cinfo
? vec_safe_copy (cinfo
->tree_map
) : NULL
;
4570 for (i
= 0; i
< count
; i
++)
4572 tree t
= known_csts
[i
];
4575 struct ipa_replace_map
*replace_map
;
4577 gcc_checking_assert (TREE_CODE (t
) != TREE_BINFO
);
4578 replace_map
= get_replacement_map (info
, t
, i
);
4580 vec_safe_push (replace_trees
, replace_map
);
4583 auto_vec
<cgraph_edge
*, 2> self_recursive_calls
;
4584 for (i
= callers
.length () - 1; i
>= 0; i
--)
4586 cgraph_edge
*cs
= callers
[i
];
4587 if (cs
->caller
== node
)
4589 self_recursive_calls
.safe_push (cs
);
4590 callers
.unordered_remove (i
);
4594 unsigned &suffix_counter
= clone_num_suffixes
->get_or_insert (
4595 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4597 new_node
= node
->create_virtual_clone (callers
, replace_trees
,
4598 new_adjustments
, "constprop",
4602 bool have_self_recursive_calls
= !self_recursive_calls
.is_empty ();
4603 for (unsigned j
= 0; j
< self_recursive_calls
.length (); j
++)
4605 cgraph_edge
*cs
= get_next_cgraph_edge_clone (self_recursive_calls
[j
]);
4606 /* Cloned edges can disappear during cloning as speculation can be
4607 resolved, check that we have one and that it comes from the last
4609 if (cs
&& cs
->caller
== new_node
)
4610 cs
->redirect_callee_duplicating_thunks (new_node
);
4611 /* Any future code that would make more than one clone of an outgoing
4612 edge would confuse this mechanism, so let's check that does not
4614 gcc_checking_assert (!cs
4615 || !get_next_cgraph_edge_clone (cs
)
4616 || get_next_cgraph_edge_clone (cs
)->caller
!= new_node
);
4618 if (have_self_recursive_calls
)
4619 new_node
->expand_all_artificial_thunks ();
4621 ipa_set_node_agg_value_chain (new_node
, aggvals
);
4622 for (av
= aggvals
; av
; av
= av
->next
)
4623 new_node
->maybe_create_reference (av
->value
, NULL
);
4625 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4627 fprintf (dump_file
, " the new node is %s.\n", new_node
->dump_name ());
4628 if (known_contexts
.exists ())
4630 for (i
= 0; i
< count
; i
++)
4631 if (!known_contexts
[i
].useless_p ())
4633 fprintf (dump_file
, " known ctx %i is ", i
);
4634 known_contexts
[i
].dump (dump_file
);
4638 ipa_dump_agg_replacement_values (dump_file
, aggvals
);
4640 ipa_check_create_node_params ();
4641 update_profiling_info (node
, new_node
);
4642 new_info
= IPA_NODE_REF (new_node
);
4643 new_info
->ipcp_orig_node
= node
;
4644 new_node
->ipcp_clone
= true;
4645 new_info
->known_csts
= known_csts
;
4646 new_info
->known_contexts
= known_contexts
;
4648 ipcp_discover_new_direct_edges (new_node
, known_csts
, known_contexts
, aggvals
);
4654 /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
4655 pass-through function to itself when the cgraph_node involved is not an
4656 IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
4657 no-operation pass-through. */
4660 self_recursive_pass_through_p (cgraph_edge
*cs
, ipa_jump_func
*jfunc
, int i
,
4663 enum availability availability
;
4664 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
4665 && availability
> AVAIL_INTERPOSABLE
4666 && jfunc
->type
== IPA_JF_PASS_THROUGH
4667 && (!simple
|| ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4668 && ipa_get_jf_pass_through_formal_id (jfunc
) == i
4669 && IPA_NODE_REF (cs
->caller
)
4670 && !IPA_NODE_REF (cs
->caller
)->ipcp_orig_node
)
4675 /* Return true if JFUNC, which describes a part of an aggregate represented or
4676 pointed to by the i-th parameter of call CS, is a pass-through function to
4677 itself when the cgraph_node involved is not an IPA-CP clone.. When
4678 SIMPLE is true, further check if JFUNC is a simple no-operation
4682 self_recursive_agg_pass_through_p (cgraph_edge
*cs
, ipa_agg_jf_item
*jfunc
,
4683 int i
, bool simple
= true)
4685 enum availability availability
;
4686 if (cs
->caller
== cs
->callee
->function_symbol (&availability
)
4687 && availability
> AVAIL_INTERPOSABLE
4688 && jfunc
->jftype
== IPA_JF_LOAD_AGG
4689 && jfunc
->offset
== jfunc
->value
.load_agg
.offset
4690 && (!simple
|| jfunc
->value
.pass_through
.operation
== NOP_EXPR
)
4691 && jfunc
->value
.pass_through
.formal_id
== i
4692 && useless_type_conversion_p (jfunc
->value
.load_agg
.type
, jfunc
->type
)
4693 && IPA_NODE_REF (cs
->caller
)
4694 && !IPA_NODE_REF (cs
->caller
)->ipcp_orig_node
)
4699 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
4700 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
4703 find_more_scalar_values_for_callers_subset (struct cgraph_node
*node
,
4704 vec
<tree
> known_csts
,
4705 vec
<cgraph_edge
*> callers
)
4707 class ipa_node_params
*info
= IPA_NODE_REF (node
);
4708 int i
, count
= ipa_get_param_count (info
);
4710 for (i
= 0; i
< count
; i
++)
4712 struct cgraph_edge
*cs
;
4713 tree newval
= NULL_TREE
;
4716 tree type
= ipa_get_type (info
, i
);
4718 if (ipa_get_scalar_lat (info
, i
)->bottom
|| known_csts
[i
])
4721 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4723 struct ipa_jump_func
*jump_func
;
4726 if (!IPA_EDGE_REF (cs
)
4727 || i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
))
4729 && call_passes_through_thunk (cs
)))
4734 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
4736 /* Besides simple pass-through jump function, arithmetic jump
4737 function could also introduce argument-direct-pass-through for
4738 self-feeding recursive call. For example,
4745 Given that i is 0, recursive propagation via (i & 1) also gets
4747 if (self_recursive_pass_through_p (cs
, jump_func
, i
, false))
4749 gcc_assert (newval
);
4750 t
= ipa_get_jf_arith_result (
4751 ipa_get_jf_pass_through_operation (jump_func
),
4753 ipa_get_jf_pass_through_operand (jump_func
),
4757 t
= ipa_value_from_jfunc (IPA_NODE_REF (cs
->caller
), jump_func
,
4761 && !values_equal_for_ipcp_p (t
, newval
))
4762 || (!first
&& !newval
))
4774 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4776 fprintf (dump_file
, " adding an extra known scalar value ");
4777 print_ipcp_constant_value (dump_file
, newval
);
4778 fprintf (dump_file
, " for ");
4779 ipa_dump_param (dump_file
, info
, i
);
4780 fprintf (dump_file
, "\n");
4783 known_csts
[i
] = newval
;
4788 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4789 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4793 find_more_contexts_for_caller_subset (cgraph_node
*node
,
4794 vec
<ipa_polymorphic_call_context
>
4796 vec
<cgraph_edge
*> callers
)
4798 ipa_node_params
*info
= IPA_NODE_REF (node
);
4799 int i
, count
= ipa_get_param_count (info
);
4801 for (i
= 0; i
< count
; i
++)
4805 if (ipa_get_poly_ctx_lat (info
, i
)->bottom
4806 || (known_contexts
->exists ()
4807 && !(*known_contexts
)[i
].useless_p ()))
4810 ipa_polymorphic_call_context newval
;
4814 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4816 if (!IPA_EDGE_REF (cs
)
4817 || i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
)))
4819 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
),
4821 ipa_polymorphic_call_context ctx
;
4822 ctx
= ipa_context_from_jfunc (IPA_NODE_REF (cs
->caller
), cs
, i
,
4830 newval
.meet_with (ctx
);
4831 if (newval
.useless_p ())
4835 if (!newval
.useless_p ())
4837 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4839 fprintf (dump_file
, " adding an extra known polymorphic "
4841 print_ipcp_constant_value (dump_file
, newval
);
4842 fprintf (dump_file
, " for ");
4843 ipa_dump_param (dump_file
, info
, i
);
4844 fprintf (dump_file
, "\n");
4847 if (!known_contexts
->exists ())
4848 known_contexts
->safe_grow_cleared (ipa_get_param_count (info
),
4850 (*known_contexts
)[i
] = newval
;
4856 /* Go through PLATS and create a vector of values consisting of values and
4857 offsets (minus OFFSET) of lattices that contain only a single value. */
4859 static vec
<ipa_agg_value
>
4860 copy_plats_to_inter (class ipcp_param_lattices
*plats
, HOST_WIDE_INT offset
)
4862 vec
<ipa_agg_value
> res
= vNULL
;
4864 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4867 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4868 if (aglat
->is_single_const ())
4870 struct ipa_agg_value ti
;
4871 ti
.offset
= aglat
->offset
- offset
;
4872 ti
.value
= aglat
->values
->value
;
4878 /* Intersect all values in INTER with single value lattices in PLATS (while
4879 subtracting OFFSET). */
4882 intersect_with_plats (class ipcp_param_lattices
*plats
,
4883 vec
<ipa_agg_value
> *inter
,
4884 HOST_WIDE_INT offset
)
4886 struct ipcp_agg_lattice
*aglat
;
4887 struct ipa_agg_value
*item
;
4890 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4896 aglat
= plats
->aggs
;
4897 FOR_EACH_VEC_ELT (*inter
, k
, item
)
4904 if (aglat
->offset
- offset
> item
->offset
)
4906 if (aglat
->offset
- offset
== item
->offset
)
4908 if (aglat
->is_single_const ())
4910 tree value
= aglat
->values
->value
;
4912 if (values_equal_for_ipcp_p (item
->value
, value
))
4917 aglat
= aglat
->next
;
4920 item
->value
= NULL_TREE
;
4924 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4925 vector result while subtracting OFFSET from the individual value offsets. */
4927 static vec
<ipa_agg_value
>
4928 agg_replacements_to_vector (struct cgraph_node
*node
, int index
,
4929 HOST_WIDE_INT offset
)
4931 struct ipa_agg_replacement_value
*av
;
4932 vec
<ipa_agg_value
> res
= vNULL
;
4934 for (av
= ipa_get_agg_replacements_for_node (node
); av
; av
= av
->next
)
4935 if (av
->index
== index
4936 && (av
->offset
- offset
) >= 0)
4938 struct ipa_agg_value item
;
4939 gcc_checking_assert (av
->value
);
4940 item
.offset
= av
->offset
- offset
;
4941 item
.value
= av
->value
;
4942 res
.safe_push (item
);
4948 /* Intersect all values in INTER with those that we have already scheduled to
4949 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4950 (while subtracting OFFSET). */
4953 intersect_with_agg_replacements (struct cgraph_node
*node
, int index
,
4954 vec
<ipa_agg_value
> *inter
,
4955 HOST_WIDE_INT offset
)
4957 struct ipa_agg_replacement_value
*srcvals
;
4958 struct ipa_agg_value
*item
;
4961 srcvals
= ipa_get_agg_replacements_for_node (node
);
4968 FOR_EACH_VEC_ELT (*inter
, i
, item
)
4970 struct ipa_agg_replacement_value
*av
;
4974 for (av
= srcvals
; av
; av
= av
->next
)
4976 gcc_checking_assert (av
->value
);
4977 if (av
->index
== index
4978 && av
->offset
- offset
== item
->offset
)
4980 if (values_equal_for_ipcp_p (item
->value
, av
->value
))
4986 item
->value
= NULL_TREE
;
4990 /* Intersect values in INTER with aggregate values that come along edge CS to
4991 parameter number INDEX and return it. If INTER does not actually exist yet,
4992 copy all incoming values to it. If we determine we ended up with no values
4993 whatsoever, return a released vector. */
4995 static vec
<ipa_agg_value
>
4996 intersect_aggregates_with_edge (struct cgraph_edge
*cs
, int index
,
4997 vec
<ipa_agg_value
> inter
)
4999 struct ipa_jump_func
*jfunc
;
5000 jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), index
);
5001 if (jfunc
->type
== IPA_JF_PASS_THROUGH
5002 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
5004 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
5005 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
5007 if (caller_info
->ipcp_orig_node
)
5009 struct cgraph_node
*orig_node
= caller_info
->ipcp_orig_node
;
5010 class ipcp_param_lattices
*orig_plats
;
5011 orig_plats
= ipa_get_parm_lattices (IPA_NODE_REF (orig_node
),
5013 if (agg_pass_through_permissible_p (orig_plats
, jfunc
))
5015 if (!inter
.exists ())
5016 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, 0);
5018 intersect_with_agg_replacements (cs
->caller
, src_idx
,
5025 class ipcp_param_lattices
*src_plats
;
5026 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
5027 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
5029 /* Currently we do not produce clobber aggregate jump
5030 functions, adjust when we do. */
5031 gcc_checking_assert (!jfunc
->agg
.items
);
5032 if (!inter
.exists ())
5033 inter
= copy_plats_to_inter (src_plats
, 0);
5035 intersect_with_plats (src_plats
, &inter
, 0);
5040 else if (jfunc
->type
== IPA_JF_ANCESTOR
5041 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
5043 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
5044 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
5045 class ipcp_param_lattices
*src_plats
;
5046 HOST_WIDE_INT delta
= ipa_get_jf_ancestor_offset (jfunc
);
5048 if (caller_info
->ipcp_orig_node
)
5050 if (!inter
.exists ())
5051 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, delta
);
5053 intersect_with_agg_replacements (cs
->caller
, src_idx
, &inter
,
5058 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
5059 /* Currently we do not produce clobber aggregate jump
5060 functions, adjust when we do. */
5061 gcc_checking_assert (!src_plats
->aggs
|| !jfunc
->agg
.items
);
5062 if (!inter
.exists ())
5063 inter
= copy_plats_to_inter (src_plats
, delta
);
5065 intersect_with_plats (src_plats
, &inter
, delta
);
5070 if (jfunc
->agg
.items
)
5072 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
5073 struct ipa_agg_value
*item
;
5076 if (!inter
.exists ())
5077 for (unsigned i
= 0; i
< jfunc
->agg
.items
->length (); i
++)
5079 struct ipa_agg_jf_item
*agg_item
= &(*jfunc
->agg
.items
)[i
];
5080 tree value
= ipa_agg_value_from_node (caller_info
, cs
->caller
,
5084 struct ipa_agg_value agg_value
;
5086 agg_value
.value
= value
;
5087 agg_value
.offset
= agg_item
->offset
;
5088 inter
.safe_push (agg_value
);
5092 FOR_EACH_VEC_ELT (inter
, k
, item
)
5100 while ((unsigned) l
< jfunc
->agg
.items
->length ())
5102 struct ipa_agg_jf_item
*ti
;
5103 ti
= &(*jfunc
->agg
.items
)[l
];
5104 if (ti
->offset
> item
->offset
)
5106 if (ti
->offset
== item
->offset
)
5110 /* Besides simple pass-through aggregate jump function,
5111 arithmetic aggregate jump function could also bring
5112 same aggregate value as parameter passed-in for
5113 self-feeding recursive call. For example,
5121 Given that *i is 0, recursive propagation via (*i & 1)
5123 if (self_recursive_agg_pass_through_p (cs
, ti
, index
,
5125 value
= ipa_get_jf_arith_result (
5126 ti
->value
.pass_through
.operation
,
5128 ti
->value
.pass_through
.operand
,
5131 value
= ipa_agg_value_from_node (caller_info
,
5134 if (value
&& values_equal_for_ipcp_p (item
->value
, value
))
5152 /* Look at edges in CALLERS and collect all known aggregate values that arrive
5153 from all of them. */
5155 static struct ipa_agg_replacement_value
*
5156 find_aggregate_values_for_callers_subset (struct cgraph_node
*node
,
5157 vec
<cgraph_edge
*> callers
)
5159 class ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
5160 struct ipa_agg_replacement_value
*res
;
5161 struct ipa_agg_replacement_value
**tail
= &res
;
5162 struct cgraph_edge
*cs
;
5163 int i
, j
, count
= ipa_get_param_count (dest_info
);
5165 FOR_EACH_VEC_ELT (callers
, j
, cs
)
5167 if (!IPA_EDGE_REF (cs
))
5172 int c
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
5177 for (i
= 0; i
< count
; i
++)
5179 struct cgraph_edge
*cs
;
5180 vec
<ipa_agg_value
> inter
= vNULL
;
5181 struct ipa_agg_value
*item
;
5182 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (dest_info
, i
);
5185 /* Among other things, the following check should deal with all by_ref
5187 if (plats
->aggs_bottom
)
5190 FOR_EACH_VEC_ELT (callers
, j
, cs
)
5192 struct ipa_jump_func
*jfunc
5193 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
5194 if (self_recursive_pass_through_p (cs
, jfunc
, i
)
5195 && (!plats
->aggs_by_ref
5196 || ipa_get_jf_pass_through_agg_preserved (jfunc
)))
5198 inter
= intersect_aggregates_with_edge (cs
, i
, inter
);
5200 if (!inter
.exists ())
5204 FOR_EACH_VEC_ELT (inter
, j
, item
)
5206 struct ipa_agg_replacement_value
*v
;
5211 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
5213 v
->offset
= item
->offset
;
5214 v
->value
= item
->value
;
5215 v
->by_ref
= plats
->aggs_by_ref
;
5221 if (inter
.exists ())
5228 /* Determine whether CS also brings all scalar values that the NODE is
5232 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge
*cs
,
5233 struct cgraph_node
*node
)
5235 class ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
5236 int count
= ipa_get_param_count (dest_info
);
5237 class ipa_node_params
*caller_info
;
5238 class ipa_edge_args
*args
;
5241 caller_info
= IPA_NODE_REF (cs
->caller
);
5242 args
= IPA_EDGE_REF (cs
);
5243 for (i
= 0; i
< count
; i
++)
5245 struct ipa_jump_func
*jump_func
;
5248 val
= dest_info
->known_csts
[i
];
5252 if (i
>= ipa_get_cs_argument_count (args
))
5254 jump_func
= ipa_get_ith_jump_func (args
, i
);
5255 t
= ipa_value_from_jfunc (caller_info
, jump_func
,
5256 ipa_get_type (dest_info
, i
));
5257 if (!t
|| !values_equal_for_ipcp_p (val
, t
))
5263 /* Determine whether CS also brings all aggregate values that NODE is
5266 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge
*cs
,
5267 struct cgraph_node
*node
)
5269 class ipa_node_params
*orig_node_info
;
5270 struct ipa_agg_replacement_value
*aggval
;
5273 aggval
= ipa_get_agg_replacements_for_node (node
);
5277 count
= ipa_get_param_count (IPA_NODE_REF (node
));
5278 ec
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
5280 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5281 if (aggval
->index
>= ec
)
5284 orig_node_info
= IPA_NODE_REF (IPA_NODE_REF (node
)->ipcp_orig_node
);
5286 for (i
= 0; i
< count
; i
++)
5288 class ipcp_param_lattices
*plats
;
5289 bool interesting
= false;
5290 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5291 if (aggval
->index
== i
)
5299 plats
= ipa_get_parm_lattices (orig_node_info
, aggval
->index
);
5300 if (plats
->aggs_bottom
)
5303 vec
<ipa_agg_value
> values
= intersect_aggregates_with_edge (cs
, i
, vNULL
);
5304 if (!values
.exists ())
5307 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
5308 if (aggval
->index
== i
)
5310 struct ipa_agg_value
*item
;
5313 FOR_EACH_VEC_ELT (values
, j
, item
)
5315 && item
->offset
== av
->offset
5316 && values_equal_for_ipcp_p (item
->value
, av
->value
))
5332 /* Given an original NODE and a VAL for which we have already created a
5333 specialized clone, look whether there are incoming edges that still lead
5334 into the old node but now also bring the requested value and also conform to
5335 all other criteria such that they can be redirected the special node.
5336 This function can therefore redirect the final edge in a SCC. */
5338 template <typename valtype
>
5340 perhaps_add_new_callers (cgraph_node
*node
, ipcp_value
<valtype
> *val
)
5342 ipcp_value_source
<valtype
> *src
;
5343 profile_count redirected_sum
= profile_count::zero ();
5345 for (src
= val
->sources
; src
; src
= src
->next
)
5347 struct cgraph_edge
*cs
= src
->cs
;
5350 if (cgraph_edge_brings_value_p (cs
, src
, node
, val
)
5351 && cgraph_edge_brings_all_scalars_for_node (cs
, val
->spec_node
)
5352 && cgraph_edge_brings_all_agg_vals_for_node (cs
, val
->spec_node
))
5355 fprintf (dump_file
, " - adding an extra caller %s of %s\n",
5356 cs
->caller
->dump_name (),
5357 val
->spec_node
->dump_name ());
5359 cs
->redirect_callee_duplicating_thunks (val
->spec_node
);
5360 val
->spec_node
->expand_all_artificial_thunks ();
5361 if (cs
->count
.ipa ().initialized_p ())
5362 redirected_sum
= redirected_sum
+ cs
->count
.ipa ();
5364 cs
= get_next_cgraph_edge_clone (cs
);
5368 if (redirected_sum
.nonzero_p ())
5369 update_specialized_profile (val
->spec_node
, node
, redirected_sum
);
5372 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5375 known_contexts_useful_p (vec
<ipa_polymorphic_call_context
> known_contexts
)
5377 ipa_polymorphic_call_context
*ctx
;
5380 FOR_EACH_VEC_ELT (known_contexts
, i
, ctx
)
5381 if (!ctx
->useless_p ())
5386 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5388 static vec
<ipa_polymorphic_call_context
>
5389 copy_useful_known_contexts (vec
<ipa_polymorphic_call_context
> known_contexts
)
5391 if (known_contexts_useful_p (known_contexts
))
5392 return known_contexts
.copy ();
5397 /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
5398 according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its
5402 copy_known_vectors_add_val (ipa_auto_call_arg_values
*avals
,
5403 vec
<tree
> *known_csts
,
5404 vec
<ipa_polymorphic_call_context
> *known_contexts
,
5405 ipcp_value
<tree
> *val
, int index
)
5407 *known_csts
= avals
->m_known_vals
.copy ();
5408 *known_contexts
= copy_useful_known_contexts (avals
->m_known_contexts
);
5409 (*known_csts
)[index
] = val
->value
;
5412 /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy
5413 contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
5417 copy_known_vectors_add_val (ipa_auto_call_arg_values
*avals
,
5418 vec
<tree
> *known_csts
,
5419 vec
<ipa_polymorphic_call_context
> *known_contexts
,
5420 ipcp_value
<ipa_polymorphic_call_context
> *val
,
5423 *known_csts
= avals
->m_known_vals
.copy ();
5424 *known_contexts
= avals
->m_known_contexts
.copy ();
5425 (*known_contexts
)[index
] = val
->value
;
5428 /* Return true if OFFSET indicates this was not an aggregate value or there is
5429 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5433 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*aggvals
,
5434 int index
, HOST_WIDE_INT offset
, tree value
)
5441 if (aggvals
->index
== index
5442 && aggvals
->offset
== offset
5443 && values_equal_for_ipcp_p (aggvals
->value
, value
))
5445 aggvals
= aggvals
->next
;
5450 /* Return true if offset is minus one because source of a polymorphic context
5451 cannot be an aggregate value. */
5454 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*,
5455 int , HOST_WIDE_INT offset
,
5456 ipa_polymorphic_call_context
)
5458 return offset
== -1;
5461 /* Decide whether to create a special version of NODE for value VAL of
5462 parameter at the given INDEX. If OFFSET is -1, the value is for the
5463 parameter itself, otherwise it is stored at the given OFFSET of the
5464 parameter. AVALS describes the other already known values. */
5466 template <typename valtype
>
5468 decide_about_value (struct cgraph_node
*node
, int index
, HOST_WIDE_INT offset
,
5469 ipcp_value
<valtype
> *val
, ipa_auto_call_arg_values
*avals
)
5471 struct ipa_agg_replacement_value
*aggvals
;
5474 profile_count count_sum
;
5475 vec
<cgraph_edge
*> callers
;
5479 perhaps_add_new_callers (node
, val
);
5482 else if (val
->local_size_cost
+ overall_size
> get_max_overall_size (node
))
5484 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5485 fprintf (dump_file
, " Ignoring candidate value because "
5486 "maximum unit size would be reached with %li.\n",
5487 val
->local_size_cost
+ overall_size
);
5490 else if (!get_info_about_necessary_edges (val
, node
, &freq_sum
, &count_sum
,
5494 if (!dbg_cnt (ipa_cp_values
))
5497 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5499 fprintf (dump_file
, " - considering value ");
5500 print_ipcp_constant_value (dump_file
, val
->value
);
5501 fprintf (dump_file
, " for ");
5502 ipa_dump_param (dump_file
, IPA_NODE_REF (node
), index
);
5504 fprintf (dump_file
, ", offset: " HOST_WIDE_INT_PRINT_DEC
, offset
);
5505 fprintf (dump_file
, " (caller_count: %i)\n", caller_count
);
5508 if (!good_cloning_opportunity_p (node
, val
->local_time_benefit
,
5509 freq_sum
, count_sum
,
5510 val
->local_size_cost
)
5511 && !good_cloning_opportunity_p (node
,
5512 val
->local_time_benefit
5513 + val
->prop_time_benefit
,
5514 freq_sum
, count_sum
,
5515 safe_add (val
->local_size_cost
,
5516 val
->prop_size_cost
)))
5520 fprintf (dump_file
, " Creating a specialized node of %s.\n",
5521 node
->dump_name ());
5523 vec
<tree
> known_csts
;
5524 vec
<ipa_polymorphic_call_context
> known_contexts
;
5526 callers
= gather_edges_for_value (val
, node
, caller_count
);
5528 copy_known_vectors_add_val (avals
, &known_csts
, &known_contexts
, val
, index
);
5531 known_csts
= avals
->m_known_vals
.copy ();
5532 known_contexts
= copy_useful_known_contexts (avals
->m_known_contexts
);
5534 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
5535 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
5536 aggvals
= find_aggregate_values_for_callers_subset (node
, callers
);
5537 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals
, index
,
5538 offset
, val
->value
));
5539 val
->spec_node
= create_specialized_node (node
, known_csts
, known_contexts
,
5541 overall_size
+= val
->local_size_cost
;
5542 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5543 fprintf (dump_file
, " overall size reached %li\n",
5546 /* TODO: If for some lattice there is only one other known value
5547 left, make a special node for it too. */
5552 /* Decide whether and what specialized clones of NODE should be created. */
5555 decide_whether_version_node (struct cgraph_node
*node
)
5557 class ipa_node_params
*info
= IPA_NODE_REF (node
);
5558 int i
, count
= ipa_get_param_count (info
);
5564 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5565 fprintf (dump_file
, "\nEvaluating opportunities for %s.\n",
5566 node
->dump_name ());
5568 ipa_auto_call_arg_values avals
;
5569 gather_context_independent_values (info
, &avals
, false, NULL
);
5571 for (i
= 0; i
< count
;i
++)
5573 class ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5574 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
5575 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
5578 && !avals
.m_known_vals
[i
])
5580 ipcp_value
<tree
> *val
;
5581 for (val
= lat
->values
; val
; val
= val
->next
)
5582 ret
|= decide_about_value (node
, i
, -1, val
, &avals
);
5585 if (!plats
->aggs_bottom
)
5587 struct ipcp_agg_lattice
*aglat
;
5588 ipcp_value
<tree
> *val
;
5589 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
5590 if (!aglat
->bottom
&& aglat
->values
5591 /* If the following is false, the one value has been considered
5592 for cloning for all contexts. */
5593 && (plats
->aggs_contain_variable
5594 || !aglat
->is_single_const ()))
5595 for (val
= aglat
->values
; val
; val
= val
->next
)
5596 ret
|= decide_about_value (node
, i
, aglat
->offset
, val
, &avals
);
5600 && avals
.m_known_contexts
[i
].useless_p ())
5602 ipcp_value
<ipa_polymorphic_call_context
> *val
;
5603 for (val
= ctxlat
->values
; val
; val
= val
->next
)
5604 ret
|= decide_about_value (node
, i
, -1, val
, &avals
);
5607 info
= IPA_NODE_REF (node
);
5610 if (info
->do_clone_for_all_contexts
)
5612 if (!dbg_cnt (ipa_cp_values
))
5614 info
->do_clone_for_all_contexts
= false;
5618 struct cgraph_node
*clone
;
5619 vec
<cgraph_edge
*> callers
= node
->collect_callers ();
5621 for (int i
= callers
.length () - 1; i
>= 0; i
--)
5623 cgraph_edge
*cs
= callers
[i
];
5624 class ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
5626 if (caller_info
&& caller_info
->node_dead
)
5627 callers
.unordered_remove (i
);
5630 if (!adjust_callers_for_value_intersection (callers
, node
))
5632 /* If node is not called by anyone, or all its caller edges are
5633 self-recursive, the node is not really in use, no need to do
5636 info
->do_clone_for_all_contexts
= false;
5641 fprintf (dump_file
, " - Creating a specialized node of %s "
5642 "for all known contexts.\n", node
->dump_name ());
5644 vec
<tree
> known_csts
= avals
.m_known_vals
.copy ();
5645 vec
<ipa_polymorphic_call_context
> known_contexts
5646 = copy_useful_known_contexts (avals
.m_known_contexts
);
5647 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
5648 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
5649 ipa_agg_replacement_value
*aggvals
5650 = find_aggregate_values_for_callers_subset (node
, callers
);
5652 if (!known_contexts_useful_p (known_contexts
))
5654 known_contexts
.release ();
5655 known_contexts
= vNULL
;
5657 clone
= create_specialized_node (node
, known_csts
, known_contexts
,
5659 info
= IPA_NODE_REF (node
);
5660 info
->do_clone_for_all_contexts
= false;
5661 IPA_NODE_REF (clone
)->is_all_contexts_clone
= true;
5668 /* Transitively mark all callees of NODE within the same SCC as not dead. */
5671 spread_undeadness (struct cgraph_node
*node
)
5673 struct cgraph_edge
*cs
;
5675 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
5676 if (ipa_edge_within_scc (cs
))
5678 struct cgraph_node
*callee
;
5679 class ipa_node_params
*info
;
5681 callee
= cs
->callee
->function_symbol (NULL
);
5682 info
= IPA_NODE_REF (callee
);
5684 if (info
&& info
->node_dead
)
5686 info
->node_dead
= 0;
5687 spread_undeadness (callee
);
5692 /* Return true if NODE has a caller from outside of its SCC that is not
5693 dead. Worker callback for cgraph_for_node_and_aliases. */
5696 has_undead_caller_from_outside_scc_p (struct cgraph_node
*node
,
5697 void *data ATTRIBUTE_UNUSED
)
5699 struct cgraph_edge
*cs
;
5701 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
5702 if (cs
->caller
->thunk
5703 && cs
->caller
->call_for_symbol_thunks_and_aliases
5704 (has_undead_caller_from_outside_scc_p
, NULL
, true))
5706 else if (!ipa_edge_within_scc (cs
)
5707 && (!IPA_NODE_REF (cs
->caller
) /* Unoptimized caller. */
5708 || !IPA_NODE_REF (cs
->caller
)->node_dead
))
5714 /* Identify nodes within the same SCC as NODE which are no longer needed
5715 because of new clones and will be removed as unreachable. */
5718 identify_dead_nodes (struct cgraph_node
*node
)
5720 struct cgraph_node
*v
;
5721 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5724 && !v
->call_for_symbol_thunks_and_aliases
5725 (has_undead_caller_from_outside_scc_p
, NULL
, true))
5726 IPA_NODE_REF (v
)->node_dead
= 1;
5728 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5729 if (IPA_NODE_REF (v
) && !IPA_NODE_REF (v
)->node_dead
)
5730 spread_undeadness (v
);
5732 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5734 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5735 if (IPA_NODE_REF (v
) && IPA_NODE_REF (v
)->node_dead
)
5736 fprintf (dump_file
, " Marking node as dead: %s.\n", v
->dump_name ());
5740 /* The decision stage. Iterate over the topological order of call graph nodes
5741 TOPO and make specialized clones if deemed beneficial. */
5744 ipcp_decision_stage (class ipa_topo_info
*topo
)
5749 fprintf (dump_file
, "\nIPA decision stage:\n\n");
5751 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
5753 struct cgraph_node
*node
= topo
->order
[i
];
5754 bool change
= false, iterate
= true;
5758 struct cgraph_node
*v
;
5760 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
5761 if (v
->has_gimple_body_p ()
5762 && ipcp_versionable_function_p (v
))
5763 iterate
|= decide_whether_version_node (v
);
5768 identify_dead_nodes (node
);
5772 /* Look up all the bits information that we have discovered and copy it over
5773 to the transformation summary. */
5776 ipcp_store_bits_results (void)
5780 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5782 ipa_node_params
*info
= IPA_NODE_REF (node
);
5783 bool dumped_sth
= false;
5784 bool found_useful_result
= false;
5786 if (!opt_for_fn (node
->decl
, flag_ipa_bit_cp
) || !info
)
5789 fprintf (dump_file
, "Not considering %s for ipa bitwise propagation "
5790 "; -fipa-bit-cp: disabled.\n",
5791 node
->dump_name ());
5795 if (info
->ipcp_orig_node
)
5796 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
5797 if (!info
->lattices
)
5798 /* Newly expanded artificial thunks do not have lattices. */
5801 unsigned count
= ipa_get_param_count (info
);
5802 for (unsigned i
= 0; i
< count
; i
++)
5804 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5805 if (plats
->bits_lattice
.constant_p ())
5807 found_useful_result
= true;
5812 if (!found_useful_result
)
5815 ipcp_transformation_initialize ();
5816 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5817 vec_safe_reserve_exact (ts
->bits
, count
);
5819 for (unsigned i
= 0; i
< count
; i
++)
5821 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5824 if (plats
->bits_lattice
.constant_p ())
5827 = ipa_get_ipa_bits_for_value (plats
->bits_lattice
.get_value (),
5828 plats
->bits_lattice
.get_mask ());
5829 if (!dbg_cnt (ipa_cp_bits
))
5835 ts
->bits
->quick_push (jfbits
);
5836 if (!dump_file
|| !jfbits
)
5840 fprintf (dump_file
, "Propagated bits info for function %s:\n",
5841 node
->dump_name ());
5844 fprintf (dump_file
, " param %i: value = ", i
);
5845 print_hex (jfbits
->value
, dump_file
);
5846 fprintf (dump_file
, ", mask = ");
5847 print_hex (jfbits
->mask
, dump_file
);
5848 fprintf (dump_file
, "\n");
5853 /* Look up all VR information that we have discovered and copy it over
5854 to the transformation summary. */
5857 ipcp_store_vr_results (void)
5861 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5863 ipa_node_params
*info
= IPA_NODE_REF (node
);
5864 bool found_useful_result
= false;
5866 if (!info
|| !opt_for_fn (node
->decl
, flag_ipa_vrp
))
5869 fprintf (dump_file
, "Not considering %s for VR discovery "
5870 "and propagate; -fipa-ipa-vrp: disabled.\n",
5871 node
->dump_name ());
5875 if (info
->ipcp_orig_node
)
5876 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
5877 if (!info
->lattices
)
5878 /* Newly expanded artificial thunks do not have lattices. */
5881 unsigned count
= ipa_get_param_count (info
);
5882 for (unsigned i
= 0; i
< count
; i
++)
5884 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5885 if (!plats
->m_value_range
.bottom_p ()
5886 && !plats
->m_value_range
.top_p ())
5888 found_useful_result
= true;
5892 if (!found_useful_result
)
5895 ipcp_transformation_initialize ();
5896 ipcp_transformation
*ts
= ipcp_transformation_sum
->get_create (node
);
5897 vec_safe_reserve_exact (ts
->m_vr
, count
);
5899 for (unsigned i
= 0; i
< count
; i
++)
5901 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
5904 if (!plats
->m_value_range
.bottom_p ()
5905 && !plats
->m_value_range
.top_p ()
5906 && dbg_cnt (ipa_cp_vr
))
5909 vr
.type
= plats
->m_value_range
.m_vr
.kind ();
5910 vr
.min
= wi::to_wide (plats
->m_value_range
.m_vr
.min ());
5911 vr
.max
= wi::to_wide (plats
->m_value_range
.m_vr
.max ());
5916 vr
.type
= VR_VARYING
;
5917 vr
.min
= vr
.max
= wi::zero (INT_TYPE_SIZE
);
5919 ts
->m_vr
->quick_push (vr
);
5924 /* The IPCP driver. */
5929 class ipa_topo_info topo
;
5931 if (edge_clone_summaries
== NULL
)
5932 edge_clone_summaries
= new edge_clone_summary_t (symtab
);
5934 ipa_check_create_node_params ();
5935 ipa_check_create_edge_args ();
5936 clone_num_suffixes
= new hash_map
<const char *, unsigned>;
5940 fprintf (dump_file
, "\nIPA structures before propagation:\n");
5941 if (dump_flags
& TDF_DETAILS
)
5942 ipa_print_all_params (dump_file
);
5943 ipa_print_all_jump_functions (dump_file
);
5946 /* Topological sort. */
5947 build_toporder_info (&topo
);
5948 /* Do the interprocedural propagation. */
5949 ipcp_propagate_stage (&topo
);
5950 /* Decide what constant propagation and cloning should be performed. */
5951 ipcp_decision_stage (&topo
);
5952 /* Store results of bits propagation. */
5953 ipcp_store_bits_results ();
5954 /* Store results of value range propagation. */
5955 ipcp_store_vr_results ();
5957 /* Free all IPCP structures. */
5958 delete clone_num_suffixes
;
5959 free_toporder_info (&topo
);
5960 delete edge_clone_summaries
;
5961 edge_clone_summaries
= NULL
;
5962 ipa_free_all_structures_after_ipa_cp ();
5964 fprintf (dump_file
, "\nIPA constant propagation end\n");
5968 /* Initialization and computation of IPCP data structures. This is the initial
5969 intraprocedural analysis of functions, which gathers information to be
5970 propagated later on. */
5973 ipcp_generate_summary (void)
5975 struct cgraph_node
*node
;
5978 fprintf (dump_file
, "\nIPA constant propagation start:\n");
5979 ipa_register_cgraph_hooks ();
5981 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5982 ipa_analyze_node (node
);
5987 const pass_data pass_data_ipa_cp
=
5989 IPA_PASS
, /* type */
5991 OPTGROUP_NONE
, /* optinfo_flags */
5992 TV_IPA_CONSTANT_PROP
, /* tv_id */
5993 0, /* properties_required */
5994 0, /* properties_provided */
5995 0, /* properties_destroyed */
5996 0, /* todo_flags_start */
5997 ( TODO_dump_symtab
| TODO_remove_functions
), /* todo_flags_finish */
6000 class pass_ipa_cp
: public ipa_opt_pass_d
6003 pass_ipa_cp (gcc::context
*ctxt
)
6004 : ipa_opt_pass_d (pass_data_ipa_cp
, ctxt
,
6005 ipcp_generate_summary
, /* generate_summary */
6006 NULL
, /* write_summary */
6007 NULL
, /* read_summary */
6008 ipcp_write_transformation_summaries
, /*
6009 write_optimization_summary */
6010 ipcp_read_transformation_summaries
, /*
6011 read_optimization_summary */
6012 NULL
, /* stmt_fixup */
6013 0, /* function_transform_todo_flags_start */
6014 ipcp_transform_function
, /* function_transform */
6015 NULL
) /* variable_transform */
6018 /* opt_pass methods: */
6019 virtual bool gate (function
*)
6021 /* FIXME: We should remove the optimize check after we ensure we never run
6022 IPA passes when not optimizing. */
6023 return (flag_ipa_cp
&& optimize
) || in_lto_p
;
6026 virtual unsigned int execute (function
*) { return ipcp_driver (); }
6028 }; // class pass_ipa_cp
6033 make_pass_ipa_cp (gcc::context
*ctxt
)
6035 return new pass_ipa_cp (ctxt
);
6038 /* Reset all state within ipa-cp.c so that we can rerun the compiler
6039 within the same process. For use by toplev::finalize. */
6042 ipa_cp_c_finalize (void)
6044 max_count
= profile_count::uninitialized ();
6046 orig_overall_size
= 0;
6047 ipcp_free_transformation_sum ();