1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2018 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* Interprocedural constant propagation (IPA-CP).
25 The goal of this transformation is to
27 1) discover functions which are always invoked with some arguments with the
28 same known constant values and modify the functions so that the
29 subsequent optimizations can take advantage of the knowledge, and
31 2) partial specialization - create specialized versions of functions
32 transformed in this way if some parameters are known constants only in
33 certain contexts but the estimated tradeoff between speedup and cost size
36 The algorithm also propagates types and attempts to perform type based
37 devirtualization. Types are propagated much like constants.
39 The algorithm basically consists of three stages. In the first, functions
40 are analyzed one at a time and jump functions are constructed for all known
41 call-sites. In the second phase, the pass propagates information from the
42 jump functions across the call to reveal what values are available at what
43 call sites, performs estimations of effects of known values on functions and
44 their callees, and finally decides what specialized extra versions should be
45 created. In the third, the special versions materialize and appropriate
48 The algorithm used is to a certain extent based on "Interprocedural Constant
49 Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
50 Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
51 Cooper, Mary W. Hall, and Ken Kennedy.
54 First stage - intraprocedural analysis
55 =======================================
57 This phase computes jump_function and modification flags.
59 A jump function for a call-site represents the values passed as an actual
60 arguments of a given call-site. In principle, there are three types of
63 Pass through - the caller's formal parameter is passed as an actual
64 argument, plus an operation on it can be performed.
65 Constant - a constant is passed as an actual argument.
66 Unknown - neither of the above.
68 All jump function types are described in detail in ipa-prop.h, together with
69 the data structures that represent them and methods of accessing them.
71 ipcp_generate_summary() is the main function of the first stage.
73 Second stage - interprocedural analysis
74 ========================================
76 This stage is itself divided into two phases. In the first, we propagate
77 known values over the call graph, in the second, we make cloning decisions.
78 It uses a different algorithm than the original Callahan's paper.
80 First, we traverse the functions topologically from callers to callees and,
81 for each strongly connected component (SCC), we propagate constants
82 according to previously computed jump functions. We also record what known
83 values depend on other known values and estimate local effects. Finally, we
84 propagate cumulative information about these effects from dependent values
85 to those on which they depend.
87 Second, we again traverse the call graph in the same topological order and
88 make clones for functions which we know are called with the same values in
89 all contexts and decide about extra specialized clones of functions just for
90 some contexts - these decisions are based on both local estimates and
91 cumulative estimates propagated from callees.
93 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
96 Third phase - materialization of clones, call statement updates.
97 ============================================
99 This stage is currently performed by call graph code (mainly in cgraphunit.c
100 and tree-inline.c) according to instructions inserted to the call graph by
105 #include "coretypes.h"
108 #include "gimple-expr.h"
110 #include "alloc-pool.h"
111 #include "tree-pass.h"
113 #include "diagnostic.h"
114 #include "fold-const.h"
115 #include "gimple-fold.h"
116 #include "symbol-summary.h"
117 #include "tree-vrp.h"
118 #include "ipa-prop.h"
119 #include "tree-pretty-print.h"
120 #include "tree-inline.h"
122 #include "ipa-fnsummary.h"
123 #include "ipa-utils.h"
124 #include "tree-ssa-ccp.h"
125 #include "stringpool.h"
128 template <typename valtype
> class ipcp_value
;
130 /* Describes a particular source for an IPA-CP value. */
132 template <typename valtype
>
133 class ipcp_value_source
136 /* Aggregate offset of the source, negative if the source is scalar value of
137 the argument itself. */
138 HOST_WIDE_INT offset
;
139 /* The incoming edge that brought the value. */
141 /* If the jump function that resulted into his value was a pass-through or an
142 ancestor, this is the ipcp_value of the caller from which the described
143 value has been derived. Otherwise it is NULL. */
144 ipcp_value
<valtype
> *val
;
145 /* Next pointer in a linked list of sources of a value. */
146 ipcp_value_source
*next
;
147 /* If the jump function that resulted into his value was a pass-through or an
148 ancestor, this is the index of the parameter of the caller the jump
149 function references. */
153 /* Common ancestor for all ipcp_value instantiations. */
155 class ipcp_value_base
158 /* Time benefit and size cost that specializing the function for this value
159 would bring about in this function alone. */
160 int local_time_benefit
, local_size_cost
;
161 /* Time benefit and size cost that specializing the function for this value
162 can bring about in it's callees (transitively). */
163 int prop_time_benefit
, prop_size_cost
;
166 : local_time_benefit (0), local_size_cost (0),
167 prop_time_benefit (0), prop_size_cost (0) {}
170 /* Describes one particular value stored in struct ipcp_lattice. */
172 template <typename valtype
>
173 class ipcp_value
: public ipcp_value_base
176 /* The actual value for the given parameter. */
178 /* The list of sources from which this value originates. */
179 ipcp_value_source
<valtype
> *sources
;
180 /* Next pointers in a linked list of all values in a lattice. */
182 /* Next pointers in a linked list of values in a strongly connected component
184 ipcp_value
*scc_next
;
185 /* Next pointers in a linked list of SCCs of values sorted topologically
186 according their sources. */
187 ipcp_value
*topo_next
;
188 /* A specialized node created for this value, NULL if none has been (so far)
190 cgraph_node
*spec_node
;
191 /* Depth first search number and low link for topological sorting of
194 /* True if this valye is currently on the topo-sort stack. */
198 : sources (0), next (0), scc_next (0), topo_next (0),
199 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
201 void add_source (cgraph_edge
*cs
, ipcp_value
*src_val
, int src_idx
,
202 HOST_WIDE_INT offset
);
205 /* Lattice describing potential values of a formal parameter of a function, or
206 a part of an aggregate. TOP is represented by a lattice with zero values
207 and with contains_variable and bottom flags cleared. BOTTOM is represented
208 by a lattice with the bottom flag set. In that case, values and
209 contains_variable flag should be disregarded. */
211 template <typename valtype
>
215 /* The list of known values and types in this lattice. Note that values are
216 not deallocated if a lattice is set to bottom because there may be value
217 sources referencing them. */
218 ipcp_value
<valtype
> *values
;
219 /* Number of known values and types in this lattice. */
221 /* The lattice contains a variable component (in addition to values). */
222 bool contains_variable
;
223 /* The value of the lattice is bottom (i.e. variable and unusable for any
227 inline bool is_single_const ();
228 inline bool set_to_bottom ();
229 inline bool set_contains_variable ();
230 bool add_value (valtype newval
, cgraph_edge
*cs
,
231 ipcp_value
<valtype
> *src_val
= NULL
,
232 int src_idx
= 0, HOST_WIDE_INT offset
= -1);
233 void print (FILE * f
, bool dump_sources
, bool dump_benefits
);
236 /* Lattice of tree values with an offset to describe a part of an
239 class ipcp_agg_lattice
: public ipcp_lattice
<tree
>
242 /* Offset that is being described by this lattice. */
243 HOST_WIDE_INT offset
;
244 /* Size so that we don't have to re-compute it every time we traverse the
245 list. Must correspond to TYPE_SIZE of all lat values. */
247 /* Next element of the linked list. */
248 struct ipcp_agg_lattice
*next
;
251 /* Lattice of known bits, only capable of holding one value.
252 Bitwise constant propagation propagates which bits of a
268 In the above case, the param 'x' will always have all
269 the bits (except the bits in lsb) set to 0.
270 Hence the mask of 'x' would be 0xff. The mask
271 reflects that the bits in lsb are unknown.
272 The actual propagated value is given by m_value & ~m_mask. */
274 class ipcp_bits_lattice
277 bool bottom_p () { return m_lattice_val
== IPA_BITS_VARYING
; }
278 bool top_p () { return m_lattice_val
== IPA_BITS_UNDEFINED
; }
279 bool constant_p () { return m_lattice_val
== IPA_BITS_CONSTANT
; }
280 bool set_to_bottom ();
281 bool set_to_constant (widest_int
, widest_int
);
283 widest_int
get_value () { return m_value
; }
284 widest_int
get_mask () { return m_mask
; }
286 bool meet_with (ipcp_bits_lattice
& other
, unsigned, signop
,
287 enum tree_code
, tree
);
289 bool meet_with (widest_int
, widest_int
, unsigned);
294 enum { IPA_BITS_UNDEFINED
, IPA_BITS_CONSTANT
, IPA_BITS_VARYING
} m_lattice_val
;
296 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
297 If a bit in mask is set to 0, then the corresponding bit in
298 value is known to be constant. */
299 widest_int m_value
, m_mask
;
301 bool meet_with_1 (widest_int
, widest_int
, unsigned);
302 void get_value_and_mask (tree
, widest_int
*, widest_int
*);
305 /* Lattice of value ranges. */
307 class ipcp_vr_lattice
312 inline bool bottom_p () const;
313 inline bool top_p () const;
314 inline bool set_to_bottom ();
315 bool meet_with (const value_range
*p_vr
);
316 bool meet_with (const ipcp_vr_lattice
&other
);
317 void init () { m_vr
.type
= VR_UNDEFINED
; }
318 void print (FILE * f
);
321 bool meet_with_1 (const value_range
*other_vr
);
324 /* Structure containing lattices for a parameter itself and for pieces of
325 aggregates that are passed in the parameter or by a reference in a parameter
326 plus some other useful flags. */
328 class ipcp_param_lattices
331 /* Lattice describing the value of the parameter itself. */
332 ipcp_lattice
<tree
> itself
;
333 /* Lattice describing the polymorphic contexts of a parameter. */
334 ipcp_lattice
<ipa_polymorphic_call_context
> ctxlat
;
335 /* Lattices describing aggregate parts. */
336 ipcp_agg_lattice
*aggs
;
337 /* Lattice describing known bits. */
338 ipcp_bits_lattice bits_lattice
;
339 /* Lattice describing value range. */
340 ipcp_vr_lattice m_value_range
;
341 /* Number of aggregate lattices */
343 /* True if aggregate data were passed by reference (as opposed to by
346 /* All aggregate lattices contain a variable component (in addition to
348 bool aggs_contain_variable
;
349 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
350 for any propagation). */
353 /* There is a virtual call based on this parameter. */
357 /* Allocation pools for values and their sources in ipa-cp. */
359 object_allocator
<ipcp_value
<tree
> > ipcp_cst_values_pool
360 ("IPA-CP constant values");
362 object_allocator
<ipcp_value
<ipa_polymorphic_call_context
> >
363 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
365 object_allocator
<ipcp_value_source
<tree
> > ipcp_sources_pool
366 ("IPA-CP value sources");
368 object_allocator
<ipcp_agg_lattice
> ipcp_agg_lattice_pool
369 ("IPA_CP aggregate lattices");
371 /* Maximal count found in program. */
373 static profile_count max_count
;
375 /* Original overall size of the program. */
377 static long overall_size
, max_new_size
;
379 /* Return the param lattices structure corresponding to the Ith formal
380 parameter of the function described by INFO. */
381 static inline struct ipcp_param_lattices
*
382 ipa_get_parm_lattices (struct ipa_node_params
*info
, int i
)
384 gcc_assert (i
>= 0 && i
< ipa_get_param_count (info
));
385 gcc_checking_assert (!info
->ipcp_orig_node
);
386 gcc_checking_assert (info
->lattices
);
387 return &(info
->lattices
[i
]);
390 /* Return the lattice corresponding to the scalar value of the Ith formal
391 parameter of the function described by INFO. */
392 static inline ipcp_lattice
<tree
> *
393 ipa_get_scalar_lat (struct ipa_node_params
*info
, int i
)
395 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
396 return &plats
->itself
;
399 /* Return the lattice corresponding to the scalar value of the Ith formal
400 parameter of the function described by INFO. */
401 static inline ipcp_lattice
<ipa_polymorphic_call_context
> *
402 ipa_get_poly_ctx_lat (struct ipa_node_params
*info
, int i
)
404 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
405 return &plats
->ctxlat
;
408 /* Return the lattice corresponding to the value range of the Ith formal
409 parameter of the function described by INFO. */
411 static inline ipcp_vr_lattice
*
412 ipa_get_vr_lat (struct ipa_node_params
*info
, int i
)
414 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
415 return &plats
->m_value_range
;
418 /* Return whether LAT is a lattice with a single constant and without an
421 template <typename valtype
>
423 ipcp_lattice
<valtype
>::is_single_const ()
425 if (bottom
|| contains_variable
|| values_count
!= 1)
431 /* Print V which is extracted from a value in a lattice to F. */
434 print_ipcp_constant_value (FILE * f
, tree v
)
436 if (TREE_CODE (v
) == ADDR_EXPR
437 && TREE_CODE (TREE_OPERAND (v
, 0)) == CONST_DECL
)
440 print_generic_expr (f
, DECL_INITIAL (TREE_OPERAND (v
, 0)));
443 print_generic_expr (f
, v
);
446 /* Print V which is extracted from a value in a lattice to F. */
449 print_ipcp_constant_value (FILE * f
, ipa_polymorphic_call_context v
)
454 /* Print a lattice LAT to F. */
456 template <typename valtype
>
458 ipcp_lattice
<valtype
>::print (FILE * f
, bool dump_sources
, bool dump_benefits
)
460 ipcp_value
<valtype
> *val
;
465 fprintf (f
, "BOTTOM\n");
469 if (!values_count
&& !contains_variable
)
471 fprintf (f
, "TOP\n");
475 if (contains_variable
)
477 fprintf (f
, "VARIABLE");
483 for (val
= values
; val
; val
= val
->next
)
485 if (dump_benefits
&& prev
)
487 else if (!dump_benefits
&& prev
)
492 print_ipcp_constant_value (f
, val
->value
);
496 ipcp_value_source
<valtype
> *s
;
498 fprintf (f
, " [from:");
499 for (s
= val
->sources
; s
; s
= s
->next
)
500 fprintf (f
, " %i(%f)", s
->cs
->caller
->order
,
501 s
->cs
->sreal_frequency ().to_double ());
506 fprintf (f
, " [loc_time: %i, loc_size: %i, "
507 "prop_time: %i, prop_size: %i]\n",
508 val
->local_time_benefit
, val
->local_size_cost
,
509 val
->prop_time_benefit
, val
->prop_size_cost
);
516 ipcp_bits_lattice::print (FILE *f
)
519 fprintf (f
, " Bits unknown (TOP)\n");
520 else if (bottom_p ())
521 fprintf (f
, " Bits unusable (BOTTOM)\n");
524 fprintf (f
, " Bits: value = "); print_hex (get_value (), f
);
525 fprintf (f
, ", mask = "); print_hex (get_mask (), f
);
530 /* Print value range lattice to F. */
533 ipcp_vr_lattice::print (FILE * f
)
535 dump_value_range (f
, &m_vr
);
538 /* Print all ipcp_lattices of all functions to F. */
541 print_all_lattices (FILE * f
, bool dump_sources
, bool dump_benefits
)
543 struct cgraph_node
*node
;
546 fprintf (f
, "\nLattices:\n");
547 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
549 struct ipa_node_params
*info
;
551 info
= IPA_NODE_REF (node
);
552 fprintf (f
, " Node: %s:\n", node
->dump_name ());
553 count
= ipa_get_param_count (info
);
554 for (i
= 0; i
< count
; i
++)
556 struct ipcp_agg_lattice
*aglat
;
557 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
558 fprintf (f
, " param [%d]: ", i
);
559 plats
->itself
.print (f
, dump_sources
, dump_benefits
);
560 fprintf (f
, " ctxs: ");
561 plats
->ctxlat
.print (f
, dump_sources
, dump_benefits
);
562 plats
->bits_lattice
.print (f
);
564 plats
->m_value_range
.print (f
);
566 if (plats
->virt_call
)
567 fprintf (f
, " virt_call flag set\n");
569 if (plats
->aggs_bottom
)
571 fprintf (f
, " AGGS BOTTOM\n");
574 if (plats
->aggs_contain_variable
)
575 fprintf (f
, " AGGS VARIABLE\n");
576 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
578 fprintf (f
, " %soffset " HOST_WIDE_INT_PRINT_DEC
": ",
579 plats
->aggs_by_ref
? "ref " : "", aglat
->offset
);
580 aglat
->print (f
, dump_sources
, dump_benefits
);
586 /* Determine whether it is at all technically possible to create clones of NODE
587 and store this information in the ipa_node_params structure associated
591 determine_versionability (struct cgraph_node
*node
,
592 struct ipa_node_params
*info
)
594 const char *reason
= NULL
;
596 /* There are a number of generic reasons functions cannot be versioned. We
597 also cannot remove parameters if there are type attributes such as fnspec
599 if (node
->alias
|| node
->thunk
.thunk_p
)
600 reason
= "alias or thunk";
601 else if (!node
->local
.versionable
)
602 reason
= "not a tree_versionable_function";
603 else if (node
->get_availability () <= AVAIL_INTERPOSABLE
)
604 reason
= "insufficient body availability";
605 else if (!opt_for_fn (node
->decl
, optimize
)
606 || !opt_for_fn (node
->decl
, flag_ipa_cp
))
607 reason
= "non-optimized function";
608 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node
->decl
)))
610 /* Ideally we should clone the SIMD clones themselves and create
611 vector copies of them, so IPA-cp and SIMD clones can happily
612 coexist, but that may not be worth the effort. */
613 reason
= "function has SIMD clones";
615 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node
->decl
)))
617 /* Ideally we should clone the target clones themselves and create
618 copies of them, so IPA-cp and target clones can happily
619 coexist, but that may not be worth the effort. */
620 reason
= "function target_clones attribute";
622 /* Don't clone decls local to a comdat group; it breaks and for C++
623 decloned constructors, inlining is always better anyway. */
624 else if (node
->comdat_local_p ())
625 reason
= "comdat-local function";
626 else if (node
->calls_comdat_local
)
628 /* TODO: call is versionable if we make sure that all
629 callers are inside of a comdat group. */
630 reason
= "calls comdat-local function";
633 if (reason
&& dump_file
&& !node
->alias
&& !node
->thunk
.thunk_p
)
634 fprintf (dump_file
, "Function %s is not versionable, reason: %s.\n",
635 node
->dump_name (), reason
);
637 info
->versionable
= (reason
== NULL
);
640 /* Return true if it is at all technically possible to create clones of a
644 ipcp_versionable_function_p (struct cgraph_node
*node
)
646 return IPA_NODE_REF (node
)->versionable
;
649 /* Structure holding accumulated information about callers of a node. */
651 struct caller_statistics
653 profile_count count_sum
;
654 int n_calls
, n_hot_calls
, freq_sum
;
657 /* Initialize fields of STAT to zeroes. */
660 init_caller_stats (struct caller_statistics
*stats
)
662 stats
->count_sum
= profile_count::zero ();
664 stats
->n_hot_calls
= 0;
668 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
669 non-thunk incoming edges to NODE. */
672 gather_caller_stats (struct cgraph_node
*node
, void *data
)
674 struct caller_statistics
*stats
= (struct caller_statistics
*) data
;
675 struct cgraph_edge
*cs
;
677 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
678 if (!cs
->caller
->thunk
.thunk_p
)
680 if (cs
->count
.ipa ().initialized_p ())
681 stats
->count_sum
+= cs
->count
.ipa ();
682 stats
->freq_sum
+= cs
->frequency ();
684 if (cs
->maybe_hot_p ())
685 stats
->n_hot_calls
++;
691 /* Return true if this NODE is viable candidate for cloning. */
694 ipcp_cloning_candidate_p (struct cgraph_node
*node
)
696 struct caller_statistics stats
;
698 gcc_checking_assert (node
->has_gimple_body_p ());
700 if (!opt_for_fn (node
->decl
, flag_ipa_cp_clone
))
703 fprintf (dump_file
, "Not considering %s for cloning; "
704 "-fipa-cp-clone disabled.\n",
709 if (node
->optimize_for_size_p ())
712 fprintf (dump_file
, "Not considering %s for cloning; "
713 "optimizing it for size.\n",
718 init_caller_stats (&stats
);
719 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
, false);
721 if (ipa_fn_summaries
->get (node
)->self_size
< stats
.n_calls
)
724 fprintf (dump_file
, "Considering %s for cloning; code might shrink.\n",
729 /* When profile is available and function is hot, propagate into it even if
730 calls seems cold; constant propagation can improve function's speed
732 if (max_count
> profile_count::zero ())
734 if (stats
.count_sum
> node
->count
.ipa ().apply_scale (90, 100))
737 fprintf (dump_file
, "Considering %s for cloning; "
738 "usually called directly.\n",
743 if (!stats
.n_hot_calls
)
746 fprintf (dump_file
, "Not considering %s for cloning; no hot calls.\n",
751 fprintf (dump_file
, "Considering %s for cloning.\n",
756 template <typename valtype
>
757 class value_topo_info
760 /* Head of the linked list of topologically sorted values. */
761 ipcp_value
<valtype
> *values_topo
;
762 /* Stack for creating SCCs, represented by a linked list too. */
763 ipcp_value
<valtype
> *stack
;
764 /* Counter driving the algorithm in add_val_to_toposort. */
767 value_topo_info () : values_topo (NULL
), stack (NULL
), dfs_counter (0)
769 void add_val (ipcp_value
<valtype
> *cur_val
);
770 void propagate_effects ();
773 /* Arrays representing a topological ordering of call graph nodes and a stack
774 of nodes used during constant propagation and also data required to perform
775 topological sort of values and propagation of benefits in the determined
781 /* Array with obtained topological order of cgraph nodes. */
782 struct cgraph_node
**order
;
783 /* Stack of cgraph nodes used during propagation within SCC until all values
784 in the SCC stabilize. */
785 struct cgraph_node
**stack
;
786 int nnodes
, stack_top
;
788 value_topo_info
<tree
> constants
;
789 value_topo_info
<ipa_polymorphic_call_context
> contexts
;
791 ipa_topo_info () : order(NULL
), stack(NULL
), nnodes(0), stack_top(0),
796 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
799 build_toporder_info (struct ipa_topo_info
*topo
)
801 topo
->order
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
802 topo
->stack
= XCNEWVEC (struct cgraph_node
*, symtab
->cgraph_count
);
804 gcc_checking_assert (topo
->stack_top
== 0);
805 topo
->nnodes
= ipa_reduced_postorder (topo
->order
, true, true, NULL
);
808 /* Free information about strongly connected components and the arrays in
812 free_toporder_info (struct ipa_topo_info
*topo
)
814 ipa_free_postorder_info ();
819 /* Add NODE to the stack in TOPO, unless it is already there. */
822 push_node_to_stack (struct ipa_topo_info
*topo
, struct cgraph_node
*node
)
824 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
825 if (info
->node_enqueued
)
827 info
->node_enqueued
= 1;
828 topo
->stack
[topo
->stack_top
++] = node
;
831 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
834 static struct cgraph_node
*
835 pop_node_from_stack (struct ipa_topo_info
*topo
)
839 struct cgraph_node
*node
;
841 node
= topo
->stack
[topo
->stack_top
];
842 IPA_NODE_REF (node
)->node_enqueued
= 0;
849 /* Set lattice LAT to bottom and return true if it previously was not set as
852 template <typename valtype
>
854 ipcp_lattice
<valtype
>::set_to_bottom ()
861 /* Mark lattice as containing an unknown value and return true if it previously
862 was not marked as such. */
864 template <typename valtype
>
866 ipcp_lattice
<valtype
>::set_contains_variable ()
868 bool ret
= !contains_variable
;
869 contains_variable
= true;
873 /* Set all aggegate lattices in PLATS to bottom and return true if they were
874 not previously set as such. */
877 set_agg_lats_to_bottom (struct ipcp_param_lattices
*plats
)
879 bool ret
= !plats
->aggs_bottom
;
880 plats
->aggs_bottom
= true;
884 /* Mark all aggegate lattices in PLATS as containing an unknown value and
885 return true if they were not previously marked as such. */
888 set_agg_lats_contain_variable (struct ipcp_param_lattices
*plats
)
890 bool ret
= !plats
->aggs_contain_variable
;
891 plats
->aggs_contain_variable
= true;
896 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice
&other
)
898 return meet_with_1 (&other
.m_vr
);
901 /* Meet the current value of the lattice with value ranfge described by VR
905 ipcp_vr_lattice::meet_with (const value_range
*p_vr
)
907 return meet_with_1 (p_vr
);
910 /* Meet the current value of the lattice with value ranfge described by
914 ipcp_vr_lattice::meet_with_1 (const value_range
*other_vr
)
916 tree min
= m_vr
.min
, max
= m_vr
.max
;
917 value_range_type type
= m_vr
.type
;
922 if (other_vr
->type
== VR_VARYING
)
923 return set_to_bottom ();
925 vrp_meet (&m_vr
, other_vr
);
926 if (type
!= m_vr
.type
934 /* Return true if value range information in the lattice is yet unknown. */
937 ipcp_vr_lattice::top_p () const
939 return m_vr
.type
== VR_UNDEFINED
;
942 /* Return true if value range information in the lattice is known to be
946 ipcp_vr_lattice::bottom_p () const
948 return m_vr
.type
== VR_VARYING
;
951 /* Set value range information in the lattice to bottom. Return true if it
952 previously was in a different state. */
955 ipcp_vr_lattice::set_to_bottom ()
957 if (m_vr
.type
== VR_VARYING
)
959 m_vr
.type
= VR_VARYING
;
963 /* Set lattice value to bottom, if it already isn't the case. */
966 ipcp_bits_lattice::set_to_bottom ()
970 m_lattice_val
= IPA_BITS_VARYING
;
976 /* Set to constant if it isn't already. Only meant to be called
977 when switching state from TOP. */
980 ipcp_bits_lattice::set_to_constant (widest_int value
, widest_int mask
)
982 gcc_assert (top_p ());
983 m_lattice_val
= IPA_BITS_CONSTANT
;
989 /* Convert operand to value, mask form. */
992 ipcp_bits_lattice::get_value_and_mask (tree operand
, widest_int
*valuep
, widest_int
*maskp
)
994 wide_int
get_nonzero_bits (const_tree
);
996 if (TREE_CODE (operand
) == INTEGER_CST
)
998 *valuep
= wi::to_widest (operand
);
1008 /* Meet operation, similar to ccp_lattice_meet, we xor values
1009 if this->value, value have different values at same bit positions, we want
1010 to drop that bit to varying. Return true if mask is changed.
1011 This function assumes that the lattice value is in CONSTANT state */
1014 ipcp_bits_lattice::meet_with_1 (widest_int value
, widest_int mask
,
1017 gcc_assert (constant_p ());
1019 widest_int old_mask
= m_mask
;
1020 m_mask
= (m_mask
| mask
) | (m_value
^ value
);
1022 if (wi::sext (m_mask
, precision
) == -1)
1023 return set_to_bottom ();
1025 return m_mask
!= old_mask
;
1028 /* Meet the bits lattice with operand
1029 described by <value, mask, sgn, precision. */
1032 ipcp_bits_lattice::meet_with (widest_int value
, widest_int mask
,
1040 if (wi::sext (mask
, precision
) == -1)
1041 return set_to_bottom ();
1042 return set_to_constant (value
, mask
);
1045 return meet_with_1 (value
, mask
, precision
);
1048 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1049 if code is binary operation or bit_value_unop (other) if code is unary op.
1050 In the case when code is nop_expr, no adjustment is required. */
1053 ipcp_bits_lattice::meet_with (ipcp_bits_lattice
& other
, unsigned precision
,
1054 signop sgn
, enum tree_code code
, tree operand
)
1056 if (other
.bottom_p ())
1057 return set_to_bottom ();
1059 if (bottom_p () || other
.top_p ())
1062 widest_int adjusted_value
, adjusted_mask
;
1064 if (TREE_CODE_CLASS (code
) == tcc_binary
)
1066 tree type
= TREE_TYPE (operand
);
1067 gcc_assert (INTEGRAL_TYPE_P (type
));
1068 widest_int o_value
, o_mask
;
1069 get_value_and_mask (operand
, &o_value
, &o_mask
);
1071 bit_value_binop (code
, sgn
, precision
, &adjusted_value
, &adjusted_mask
,
1072 sgn
, precision
, other
.get_value (), other
.get_mask (),
1073 TYPE_SIGN (type
), TYPE_PRECISION (type
), o_value
, o_mask
);
1075 if (wi::sext (adjusted_mask
, precision
) == -1)
1076 return set_to_bottom ();
1079 else if (TREE_CODE_CLASS (code
) == tcc_unary
)
1081 bit_value_unop (code
, sgn
, precision
, &adjusted_value
,
1082 &adjusted_mask
, sgn
, precision
, other
.get_value (),
1085 if (wi::sext (adjusted_mask
, precision
) == -1)
1086 return set_to_bottom ();
1090 return set_to_bottom ();
1094 if (wi::sext (adjusted_mask
, precision
) == -1)
1095 return set_to_bottom ();
1096 return set_to_constant (adjusted_value
, adjusted_mask
);
1099 return meet_with_1 (adjusted_value
, adjusted_mask
, precision
);
1102 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1103 return true is any of them has not been marked as such so far. */
1106 set_all_contains_variable (struct ipcp_param_lattices
*plats
)
1109 ret
= plats
->itself
.set_contains_variable ();
1110 ret
|= plats
->ctxlat
.set_contains_variable ();
1111 ret
|= set_agg_lats_contain_variable (plats
);
1112 ret
|= plats
->bits_lattice
.set_to_bottom ();
1113 ret
|= plats
->m_value_range
.set_to_bottom ();
1117 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1118 points to by the number of callers to NODE. */
1121 count_callers (cgraph_node
*node
, void *data
)
1123 int *caller_count
= (int *) data
;
1125 for (cgraph_edge
*cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
1126 /* Local thunks can be handled transparently, but if the thunk can not
1127 be optimized out, count it as a real use. */
1128 if (!cs
->caller
->thunk
.thunk_p
|| !cs
->caller
->local
.local
)
1133 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1134 the one caller of some other node. Set the caller's corresponding flag. */
1137 set_single_call_flag (cgraph_node
*node
, void *)
1139 cgraph_edge
*cs
= node
->callers
;
1140 /* Local thunks can be handled transparently, skip them. */
1141 while (cs
&& cs
->caller
->thunk
.thunk_p
&& cs
->caller
->local
.local
)
1142 cs
= cs
->next_caller
;
1145 IPA_NODE_REF (cs
->caller
)->node_calling_single_call
= true;
1151 /* Initialize ipcp_lattices. */
1154 initialize_node_lattices (struct cgraph_node
*node
)
1156 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
1157 struct cgraph_edge
*ie
;
1158 bool disable
= false, variable
= false;
1161 gcc_checking_assert (node
->has_gimple_body_p ());
1162 if (cgraph_local_p (node
))
1164 int caller_count
= 0;
1165 node
->call_for_symbol_thunks_and_aliases (count_callers
, &caller_count
,
1167 gcc_checking_assert (caller_count
> 0);
1168 if (caller_count
== 1)
1169 node
->call_for_symbol_thunks_and_aliases (set_single_call_flag
,
1174 /* When cloning is allowed, we can assume that externally visible
1175 functions are not called. We will compensate this by cloning
1177 if (ipcp_versionable_function_p (node
)
1178 && ipcp_cloning_candidate_p (node
))
1184 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1186 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1187 plats
->m_value_range
.init ();
1190 if (disable
|| variable
)
1192 for (i
= 0; i
< ipa_get_param_count (info
); i
++)
1194 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
1197 plats
->itself
.set_to_bottom ();
1198 plats
->ctxlat
.set_to_bottom ();
1199 set_agg_lats_to_bottom (plats
);
1200 plats
->bits_lattice
.set_to_bottom ();
1201 plats
->m_value_range
.set_to_bottom ();
1204 set_all_contains_variable (plats
);
1206 if (dump_file
&& (dump_flags
& TDF_DETAILS
)
1207 && !node
->alias
&& !node
->thunk
.thunk_p
)
1208 fprintf (dump_file
, "Marking all lattices of %s as %s\n",
1209 node
->dump_name (), disable
? "BOTTOM" : "VARIABLE");
1212 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
1213 if (ie
->indirect_info
->polymorphic
1214 && ie
->indirect_info
->param_index
>= 0)
1216 gcc_checking_assert (ie
->indirect_info
->param_index
>= 0);
1217 ipa_get_parm_lattices (info
,
1218 ie
->indirect_info
->param_index
)->virt_call
= 1;
1222 /* Return the result of a (possibly arithmetic) pass through jump function
1223 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1224 to which the result is passed. Return NULL_TREE if that cannot be
1225 determined or be considered an interprocedural invariant. */
1228 ipa_get_jf_pass_through_result (struct ipa_jump_func
*jfunc
, tree input
,
1233 if (ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
1235 if (!is_gimple_ip_invariant (input
))
1238 tree_code opcode
= ipa_get_jf_pass_through_operation (jfunc
);
1241 if (TREE_CODE_CLASS (opcode
) == tcc_comparison
)
1242 res_type
= boolean_type_node
;
1243 else if (expr_type_first_operand_type_p (opcode
))
1244 res_type
= TREE_TYPE (input
);
1249 if (TREE_CODE_CLASS (opcode
) == tcc_unary
)
1250 res
= fold_unary (opcode
, res_type
, input
);
1252 res
= fold_binary (opcode
, res_type
, input
,
1253 ipa_get_jf_pass_through_operand (jfunc
));
1255 if (res
&& !is_gimple_ip_invariant (res
))
1261 /* Return the result of an ancestor jump function JFUNC on the constant value
1262 INPUT. Return NULL_TREE if that cannot be determined. */
1265 ipa_get_jf_ancestor_result (struct ipa_jump_func
*jfunc
, tree input
)
1267 gcc_checking_assert (TREE_CODE (input
) != TREE_BINFO
);
1268 if (TREE_CODE (input
) == ADDR_EXPR
)
1270 tree t
= TREE_OPERAND (input
, 0);
1271 t
= build_ref_for_offset (EXPR_LOCATION (t
), t
,
1272 ipa_get_jf_ancestor_offset (jfunc
), false,
1273 ptr_type_node
, NULL
, false);
1274 return build_fold_addr_expr (t
);
1280 /* Determine whether JFUNC evaluates to a single known constant value and if
1281 so, return it. Otherwise return NULL. INFO describes the caller node or
1282 the one it is inlined to, so that pass-through jump functions can be
1283 evaluated. PARM_TYPE is the type of the parameter to which the result is
1287 ipa_value_from_jfunc (struct ipa_node_params
*info
, struct ipa_jump_func
*jfunc
,
1290 if (jfunc
->type
== IPA_JF_CONST
)
1291 return ipa_get_jf_constant (jfunc
);
1292 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1293 || jfunc
->type
== IPA_JF_ANCESTOR
)
1298 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1299 idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1301 idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1303 if (info
->ipcp_orig_node
)
1304 input
= info
->known_csts
[idx
];
1307 ipcp_lattice
<tree
> *lat
;
1310 || idx
>= ipa_get_param_count (info
))
1312 lat
= ipa_get_scalar_lat (info
, idx
);
1313 if (!lat
->is_single_const ())
1315 input
= lat
->values
->value
;
1321 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1322 return ipa_get_jf_pass_through_result (jfunc
, input
, parm_type
);
1324 return ipa_get_jf_ancestor_result (jfunc
, input
);
1330 /* Determie whether JFUNC evaluates to single known polymorphic context, given
1331 that INFO describes the caller node or the one it is inlined to, CS is the
1332 call graph edge corresponding to JFUNC and CSIDX index of the described
1335 ipa_polymorphic_call_context
1336 ipa_context_from_jfunc (ipa_node_params
*info
, cgraph_edge
*cs
, int csidx
,
1337 ipa_jump_func
*jfunc
)
1339 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1340 ipa_polymorphic_call_context ctx
;
1341 ipa_polymorphic_call_context
*edge_ctx
1342 = cs
? ipa_get_ith_polymorhic_call_context (args
, csidx
) : NULL
;
1344 if (edge_ctx
&& !edge_ctx
->useless_p ())
1347 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1348 || jfunc
->type
== IPA_JF_ANCESTOR
)
1350 ipa_polymorphic_call_context srcctx
;
1352 bool type_preserved
= true;
1353 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1355 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1357 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1358 srcidx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1362 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1363 srcidx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1365 if (info
->ipcp_orig_node
)
1367 if (info
->known_contexts
.exists ())
1368 srcctx
= info
->known_contexts
[srcidx
];
1373 || srcidx
>= ipa_get_param_count (info
))
1375 ipcp_lattice
<ipa_polymorphic_call_context
> *lat
;
1376 lat
= ipa_get_poly_ctx_lat (info
, srcidx
);
1377 if (!lat
->is_single_const ())
1379 srcctx
= lat
->values
->value
;
1381 if (srcctx
.useless_p ())
1383 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1384 srcctx
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1385 if (!type_preserved
)
1386 srcctx
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1387 srcctx
.combine_with (ctx
);
1394 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1395 bottom, not containing a variable component and without any known value at
1399 ipcp_verify_propagated_values (void)
1401 struct cgraph_node
*node
;
1403 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
1405 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
1406 int i
, count
= ipa_get_param_count (info
);
1408 for (i
= 0; i
< count
; i
++)
1410 ipcp_lattice
<tree
> *lat
= ipa_get_scalar_lat (info
, i
);
1413 && !lat
->contains_variable
1414 && lat
->values_count
== 0)
1418 symtab
->dump (dump_file
);
1419 fprintf (dump_file
, "\nIPA lattices after constant "
1420 "propagation, before gcc_unreachable:\n");
1421 print_all_lattices (dump_file
, true, false);
1430 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1433 values_equal_for_ipcp_p (tree x
, tree y
)
1435 gcc_checking_assert (x
!= NULL_TREE
&& y
!= NULL_TREE
);
1440 if (TREE_CODE (x
) == ADDR_EXPR
1441 && TREE_CODE (y
) == ADDR_EXPR
1442 && TREE_CODE (TREE_OPERAND (x
, 0)) == CONST_DECL
1443 && TREE_CODE (TREE_OPERAND (y
, 0)) == CONST_DECL
)
1444 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x
, 0)),
1445 DECL_INITIAL (TREE_OPERAND (y
, 0)), 0);
1447 return operand_equal_p (x
, y
, 0);
1450 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1453 values_equal_for_ipcp_p (ipa_polymorphic_call_context x
,
1454 ipa_polymorphic_call_context y
)
1456 return x
.equal_to (y
);
1460 /* Add a new value source to the value represented by THIS, marking that a
1461 value comes from edge CS and (if the underlying jump function is a
1462 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1463 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1464 scalar value of the parameter itself or the offset within an aggregate. */
1466 template <typename valtype
>
1468 ipcp_value
<valtype
>::add_source (cgraph_edge
*cs
, ipcp_value
*src_val
,
1469 int src_idx
, HOST_WIDE_INT offset
)
1471 ipcp_value_source
<valtype
> *src
;
1473 src
= new (ipcp_sources_pool
.allocate ()) ipcp_value_source
<valtype
>;
1474 src
->offset
= offset
;
1477 src
->index
= src_idx
;
1479 src
->next
= sources
;
1483 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1484 SOURCE and clear all other fields. */
1486 static ipcp_value
<tree
> *
1487 allocate_and_init_ipcp_value (tree source
)
1489 ipcp_value
<tree
> *val
;
1491 val
= new (ipcp_cst_values_pool
.allocate ()) ipcp_value
<tree
>();
1492 val
->value
= source
;
1496 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1497 value to SOURCE and clear all other fields. */
1499 static ipcp_value
<ipa_polymorphic_call_context
> *
1500 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source
)
1502 ipcp_value
<ipa_polymorphic_call_context
> *val
;
1505 val
= new (ipcp_poly_ctx_values_pool
.allocate ())
1506 ipcp_value
<ipa_polymorphic_call_context
>();
1507 val
->value
= source
;
1511 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1512 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1513 meaning. OFFSET -1 means the source is scalar and not a part of an
1516 template <typename valtype
>
1518 ipcp_lattice
<valtype
>::add_value (valtype newval
, cgraph_edge
*cs
,
1519 ipcp_value
<valtype
> *src_val
,
1520 int src_idx
, HOST_WIDE_INT offset
)
1522 ipcp_value
<valtype
> *val
;
1527 for (val
= values
; val
; val
= val
->next
)
1528 if (values_equal_for_ipcp_p (val
->value
, newval
))
1530 if (ipa_edge_within_scc (cs
))
1532 ipcp_value_source
<valtype
> *s
;
1533 for (s
= val
->sources
; s
; s
= s
->next
)
1540 val
->add_source (cs
, src_val
, src_idx
, offset
);
1544 if (values_count
== PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE
))
1546 /* We can only free sources, not the values themselves, because sources
1547 of other values in this SCC might point to them. */
1548 for (val
= values
; val
; val
= val
->next
)
1550 while (val
->sources
)
1552 ipcp_value_source
<valtype
> *src
= val
->sources
;
1553 val
->sources
= src
->next
;
1554 ipcp_sources_pool
.remove ((ipcp_value_source
<tree
>*)src
);
1559 return set_to_bottom ();
1563 val
= allocate_and_init_ipcp_value (newval
);
1564 val
->add_source (cs
, src_val
, src_idx
, offset
);
1570 /* Propagate values through a pass-through jump function JFUNC associated with
1571 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1572 is the index of the source parameter. PARM_TYPE is the type of the
1573 parameter to which the result is passed. */
1576 propagate_vals_across_pass_through (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
1577 ipcp_lattice
<tree
> *src_lat
,
1578 ipcp_lattice
<tree
> *dest_lat
, int src_idx
,
1581 ipcp_value
<tree
> *src_val
;
1584 /* Do not create new values when propagating within an SCC because if there
1585 are arithmetic functions with circular dependencies, there is infinite
1586 number of them and we would just make lattices bottom. */
1587 if ((ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1588 && ipa_edge_within_scc (cs
))
1589 ret
= dest_lat
->set_contains_variable ();
1591 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1593 tree cstval
= ipa_get_jf_pass_through_result (jfunc
, src_val
->value
,
1597 ret
|= dest_lat
->add_value (cstval
, cs
, src_val
, src_idx
);
1599 ret
|= dest_lat
->set_contains_variable ();
1605 /* Propagate values through an ancestor jump function JFUNC associated with
1606 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1607 is the index of the source parameter. */
1610 propagate_vals_across_ancestor (struct cgraph_edge
*cs
,
1611 struct ipa_jump_func
*jfunc
,
1612 ipcp_lattice
<tree
> *src_lat
,
1613 ipcp_lattice
<tree
> *dest_lat
, int src_idx
)
1615 ipcp_value
<tree
> *src_val
;
1618 if (ipa_edge_within_scc (cs
))
1619 return dest_lat
->set_contains_variable ();
1621 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1623 tree t
= ipa_get_jf_ancestor_result (jfunc
, src_val
->value
);
1626 ret
|= dest_lat
->add_value (t
, cs
, src_val
, src_idx
);
1628 ret
|= dest_lat
->set_contains_variable ();
1634 /* Propagate scalar values across jump function JFUNC that is associated with
1635 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
1636 parameter to which the result is passed. */
1639 propagate_scalar_across_jump_function (struct cgraph_edge
*cs
,
1640 struct ipa_jump_func
*jfunc
,
1641 ipcp_lattice
<tree
> *dest_lat
,
1644 if (dest_lat
->bottom
)
1647 if (jfunc
->type
== IPA_JF_CONST
)
1649 tree val
= ipa_get_jf_constant (jfunc
);
1650 return dest_lat
->add_value (val
, cs
, NULL
, 0);
1652 else if (jfunc
->type
== IPA_JF_PASS_THROUGH
1653 || jfunc
->type
== IPA_JF_ANCESTOR
)
1655 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1656 ipcp_lattice
<tree
> *src_lat
;
1660 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1661 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1663 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1665 src_lat
= ipa_get_scalar_lat (caller_info
, src_idx
);
1666 if (src_lat
->bottom
)
1667 return dest_lat
->set_contains_variable ();
1669 /* If we would need to clone the caller and cannot, do not propagate. */
1670 if (!ipcp_versionable_function_p (cs
->caller
)
1671 && (src_lat
->contains_variable
1672 || (src_lat
->values_count
> 1)))
1673 return dest_lat
->set_contains_variable ();
1675 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1676 ret
= propagate_vals_across_pass_through (cs
, jfunc
, src_lat
,
1677 dest_lat
, src_idx
, param_type
);
1679 ret
= propagate_vals_across_ancestor (cs
, jfunc
, src_lat
, dest_lat
,
1682 if (src_lat
->contains_variable
)
1683 ret
|= dest_lat
->set_contains_variable ();
1688 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
1689 use it for indirect inlining), we should propagate them too. */
1690 return dest_lat
->set_contains_variable ();
1693 /* Propagate scalar values across jump function JFUNC that is associated with
1694 edge CS and describes argument IDX and put the values into DEST_LAT. */
1697 propagate_context_across_jump_function (cgraph_edge
*cs
,
1698 ipa_jump_func
*jfunc
, int idx
,
1699 ipcp_lattice
<ipa_polymorphic_call_context
> *dest_lat
)
1701 ipa_edge_args
*args
= IPA_EDGE_REF (cs
);
1702 if (dest_lat
->bottom
)
1705 bool added_sth
= false;
1706 bool type_preserved
= true;
1708 ipa_polymorphic_call_context edge_ctx
, *edge_ctx_ptr
1709 = ipa_get_ith_polymorhic_call_context (args
, idx
);
1712 edge_ctx
= *edge_ctx_ptr
;
1714 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1715 || jfunc
->type
== IPA_JF_ANCESTOR
)
1717 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1719 ipcp_lattice
<ipa_polymorphic_call_context
> *src_lat
;
1721 /* TODO: Once we figure out how to propagate speculations, it will
1722 probably be a good idea to switch to speculation if type_preserved is
1723 not set instead of punting. */
1724 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1726 if (ipa_get_jf_pass_through_operation (jfunc
) != NOP_EXPR
)
1728 type_preserved
= ipa_get_jf_pass_through_type_preserved (jfunc
);
1729 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1733 type_preserved
= ipa_get_jf_ancestor_type_preserved (jfunc
);
1734 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1737 src_lat
= ipa_get_poly_ctx_lat (caller_info
, src_idx
);
1738 /* If we would need to clone the caller and cannot, do not propagate. */
1739 if (!ipcp_versionable_function_p (cs
->caller
)
1740 && (src_lat
->contains_variable
1741 || (src_lat
->values_count
> 1)))
1744 ipcp_value
<ipa_polymorphic_call_context
> *src_val
;
1745 for (src_val
= src_lat
->values
; src_val
; src_val
= src_val
->next
)
1747 ipa_polymorphic_call_context cur
= src_val
->value
;
1749 if (!type_preserved
)
1750 cur
.possible_dynamic_type_change (cs
->in_polymorphic_cdtor
);
1751 if (jfunc
->type
== IPA_JF_ANCESTOR
)
1752 cur
.offset_by (ipa_get_jf_ancestor_offset (jfunc
));
1753 /* TODO: In cases we know how the context is going to be used,
1754 we can improve the result by passing proper OTR_TYPE. */
1755 cur
.combine_with (edge_ctx
);
1756 if (!cur
.useless_p ())
1758 if (src_lat
->contains_variable
1759 && !edge_ctx
.equal_to (cur
))
1760 ret
|= dest_lat
->set_contains_variable ();
1761 ret
|= dest_lat
->add_value (cur
, cs
, src_val
, src_idx
);
1771 if (!edge_ctx
.useless_p ())
1772 ret
|= dest_lat
->add_value (edge_ctx
, cs
);
1774 ret
|= dest_lat
->set_contains_variable ();
1780 /* Propagate bits across jfunc that is associated with
1781 edge cs and update dest_lattice accordingly. */
1784 propagate_bits_across_jump_function (cgraph_edge
*cs
, int idx
,
1785 ipa_jump_func
*jfunc
,
1786 ipcp_bits_lattice
*dest_lattice
)
1788 if (dest_lattice
->bottom_p ())
1791 enum availability availability
;
1792 cgraph_node
*callee
= cs
->callee
->function_symbol (&availability
);
1793 struct ipa_node_params
*callee_info
= IPA_NODE_REF (callee
);
1794 tree parm_type
= ipa_get_type (callee_info
, idx
);
1796 /* For K&R C programs, ipa_get_type() could return NULL_TREE.
1797 Avoid the transform for these cases. */
1800 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
1801 fprintf (dump_file
, "Setting dest_lattice to bottom, because"
1802 " param %i type is NULL for %s\n", idx
,
1803 cs
->callee
->name ());
1805 return dest_lattice
->set_to_bottom ();
1808 unsigned precision
= TYPE_PRECISION (parm_type
);
1809 signop sgn
= TYPE_SIGN (parm_type
);
1811 if (jfunc
->type
== IPA_JF_PASS_THROUGH
1812 || jfunc
->type
== IPA_JF_ANCESTOR
)
1814 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1815 tree operand
= NULL_TREE
;
1816 enum tree_code code
;
1819 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1821 code
= ipa_get_jf_pass_through_operation (jfunc
);
1822 src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1823 if (code
!= NOP_EXPR
)
1824 operand
= ipa_get_jf_pass_through_operand (jfunc
);
1828 code
= POINTER_PLUS_EXPR
;
1829 src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
1830 unsigned HOST_WIDE_INT offset
= ipa_get_jf_ancestor_offset (jfunc
) / BITS_PER_UNIT
;
1831 operand
= build_int_cstu (size_type_node
, offset
);
1834 struct ipcp_param_lattices
*src_lats
1835 = ipa_get_parm_lattices (caller_info
, src_idx
);
1837 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
1843 Assume lattice for x is bottom, however we can still propagate
1844 result of x & 0xff == 0xff, which gets computed during ccp1 pass
1845 and we store it in jump function during analysis stage. */
1847 if (src_lats
->bits_lattice
.bottom_p ()
1849 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
1852 return dest_lattice
->meet_with (src_lats
->bits_lattice
, precision
, sgn
,
1856 else if (jfunc
->type
== IPA_JF_ANCESTOR
)
1857 return dest_lattice
->set_to_bottom ();
1858 else if (jfunc
->bits
)
1859 return dest_lattice
->meet_with (jfunc
->bits
->value
, jfunc
->bits
->mask
,
1862 return dest_lattice
->set_to_bottom ();
1865 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1866 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1867 the result is a range or an anti-range. */
1870 ipa_vr_operation_and_type_effects (value_range
*dst_vr
, value_range
*src_vr
,
1871 enum tree_code operation
,
1872 tree dst_type
, tree src_type
)
1874 memset (dst_vr
, 0, sizeof (*dst_vr
));
1875 extract_range_from_unary_expr (dst_vr
, operation
, dst_type
, src_vr
, src_type
);
1876 if (dst_vr
->type
== VR_RANGE
|| dst_vr
->type
== VR_ANTI_RANGE
)
1882 /* Propagate value range across jump function JFUNC that is associated with
1883 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
1887 propagate_vr_across_jump_function (cgraph_edge
*cs
, ipa_jump_func
*jfunc
,
1888 struct ipcp_param_lattices
*dest_plats
,
1891 ipcp_vr_lattice
*dest_lat
= &dest_plats
->m_value_range
;
1893 if (dest_lat
->bottom_p ())
1897 || (!INTEGRAL_TYPE_P (param_type
)
1898 && !POINTER_TYPE_P (param_type
)))
1899 return dest_lat
->set_to_bottom ();
1901 if (jfunc
->type
== IPA_JF_PASS_THROUGH
)
1903 enum tree_code operation
= ipa_get_jf_pass_through_operation (jfunc
);
1905 if (TREE_CODE_CLASS (operation
) == tcc_unary
)
1907 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
1908 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
1909 tree operand_type
= ipa_get_type (caller_info
, src_idx
);
1910 struct ipcp_param_lattices
*src_lats
1911 = ipa_get_parm_lattices (caller_info
, src_idx
);
1913 if (src_lats
->m_value_range
.bottom_p ())
1914 return dest_lat
->set_to_bottom ();
1916 if (ipa_vr_operation_and_type_effects (&vr
,
1917 &src_lats
->m_value_range
.m_vr
,
1918 operation
, param_type
,
1920 return dest_lat
->meet_with (&vr
);
1923 else if (jfunc
->type
== IPA_JF_CONST
)
1925 tree val
= ipa_get_jf_constant (jfunc
);
1926 if (TREE_CODE (val
) == INTEGER_CST
)
1928 val
= fold_convert (param_type
, val
);
1929 if (TREE_OVERFLOW_P (val
))
1930 val
= drop_tree_overflow (val
);
1933 memset (&tmpvr
, 0, sizeof (tmpvr
));
1934 tmpvr
.type
= VR_RANGE
;
1937 return dest_lat
->meet_with (&tmpvr
);
1943 && ipa_vr_operation_and_type_effects (&vr
, jfunc
->m_vr
, NOP_EXPR
,
1945 TREE_TYPE (jfunc
->m_vr
->min
)))
1946 return dest_lat
->meet_with (&vr
);
1948 return dest_lat
->set_to_bottom ();
1951 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
1952 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
1953 other cases, return false). If there are no aggregate items, set
1954 aggs_by_ref to NEW_AGGS_BY_REF. */
1957 set_check_aggs_by_ref (struct ipcp_param_lattices
*dest_plats
,
1958 bool new_aggs_by_ref
)
1960 if (dest_plats
->aggs
)
1962 if (dest_plats
->aggs_by_ref
!= new_aggs_by_ref
)
1964 set_agg_lats_to_bottom (dest_plats
);
1969 dest_plats
->aggs_by_ref
= new_aggs_by_ref
;
1973 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
1974 already existing lattice for the given OFFSET and SIZE, marking all skipped
1975 lattices as containing variable and checking for overlaps. If there is no
1976 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
1977 it with offset, size and contains_variable to PRE_EXISTING, and return true,
1978 unless there are too many already. If there are two many, return false. If
1979 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
1980 skipped lattices were newly marked as containing variable, set *CHANGE to
1984 merge_agg_lats_step (struct ipcp_param_lattices
*dest_plats
,
1985 HOST_WIDE_INT offset
, HOST_WIDE_INT val_size
,
1986 struct ipcp_agg_lattice
***aglat
,
1987 bool pre_existing
, bool *change
)
1989 gcc_checking_assert (offset
>= 0);
1991 while (**aglat
&& (**aglat
)->offset
< offset
)
1993 if ((**aglat
)->offset
+ (**aglat
)->size
> offset
)
1995 set_agg_lats_to_bottom (dest_plats
);
1998 *change
|= (**aglat
)->set_contains_variable ();
1999 *aglat
= &(**aglat
)->next
;
2002 if (**aglat
&& (**aglat
)->offset
== offset
)
2004 if ((**aglat
)->size
!= val_size
2006 && (**aglat
)->next
->offset
< offset
+ val_size
))
2008 set_agg_lats_to_bottom (dest_plats
);
2011 gcc_checking_assert (!(**aglat
)->next
2012 || (**aglat
)->next
->offset
>= offset
+ val_size
);
2017 struct ipcp_agg_lattice
*new_al
;
2019 if (**aglat
&& (**aglat
)->offset
< offset
+ val_size
)
2021 set_agg_lats_to_bottom (dest_plats
);
2024 if (dest_plats
->aggs_count
== PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS
))
2026 dest_plats
->aggs_count
++;
2027 new_al
= ipcp_agg_lattice_pool
.allocate ();
2028 memset (new_al
, 0, sizeof (*new_al
));
2030 new_al
->offset
= offset
;
2031 new_al
->size
= val_size
;
2032 new_al
->contains_variable
= pre_existing
;
2034 new_al
->next
= **aglat
;
2040 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2041 containing an unknown value. */
2044 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice
*aglat
)
2049 ret
|= aglat
->set_contains_variable ();
2050 aglat
= aglat
->next
;
2055 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2056 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2057 parameter used for lattice value sources. Return true if DEST_PLATS changed
2061 merge_aggregate_lattices (struct cgraph_edge
*cs
,
2062 struct ipcp_param_lattices
*dest_plats
,
2063 struct ipcp_param_lattices
*src_plats
,
2064 int src_idx
, HOST_WIDE_INT offset_delta
)
2066 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2067 struct ipcp_agg_lattice
**dst_aglat
;
2070 if (set_check_aggs_by_ref (dest_plats
, src_plats
->aggs_by_ref
))
2072 if (src_plats
->aggs_bottom
)
2073 return set_agg_lats_contain_variable (dest_plats
);
2074 if (src_plats
->aggs_contain_variable
)
2075 ret
|= set_agg_lats_contain_variable (dest_plats
);
2076 dst_aglat
= &dest_plats
->aggs
;
2078 for (struct ipcp_agg_lattice
*src_aglat
= src_plats
->aggs
;
2080 src_aglat
= src_aglat
->next
)
2082 HOST_WIDE_INT new_offset
= src_aglat
->offset
- offset_delta
;
2086 if (merge_agg_lats_step (dest_plats
, new_offset
, src_aglat
->size
,
2087 &dst_aglat
, pre_existing
, &ret
))
2089 struct ipcp_agg_lattice
*new_al
= *dst_aglat
;
2091 dst_aglat
= &(*dst_aglat
)->next
;
2092 if (src_aglat
->bottom
)
2094 ret
|= new_al
->set_contains_variable ();
2097 if (src_aglat
->contains_variable
)
2098 ret
|= new_al
->set_contains_variable ();
2099 for (ipcp_value
<tree
> *val
= src_aglat
->values
;
2102 ret
|= new_al
->add_value (val
->value
, cs
, val
, src_idx
,
2105 else if (dest_plats
->aggs_bottom
)
2108 ret
|= set_chain_of_aglats_contains_variable (*dst_aglat
);
2112 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2113 pass-through JFUNC and if so, whether it has conform and conforms to the
2114 rules about propagating values passed by reference. */
2117 agg_pass_through_permissible_p (struct ipcp_param_lattices
*src_plats
,
2118 struct ipa_jump_func
*jfunc
)
2120 return src_plats
->aggs
2121 && (!src_plats
->aggs_by_ref
2122 || ipa_get_jf_pass_through_agg_preserved (jfunc
));
2125 /* Propagate scalar values across jump function JFUNC that is associated with
2126 edge CS and put the values into DEST_LAT. */
2129 propagate_aggs_across_jump_function (struct cgraph_edge
*cs
,
2130 struct ipa_jump_func
*jfunc
,
2131 struct ipcp_param_lattices
*dest_plats
)
2135 if (dest_plats
->aggs_bottom
)
2138 if (jfunc
->type
== IPA_JF_PASS_THROUGH
2139 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
2141 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2142 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
2143 struct ipcp_param_lattices
*src_plats
;
2145 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2146 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
2148 /* Currently we do not produce clobber aggregate jump
2149 functions, replace with merging when we do. */
2150 gcc_assert (!jfunc
->agg
.items
);
2151 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
,
2155 ret
|= set_agg_lats_contain_variable (dest_plats
);
2157 else if (jfunc
->type
== IPA_JF_ANCESTOR
2158 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
2160 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
2161 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
2162 struct ipcp_param_lattices
*src_plats
;
2164 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
2165 if (src_plats
->aggs
&& src_plats
->aggs_by_ref
)
2167 /* Currently we do not produce clobber aggregate jump
2168 functions, replace with merging when we do. */
2169 gcc_assert (!jfunc
->agg
.items
);
2170 ret
|= merge_aggregate_lattices (cs
, dest_plats
, src_plats
, src_idx
,
2171 ipa_get_jf_ancestor_offset (jfunc
));
2173 else if (!src_plats
->aggs_by_ref
)
2174 ret
|= set_agg_lats_to_bottom (dest_plats
);
2176 ret
|= set_agg_lats_contain_variable (dest_plats
);
2178 else if (jfunc
->agg
.items
)
2180 bool pre_existing
= dest_plats
->aggs
!= NULL
;
2181 struct ipcp_agg_lattice
**aglat
= &dest_plats
->aggs
;
2182 struct ipa_agg_jf_item
*item
;
2185 if (set_check_aggs_by_ref (dest_plats
, jfunc
->agg
.by_ref
))
2188 FOR_EACH_VEC_ELT (*jfunc
->agg
.items
, i
, item
)
2190 HOST_WIDE_INT val_size
;
2192 if (item
->offset
< 0)
2194 gcc_checking_assert (is_gimple_ip_invariant (item
->value
));
2195 val_size
= tree_to_uhwi (TYPE_SIZE (TREE_TYPE (item
->value
)));
2197 if (merge_agg_lats_step (dest_plats
, item
->offset
, val_size
,
2198 &aglat
, pre_existing
, &ret
))
2200 ret
|= (*aglat
)->add_value (item
->value
, cs
, NULL
, 0, 0);
2201 aglat
= &(*aglat
)->next
;
2203 else if (dest_plats
->aggs_bottom
)
2207 ret
|= set_chain_of_aglats_contains_variable (*aglat
);
2210 ret
|= set_agg_lats_contain_variable (dest_plats
);
2215 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2216 non-thunk) destination, the call passes through a thunk. */
2219 call_passes_through_thunk_p (cgraph_edge
*cs
)
2221 cgraph_node
*alias_or_thunk
= cs
->callee
;
2222 while (alias_or_thunk
->alias
)
2223 alias_or_thunk
= alias_or_thunk
->get_alias_target ();
2224 return alias_or_thunk
->thunk
.thunk_p
;
2227 /* Propagate constants from the caller to the callee of CS. INFO describes the
2231 propagate_constants_across_call (struct cgraph_edge
*cs
)
2233 struct ipa_node_params
*callee_info
;
2234 enum availability availability
;
2235 cgraph_node
*callee
;
2236 struct ipa_edge_args
*args
;
2238 int i
, args_count
, parms_count
;
2240 callee
= cs
->callee
->function_symbol (&availability
);
2241 if (!callee
->definition
)
2243 gcc_checking_assert (callee
->has_gimple_body_p ());
2244 callee_info
= IPA_NODE_REF (callee
);
2246 args
= IPA_EDGE_REF (cs
);
2247 args_count
= ipa_get_cs_argument_count (args
);
2248 parms_count
= ipa_get_param_count (callee_info
);
2249 if (parms_count
== 0)
2252 /* No propagation through instrumentation thunks is available yet.
2253 It should be possible with proper mapping of call args and
2254 instrumented callee params in the propagation loop below. But
2255 this case mostly occurs when legacy code calls instrumented code
2256 and it is not a primary target for optimizations.
2257 We detect instrumentation thunks in aliases and thunks chain by
2258 checking instrumentation_clone flag for chain source and target.
2259 Going through instrumentation thunks we always have it changed
2260 from 0 to 1 and all other nodes do not change it. */
2261 if (!cs
->callee
->instrumentation_clone
2262 && callee
->instrumentation_clone
)
2264 for (i
= 0; i
< parms_count
; i
++)
2265 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2270 /* If this call goes through a thunk we must not propagate to the first (0th)
2271 parameter. However, we might need to uncover a thunk from below a series
2272 of aliases first. */
2273 if (call_passes_through_thunk_p (cs
))
2275 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
,
2282 for (; (i
< args_count
) && (i
< parms_count
); i
++)
2284 struct ipa_jump_func
*jump_func
= ipa_get_ith_jump_func (args
, i
);
2285 struct ipcp_param_lattices
*dest_plats
;
2286 tree param_type
= ipa_get_type (callee_info
, i
);
2288 dest_plats
= ipa_get_parm_lattices (callee_info
, i
);
2289 if (availability
== AVAIL_INTERPOSABLE
)
2290 ret
|= set_all_contains_variable (dest_plats
);
2293 ret
|= propagate_scalar_across_jump_function (cs
, jump_func
,
2294 &dest_plats
->itself
,
2296 ret
|= propagate_context_across_jump_function (cs
, jump_func
, i
,
2297 &dest_plats
->ctxlat
);
2299 |= propagate_bits_across_jump_function (cs
, i
, jump_func
,
2300 &dest_plats
->bits_lattice
);
2301 ret
|= propagate_aggs_across_jump_function (cs
, jump_func
,
2303 if (opt_for_fn (callee
->decl
, flag_ipa_vrp
))
2304 ret
|= propagate_vr_across_jump_function (cs
, jump_func
,
2305 dest_plats
, param_type
);
2307 ret
|= dest_plats
->m_value_range
.set_to_bottom ();
2310 for (; i
< parms_count
; i
++)
2311 ret
|= set_all_contains_variable (ipa_get_parm_lattices (callee_info
, i
));
2316 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2317 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2318 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2321 ipa_get_indirect_edge_target_1 (struct cgraph_edge
*ie
,
2322 vec
<tree
> known_csts
,
2323 vec
<ipa_polymorphic_call_context
> known_contexts
,
2324 vec
<ipa_agg_jump_function_p
> known_aggs
,
2325 struct ipa_agg_replacement_value
*agg_reps
,
2328 int param_index
= ie
->indirect_info
->param_index
;
2329 HOST_WIDE_INT anc_offset
;
2333 *speculative
= false;
2335 if (param_index
== -1
2336 || known_csts
.length () <= (unsigned int) param_index
)
2339 if (!ie
->indirect_info
->polymorphic
)
2343 if (ie
->indirect_info
->agg_contents
)
2346 if (agg_reps
&& ie
->indirect_info
->guaranteed_unmodified
)
2350 if (agg_reps
->index
== param_index
2351 && agg_reps
->offset
== ie
->indirect_info
->offset
2352 && agg_reps
->by_ref
== ie
->indirect_info
->by_ref
)
2354 t
= agg_reps
->value
;
2357 agg_reps
= agg_reps
->next
;
2362 struct ipa_agg_jump_function
*agg
;
2363 if (known_aggs
.length () > (unsigned int) param_index
)
2364 agg
= known_aggs
[param_index
];
2367 bool from_global_constant
;
2368 t
= ipa_find_agg_cst_for_param (agg
, known_csts
[param_index
],
2369 ie
->indirect_info
->offset
,
2370 ie
->indirect_info
->by_ref
,
2371 &from_global_constant
);
2373 && !from_global_constant
2374 && !ie
->indirect_info
->guaranteed_unmodified
)
2379 t
= known_csts
[param_index
];
2382 && TREE_CODE (t
) == ADDR_EXPR
2383 && TREE_CODE (TREE_OPERAND (t
, 0)) == FUNCTION_DECL
)
2384 return TREE_OPERAND (t
, 0);
2389 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize
))
2392 gcc_assert (!ie
->indirect_info
->agg_contents
);
2393 anc_offset
= ie
->indirect_info
->offset
;
2397 /* Try to work out value of virtual table pointer value in replacemnets. */
2398 if (!t
&& agg_reps
&& !ie
->indirect_info
->by_ref
)
2402 if (agg_reps
->index
== param_index
2403 && agg_reps
->offset
== ie
->indirect_info
->offset
2404 && agg_reps
->by_ref
)
2406 t
= agg_reps
->value
;
2409 agg_reps
= agg_reps
->next
;
2413 /* Try to work out value of virtual table pointer value in known
2414 aggregate values. */
2415 if (!t
&& known_aggs
.length () > (unsigned int) param_index
2416 && !ie
->indirect_info
->by_ref
)
2418 struct ipa_agg_jump_function
*agg
;
2419 agg
= known_aggs
[param_index
];
2420 t
= ipa_find_agg_cst_for_param (agg
, known_csts
[param_index
],
2421 ie
->indirect_info
->offset
, true);
2424 /* If we found the virtual table pointer, lookup the target. */
2428 unsigned HOST_WIDE_INT offset
;
2429 if (vtable_pointer_value_to_vtable (t
, &vtable
, &offset
))
2432 target
= gimple_get_virt_method_for_vtable (ie
->indirect_info
->otr_token
,
2433 vtable
, offset
, &can_refer
);
2437 || (TREE_CODE (TREE_TYPE (target
)) == FUNCTION_TYPE
2438 && DECL_FUNCTION_CODE (target
) == BUILT_IN_UNREACHABLE
)
2439 || !possible_polymorphic_call_target_p
2440 (ie
, cgraph_node::get (target
)))
2442 /* Do not speculate builtin_unreachable, it is stupid! */
2443 if (ie
->indirect_info
->vptr_changed
)
2445 target
= ipa_impossible_devirt_target (ie
, target
);
2447 *speculative
= ie
->indirect_info
->vptr_changed
;
2454 /* Do we know the constant value of pointer? */
2456 t
= known_csts
[param_index
];
2458 gcc_checking_assert (!t
|| TREE_CODE (t
) != TREE_BINFO
);
2460 ipa_polymorphic_call_context context
;
2461 if (known_contexts
.length () > (unsigned int) param_index
)
2463 context
= known_contexts
[param_index
];
2464 context
.offset_by (anc_offset
);
2465 if (ie
->indirect_info
->vptr_changed
)
2466 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
2467 ie
->indirect_info
->otr_type
);
2470 ipa_polymorphic_call_context ctx2
= ipa_polymorphic_call_context
2471 (t
, ie
->indirect_info
->otr_type
, anc_offset
);
2472 if (!ctx2
.useless_p ())
2473 context
.combine_with (ctx2
, ie
->indirect_info
->otr_type
);
2478 context
= ipa_polymorphic_call_context (t
, ie
->indirect_info
->otr_type
,
2480 if (ie
->indirect_info
->vptr_changed
)
2481 context
.possible_dynamic_type_change (ie
->in_polymorphic_cdtor
,
2482 ie
->indirect_info
->otr_type
);
2487 vec
<cgraph_node
*>targets
;
2490 targets
= possible_polymorphic_call_targets
2491 (ie
->indirect_info
->otr_type
,
2492 ie
->indirect_info
->otr_token
,
2494 if (!final
|| targets
.length () > 1)
2496 struct cgraph_node
*node
;
2499 if (!opt_for_fn (ie
->caller
->decl
, flag_devirtualize_speculatively
)
2500 || ie
->speculative
|| !ie
->maybe_hot_p ())
2502 node
= try_speculative_devirtualization (ie
->indirect_info
->otr_type
,
2503 ie
->indirect_info
->otr_token
,
2507 *speculative
= true;
2508 target
= node
->decl
;
2515 *speculative
= false;
2516 if (targets
.length () == 1)
2517 target
= targets
[0]->decl
;
2519 target
= ipa_impossible_devirt_target (ie
, NULL_TREE
);
2522 if (target
&& !possible_polymorphic_call_target_p (ie
,
2523 cgraph_node::get (target
)))
2527 target
= ipa_impossible_devirt_target (ie
, target
);
2534 /* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
2535 KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
2536 return the destination. */
2539 ipa_get_indirect_edge_target (struct cgraph_edge
*ie
,
2540 vec
<tree
> known_csts
,
2541 vec
<ipa_polymorphic_call_context
> known_contexts
,
2542 vec
<ipa_agg_jump_function_p
> known_aggs
,
2545 return ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
2546 known_aggs
, NULL
, speculative
);
2549 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
2550 and KNOWN_CONTEXTS. */
2553 devirtualization_time_bonus (struct cgraph_node
*node
,
2554 vec
<tree
> known_csts
,
2555 vec
<ipa_polymorphic_call_context
> known_contexts
,
2556 vec
<ipa_agg_jump_function_p
> known_aggs
)
2558 struct cgraph_edge
*ie
;
2561 for (ie
= node
->indirect_calls
; ie
; ie
= ie
->next_callee
)
2563 struct cgraph_node
*callee
;
2564 struct ipa_fn_summary
*isummary
;
2565 enum availability avail
;
2569 target
= ipa_get_indirect_edge_target (ie
, known_csts
, known_contexts
,
2570 known_aggs
, &speculative
);
2574 /* Only bare minimum benefit for clearly un-inlineable targets. */
2576 callee
= cgraph_node::get (target
);
2577 if (!callee
|| !callee
->definition
)
2579 callee
= callee
->function_symbol (&avail
);
2580 if (avail
< AVAIL_AVAILABLE
)
2582 isummary
= ipa_fn_summaries
->get (callee
);
2583 if (!isummary
->inlinable
)
2586 /* FIXME: The values below need re-considering and perhaps also
2587 integrating into the cost metrics, at lest in some very basic way. */
2588 if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
/ 4)
2589 res
+= 31 / ((int)speculative
+ 1);
2590 else if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
/ 2)
2591 res
+= 15 / ((int)speculative
+ 1);
2592 else if (isummary
->size
<= MAX_INLINE_INSNS_AUTO
2593 || DECL_DECLARED_INLINE_P (callee
->decl
))
2594 res
+= 7 / ((int)speculative
+ 1);
2600 /* Return time bonus incurred because of HINTS. */
2603 hint_time_bonus (ipa_hints hints
)
2606 if (hints
& (INLINE_HINT_loop_iterations
| INLINE_HINT_loop_stride
))
2607 result
+= PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS
);
2608 if (hints
& INLINE_HINT_array_index
)
2609 result
+= PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS
);
2613 /* If there is a reason to penalize the function described by INFO in the
2614 cloning goodness evaluation, do so. */
2616 static inline int64_t
2617 incorporate_penalties (ipa_node_params
*info
, int64_t evaluation
)
2619 if (info
->node_within_scc
)
2620 evaluation
= (evaluation
2621 * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY
))) / 100;
2623 if (info
->node_calling_single_call
)
2624 evaluation
= (evaluation
2625 * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY
)))
2631 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
2632 and SIZE_COST and with the sum of frequencies of incoming edges to the
2633 potential new clone in FREQUENCIES. */
2636 good_cloning_opportunity_p (struct cgraph_node
*node
, int time_benefit
,
2637 int freq_sum
, profile_count count_sum
, int size_cost
)
2639 if (time_benefit
== 0
2640 || !opt_for_fn (node
->decl
, flag_ipa_cp_clone
)
2641 || node
->optimize_for_size_p ())
2644 gcc_assert (size_cost
> 0);
2646 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2647 if (max_count
> profile_count::zero ())
2649 int factor
= RDIV (count_sum
.probability_in
2650 (max_count
).to_reg_br_prob_base ()
2651 * 1000, REG_BR_PROB_BASE
);
2652 int64_t evaluation
= (((int64_t) time_benefit
* factor
)
2654 evaluation
= incorporate_penalties (info
, evaluation
);
2656 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2658 fprintf (dump_file
, " good_cloning_opportunity_p (time: %i, "
2659 "size: %i, count_sum: ", time_benefit
, size_cost
);
2660 count_sum
.dump (dump_file
);
2661 fprintf (dump_file
, "%s%s) -> evaluation: " "%" PRId64
2662 ", threshold: %i\n",
2663 info
->node_within_scc
? ", scc" : "",
2664 info
->node_calling_single_call
? ", single_call" : "",
2665 evaluation
, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
));
2668 return evaluation
>= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
);
2672 int64_t evaluation
= (((int64_t) time_benefit
* freq_sum
)
2674 evaluation
= incorporate_penalties (info
, evaluation
);
2676 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2677 fprintf (dump_file
, " good_cloning_opportunity_p (time: %i, "
2678 "size: %i, freq_sum: %i%s%s) -> evaluation: "
2679 "%" PRId64
", threshold: %i\n",
2680 time_benefit
, size_cost
, freq_sum
,
2681 info
->node_within_scc
? ", scc" : "",
2682 info
->node_calling_single_call
? ", single_call" : "",
2683 evaluation
, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
));
2685 return evaluation
>= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD
);
2689 /* Return all context independent values from aggregate lattices in PLATS in a
2690 vector. Return NULL if there are none. */
2692 static vec
<ipa_agg_jf_item
, va_gc
> *
2693 context_independent_aggregate_values (struct ipcp_param_lattices
*plats
)
2695 vec
<ipa_agg_jf_item
, va_gc
> *res
= NULL
;
2697 if (plats
->aggs_bottom
2698 || plats
->aggs_contain_variable
2699 || plats
->aggs_count
== 0)
2702 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
;
2704 aglat
= aglat
->next
)
2705 if (aglat
->is_single_const ())
2707 struct ipa_agg_jf_item item
;
2708 item
.offset
= aglat
->offset
;
2709 item
.value
= aglat
->values
->value
;
2710 vec_safe_push (res
, item
);
2715 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
2716 populate them with values of parameters that are known independent of the
2717 context. INFO describes the function. If REMOVABLE_PARAMS_COST is
2718 non-NULL, the movement cost of all removable parameters will be stored in
2722 gather_context_independent_values (struct ipa_node_params
*info
,
2723 vec
<tree
> *known_csts
,
2724 vec
<ipa_polymorphic_call_context
>
2726 vec
<ipa_agg_jump_function
> *known_aggs
,
2727 int *removable_params_cost
)
2729 int i
, count
= ipa_get_param_count (info
);
2732 known_csts
->create (0);
2733 known_contexts
->create (0);
2734 known_csts
->safe_grow_cleared (count
);
2735 known_contexts
->safe_grow_cleared (count
);
2738 known_aggs
->create (0);
2739 known_aggs
->safe_grow_cleared (count
);
2742 if (removable_params_cost
)
2743 *removable_params_cost
= 0;
2745 for (i
= 0; i
< count
; i
++)
2747 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2748 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
2750 if (lat
->is_single_const ())
2752 ipcp_value
<tree
> *val
= lat
->values
;
2753 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
2754 (*known_csts
)[i
] = val
->value
;
2755 if (removable_params_cost
)
2756 *removable_params_cost
2757 += estimate_move_cost (TREE_TYPE (val
->value
), false);
2760 else if (removable_params_cost
2761 && !ipa_is_param_used (info
, i
))
2762 *removable_params_cost
2763 += ipa_get_param_move_cost (info
, i
);
2765 if (!ipa_is_param_used (info
, i
))
2768 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
2769 /* Do not account known context as reason for cloning. We can see
2770 if it permits devirtualization. */
2771 if (ctxlat
->is_single_const ())
2772 (*known_contexts
)[i
] = ctxlat
->values
->value
;
2776 vec
<ipa_agg_jf_item
, va_gc
> *agg_items
;
2777 struct ipa_agg_jump_function
*ajf
;
2779 agg_items
= context_independent_aggregate_values (plats
);
2780 ajf
= &(*known_aggs
)[i
];
2781 ajf
->items
= agg_items
;
2782 ajf
->by_ref
= plats
->aggs_by_ref
;
2783 ret
|= agg_items
!= NULL
;
2790 /* The current interface in ipa-inline-analysis requires a pointer vector.
2793 FIXME: That interface should be re-worked, this is slightly silly. Still,
2794 I'd like to discuss how to change it first and this demonstrates the
2797 static vec
<ipa_agg_jump_function_p
>
2798 agg_jmp_p_vec_for_t_vec (vec
<ipa_agg_jump_function
> known_aggs
)
2800 vec
<ipa_agg_jump_function_p
> ret
;
2801 struct ipa_agg_jump_function
*ajf
;
2804 ret
.create (known_aggs
.length ());
2805 FOR_EACH_VEC_ELT (known_aggs
, i
, ajf
)
2806 ret
.quick_push (ajf
);
2810 /* Perform time and size measurement of NODE with the context given in
2811 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
2812 given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
2813 all context-independent removable parameters and EST_MOVE_COST of estimated
2814 movement of the considered parameter and store it into VAL. */
2817 perform_estimation_of_a_value (cgraph_node
*node
, vec
<tree
> known_csts
,
2818 vec
<ipa_polymorphic_call_context
> known_contexts
,
2819 vec
<ipa_agg_jump_function_p
> known_aggs_ptrs
,
2820 int removable_params_cost
,
2821 int est_move_cost
, ipcp_value_base
*val
)
2823 int size
, time_benefit
;
2824 sreal time
, base_time
;
2827 estimate_ipcp_clone_size_and_time (node
, known_csts
, known_contexts
,
2828 known_aggs_ptrs
, &size
, &time
,
2829 &base_time
, &hints
);
2831 if (base_time
> 65535)
2833 time_benefit
= base_time
.to_int ()
2834 + devirtualization_time_bonus (node
, known_csts
, known_contexts
,
2836 + hint_time_bonus (hints
)
2837 + removable_params_cost
+ est_move_cost
;
2839 gcc_checking_assert (size
>=0);
2840 /* The inliner-heuristics based estimates may think that in certain
2841 contexts some functions do not have any size at all but we want
2842 all specializations to have at least a tiny cost, not least not to
2847 val
->local_time_benefit
= time_benefit
;
2848 val
->local_size_cost
= size
;
2851 /* Iterate over known values of parameters of NODE and estimate the local
2852 effects in terms of time and size they have. */
2855 estimate_local_effects (struct cgraph_node
*node
)
2857 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
2858 int i
, count
= ipa_get_param_count (info
);
2859 vec
<tree
> known_csts
;
2860 vec
<ipa_polymorphic_call_context
> known_contexts
;
2861 vec
<ipa_agg_jump_function
> known_aggs
;
2862 vec
<ipa_agg_jump_function_p
> known_aggs_ptrs
;
2864 int removable_params_cost
;
2866 if (!count
|| !ipcp_versionable_function_p (node
))
2869 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2870 fprintf (dump_file
, "\nEstimating effects for %s.\n", node
->dump_name ());
2872 always_const
= gather_context_independent_values (info
, &known_csts
,
2873 &known_contexts
, &known_aggs
,
2874 &removable_params_cost
);
2875 known_aggs_ptrs
= agg_jmp_p_vec_for_t_vec (known_aggs
);
2876 int devirt_bonus
= devirtualization_time_bonus (node
, known_csts
,
2877 known_contexts
, known_aggs_ptrs
);
2878 if (always_const
|| devirt_bonus
2879 || (removable_params_cost
&& node
->local
.can_change_signature
))
2881 struct caller_statistics stats
;
2883 sreal time
, base_time
;
2886 init_caller_stats (&stats
);
2887 node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
2889 estimate_ipcp_clone_size_and_time (node
, known_csts
, known_contexts
,
2890 known_aggs_ptrs
, &size
, &time
,
2891 &base_time
, &hints
);
2892 time
-= devirt_bonus
;
2893 time
-= hint_time_bonus (hints
);
2894 time
-= removable_params_cost
;
2895 size
-= stats
.n_calls
* removable_params_cost
;
2898 fprintf (dump_file
, " - context independent values, size: %i, "
2899 "time_benefit: %f\n", size
, (base_time
- time
).to_double ());
2901 if (size
<= 0 || node
->local
.local
)
2903 info
->do_clone_for_all_contexts
= true;
2906 fprintf (dump_file
, " Decided to specialize for all "
2907 "known contexts, code not going to grow.\n");
2909 else if (good_cloning_opportunity_p (node
,
2910 MAX ((base_time
- time
).to_int (),
2912 stats
.freq_sum
, stats
.count_sum
,
2915 if (size
+ overall_size
<= max_new_size
)
2917 info
->do_clone_for_all_contexts
= true;
2918 overall_size
+= size
;
2921 fprintf (dump_file
, " Decided to specialize for all "
2922 "known contexts, growth deemed beneficial.\n");
2924 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2925 fprintf (dump_file
, " Not cloning for all contexts because "
2926 "max_new_size would be reached with %li.\n",
2927 size
+ overall_size
);
2929 else if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2930 fprintf (dump_file
, " Not cloning for all contexts because "
2931 "!good_cloning_opportunity_p.\n");
2935 for (i
= 0; i
< count
; i
++)
2937 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2938 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
2939 ipcp_value
<tree
> *val
;
2946 for (val
= lat
->values
; val
; val
= val
->next
)
2948 gcc_checking_assert (TREE_CODE (val
->value
) != TREE_BINFO
);
2949 known_csts
[i
] = val
->value
;
2951 int emc
= estimate_move_cost (TREE_TYPE (val
->value
), true);
2952 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2954 removable_params_cost
, emc
, val
);
2956 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2958 fprintf (dump_file
, " - estimates for value ");
2959 print_ipcp_constant_value (dump_file
, val
->value
);
2960 fprintf (dump_file
, " for ");
2961 ipa_dump_param (dump_file
, info
, i
);
2962 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2963 val
->local_time_benefit
, val
->local_size_cost
);
2966 known_csts
[i
] = NULL_TREE
;
2969 for (i
= 0; i
< count
; i
++)
2971 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
2973 if (!plats
->virt_call
)
2976 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
2977 ipcp_value
<ipa_polymorphic_call_context
> *val
;
2981 || !known_contexts
[i
].useless_p ())
2984 for (val
= ctxlat
->values
; val
; val
= val
->next
)
2986 known_contexts
[i
] = val
->value
;
2987 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
2989 removable_params_cost
, 0, val
);
2991 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2993 fprintf (dump_file
, " - estimates for polymorphic context ");
2994 print_ipcp_constant_value (dump_file
, val
->value
);
2995 fprintf (dump_file
, " for ");
2996 ipa_dump_param (dump_file
, info
, i
);
2997 fprintf (dump_file
, ": time_benefit: %i, size: %i\n",
2998 val
->local_time_benefit
, val
->local_size_cost
);
3001 known_contexts
[i
] = ipa_polymorphic_call_context ();
3004 for (i
= 0; i
< count
; i
++)
3006 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3007 struct ipa_agg_jump_function
*ajf
;
3008 struct ipcp_agg_lattice
*aglat
;
3010 if (plats
->aggs_bottom
|| !plats
->aggs
)
3013 ajf
= &known_aggs
[i
];
3014 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3016 ipcp_value
<tree
> *val
;
3017 if (aglat
->bottom
|| !aglat
->values
3018 /* If the following is true, the one value is in known_aggs. */
3019 || (!plats
->aggs_contain_variable
3020 && aglat
->is_single_const ()))
3023 for (val
= aglat
->values
; val
; val
= val
->next
)
3025 struct ipa_agg_jf_item item
;
3027 item
.offset
= aglat
->offset
;
3028 item
.value
= val
->value
;
3029 vec_safe_push (ajf
->items
, item
);
3031 perform_estimation_of_a_value (node
, known_csts
, known_contexts
,
3033 removable_params_cost
, 0, val
);
3035 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3037 fprintf (dump_file
, " - estimates for value ");
3038 print_ipcp_constant_value (dump_file
, val
->value
);
3039 fprintf (dump_file
, " for ");
3040 ipa_dump_param (dump_file
, info
, i
);
3041 fprintf (dump_file
, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3042 "]: time_benefit: %i, size: %i\n",
3043 plats
->aggs_by_ref
? "ref " : "",
3045 val
->local_time_benefit
, val
->local_size_cost
);
3053 for (i
= 0; i
< count
; i
++)
3054 vec_free (known_aggs
[i
].items
);
3056 known_csts
.release ();
3057 known_contexts
.release ();
3058 known_aggs
.release ();
3059 known_aggs_ptrs
.release ();
3063 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3064 topological sort of values. */
3066 template <typename valtype
>
3068 value_topo_info
<valtype
>::add_val (ipcp_value
<valtype
> *cur_val
)
3070 ipcp_value_source
<valtype
> *src
;
3076 cur_val
->dfs
= dfs_counter
;
3077 cur_val
->low_link
= dfs_counter
;
3079 cur_val
->topo_next
= stack
;
3081 cur_val
->on_stack
= true;
3083 for (src
= cur_val
->sources
; src
; src
= src
->next
)
3086 if (src
->val
->dfs
== 0)
3089 if (src
->val
->low_link
< cur_val
->low_link
)
3090 cur_val
->low_link
= src
->val
->low_link
;
3092 else if (src
->val
->on_stack
3093 && src
->val
->dfs
< cur_val
->low_link
)
3094 cur_val
->low_link
= src
->val
->dfs
;
3097 if (cur_val
->dfs
== cur_val
->low_link
)
3099 ipcp_value
<valtype
> *v
, *scc_list
= NULL
;
3104 stack
= v
->topo_next
;
3105 v
->on_stack
= false;
3107 v
->scc_next
= scc_list
;
3110 while (v
!= cur_val
);
3112 cur_val
->topo_next
= values_topo
;
3113 values_topo
= cur_val
;
3117 /* Add all values in lattices associated with NODE to the topological sort if
3118 they are not there yet. */
3121 add_all_node_vals_to_toposort (cgraph_node
*node
, ipa_topo_info
*topo
)
3123 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3124 int i
, count
= ipa_get_param_count (info
);
3126 for (i
= 0; i
< count
; i
++)
3128 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
3129 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
3130 struct ipcp_agg_lattice
*aglat
;
3134 ipcp_value
<tree
> *val
;
3135 for (val
= lat
->values
; val
; val
= val
->next
)
3136 topo
->constants
.add_val (val
);
3139 if (!plats
->aggs_bottom
)
3140 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3143 ipcp_value
<tree
> *val
;
3144 for (val
= aglat
->values
; val
; val
= val
->next
)
3145 topo
->constants
.add_val (val
);
3148 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
3149 if (!ctxlat
->bottom
)
3151 ipcp_value
<ipa_polymorphic_call_context
> *ctxval
;
3152 for (ctxval
= ctxlat
->values
; ctxval
; ctxval
= ctxval
->next
)
3153 topo
->contexts
.add_val (ctxval
);
3158 /* One pass of constants propagation along the call graph edges, from callers
3159 to callees (requires topological ordering in TOPO), iterate over strongly
3160 connected components. */
3163 propagate_constants_topo (struct ipa_topo_info
*topo
)
3167 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
3170 struct cgraph_node
*v
, *node
= topo
->order
[i
];
3171 vec
<cgraph_node
*> cycle_nodes
= ipa_get_nodes_in_cycle (node
);
3173 /* First, iteratively propagate within the strongly connected component
3174 until all lattices stabilize. */
3175 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3176 if (v
->has_gimple_body_p ())
3177 push_node_to_stack (topo
, v
);
3179 v
= pop_node_from_stack (topo
);
3182 struct cgraph_edge
*cs
;
3184 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3185 if (ipa_edge_within_scc (cs
))
3187 IPA_NODE_REF (v
)->node_within_scc
= true;
3188 if (propagate_constants_across_call (cs
))
3189 push_node_to_stack (topo
, cs
->callee
->function_symbol ());
3191 v
= pop_node_from_stack (topo
);
3194 /* Afterwards, propagate along edges leading out of the SCC, calculates
3195 the local effects of the discovered constants and all valid values to
3196 their topological sort. */
3197 FOR_EACH_VEC_ELT (cycle_nodes
, j
, v
)
3198 if (v
->has_gimple_body_p ())
3200 struct cgraph_edge
*cs
;
3202 estimate_local_effects (v
);
3203 add_all_node_vals_to_toposort (v
, topo
);
3204 for (cs
= v
->callees
; cs
; cs
= cs
->next_callee
)
3205 if (!ipa_edge_within_scc (cs
))
3206 propagate_constants_across_call (cs
);
3208 cycle_nodes
.release ();
3213 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3214 the bigger one if otherwise. */
3217 safe_add (int a
, int b
)
3219 if (a
> INT_MAX
/2 || b
> INT_MAX
/2)
3220 return a
> b
? a
: b
;
3226 /* Propagate the estimated effects of individual values along the topological
3227 from the dependent values to those they depend on. */
3229 template <typename valtype
>
3231 value_topo_info
<valtype
>::propagate_effects ()
3233 ipcp_value
<valtype
> *base
;
3235 for (base
= values_topo
; base
; base
= base
->topo_next
)
3237 ipcp_value_source
<valtype
> *src
;
3238 ipcp_value
<valtype
> *val
;
3239 int time
= 0, size
= 0;
3241 for (val
= base
; val
; val
= val
->scc_next
)
3243 time
= safe_add (time
,
3244 val
->local_time_benefit
+ val
->prop_time_benefit
);
3245 size
= safe_add (size
, val
->local_size_cost
+ val
->prop_size_cost
);
3248 for (val
= base
; val
; val
= val
->scc_next
)
3249 for (src
= val
->sources
; src
; src
= src
->next
)
3251 && src
->cs
->maybe_hot_p ())
3253 src
->val
->prop_time_benefit
= safe_add (time
,
3254 src
->val
->prop_time_benefit
);
3255 src
->val
->prop_size_cost
= safe_add (size
,
3256 src
->val
->prop_size_cost
);
3262 /* Propagate constants, polymorphic contexts and their effects from the
3263 summaries interprocedurally. */
3266 ipcp_propagate_stage (struct ipa_topo_info
*topo
)
3268 struct cgraph_node
*node
;
3271 fprintf (dump_file
, "\n Propagating constants:\n\n");
3273 max_count
= profile_count::uninitialized ();
3275 FOR_EACH_DEFINED_FUNCTION (node
)
3277 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3279 determine_versionability (node
, info
);
3280 if (node
->has_gimple_body_p ())
3282 info
->lattices
= XCNEWVEC (struct ipcp_param_lattices
,
3283 ipa_get_param_count (info
));
3284 initialize_node_lattices (node
);
3286 if (node
->definition
&& !node
->alias
)
3287 overall_size
+= ipa_fn_summaries
->get (node
)->self_size
;
3288 max_count
= max_count
.max (node
->count
.ipa ());
3291 max_new_size
= overall_size
;
3292 if (max_new_size
< PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
))
3293 max_new_size
= PARAM_VALUE (PARAM_LARGE_UNIT_INSNS
);
3294 max_new_size
+= max_new_size
* PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH
) / 100 + 1;
3297 fprintf (dump_file
, "\noverall_size: %li, max_new_size: %li\n",
3298 overall_size
, max_new_size
);
3300 propagate_constants_topo (topo
);
3302 ipcp_verify_propagated_values ();
3303 topo
->constants
.propagate_effects ();
3304 topo
->contexts
.propagate_effects ();
3308 fprintf (dump_file
, "\nIPA lattices after all propagation:\n");
3309 print_all_lattices (dump_file
, (dump_flags
& TDF_DETAILS
), true);
3313 /* Discover newly direct outgoing edges from NODE which is a new clone with
3314 known KNOWN_CSTS and make them direct. */
3317 ipcp_discover_new_direct_edges (struct cgraph_node
*node
,
3318 vec
<tree
> known_csts
,
3319 vec
<ipa_polymorphic_call_context
>
3321 struct ipa_agg_replacement_value
*aggvals
)
3323 struct cgraph_edge
*ie
, *next_ie
;
3326 for (ie
= node
->indirect_calls
; ie
; ie
= next_ie
)
3331 next_ie
= ie
->next_callee
;
3332 target
= ipa_get_indirect_edge_target_1 (ie
, known_csts
, known_contexts
,
3333 vNULL
, aggvals
, &speculative
);
3336 bool agg_contents
= ie
->indirect_info
->agg_contents
;
3337 bool polymorphic
= ie
->indirect_info
->polymorphic
;
3338 int param_index
= ie
->indirect_info
->param_index
;
3339 struct cgraph_edge
*cs
= ipa_make_edge_direct_to_target (ie
, target
,
3343 if (cs
&& !agg_contents
&& !polymorphic
)
3345 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3346 int c
= ipa_get_controlled_uses (info
, param_index
);
3347 if (c
!= IPA_UNDESCRIBED_USE
)
3349 struct ipa_ref
*to_del
;
3352 ipa_set_controlled_uses (info
, param_index
, c
);
3353 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3354 fprintf (dump_file
, " controlled uses count of param "
3355 "%i bumped down to %i\n", param_index
, c
);
3357 && (to_del
= node
->find_reference (cs
->callee
, NULL
, 0)))
3359 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3360 fprintf (dump_file
, " and even removing its "
3361 "cloning-created reference\n");
3362 to_del
->remove_reference ();
3368 /* Turning calls to direct calls will improve overall summary. */
3370 ipa_update_overall_fn_summary (node
);
3373 /* Vector of pointers which for linked lists of clones of an original crgaph
3376 static vec
<cgraph_edge
*> next_edge_clone
;
3377 static vec
<cgraph_edge
*> prev_edge_clone
;
3380 grow_edge_clone_vectors (void)
3382 if (next_edge_clone
.length ()
3383 <= (unsigned) symtab
->edges_max_uid
)
3384 next_edge_clone
.safe_grow_cleared (symtab
->edges_max_uid
+ 1);
3385 if (prev_edge_clone
.length ()
3386 <= (unsigned) symtab
->edges_max_uid
)
3387 prev_edge_clone
.safe_grow_cleared (symtab
->edges_max_uid
+ 1);
3390 /* Edge duplication hook to grow the appropriate linked list in
3394 ipcp_edge_duplication_hook (struct cgraph_edge
*src
, struct cgraph_edge
*dst
,
3397 grow_edge_clone_vectors ();
3399 struct cgraph_edge
*old_next
= next_edge_clone
[src
->uid
];
3401 prev_edge_clone
[old_next
->uid
] = dst
;
3402 prev_edge_clone
[dst
->uid
] = src
;
3404 next_edge_clone
[dst
->uid
] = old_next
;
3405 next_edge_clone
[src
->uid
] = dst
;
3408 /* Hook that is called by cgraph.c when an edge is removed. */
3411 ipcp_edge_removal_hook (struct cgraph_edge
*cs
, void *)
3413 grow_edge_clone_vectors ();
3415 struct cgraph_edge
*prev
= prev_edge_clone
[cs
->uid
];
3416 struct cgraph_edge
*next
= next_edge_clone
[cs
->uid
];
3418 next_edge_clone
[prev
->uid
] = next
;
3420 prev_edge_clone
[next
->uid
] = prev
;
3423 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3424 parameter with the given INDEX. */
3427 get_clone_agg_value (struct cgraph_node
*node
, HOST_WIDE_INT offset
,
3430 struct ipa_agg_replacement_value
*aggval
;
3432 aggval
= ipa_get_agg_replacements_for_node (node
);
3435 if (aggval
->offset
== offset
3436 && aggval
->index
== index
)
3437 return aggval
->value
;
3438 aggval
= aggval
->next
;
3443 /* Return true is NODE is DEST or its clone for all contexts. */
3446 same_node_or_its_all_contexts_clone_p (cgraph_node
*node
, cgraph_node
*dest
)
3451 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3452 return info
->is_all_contexts_clone
&& info
->ipcp_orig_node
== dest
;
3455 /* Return true if edge CS does bring about the value described by SRC to node
3456 DEST or its clone for all contexts. */
3459 cgraph_edge_brings_value_p (cgraph_edge
*cs
, ipcp_value_source
<tree
> *src
,
3462 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3463 enum availability availability
;
3464 cgraph_node
*real_dest
= cs
->callee
->function_symbol (&availability
);
3466 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3467 || availability
<= AVAIL_INTERPOSABLE
3468 || caller_info
->node_dead
)
3473 if (caller_info
->ipcp_orig_node
)
3476 if (src
->offset
== -1)
3477 t
= caller_info
->known_csts
[src
->index
];
3479 t
= get_clone_agg_value (cs
->caller
, src
->offset
, src
->index
);
3480 return (t
!= NULL_TREE
3481 && values_equal_for_ipcp_p (src
->val
->value
, t
));
3485 struct ipcp_agg_lattice
*aglat
;
3486 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3488 if (src
->offset
== -1)
3489 return (plats
->itself
.is_single_const ()
3490 && values_equal_for_ipcp_p (src
->val
->value
,
3491 plats
->itself
.values
->value
));
3494 if (plats
->aggs_bottom
|| plats
->aggs_contain_variable
)
3496 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3497 if (aglat
->offset
== src
->offset
)
3498 return (aglat
->is_single_const ()
3499 && values_equal_for_ipcp_p (src
->val
->value
,
3500 aglat
->values
->value
));
3506 /* Return true if edge CS does bring about the value described by SRC to node
3507 DEST or its clone for all contexts. */
3510 cgraph_edge_brings_value_p (cgraph_edge
*cs
,
3511 ipcp_value_source
<ipa_polymorphic_call_context
> *src
,
3514 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
3515 cgraph_node
*real_dest
= cs
->callee
->function_symbol ();
3517 if (!same_node_or_its_all_contexts_clone_p (real_dest
, dest
)
3518 || caller_info
->node_dead
)
3523 if (caller_info
->ipcp_orig_node
)
3524 return (caller_info
->known_contexts
.length () > (unsigned) src
->index
)
3525 && values_equal_for_ipcp_p (src
->val
->value
,
3526 caller_info
->known_contexts
[src
->index
]);
3528 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (caller_info
,
3530 return plats
->ctxlat
.is_single_const ()
3531 && values_equal_for_ipcp_p (src
->val
->value
,
3532 plats
->ctxlat
.values
->value
);
3535 /* Get the next clone in the linked list of clones of an edge. */
3537 static inline struct cgraph_edge
*
3538 get_next_cgraph_edge_clone (struct cgraph_edge
*cs
)
3540 return next_edge_clone
[cs
->uid
];
3543 /* Given VAL that is intended for DEST, iterate over all its sources and if
3544 they still hold, add their edge frequency and their number into *FREQUENCY
3545 and *CALLER_COUNT respectively. */
3547 template <typename valtype
>
3549 get_info_about_necessary_edges (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3551 profile_count
*count_sum
, int *caller_count
)
3553 ipcp_value_source
<valtype
> *src
;
3554 int freq
= 0, count
= 0;
3555 profile_count cnt
= profile_count::zero ();
3558 for (src
= val
->sources
; src
; src
= src
->next
)
3560 struct cgraph_edge
*cs
= src
->cs
;
3563 if (cgraph_edge_brings_value_p (cs
, src
, dest
))
3566 freq
+= cs
->frequency ();
3567 if (cs
->count
.ipa ().initialized_p ())
3568 cnt
+= cs
->count
.ipa ();
3569 hot
|= cs
->maybe_hot_p ();
3571 cs
= get_next_cgraph_edge_clone (cs
);
3577 *caller_count
= count
;
3581 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
3582 is assumed their number is known and equal to CALLER_COUNT. */
3584 template <typename valtype
>
3585 static vec
<cgraph_edge
*>
3586 gather_edges_for_value (ipcp_value
<valtype
> *val
, cgraph_node
*dest
,
3589 ipcp_value_source
<valtype
> *src
;
3590 vec
<cgraph_edge
*> ret
;
3592 ret
.create (caller_count
);
3593 for (src
= val
->sources
; src
; src
= src
->next
)
3595 struct cgraph_edge
*cs
= src
->cs
;
3598 if (cgraph_edge_brings_value_p (cs
, src
, dest
))
3599 ret
.quick_push (cs
);
3600 cs
= get_next_cgraph_edge_clone (cs
);
3607 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3608 Return it or NULL if for some reason it cannot be created. */
3610 static struct ipa_replace_map
*
3611 get_replacement_map (struct ipa_node_params
*info
, tree value
, int parm_num
)
3613 struct ipa_replace_map
*replace_map
;
3616 replace_map
= ggc_alloc
<ipa_replace_map
> ();
3619 fprintf (dump_file
, " replacing ");
3620 ipa_dump_param (dump_file
, info
, parm_num
);
3622 fprintf (dump_file
, " with const ");
3623 print_generic_expr (dump_file
, value
);
3624 fprintf (dump_file
, "\n");
3626 replace_map
->old_tree
= NULL
;
3627 replace_map
->parm_num
= parm_num
;
3628 replace_map
->new_tree
= value
;
3629 replace_map
->replace_p
= true;
3630 replace_map
->ref_p
= false;
3635 /* Dump new profiling counts */
3638 dump_profile_updates (struct cgraph_node
*orig_node
,
3639 struct cgraph_node
*new_node
)
3641 struct cgraph_edge
*cs
;
3643 fprintf (dump_file
, " setting count of the specialized node to ");
3644 new_node
->count
.dump (dump_file
);
3645 fprintf (dump_file
, "\n");
3646 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3648 fprintf (dump_file
, " edge to %s has count ",
3649 cs
->callee
->name ());
3650 cs
->count
.dump (dump_file
);
3651 fprintf (dump_file
, "\n");
3654 fprintf (dump_file
, " setting count of the original node to ");
3655 orig_node
->count
.dump (dump_file
);
3656 fprintf (dump_file
, "\n");
3657 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3659 fprintf (dump_file
, " edge to %s is left with ",
3660 cs
->callee
->name ());
3661 cs
->count
.dump (dump_file
);
3662 fprintf (dump_file
, "\n");
3666 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
3667 their profile information to reflect this. */
3670 update_profiling_info (struct cgraph_node
*orig_node
,
3671 struct cgraph_node
*new_node
)
3673 struct cgraph_edge
*cs
;
3674 struct caller_statistics stats
;
3675 profile_count new_sum
, orig_sum
;
3676 profile_count remainder
, orig_node_count
= orig_node
->count
;
3678 if (!(orig_node_count
.ipa () > profile_count::zero ()))
3681 init_caller_stats (&stats
);
3682 orig_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3684 orig_sum
= stats
.count_sum
;
3685 init_caller_stats (&stats
);
3686 new_node
->call_for_symbol_thunks_and_aliases (gather_caller_stats
, &stats
,
3688 new_sum
= stats
.count_sum
;
3690 if (orig_node_count
< orig_sum
+ new_sum
)
3694 fprintf (dump_file
, " Problem: node %s has too low count ",
3695 orig_node
->dump_name ());
3696 orig_node_count
.dump (dump_file
);
3697 fprintf (dump_file
, "while the sum of incoming count is ");
3698 (orig_sum
+ new_sum
).dump (dump_file
);
3699 fprintf (dump_file
, "\n");
3702 orig_node_count
= (orig_sum
+ new_sum
).apply_scale (12, 10);
3705 fprintf (dump_file
, " proceeding by pretending it was ");
3706 orig_node_count
.dump (dump_file
);
3707 fprintf (dump_file
, "\n");
3711 remainder
= orig_node_count
.combine_with_ipa_count (orig_node_count
.ipa ()
3713 new_sum
= orig_node_count
.combine_with_ipa_count (new_sum
);
3714 orig_node
->count
= remainder
;
3716 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3717 cs
->count
= cs
->count
.apply_scale (new_sum
, orig_node_count
);
3719 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3720 cs
->count
= cs
->count
.apply_scale (remainder
, orig_node_count
);
3723 dump_profile_updates (orig_node
, new_node
);
3726 /* Update the respective profile of specialized NEW_NODE and the original
3727 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
3728 have been redirected to the specialized version. */
3731 update_specialized_profile (struct cgraph_node
*new_node
,
3732 struct cgraph_node
*orig_node
,
3733 profile_count redirected_sum
)
3735 struct cgraph_edge
*cs
;
3736 profile_count new_node_count
, orig_node_count
= orig_node
->count
;
3740 fprintf (dump_file
, " the sum of counts of redirected edges is ");
3741 redirected_sum
.dump (dump_file
);
3742 fprintf (dump_file
, "\n");
3744 if (!(orig_node_count
> profile_count::zero ()))
3747 gcc_assert (orig_node_count
>= redirected_sum
);
3749 new_node_count
= new_node
->count
;
3750 new_node
->count
+= redirected_sum
;
3751 orig_node
->count
-= redirected_sum
;
3753 for (cs
= new_node
->callees
; cs
; cs
= cs
->next_callee
)
3754 cs
->count
+= cs
->count
.apply_scale (redirected_sum
, new_node_count
);
3756 for (cs
= orig_node
->callees
; cs
; cs
= cs
->next_callee
)
3758 profile_count dec
= cs
->count
.apply_scale (redirected_sum
,
3764 dump_profile_updates (orig_node
, new_node
);
3767 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3768 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3769 redirect all edges in CALLERS to it. */
3771 static struct cgraph_node
*
3772 create_specialized_node (struct cgraph_node
*node
,
3773 vec
<tree
> known_csts
,
3774 vec
<ipa_polymorphic_call_context
> known_contexts
,
3775 struct ipa_agg_replacement_value
*aggvals
,
3776 vec
<cgraph_edge
*> callers
)
3778 struct ipa_node_params
*new_info
, *info
= IPA_NODE_REF (node
);
3779 vec
<ipa_replace_map
*, va_gc
> *replace_trees
= NULL
;
3780 struct ipa_agg_replacement_value
*av
;
3781 struct cgraph_node
*new_node
;
3782 int i
, count
= ipa_get_param_count (info
);
3783 bitmap args_to_skip
;
3785 gcc_assert (!info
->ipcp_orig_node
);
3787 if (node
->local
.can_change_signature
)
3789 args_to_skip
= BITMAP_GGC_ALLOC ();
3790 for (i
= 0; i
< count
; i
++)
3792 tree t
= known_csts
[i
];
3794 if (t
|| !ipa_is_param_used (info
, i
))
3795 bitmap_set_bit (args_to_skip
, i
);
3800 args_to_skip
= NULL
;
3801 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3802 fprintf (dump_file
, " cannot change function signature\n");
3805 for (i
= 0; i
< count
; i
++)
3807 tree t
= known_csts
[i
];
3810 struct ipa_replace_map
*replace_map
;
3812 gcc_checking_assert (TREE_CODE (t
) != TREE_BINFO
);
3813 replace_map
= get_replacement_map (info
, t
, i
);
3815 vec_safe_push (replace_trees
, replace_map
);
3819 new_node
= node
->create_virtual_clone (callers
, replace_trees
,
3820 args_to_skip
, "constprop");
3821 ipa_set_node_agg_value_chain (new_node
, aggvals
);
3822 for (av
= aggvals
; av
; av
= av
->next
)
3823 new_node
->maybe_create_reference (av
->value
, NULL
);
3825 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3827 fprintf (dump_file
, " the new node is %s.\n", new_node
->dump_name ());
3828 if (known_contexts
.exists ())
3830 for (i
= 0; i
< count
; i
++)
3831 if (!known_contexts
[i
].useless_p ())
3833 fprintf (dump_file
, " known ctx %i is ", i
);
3834 known_contexts
[i
].dump (dump_file
);
3838 ipa_dump_agg_replacement_values (dump_file
, aggvals
);
3840 ipa_check_create_node_params ();
3841 update_profiling_info (node
, new_node
);
3842 new_info
= IPA_NODE_REF (new_node
);
3843 new_info
->ipcp_orig_node
= node
;
3844 new_info
->known_csts
= known_csts
;
3845 new_info
->known_contexts
= known_contexts
;
3847 ipcp_discover_new_direct_edges (new_node
, known_csts
, known_contexts
, aggvals
);
3853 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3854 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
3857 find_more_scalar_values_for_callers_subset (struct cgraph_node
*node
,
3858 vec
<tree
> known_csts
,
3859 vec
<cgraph_edge
*> callers
)
3861 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
3862 int i
, count
= ipa_get_param_count (info
);
3864 for (i
= 0; i
< count
; i
++)
3866 struct cgraph_edge
*cs
;
3867 tree newval
= NULL_TREE
;
3870 tree type
= ipa_get_type (info
, i
);
3872 if (ipa_get_scalar_lat (info
, i
)->bottom
|| known_csts
[i
])
3875 FOR_EACH_VEC_ELT (callers
, j
, cs
)
3877 struct ipa_jump_func
*jump_func
;
3880 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
))
3882 && call_passes_through_thunk_p (cs
))
3883 || (!cs
->callee
->instrumentation_clone
3884 && cs
->callee
->function_symbol ()->instrumentation_clone
))
3889 jump_func
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), i
);
3890 t
= ipa_value_from_jfunc (IPA_NODE_REF (cs
->caller
), jump_func
, type
);
3893 && !values_equal_for_ipcp_p (t
, newval
))
3894 || (!first
&& !newval
))
3906 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3908 fprintf (dump_file
, " adding an extra known scalar value ");
3909 print_ipcp_constant_value (dump_file
, newval
);
3910 fprintf (dump_file
, " for ");
3911 ipa_dump_param (dump_file
, info
, i
);
3912 fprintf (dump_file
, "\n");
3915 known_csts
[i
] = newval
;
3920 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
3921 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
3925 find_more_contexts_for_caller_subset (cgraph_node
*node
,
3926 vec
<ipa_polymorphic_call_context
>
3928 vec
<cgraph_edge
*> callers
)
3930 ipa_node_params
*info
= IPA_NODE_REF (node
);
3931 int i
, count
= ipa_get_param_count (info
);
3933 for (i
= 0; i
< count
; i
++)
3937 if (ipa_get_poly_ctx_lat (info
, i
)->bottom
3938 || (known_contexts
->exists ()
3939 && !(*known_contexts
)[i
].useless_p ()))
3942 ipa_polymorphic_call_context newval
;
3946 FOR_EACH_VEC_ELT (callers
, j
, cs
)
3948 if (i
>= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
)))
3950 ipa_jump_func
*jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
),
3952 ipa_polymorphic_call_context ctx
;
3953 ctx
= ipa_context_from_jfunc (IPA_NODE_REF (cs
->caller
), cs
, i
,
3961 newval
.meet_with (ctx
);
3962 if (newval
.useless_p ())
3966 if (!newval
.useless_p ())
3968 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3970 fprintf (dump_file
, " adding an extra known polymorphic "
3972 print_ipcp_constant_value (dump_file
, newval
);
3973 fprintf (dump_file
, " for ");
3974 ipa_dump_param (dump_file
, info
, i
);
3975 fprintf (dump_file
, "\n");
3978 if (!known_contexts
->exists ())
3979 known_contexts
->safe_grow_cleared (ipa_get_param_count (info
));
3980 (*known_contexts
)[i
] = newval
;
3986 /* Go through PLATS and create a vector of values consisting of values and
3987 offsets (minus OFFSET) of lattices that contain only a single value. */
3989 static vec
<ipa_agg_jf_item
>
3990 copy_plats_to_inter (struct ipcp_param_lattices
*plats
, HOST_WIDE_INT offset
)
3992 vec
<ipa_agg_jf_item
> res
= vNULL
;
3994 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
3997 for (struct ipcp_agg_lattice
*aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
3998 if (aglat
->is_single_const ())
4000 struct ipa_agg_jf_item ti
;
4001 ti
.offset
= aglat
->offset
- offset
;
4002 ti
.value
= aglat
->values
->value
;
4008 /* Intersect all values in INTER with single value lattices in PLATS (while
4009 subtracting OFFSET). */
4012 intersect_with_plats (struct ipcp_param_lattices
*plats
,
4013 vec
<ipa_agg_jf_item
> *inter
,
4014 HOST_WIDE_INT offset
)
4016 struct ipcp_agg_lattice
*aglat
;
4017 struct ipa_agg_jf_item
*item
;
4020 if (!plats
->aggs
|| plats
->aggs_contain_variable
|| plats
->aggs_bottom
)
4026 aglat
= plats
->aggs
;
4027 FOR_EACH_VEC_ELT (*inter
, k
, item
)
4034 if (aglat
->offset
- offset
> item
->offset
)
4036 if (aglat
->offset
- offset
== item
->offset
)
4038 gcc_checking_assert (item
->value
);
4039 if (values_equal_for_ipcp_p (item
->value
, aglat
->values
->value
))
4043 aglat
= aglat
->next
;
4046 item
->value
= NULL_TREE
;
4050 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4051 vector result while subtracting OFFSET from the individual value offsets. */
4053 static vec
<ipa_agg_jf_item
>
4054 agg_replacements_to_vector (struct cgraph_node
*node
, int index
,
4055 HOST_WIDE_INT offset
)
4057 struct ipa_agg_replacement_value
*av
;
4058 vec
<ipa_agg_jf_item
> res
= vNULL
;
4060 for (av
= ipa_get_agg_replacements_for_node (node
); av
; av
= av
->next
)
4061 if (av
->index
== index
4062 && (av
->offset
- offset
) >= 0)
4064 struct ipa_agg_jf_item item
;
4065 gcc_checking_assert (av
->value
);
4066 item
.offset
= av
->offset
- offset
;
4067 item
.value
= av
->value
;
4068 res
.safe_push (item
);
4074 /* Intersect all values in INTER with those that we have already scheduled to
4075 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4076 (while subtracting OFFSET). */
4079 intersect_with_agg_replacements (struct cgraph_node
*node
, int index
,
4080 vec
<ipa_agg_jf_item
> *inter
,
4081 HOST_WIDE_INT offset
)
4083 struct ipa_agg_replacement_value
*srcvals
;
4084 struct ipa_agg_jf_item
*item
;
4087 srcvals
= ipa_get_agg_replacements_for_node (node
);
4094 FOR_EACH_VEC_ELT (*inter
, i
, item
)
4096 struct ipa_agg_replacement_value
*av
;
4100 for (av
= srcvals
; av
; av
= av
->next
)
4102 gcc_checking_assert (av
->value
);
4103 if (av
->index
== index
4104 && av
->offset
- offset
== item
->offset
)
4106 if (values_equal_for_ipcp_p (item
->value
, av
->value
))
4112 item
->value
= NULL_TREE
;
4116 /* Intersect values in INTER with aggregate values that come along edge CS to
4117 parameter number INDEX and return it. If INTER does not actually exist yet,
4118 copy all incoming values to it. If we determine we ended up with no values
4119 whatsoever, return a released vector. */
4121 static vec
<ipa_agg_jf_item
>
4122 intersect_aggregates_with_edge (struct cgraph_edge
*cs
, int index
,
4123 vec
<ipa_agg_jf_item
> inter
)
4125 struct ipa_jump_func
*jfunc
;
4126 jfunc
= ipa_get_ith_jump_func (IPA_EDGE_REF (cs
), index
);
4127 if (jfunc
->type
== IPA_JF_PASS_THROUGH
4128 && ipa_get_jf_pass_through_operation (jfunc
) == NOP_EXPR
)
4130 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4131 int src_idx
= ipa_get_jf_pass_through_formal_id (jfunc
);
4133 if (caller_info
->ipcp_orig_node
)
4135 struct cgraph_node
*orig_node
= caller_info
->ipcp_orig_node
;
4136 struct ipcp_param_lattices
*orig_plats
;
4137 orig_plats
= ipa_get_parm_lattices (IPA_NODE_REF (orig_node
),
4139 if (agg_pass_through_permissible_p (orig_plats
, jfunc
))
4141 if (!inter
.exists ())
4142 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, 0);
4144 intersect_with_agg_replacements (cs
->caller
, src_idx
,
4155 struct ipcp_param_lattices
*src_plats
;
4156 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4157 if (agg_pass_through_permissible_p (src_plats
, jfunc
))
4159 /* Currently we do not produce clobber aggregate jump
4160 functions, adjust when we do. */
4161 gcc_checking_assert (!jfunc
->agg
.items
);
4162 if (!inter
.exists ())
4163 inter
= copy_plats_to_inter (src_plats
, 0);
4165 intersect_with_plats (src_plats
, &inter
, 0);
4174 else if (jfunc
->type
== IPA_JF_ANCESTOR
4175 && ipa_get_jf_ancestor_agg_preserved (jfunc
))
4177 struct ipa_node_params
*caller_info
= IPA_NODE_REF (cs
->caller
);
4178 int src_idx
= ipa_get_jf_ancestor_formal_id (jfunc
);
4179 struct ipcp_param_lattices
*src_plats
;
4180 HOST_WIDE_INT delta
= ipa_get_jf_ancestor_offset (jfunc
);
4182 if (caller_info
->ipcp_orig_node
)
4184 if (!inter
.exists ())
4185 inter
= agg_replacements_to_vector (cs
->caller
, src_idx
, delta
);
4187 intersect_with_agg_replacements (cs
->caller
, src_idx
, &inter
,
4192 src_plats
= ipa_get_parm_lattices (caller_info
, src_idx
);
4193 /* Currently we do not produce clobber aggregate jump
4194 functions, adjust when we do. */
4195 gcc_checking_assert (!src_plats
->aggs
|| !jfunc
->agg
.items
);
4196 if (!inter
.exists ())
4197 inter
= copy_plats_to_inter (src_plats
, delta
);
4199 intersect_with_plats (src_plats
, &inter
, delta
);
4202 else if (jfunc
->agg
.items
)
4204 struct ipa_agg_jf_item
*item
;
4207 if (!inter
.exists ())
4208 for (unsigned i
= 0; i
< jfunc
->agg
.items
->length (); i
++)
4209 inter
.safe_push ((*jfunc
->agg
.items
)[i
]);
4211 FOR_EACH_VEC_ELT (inter
, k
, item
)
4219 while ((unsigned) l
< jfunc
->agg
.items
->length ())
4221 struct ipa_agg_jf_item
*ti
;
4222 ti
= &(*jfunc
->agg
.items
)[l
];
4223 if (ti
->offset
> item
->offset
)
4225 if (ti
->offset
== item
->offset
)
4227 gcc_checking_assert (ti
->value
);
4228 if (values_equal_for_ipcp_p (item
->value
,
4242 return vec
<ipa_agg_jf_item
>();
4247 /* Look at edges in CALLERS and collect all known aggregate values that arrive
4248 from all of them. */
4250 static struct ipa_agg_replacement_value
*
4251 find_aggregate_values_for_callers_subset (struct cgraph_node
*node
,
4252 vec
<cgraph_edge
*> callers
)
4254 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4255 struct ipa_agg_replacement_value
*res
;
4256 struct ipa_agg_replacement_value
**tail
= &res
;
4257 struct cgraph_edge
*cs
;
4258 int i
, j
, count
= ipa_get_param_count (dest_info
);
4260 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4262 int c
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4267 for (i
= 0; i
< count
; i
++)
4269 struct cgraph_edge
*cs
;
4270 vec
<ipa_agg_jf_item
> inter
= vNULL
;
4271 struct ipa_agg_jf_item
*item
;
4272 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (dest_info
, i
);
4275 /* Among other things, the following check should deal with all by_ref
4277 if (plats
->aggs_bottom
)
4280 FOR_EACH_VEC_ELT (callers
, j
, cs
)
4282 inter
= intersect_aggregates_with_edge (cs
, i
, inter
);
4284 if (!inter
.exists ())
4288 FOR_EACH_VEC_ELT (inter
, j
, item
)
4290 struct ipa_agg_replacement_value
*v
;
4295 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
4297 v
->offset
= item
->offset
;
4298 v
->value
= item
->value
;
4299 v
->by_ref
= plats
->aggs_by_ref
;
4305 if (inter
.exists ())
4312 /* Turn KNOWN_AGGS into a list of aggregate replacement values. */
4314 static struct ipa_agg_replacement_value
*
4315 known_aggs_to_agg_replacement_list (vec
<ipa_agg_jump_function
> known_aggs
)
4317 struct ipa_agg_replacement_value
*res
;
4318 struct ipa_agg_replacement_value
**tail
= &res
;
4319 struct ipa_agg_jump_function
*aggjf
;
4320 struct ipa_agg_jf_item
*item
;
4323 FOR_EACH_VEC_ELT (known_aggs
, i
, aggjf
)
4324 FOR_EACH_VEC_SAFE_ELT (aggjf
->items
, j
, item
)
4326 struct ipa_agg_replacement_value
*v
;
4327 v
= ggc_alloc
<ipa_agg_replacement_value
> ();
4329 v
->offset
= item
->offset
;
4330 v
->value
= item
->value
;
4331 v
->by_ref
= aggjf
->by_ref
;
4339 /* Determine whether CS also brings all scalar values that the NODE is
4343 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge
*cs
,
4344 struct cgraph_node
*node
)
4346 struct ipa_node_params
*dest_info
= IPA_NODE_REF (node
);
4347 int count
= ipa_get_param_count (dest_info
);
4348 struct ipa_node_params
*caller_info
;
4349 struct ipa_edge_args
*args
;
4352 caller_info
= IPA_NODE_REF (cs
->caller
);
4353 args
= IPA_EDGE_REF (cs
);
4354 for (i
= 0; i
< count
; i
++)
4356 struct ipa_jump_func
*jump_func
;
4359 val
= dest_info
->known_csts
[i
];
4363 if (i
>= ipa_get_cs_argument_count (args
))
4365 jump_func
= ipa_get_ith_jump_func (args
, i
);
4366 t
= ipa_value_from_jfunc (caller_info
, jump_func
,
4367 ipa_get_type (dest_info
, i
));
4368 if (!t
|| !values_equal_for_ipcp_p (val
, t
))
4374 /* Determine whether CS also brings all aggregate values that NODE is
4377 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge
*cs
,
4378 struct cgraph_node
*node
)
4380 struct ipa_node_params
*orig_caller_info
= IPA_NODE_REF (cs
->caller
);
4381 struct ipa_node_params
*orig_node_info
;
4382 struct ipa_agg_replacement_value
*aggval
;
4385 aggval
= ipa_get_agg_replacements_for_node (node
);
4389 count
= ipa_get_param_count (IPA_NODE_REF (node
));
4390 ec
= ipa_get_cs_argument_count (IPA_EDGE_REF (cs
));
4392 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4393 if (aggval
->index
>= ec
)
4396 orig_node_info
= IPA_NODE_REF (IPA_NODE_REF (node
)->ipcp_orig_node
);
4397 if (orig_caller_info
->ipcp_orig_node
)
4398 orig_caller_info
= IPA_NODE_REF (orig_caller_info
->ipcp_orig_node
);
4400 for (i
= 0; i
< count
; i
++)
4402 static vec
<ipa_agg_jf_item
> values
= vec
<ipa_agg_jf_item
>();
4403 struct ipcp_param_lattices
*plats
;
4404 bool interesting
= false;
4405 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4406 if (aggval
->index
== i
)
4414 plats
= ipa_get_parm_lattices (orig_node_info
, aggval
->index
);
4415 if (plats
->aggs_bottom
)
4418 values
= intersect_aggregates_with_edge (cs
, i
, values
);
4419 if (!values
.exists ())
4422 for (struct ipa_agg_replacement_value
*av
= aggval
; av
; av
= av
->next
)
4423 if (aggval
->index
== i
)
4425 struct ipa_agg_jf_item
*item
;
4428 FOR_EACH_VEC_ELT (values
, j
, item
)
4430 && item
->offset
== av
->offset
4431 && values_equal_for_ipcp_p (item
->value
, av
->value
))
4446 /* Given an original NODE and a VAL for which we have already created a
4447 specialized clone, look whether there are incoming edges that still lead
4448 into the old node but now also bring the requested value and also conform to
4449 all other criteria such that they can be redirected the special node.
4450 This function can therefore redirect the final edge in a SCC. */
4452 template <typename valtype
>
4454 perhaps_add_new_callers (cgraph_node
*node
, ipcp_value
<valtype
> *val
)
4456 ipcp_value_source
<valtype
> *src
;
4457 profile_count redirected_sum
= profile_count::zero ();
4459 for (src
= val
->sources
; src
; src
= src
->next
)
4461 struct cgraph_edge
*cs
= src
->cs
;
4464 if (cgraph_edge_brings_value_p (cs
, src
, node
)
4465 && cgraph_edge_brings_all_scalars_for_node (cs
, val
->spec_node
)
4466 && cgraph_edge_brings_all_agg_vals_for_node (cs
, val
->spec_node
))
4469 fprintf (dump_file
, " - adding an extra caller %s of %s\n",
4470 cs
->caller
->dump_name (),
4471 val
->spec_node
->dump_name ());
4473 cs
->redirect_callee_duplicating_thunks (val
->spec_node
);
4474 val
->spec_node
->expand_all_artificial_thunks ();
4475 if (cs
->count
.ipa ().initialized_p ())
4476 redirected_sum
= redirected_sum
+ cs
->count
.ipa ();
4478 cs
= get_next_cgraph_edge_clone (cs
);
4482 if (redirected_sum
.nonzero_p ())
4483 update_specialized_profile (val
->spec_node
, node
, redirected_sum
);
4486 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
4489 known_contexts_useful_p (vec
<ipa_polymorphic_call_context
> known_contexts
)
4491 ipa_polymorphic_call_context
*ctx
;
4494 FOR_EACH_VEC_ELT (known_contexts
, i
, ctx
)
4495 if (!ctx
->useless_p ())
4500 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
4502 static vec
<ipa_polymorphic_call_context
>
4503 copy_useful_known_contexts (vec
<ipa_polymorphic_call_context
> known_contexts
)
4505 if (known_contexts_useful_p (known_contexts
))
4506 return known_contexts
.copy ();
4511 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX. If
4512 non-empty, replace KNOWN_CONTEXTS with its copy too. */
4515 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4516 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4517 ipcp_value
<tree
> *val
,
4520 *known_csts
= known_csts
->copy ();
4521 *known_contexts
= copy_useful_known_contexts (*known_contexts
);
4522 (*known_csts
)[index
] = val
->value
;
4525 /* Replace KNOWN_CSTS with its copy. Also copy KNOWN_CONTEXTS and modify the
4526 copy according to VAL and INDEX. */
4529 modify_known_vectors_with_val (vec
<tree
> *known_csts
,
4530 vec
<ipa_polymorphic_call_context
> *known_contexts
,
4531 ipcp_value
<ipa_polymorphic_call_context
> *val
,
4534 *known_csts
= known_csts
->copy ();
4535 *known_contexts
= known_contexts
->copy ();
4536 (*known_contexts
)[index
] = val
->value
;
4539 /* Return true if OFFSET indicates this was not an aggregate value or there is
4540 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
4544 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*aggvals
,
4545 int index
, HOST_WIDE_INT offset
, tree value
)
4552 if (aggvals
->index
== index
4553 && aggvals
->offset
== offset
4554 && values_equal_for_ipcp_p (aggvals
->value
, value
))
4556 aggvals
= aggvals
->next
;
4561 /* Return true if offset is minus one because source of a polymorphic contect
4562 cannot be an aggregate value. */
4565 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value
*,
4566 int , HOST_WIDE_INT offset
,
4567 ipa_polymorphic_call_context
)
4569 return offset
== -1;
4572 /* Decide wheter to create a special version of NODE for value VAL of parameter
4573 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
4574 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
4575 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
4577 template <typename valtype
>
4579 decide_about_value (struct cgraph_node
*node
, int index
, HOST_WIDE_INT offset
,
4580 ipcp_value
<valtype
> *val
, vec
<tree
> known_csts
,
4581 vec
<ipa_polymorphic_call_context
> known_contexts
)
4583 struct ipa_agg_replacement_value
*aggvals
;
4584 int freq_sum
, caller_count
;
4585 profile_count count_sum
;
4586 vec
<cgraph_edge
*> callers
;
4590 perhaps_add_new_callers (node
, val
);
4593 else if (val
->local_size_cost
+ overall_size
> max_new_size
)
4595 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4596 fprintf (dump_file
, " Ignoring candidate value because "
4597 "max_new_size would be reached with %li.\n",
4598 val
->local_size_cost
+ overall_size
);
4601 else if (!get_info_about_necessary_edges (val
, node
, &freq_sum
, &count_sum
,
4605 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4607 fprintf (dump_file
, " - considering value ");
4608 print_ipcp_constant_value (dump_file
, val
->value
);
4609 fprintf (dump_file
, " for ");
4610 ipa_dump_param (dump_file
, IPA_NODE_REF (node
), index
);
4612 fprintf (dump_file
, ", offset: " HOST_WIDE_INT_PRINT_DEC
, offset
);
4613 fprintf (dump_file
, " (caller_count: %i)\n", caller_count
);
4616 if (!good_cloning_opportunity_p (node
, val
->local_time_benefit
,
4617 freq_sum
, count_sum
,
4618 val
->local_size_cost
)
4619 && !good_cloning_opportunity_p (node
,
4620 val
->local_time_benefit
4621 + val
->prop_time_benefit
,
4622 freq_sum
, count_sum
,
4623 val
->local_size_cost
4624 + val
->prop_size_cost
))
4628 fprintf (dump_file
, " Creating a specialized node of %s.\n",
4629 node
->dump_name ());
4631 callers
= gather_edges_for_value (val
, node
, caller_count
);
4633 modify_known_vectors_with_val (&known_csts
, &known_contexts
, val
, index
);
4636 known_csts
= known_csts
.copy ();
4637 known_contexts
= copy_useful_known_contexts (known_contexts
);
4639 find_more_scalar_values_for_callers_subset (node
, known_csts
, callers
);
4640 find_more_contexts_for_caller_subset (node
, &known_contexts
, callers
);
4641 aggvals
= find_aggregate_values_for_callers_subset (node
, callers
);
4642 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals
, index
,
4643 offset
, val
->value
));
4644 val
->spec_node
= create_specialized_node (node
, known_csts
, known_contexts
,
4646 overall_size
+= val
->local_size_cost
;
4648 /* TODO: If for some lattice there is only one other known value
4649 left, make a special node for it too. */
4654 /* Decide whether and what specialized clones of NODE should be created. */
4657 decide_whether_version_node (struct cgraph_node
*node
)
4659 struct ipa_node_params
*info
= IPA_NODE_REF (node
);
4660 int i
, count
= ipa_get_param_count (info
);
4661 vec
<tree
> known_csts
;
4662 vec
<ipa_polymorphic_call_context
> known_contexts
;
4663 vec
<ipa_agg_jump_function
> known_aggs
= vNULL
;
4669 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4670 fprintf (dump_file
, "\nEvaluating opportunities for %s.\n",
4671 node
->dump_name ());
4673 gather_context_independent_values (info
, &known_csts
, &known_contexts
,
4674 info
->do_clone_for_all_contexts
? &known_aggs
4677 for (i
= 0; i
< count
;i
++)
4679 struct ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4680 ipcp_lattice
<tree
> *lat
= &plats
->itself
;
4681 ipcp_lattice
<ipa_polymorphic_call_context
> *ctxlat
= &plats
->ctxlat
;
4686 ipcp_value
<tree
> *val
;
4687 for (val
= lat
->values
; val
; val
= val
->next
)
4688 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4692 if (!plats
->aggs_bottom
)
4694 struct ipcp_agg_lattice
*aglat
;
4695 ipcp_value
<tree
> *val
;
4696 for (aglat
= plats
->aggs
; aglat
; aglat
= aglat
->next
)
4697 if (!aglat
->bottom
&& aglat
->values
4698 /* If the following is false, the one value is in
4700 && (plats
->aggs_contain_variable
4701 || !aglat
->is_single_const ()))
4702 for (val
= aglat
->values
; val
; val
= val
->next
)
4703 ret
|= decide_about_value (node
, i
, aglat
->offset
, val
,
4704 known_csts
, known_contexts
);
4708 && known_contexts
[i
].useless_p ())
4710 ipcp_value
<ipa_polymorphic_call_context
> *val
;
4711 for (val
= ctxlat
->values
; val
; val
= val
->next
)
4712 ret
|= decide_about_value (node
, i
, -1, val
, known_csts
,
4716 info
= IPA_NODE_REF (node
);
4719 if (info
->do_clone_for_all_contexts
)
4721 struct cgraph_node
*clone
;
4722 vec
<cgraph_edge
*> callers
;
4725 fprintf (dump_file
, " - Creating a specialized node of %s "
4726 "for all known contexts.\n", node
->dump_name ());
4728 callers
= node
->collect_callers ();
4730 if (!known_contexts_useful_p (known_contexts
))
4732 known_contexts
.release ();
4733 known_contexts
= vNULL
;
4735 clone
= create_specialized_node (node
, known_csts
, known_contexts
,
4736 known_aggs_to_agg_replacement_list (known_aggs
),
4738 info
= IPA_NODE_REF (node
);
4739 info
->do_clone_for_all_contexts
= false;
4740 IPA_NODE_REF (clone
)->is_all_contexts_clone
= true;
4741 for (i
= 0; i
< count
; i
++)
4742 vec_free (known_aggs
[i
].items
);
4743 known_aggs
.release ();
4748 known_csts
.release ();
4749 known_contexts
.release ();
4755 /* Transitively mark all callees of NODE within the same SCC as not dead. */
4758 spread_undeadness (struct cgraph_node
*node
)
4760 struct cgraph_edge
*cs
;
4762 for (cs
= node
->callees
; cs
; cs
= cs
->next_callee
)
4763 if (ipa_edge_within_scc (cs
))
4765 struct cgraph_node
*callee
;
4766 struct ipa_node_params
*info
;
4768 callee
= cs
->callee
->function_symbol (NULL
);
4769 info
= IPA_NODE_REF (callee
);
4771 if (info
->node_dead
)
4773 info
->node_dead
= 0;
4774 spread_undeadness (callee
);
4779 /* Return true if NODE has a caller from outside of its SCC that is not
4780 dead. Worker callback for cgraph_for_node_and_aliases. */
4783 has_undead_caller_from_outside_scc_p (struct cgraph_node
*node
,
4784 void *data ATTRIBUTE_UNUSED
)
4786 struct cgraph_edge
*cs
;
4788 for (cs
= node
->callers
; cs
; cs
= cs
->next_caller
)
4789 if (cs
->caller
->thunk
.thunk_p
4790 && cs
->caller
->call_for_symbol_thunks_and_aliases
4791 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4793 else if (!ipa_edge_within_scc (cs
)
4794 && !IPA_NODE_REF (cs
->caller
)->node_dead
)
4800 /* Identify nodes within the same SCC as NODE which are no longer needed
4801 because of new clones and will be removed as unreachable. */
4804 identify_dead_nodes (struct cgraph_node
*node
)
4806 struct cgraph_node
*v
;
4807 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4809 && !v
->call_for_symbol_thunks_and_aliases
4810 (has_undead_caller_from_outside_scc_p
, NULL
, true))
4811 IPA_NODE_REF (v
)->node_dead
= 1;
4813 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4814 if (!IPA_NODE_REF (v
)->node_dead
)
4815 spread_undeadness (v
);
4817 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
4819 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4820 if (IPA_NODE_REF (v
)->node_dead
)
4821 fprintf (dump_file
, " Marking node as dead: %s.\n", v
->dump_name ());
4825 /* The decision stage. Iterate over the topological order of call graph nodes
4826 TOPO and make specialized clones if deemed beneficial. */
4829 ipcp_decision_stage (struct ipa_topo_info
*topo
)
4834 fprintf (dump_file
, "\nIPA decision stage:\n\n");
4836 for (i
= topo
->nnodes
- 1; i
>= 0; i
--)
4838 struct cgraph_node
*node
= topo
->order
[i
];
4839 bool change
= false, iterate
= true;
4843 struct cgraph_node
*v
;
4845 for (v
= node
; v
; v
= ((struct ipa_dfs_info
*) v
->aux
)->next_cycle
)
4846 if (v
->has_gimple_body_p ()
4847 && ipcp_versionable_function_p (v
))
4848 iterate
|= decide_whether_version_node (v
);
4853 identify_dead_nodes (node
);
4857 /* Look up all the bits information that we have discovered and copy it over
4858 to the transformation summary. */
4861 ipcp_store_bits_results (void)
4865 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4867 ipa_node_params
*info
= IPA_NODE_REF (node
);
4868 bool dumped_sth
= false;
4869 bool found_useful_result
= false;
4871 if (!opt_for_fn (node
->decl
, flag_ipa_bit_cp
))
4874 fprintf (dump_file
, "Not considering %s for ipa bitwise propagation "
4875 "; -fipa-bit-cp: disabled.\n",
4880 if (info
->ipcp_orig_node
)
4881 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
4883 unsigned count
= ipa_get_param_count (info
);
4884 for (unsigned i
= 0; i
< count
; i
++)
4886 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4887 if (plats
->bits_lattice
.constant_p ())
4889 found_useful_result
= true;
4894 if (!found_useful_result
)
4897 ipcp_grow_transformations_if_necessary ();
4898 ipcp_transformation_summary
*ts
= ipcp_get_transformation_summary (node
);
4899 vec_safe_reserve_exact (ts
->bits
, count
);
4901 for (unsigned i
= 0; i
< count
; i
++)
4903 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4906 if (plats
->bits_lattice
.constant_p ())
4908 = ipa_get_ipa_bits_for_value (plats
->bits_lattice
.get_value (),
4909 plats
->bits_lattice
.get_mask ());
4913 ts
->bits
->quick_push (jfbits
);
4914 if (!dump_file
|| !jfbits
)
4918 fprintf (dump_file
, "Propagated bits info for function %s:\n",
4919 node
->dump_name ());
4922 fprintf (dump_file
, " param %i: value = ", i
);
4923 print_hex (jfbits
->value
, dump_file
);
4924 fprintf (dump_file
, ", mask = ");
4925 print_hex (jfbits
->mask
, dump_file
);
4926 fprintf (dump_file
, "\n");
4931 /* Look up all VR information that we have discovered and copy it over
4932 to the transformation summary. */
4935 ipcp_store_vr_results (void)
4939 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
4941 ipa_node_params
*info
= IPA_NODE_REF (node
);
4942 bool found_useful_result
= false;
4944 if (!opt_for_fn (node
->decl
, flag_ipa_vrp
))
4947 fprintf (dump_file
, "Not considering %s for VR discovery "
4948 "and propagate; -fipa-ipa-vrp: disabled.\n",
4953 if (info
->ipcp_orig_node
)
4954 info
= IPA_NODE_REF (info
->ipcp_orig_node
);
4956 unsigned count
= ipa_get_param_count (info
);
4957 for (unsigned i
= 0; i
< count
; i
++)
4959 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4960 if (!plats
->m_value_range
.bottom_p ()
4961 && !plats
->m_value_range
.top_p ())
4963 found_useful_result
= true;
4967 if (!found_useful_result
)
4970 ipcp_grow_transformations_if_necessary ();
4971 ipcp_transformation_summary
*ts
= ipcp_get_transformation_summary (node
);
4972 vec_safe_reserve_exact (ts
->m_vr
, count
);
4974 for (unsigned i
= 0; i
< count
; i
++)
4976 ipcp_param_lattices
*plats
= ipa_get_parm_lattices (info
, i
);
4979 if (!plats
->m_value_range
.bottom_p ()
4980 && !plats
->m_value_range
.top_p ())
4983 vr
.type
= plats
->m_value_range
.m_vr
.type
;
4984 vr
.min
= wi::to_wide (plats
->m_value_range
.m_vr
.min
);
4985 vr
.max
= wi::to_wide (plats
->m_value_range
.m_vr
.max
);
4990 vr
.type
= VR_VARYING
;
4991 vr
.min
= vr
.max
= wi::zero (INT_TYPE_SIZE
);
4993 ts
->m_vr
->quick_push (vr
);
4998 /* The IPCP driver. */
5003 struct cgraph_2edge_hook_list
*edge_duplication_hook_holder
;
5004 struct cgraph_edge_hook_list
*edge_removal_hook_holder
;
5005 struct ipa_topo_info topo
;
5007 ipa_check_create_node_params ();
5008 ipa_check_create_edge_args ();
5009 grow_edge_clone_vectors ();
5010 edge_duplication_hook_holder
5011 = symtab
->add_edge_duplication_hook (&ipcp_edge_duplication_hook
, NULL
);
5012 edge_removal_hook_holder
5013 = symtab
->add_edge_removal_hook (&ipcp_edge_removal_hook
, NULL
);
5017 fprintf (dump_file
, "\nIPA structures before propagation:\n");
5018 if (dump_flags
& TDF_DETAILS
)
5019 ipa_print_all_params (dump_file
);
5020 ipa_print_all_jump_functions (dump_file
);
5023 /* Topological sort. */
5024 build_toporder_info (&topo
);
5025 /* Do the interprocedural propagation. */
5026 ipcp_propagate_stage (&topo
);
5027 /* Decide what constant propagation and cloning should be performed. */
5028 ipcp_decision_stage (&topo
);
5029 /* Store results of bits propagation. */
5030 ipcp_store_bits_results ();
5031 /* Store results of value range propagation. */
5032 ipcp_store_vr_results ();
5034 /* Free all IPCP structures. */
5035 free_toporder_info (&topo
);
5036 next_edge_clone
.release ();
5037 prev_edge_clone
.release ();
5038 symtab
->remove_edge_removal_hook (edge_removal_hook_holder
);
5039 symtab
->remove_edge_duplication_hook (edge_duplication_hook_holder
);
5040 ipa_free_all_structures_after_ipa_cp ();
5042 fprintf (dump_file
, "\nIPA constant propagation end\n");
5046 /* Initialization and computation of IPCP data structures. This is the initial
5047 intraprocedural analysis of functions, which gathers information to be
5048 propagated later on. */
5051 ipcp_generate_summary (void)
5053 struct cgraph_node
*node
;
5056 fprintf (dump_file
, "\nIPA constant propagation start:\n");
5057 ipa_register_cgraph_hooks ();
5059 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node
)
5060 ipa_analyze_node (node
);
5063 /* Write ipcp summary for nodes in SET. */
5066 ipcp_write_summary (void)
5068 ipa_prop_write_jump_functions ();
5071 /* Read ipcp summary. */
5074 ipcp_read_summary (void)
5076 ipa_prop_read_jump_functions ();
5081 const pass_data pass_data_ipa_cp
=
5083 IPA_PASS
, /* type */
5085 OPTGROUP_NONE
, /* optinfo_flags */
5086 TV_IPA_CONSTANT_PROP
, /* tv_id */
5087 0, /* properties_required */
5088 0, /* properties_provided */
5089 0, /* properties_destroyed */
5090 0, /* todo_flags_start */
5091 ( TODO_dump_symtab
| TODO_remove_functions
), /* todo_flags_finish */
5094 class pass_ipa_cp
: public ipa_opt_pass_d
5097 pass_ipa_cp (gcc::context
*ctxt
)
5098 : ipa_opt_pass_d (pass_data_ipa_cp
, ctxt
,
5099 ipcp_generate_summary
, /* generate_summary */
5100 ipcp_write_summary
, /* write_summary */
5101 ipcp_read_summary
, /* read_summary */
5102 ipcp_write_transformation_summaries
, /*
5103 write_optimization_summary */
5104 ipcp_read_transformation_summaries
, /*
5105 read_optimization_summary */
5106 NULL
, /* stmt_fixup */
5107 0, /* function_transform_todo_flags_start */
5108 ipcp_transform_function
, /* function_transform */
5109 NULL
) /* variable_transform */
5112 /* opt_pass methods: */
5113 virtual bool gate (function
*)
5115 /* FIXME: We should remove the optimize check after we ensure we never run
5116 IPA passes when not optimizing. */
5117 return (flag_ipa_cp
&& optimize
) || in_lto_p
;
5120 virtual unsigned int execute (function
*) { return ipcp_driver (); }
5122 }; // class pass_ipa_cp
5127 make_pass_ipa_cp (gcc::context
*ctxt
)
5129 return new pass_ipa_cp (ctxt
);
5132 /* Reset all state within ipa-cp.c so that we can rerun the compiler
5133 within the same process. For use by toplev::finalize. */
5136 ipa_cp_c_finalize (void)
5138 max_count
= profile_count::uninitialized ();