typeck.c (cp_truthvalue_conversion): Add tsubst_flags_t parameter and use it in calls...
[official-gcc.git] / gcc / ipa-cp.c
blob8372dfaa7715f291e29848f621a3b84de53d2131
1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2019 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
5 <mjambor@suse.cz>
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
12 version.
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
17 for more details.
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
34 is deemed good.
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
46 calls are redirected.
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
61 values:
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
94 third stage.
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
101 the second stage. */
103 #include "config.h"
104 #include "system.h"
105 #include "coretypes.h"
106 #include "backend.h"
107 #include "tree.h"
108 #include "gimple-expr.h"
109 #include "predict.h"
110 #include "alloc-pool.h"
111 #include "tree-pass.h"
112 #include "cgraph.h"
113 #include "diagnostic.h"
114 #include "fold-const.h"
115 #include "gimple-fold.h"
116 #include "symbol-summary.h"
117 #include "tree-vrp.h"
118 #include "ipa-prop.h"
119 #include "tree-pretty-print.h"
120 #include "tree-inline.h"
121 #include "ipa-fnsummary.h"
122 #include "ipa-utils.h"
123 #include "tree-ssa-ccp.h"
124 #include "stringpool.h"
125 #include "attribs.h"
127 template <typename valtype> class ipcp_value;
129 /* Describes a particular source for an IPA-CP value. */
131 template <typename valtype>
132 struct ipcp_value_source
134 public:
135 /* Aggregate offset of the source, negative if the source is scalar value of
136 the argument itself. */
137 HOST_WIDE_INT offset;
138 /* The incoming edge that brought the value. */
139 cgraph_edge *cs;
140 /* If the jump function that resulted into his value was a pass-through or an
141 ancestor, this is the ipcp_value of the caller from which the described
142 value has been derived. Otherwise it is NULL. */
143 ipcp_value<valtype> *val;
144 /* Next pointer in a linked list of sources of a value. */
145 ipcp_value_source *next;
146 /* If the jump function that resulted into his value was a pass-through or an
147 ancestor, this is the index of the parameter of the caller the jump
148 function references. */
149 int index;
152 /* Common ancestor for all ipcp_value instantiations. */
154 class ipcp_value_base
156 public:
157 /* Time benefit and size cost that specializing the function for this value
158 would bring about in this function alone. */
159 int local_time_benefit, local_size_cost;
160 /* Time benefit and size cost that specializing the function for this value
161 can bring about in it's callees (transitively). */
162 int prop_time_benefit, prop_size_cost;
164 ipcp_value_base ()
165 : local_time_benefit (0), local_size_cost (0),
166 prop_time_benefit (0), prop_size_cost (0) {}
169 /* Describes one particular value stored in struct ipcp_lattice. */
171 template <typename valtype>
172 class ipcp_value : public ipcp_value_base
174 public:
175 /* The actual value for the given parameter. */
176 valtype value;
177 /* The list of sources from which this value originates. */
178 ipcp_value_source <valtype> *sources;
179 /* Next pointers in a linked list of all values in a lattice. */
180 ipcp_value *next;
181 /* Next pointers in a linked list of values in a strongly connected component
182 of values. */
183 ipcp_value *scc_next;
184 /* Next pointers in a linked list of SCCs of values sorted topologically
185 according their sources. */
186 ipcp_value *topo_next;
187 /* A specialized node created for this value, NULL if none has been (so far)
188 created. */
189 cgraph_node *spec_node;
190 /* Depth first search number and low link for topological sorting of
191 values. */
192 int dfs, low_link;
193 /* True if this value is currently on the topo-sort stack. */
194 bool on_stack;
196 ipcp_value()
197 : sources (0), next (0), scc_next (0), topo_next (0),
198 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
200 void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
201 HOST_WIDE_INT offset);
204 /* Lattice describing potential values of a formal parameter of a function, or
205 a part of an aggregate. TOP is represented by a lattice with zero values
206 and with contains_variable and bottom flags cleared. BOTTOM is represented
207 by a lattice with the bottom flag set. In that case, values and
208 contains_variable flag should be disregarded. */
210 template <typename valtype>
211 struct ipcp_lattice
213 public:
214 /* The list of known values and types in this lattice. Note that values are
215 not deallocated if a lattice is set to bottom because there may be value
216 sources referencing them. */
217 ipcp_value<valtype> *values;
218 /* Number of known values and types in this lattice. */
219 int values_count;
220 /* The lattice contains a variable component (in addition to values). */
221 bool contains_variable;
222 /* The value of the lattice is bottom (i.e. variable and unusable for any
223 propagation). */
224 bool bottom;
226 inline bool is_single_const ();
227 inline bool set_to_bottom ();
228 inline bool set_contains_variable ();
229 bool add_value (valtype newval, cgraph_edge *cs,
230 ipcp_value<valtype> *src_val = NULL,
231 int src_idx = 0, HOST_WIDE_INT offset = -1);
232 void print (FILE * f, bool dump_sources, bool dump_benefits);
235 /* Lattice of tree values with an offset to describe a part of an
236 aggregate. */
238 struct ipcp_agg_lattice : public ipcp_lattice<tree>
240 public:
241 /* Offset that is being described by this lattice. */
242 HOST_WIDE_INT offset;
243 /* Size so that we don't have to re-compute it every time we traverse the
244 list. Must correspond to TYPE_SIZE of all lat values. */
245 HOST_WIDE_INT size;
246 /* Next element of the linked list. */
247 struct ipcp_agg_lattice *next;
250 /* Lattice of known bits, only capable of holding one value.
251 Bitwise constant propagation propagates which bits of a
252 value are constant.
253 For eg:
254 int f(int x)
256 return some_op (x);
259 int f1(int y)
261 if (cond)
262 return f (y & 0xff);
263 else
264 return f (y & 0xf);
267 In the above case, the param 'x' will always have all
268 the bits (except the bits in lsb) set to 0.
269 Hence the mask of 'x' would be 0xff. The mask
270 reflects that the bits in lsb are unknown.
271 The actual propagated value is given by m_value & ~m_mask. */
273 class ipcp_bits_lattice
275 public:
276 bool bottom_p () { return m_lattice_val == IPA_BITS_VARYING; }
277 bool top_p () { return m_lattice_val == IPA_BITS_UNDEFINED; }
278 bool constant_p () { return m_lattice_val == IPA_BITS_CONSTANT; }
279 bool set_to_bottom ();
280 bool set_to_constant (widest_int, widest_int);
282 widest_int get_value () { return m_value; }
283 widest_int get_mask () { return m_mask; }
285 bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
286 enum tree_code, tree);
288 bool meet_with (widest_int, widest_int, unsigned);
290 void print (FILE *);
292 private:
293 enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
295 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
296 If a bit in mask is set to 0, then the corresponding bit in
297 value is known to be constant. */
298 widest_int m_value, m_mask;
300 bool meet_with_1 (widest_int, widest_int, unsigned);
301 void get_value_and_mask (tree, widest_int *, widest_int *);
304 /* Lattice of value ranges. */
306 class ipcp_vr_lattice
308 public:
309 value_range m_vr;
311 inline bool bottom_p () const;
312 inline bool top_p () const;
313 inline bool set_to_bottom ();
314 bool meet_with (const value_range *p_vr);
315 bool meet_with (const ipcp_vr_lattice &other);
316 void init () { gcc_assert (m_vr.undefined_p ()); }
317 void print (FILE * f);
319 private:
320 bool meet_with_1 (const value_range *other_vr);
323 /* Structure containing lattices for a parameter itself and for pieces of
324 aggregates that are passed in the parameter or by a reference in a parameter
325 plus some other useful flags. */
327 class ipcp_param_lattices
329 public:
330 /* Lattice describing the value of the parameter itself. */
331 ipcp_lattice<tree> itself;
332 /* Lattice describing the polymorphic contexts of a parameter. */
333 ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
334 /* Lattices describing aggregate parts. */
335 ipcp_agg_lattice *aggs;
336 /* Lattice describing known bits. */
337 ipcp_bits_lattice bits_lattice;
338 /* Lattice describing value range. */
339 ipcp_vr_lattice m_value_range;
340 /* Number of aggregate lattices */
341 int aggs_count;
342 /* True if aggregate data were passed by reference (as opposed to by
343 value). */
344 bool aggs_by_ref;
345 /* All aggregate lattices contain a variable component (in addition to
346 values). */
347 bool aggs_contain_variable;
348 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
349 for any propagation). */
350 bool aggs_bottom;
352 /* There is a virtual call based on this parameter. */
353 bool virt_call;
356 /* Allocation pools for values and their sources in ipa-cp. */
358 object_allocator<ipcp_value<tree> > ipcp_cst_values_pool
359 ("IPA-CP constant values");
361 object_allocator<ipcp_value<ipa_polymorphic_call_context> >
362 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
364 object_allocator<ipcp_value_source<tree> > ipcp_sources_pool
365 ("IPA-CP value sources");
367 object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
368 ("IPA_CP aggregate lattices");
370 /* Maximal count found in program. */
372 static profile_count max_count;
374 /* Original overall size of the program. */
376 static long overall_size, max_new_size;
378 /* Node name to unique clone suffix number map. */
379 static hash_map<const char *, unsigned> *clone_num_suffixes;
381 /* Return the param lattices structure corresponding to the Ith formal
382 parameter of the function described by INFO. */
383 static inline class ipcp_param_lattices *
384 ipa_get_parm_lattices (class ipa_node_params *info, int i)
386 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
387 gcc_checking_assert (!info->ipcp_orig_node);
388 gcc_checking_assert (info->lattices);
389 return &(info->lattices[i]);
392 /* Return the lattice corresponding to the scalar value of the Ith formal
393 parameter of the function described by INFO. */
394 static inline ipcp_lattice<tree> *
395 ipa_get_scalar_lat (class ipa_node_params *info, int i)
397 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
398 return &plats->itself;
401 /* Return the lattice corresponding to the scalar value of the Ith formal
402 parameter of the function described by INFO. */
403 static inline ipcp_lattice<ipa_polymorphic_call_context> *
404 ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
406 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
407 return &plats->ctxlat;
410 /* Return whether LAT is a lattice with a single constant and without an
411 undefined value. */
413 template <typename valtype>
414 inline bool
415 ipcp_lattice<valtype>::is_single_const ()
417 if (bottom || contains_variable || values_count != 1)
418 return false;
419 else
420 return true;
423 /* Print V which is extracted from a value in a lattice to F. */
425 static void
426 print_ipcp_constant_value (FILE * f, tree v)
428 if (TREE_CODE (v) == ADDR_EXPR
429 && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
431 fprintf (f, "& ");
432 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)));
434 else
435 print_generic_expr (f, v);
438 /* Print V which is extracted from a value in a lattice to F. */
440 static void
441 print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
443 v.dump(f, false);
446 /* Print a lattice LAT to F. */
448 template <typename valtype>
449 void
450 ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
452 ipcp_value<valtype> *val;
453 bool prev = false;
455 if (bottom)
457 fprintf (f, "BOTTOM\n");
458 return;
461 if (!values_count && !contains_variable)
463 fprintf (f, "TOP\n");
464 return;
467 if (contains_variable)
469 fprintf (f, "VARIABLE");
470 prev = true;
471 if (dump_benefits)
472 fprintf (f, "\n");
475 for (val = values; val; val = val->next)
477 if (dump_benefits && prev)
478 fprintf (f, " ");
479 else if (!dump_benefits && prev)
480 fprintf (f, ", ");
481 else
482 prev = true;
484 print_ipcp_constant_value (f, val->value);
486 if (dump_sources)
488 ipcp_value_source<valtype> *s;
490 fprintf (f, " [from:");
491 for (s = val->sources; s; s = s->next)
492 fprintf (f, " %i(%f)", s->cs->caller->order,
493 s->cs->sreal_frequency ().to_double ());
494 fprintf (f, "]");
497 if (dump_benefits)
498 fprintf (f, " [loc_time: %i, loc_size: %i, "
499 "prop_time: %i, prop_size: %i]\n",
500 val->local_time_benefit, val->local_size_cost,
501 val->prop_time_benefit, val->prop_size_cost);
503 if (!dump_benefits)
504 fprintf (f, "\n");
507 void
508 ipcp_bits_lattice::print (FILE *f)
510 if (top_p ())
511 fprintf (f, " Bits unknown (TOP)\n");
512 else if (bottom_p ())
513 fprintf (f, " Bits unusable (BOTTOM)\n");
514 else
516 fprintf (f, " Bits: value = "); print_hex (get_value (), f);
517 fprintf (f, ", mask = "); print_hex (get_mask (), f);
518 fprintf (f, "\n");
522 /* Print value range lattice to F. */
524 void
525 ipcp_vr_lattice::print (FILE * f)
527 dump_value_range (f, &m_vr);
530 /* Print all ipcp_lattices of all functions to F. */
532 static void
533 print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
535 struct cgraph_node *node;
536 int i, count;
538 fprintf (f, "\nLattices:\n");
539 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
541 class ipa_node_params *info;
543 info = IPA_NODE_REF (node);
544 /* Skip constprop clones since we don't make lattices for them. */
545 if (info->ipcp_orig_node)
546 continue;
547 fprintf (f, " Node: %s:\n", node->dump_name ());
548 count = ipa_get_param_count (info);
549 for (i = 0; i < count; i++)
551 struct ipcp_agg_lattice *aglat;
552 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
553 fprintf (f, " param [%d]: ", i);
554 plats->itself.print (f, dump_sources, dump_benefits);
555 fprintf (f, " ctxs: ");
556 plats->ctxlat.print (f, dump_sources, dump_benefits);
557 plats->bits_lattice.print (f);
558 fprintf (f, " ");
559 plats->m_value_range.print (f);
560 fprintf (f, "\n");
561 if (plats->virt_call)
562 fprintf (f, " virt_call flag set\n");
564 if (plats->aggs_bottom)
566 fprintf (f, " AGGS BOTTOM\n");
567 continue;
569 if (plats->aggs_contain_variable)
570 fprintf (f, " AGGS VARIABLE\n");
571 for (aglat = plats->aggs; aglat; aglat = aglat->next)
573 fprintf (f, " %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
574 plats->aggs_by_ref ? "ref " : "", aglat->offset);
575 aglat->print (f, dump_sources, dump_benefits);
581 /* Determine whether it is at all technically possible to create clones of NODE
582 and store this information in the ipa_node_params structure associated
583 with NODE. */
585 static void
586 determine_versionability (struct cgraph_node *node,
587 class ipa_node_params *info)
589 const char *reason = NULL;
591 /* There are a number of generic reasons functions cannot be versioned. We
592 also cannot remove parameters if there are type attributes such as fnspec
593 present. */
594 if (node->alias || node->thunk.thunk_p)
595 reason = "alias or thunk";
596 else if (!node->versionable)
597 reason = "not a tree_versionable_function";
598 else if (node->get_availability () <= AVAIL_INTERPOSABLE)
599 reason = "insufficient body availability";
600 else if (!opt_for_fn (node->decl, optimize)
601 || !opt_for_fn (node->decl, flag_ipa_cp))
602 reason = "non-optimized function";
603 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
605 /* Ideally we should clone the SIMD clones themselves and create
606 vector copies of them, so IPA-cp and SIMD clones can happily
607 coexist, but that may not be worth the effort. */
608 reason = "function has SIMD clones";
610 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)))
612 /* Ideally we should clone the target clones themselves and create
613 copies of them, so IPA-cp and target clones can happily
614 coexist, but that may not be worth the effort. */
615 reason = "function target_clones attribute";
617 /* Don't clone decls local to a comdat group; it breaks and for C++
618 decloned constructors, inlining is always better anyway. */
619 else if (node->comdat_local_p ())
620 reason = "comdat-local function";
621 else if (node->calls_comdat_local)
623 /* TODO: call is versionable if we make sure that all
624 callers are inside of a comdat group. */
625 reason = "calls comdat-local function";
628 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
629 work only when inlined. Cloning them may still lead to better code
630 because ipa-cp will not give up on cloning further. If the function is
631 external this however leads to wrong code because we may end up producing
632 offline copy of the function. */
633 if (DECL_EXTERNAL (node->decl))
634 for (cgraph_edge *edge = node->callees; !reason && edge;
635 edge = edge->next_callee)
636 if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
638 if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
639 reason = "external function which calls va_arg_pack";
640 if (DECL_FUNCTION_CODE (edge->callee->decl)
641 == BUILT_IN_VA_ARG_PACK_LEN)
642 reason = "external function which calls va_arg_pack_len";
645 if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
646 fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
647 node->dump_name (), reason);
649 info->versionable = (reason == NULL);
652 /* Return true if it is at all technically possible to create clones of a
653 NODE. */
655 static bool
656 ipcp_versionable_function_p (struct cgraph_node *node)
658 return IPA_NODE_REF (node) && IPA_NODE_REF (node)->versionable;
661 /* Structure holding accumulated information about callers of a node. */
663 struct caller_statistics
665 profile_count count_sum;
666 int n_calls, n_hot_calls, freq_sum;
669 /* Initialize fields of STAT to zeroes. */
671 static inline void
672 init_caller_stats (struct caller_statistics *stats)
674 stats->count_sum = profile_count::zero ();
675 stats->n_calls = 0;
676 stats->n_hot_calls = 0;
677 stats->freq_sum = 0;
680 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
681 non-thunk incoming edges to NODE. */
683 static bool
684 gather_caller_stats (struct cgraph_node *node, void *data)
686 struct caller_statistics *stats = (struct caller_statistics *) data;
687 struct cgraph_edge *cs;
689 for (cs = node->callers; cs; cs = cs->next_caller)
690 if (!cs->caller->thunk.thunk_p)
692 if (cs->count.ipa ().initialized_p ())
693 stats->count_sum += cs->count.ipa ();
694 stats->freq_sum += cs->frequency ();
695 stats->n_calls++;
696 if (cs->maybe_hot_p ())
697 stats->n_hot_calls ++;
699 return false;
703 /* Return true if this NODE is viable candidate for cloning. */
705 static bool
706 ipcp_cloning_candidate_p (struct cgraph_node *node)
708 struct caller_statistics stats;
710 gcc_checking_assert (node->has_gimple_body_p ());
712 if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
714 if (dump_file)
715 fprintf (dump_file, "Not considering %s for cloning; "
716 "-fipa-cp-clone disabled.\n",
717 node->name ());
718 return false;
721 if (node->optimize_for_size_p ())
723 if (dump_file)
724 fprintf (dump_file, "Not considering %s for cloning; "
725 "optimizing it for size.\n",
726 node->name ());
727 return false;
730 init_caller_stats (&stats);
731 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
733 if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
735 if (dump_file)
736 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
737 node->name ());
738 return true;
741 /* When profile is available and function is hot, propagate into it even if
742 calls seems cold; constant propagation can improve function's speed
743 significantly. */
744 if (max_count > profile_count::zero ())
746 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
748 if (dump_file)
749 fprintf (dump_file, "Considering %s for cloning; "
750 "usually called directly.\n",
751 node->name ());
752 return true;
755 if (!stats.n_hot_calls)
757 if (dump_file)
758 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
759 node->name ());
760 return false;
762 if (dump_file)
763 fprintf (dump_file, "Considering %s for cloning.\n",
764 node->name ());
765 return true;
768 template <typename valtype>
769 class value_topo_info
771 public:
772 /* Head of the linked list of topologically sorted values. */
773 ipcp_value<valtype> *values_topo;
774 /* Stack for creating SCCs, represented by a linked list too. */
775 ipcp_value<valtype> *stack;
776 /* Counter driving the algorithm in add_val_to_toposort. */
777 int dfs_counter;
779 value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
781 void add_val (ipcp_value<valtype> *cur_val);
782 void propagate_effects ();
785 /* Arrays representing a topological ordering of call graph nodes and a stack
786 of nodes used during constant propagation and also data required to perform
787 topological sort of values and propagation of benefits in the determined
788 order. */
790 class ipa_topo_info
792 public:
793 /* Array with obtained topological order of cgraph nodes. */
794 struct cgraph_node **order;
795 /* Stack of cgraph nodes used during propagation within SCC until all values
796 in the SCC stabilize. */
797 struct cgraph_node **stack;
798 int nnodes, stack_top;
800 value_topo_info<tree> constants;
801 value_topo_info<ipa_polymorphic_call_context> contexts;
803 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
804 constants ()
808 /* Skip edges from and to nodes without ipa_cp enabled.
809 Ignore not available symbols. */
811 static bool
812 ignore_edge_p (cgraph_edge *e)
814 enum availability avail;
815 cgraph_node *ultimate_target
816 = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
818 return (avail <= AVAIL_INTERPOSABLE
819 || !opt_for_fn (ultimate_target->decl, optimize)
820 || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
823 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
825 static void
826 build_toporder_info (class ipa_topo_info *topo)
828 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
829 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
831 gcc_checking_assert (topo->stack_top == 0);
832 topo->nnodes = ipa_reduced_postorder (topo->order, true,
833 ignore_edge_p);
836 /* Free information about strongly connected components and the arrays in
837 TOPO. */
839 static void
840 free_toporder_info (class ipa_topo_info *topo)
842 ipa_free_postorder_info ();
843 free (topo->order);
844 free (topo->stack);
847 /* Add NODE to the stack in TOPO, unless it is already there. */
849 static inline void
850 push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
852 class ipa_node_params *info = IPA_NODE_REF (node);
853 if (info->node_enqueued)
854 return;
855 info->node_enqueued = 1;
856 topo->stack[topo->stack_top++] = node;
859 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
860 is empty. */
862 static struct cgraph_node *
863 pop_node_from_stack (class ipa_topo_info *topo)
865 if (topo->stack_top)
867 struct cgraph_node *node;
868 topo->stack_top--;
869 node = topo->stack[topo->stack_top];
870 IPA_NODE_REF (node)->node_enqueued = 0;
871 return node;
873 else
874 return NULL;
877 /* Set lattice LAT to bottom and return true if it previously was not set as
878 such. */
880 template <typename valtype>
881 inline bool
882 ipcp_lattice<valtype>::set_to_bottom ()
884 bool ret = !bottom;
885 bottom = true;
886 return ret;
889 /* Mark lattice as containing an unknown value and return true if it previously
890 was not marked as such. */
892 template <typename valtype>
893 inline bool
894 ipcp_lattice<valtype>::set_contains_variable ()
896 bool ret = !contains_variable;
897 contains_variable = true;
898 return ret;
901 /* Set all aggregate lattices in PLATS to bottom and return true if they were
902 not previously set as such. */
904 static inline bool
905 set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
907 bool ret = !plats->aggs_bottom;
908 plats->aggs_bottom = true;
909 return ret;
912 /* Mark all aggregate lattices in PLATS as containing an unknown value and
913 return true if they were not previously marked as such. */
915 static inline bool
916 set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
918 bool ret = !plats->aggs_contain_variable;
919 plats->aggs_contain_variable = true;
920 return ret;
923 bool
924 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
926 return meet_with_1 (&other.m_vr);
929 /* Meet the current value of the lattice with value range described by VR
930 lattice. */
932 bool
933 ipcp_vr_lattice::meet_with (const value_range *p_vr)
935 return meet_with_1 (p_vr);
938 /* Meet the current value of the lattice with value range described by
939 OTHER_VR lattice. Return TRUE if anything changed. */
941 bool
942 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
944 if (bottom_p ())
945 return false;
947 if (other_vr->varying_p ())
948 return set_to_bottom ();
950 value_range save (m_vr);
951 m_vr.union_ (other_vr);
952 return !m_vr.equal_p (save);
955 /* Return true if value range information in the lattice is yet unknown. */
957 bool
958 ipcp_vr_lattice::top_p () const
960 return m_vr.undefined_p ();
963 /* Return true if value range information in the lattice is known to be
964 unusable. */
966 bool
967 ipcp_vr_lattice::bottom_p () const
969 return m_vr.varying_p ();
972 /* Set value range information in the lattice to bottom. Return true if it
973 previously was in a different state. */
975 bool
976 ipcp_vr_lattice::set_to_bottom ()
978 if (m_vr.varying_p ())
979 return false;
980 /* ?? We create all sorts of VARYING ranges for floats, structures,
981 and other types which we cannot handle as ranges. We should
982 probably avoid handling them throughout the pass, but it's easier
983 to create a sensible VARYING here and let the lattice
984 propagate. */
985 m_vr.set_varying (integer_type_node);
986 return true;
989 /* Set lattice value to bottom, if it already isn't the case. */
991 bool
992 ipcp_bits_lattice::set_to_bottom ()
994 if (bottom_p ())
995 return false;
996 m_lattice_val = IPA_BITS_VARYING;
997 m_value = 0;
998 m_mask = -1;
999 return true;
1002 /* Set to constant if it isn't already. Only meant to be called
1003 when switching state from TOP. */
1005 bool
1006 ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask)
1008 gcc_assert (top_p ());
1009 m_lattice_val = IPA_BITS_CONSTANT;
1010 m_value = value;
1011 m_mask = mask;
1012 return true;
1015 /* Convert operand to value, mask form. */
1017 void
1018 ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_int *maskp)
1020 wide_int get_nonzero_bits (const_tree);
1022 if (TREE_CODE (operand) == INTEGER_CST)
1024 *valuep = wi::to_widest (operand);
1025 *maskp = 0;
1027 else
1029 *valuep = 0;
1030 *maskp = -1;
1034 /* Meet operation, similar to ccp_lattice_meet, we xor values
1035 if this->value, value have different values at same bit positions, we want
1036 to drop that bit to varying. Return true if mask is changed.
1037 This function assumes that the lattice value is in CONSTANT state */
1039 bool
1040 ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask,
1041 unsigned precision)
1043 gcc_assert (constant_p ());
1045 widest_int old_mask = m_mask;
1046 m_mask = (m_mask | mask) | (m_value ^ value);
1048 if (wi::sext (m_mask, precision) == -1)
1049 return set_to_bottom ();
1051 return m_mask != old_mask;
1054 /* Meet the bits lattice with operand
1055 described by <value, mask, sgn, precision. */
1057 bool
1058 ipcp_bits_lattice::meet_with (widest_int value, widest_int mask,
1059 unsigned precision)
1061 if (bottom_p ())
1062 return false;
1064 if (top_p ())
1066 if (wi::sext (mask, precision) == -1)
1067 return set_to_bottom ();
1068 return set_to_constant (value, mask);
1071 return meet_with_1 (value, mask, precision);
1074 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1075 if code is binary operation or bit_value_unop (other) if code is unary op.
1076 In the case when code is nop_expr, no adjustment is required. */
1078 bool
1079 ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
1080 signop sgn, enum tree_code code, tree operand)
1082 if (other.bottom_p ())
1083 return set_to_bottom ();
1085 if (bottom_p () || other.top_p ())
1086 return false;
1088 widest_int adjusted_value, adjusted_mask;
1090 if (TREE_CODE_CLASS (code) == tcc_binary)
1092 tree type = TREE_TYPE (operand);
1093 widest_int o_value, o_mask;
1094 get_value_and_mask (operand, &o_value, &o_mask);
1096 bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask,
1097 sgn, precision, other.get_value (), other.get_mask (),
1098 TYPE_SIGN (type), TYPE_PRECISION (type), o_value, o_mask);
1100 if (wi::sext (adjusted_mask, precision) == -1)
1101 return set_to_bottom ();
1104 else if (TREE_CODE_CLASS (code) == tcc_unary)
1106 bit_value_unop (code, sgn, precision, &adjusted_value,
1107 &adjusted_mask, sgn, precision, other.get_value (),
1108 other.get_mask ());
1110 if (wi::sext (adjusted_mask, precision) == -1)
1111 return set_to_bottom ();
1114 else
1115 return set_to_bottom ();
1117 if (top_p ())
1119 if (wi::sext (adjusted_mask, precision) == -1)
1120 return set_to_bottom ();
1121 return set_to_constant (adjusted_value, adjusted_mask);
1123 else
1124 return meet_with_1 (adjusted_value, adjusted_mask, precision);
1127 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1128 return true is any of them has not been marked as such so far. */
1130 static inline bool
1131 set_all_contains_variable (class ipcp_param_lattices *plats)
1133 bool ret;
1134 ret = plats->itself.set_contains_variable ();
1135 ret |= plats->ctxlat.set_contains_variable ();
1136 ret |= set_agg_lats_contain_variable (plats);
1137 ret |= plats->bits_lattice.set_to_bottom ();
1138 ret |= plats->m_value_range.set_to_bottom ();
1139 return ret;
1142 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1143 points to by the number of callers to NODE. */
1145 static bool
1146 count_callers (cgraph_node *node, void *data)
1148 int *caller_count = (int *) data;
1150 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
1151 /* Local thunks can be handled transparently, but if the thunk cannot
1152 be optimized out, count it as a real use. */
1153 if (!cs->caller->thunk.thunk_p || !cs->caller->local)
1154 ++*caller_count;
1155 return false;
1158 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1159 the one caller of some other node. Set the caller's corresponding flag. */
1161 static bool
1162 set_single_call_flag (cgraph_node *node, void *)
1164 cgraph_edge *cs = node->callers;
1165 /* Local thunks can be handled transparently, skip them. */
1166 while (cs && cs->caller->thunk.thunk_p && cs->caller->local)
1167 cs = cs->next_caller;
1168 if (cs)
1170 IPA_NODE_REF (cs->caller)->node_calling_single_call = true;
1171 return true;
1173 return false;
1176 /* Initialize ipcp_lattices. */
1178 static void
1179 initialize_node_lattices (struct cgraph_node *node)
1181 class ipa_node_params *info = IPA_NODE_REF (node);
1182 struct cgraph_edge *ie;
1183 bool disable = false, variable = false;
1184 int i;
1186 gcc_checking_assert (node->has_gimple_body_p ());
1188 if (!ipa_get_param_count (info))
1189 disable = true;
1190 else if (node->local)
1192 int caller_count = 0;
1193 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
1194 true);
1195 gcc_checking_assert (caller_count > 0);
1196 if (caller_count == 1)
1197 node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
1198 NULL, true);
1200 else
1202 /* When cloning is allowed, we can assume that externally visible
1203 functions are not called. We will compensate this by cloning
1204 later. */
1205 if (ipcp_versionable_function_p (node)
1206 && ipcp_cloning_candidate_p (node))
1207 variable = true;
1208 else
1209 disable = true;
1212 if (dump_file && (dump_flags & TDF_DETAILS)
1213 && !node->alias && !node->thunk.thunk_p)
1215 fprintf (dump_file, "Initializing lattices of %s\n",
1216 node->dump_name ());
1217 if (disable || variable)
1218 fprintf (dump_file, " Marking all lattices as %s\n",
1219 disable ? "BOTTOM" : "VARIABLE");
1222 auto_vec<bool, 16> surviving_params;
1223 bool pre_modified = false;
1224 if (!disable && node->clone.param_adjustments)
1226 /* At the moment all IPA optimizations should use the number of
1227 parameters of the prevailing decl as the m_always_copy_start.
1228 Handling any other value would complicate the code below, so for the
1229 time bing let's only assert it is so. */
1230 gcc_assert ((node->clone.param_adjustments->m_always_copy_start
1231 == ipa_get_param_count (info))
1232 || node->clone.param_adjustments->m_always_copy_start < 0);
1234 pre_modified = true;
1235 node->clone.param_adjustments->get_surviving_params (&surviving_params);
1237 if (dump_file && (dump_flags & TDF_DETAILS)
1238 && !node->alias && !node->thunk.thunk_p)
1240 bool first = true;
1241 for (int j = 0; j < ipa_get_param_count (info); j++)
1243 if (j < (int) surviving_params.length ()
1244 && surviving_params[j])
1245 continue;
1246 if (first)
1248 fprintf (dump_file,
1249 " The following parameters are dead on arrival:");
1250 first = false;
1252 fprintf (dump_file, " %u", j);
1254 if (!first)
1255 fprintf (dump_file, "\n");
1259 for (i = 0; i < ipa_get_param_count (info); i++)
1261 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
1262 if (disable
1263 || (pre_modified && (surviving_params.length () <= (unsigned) i
1264 || !surviving_params[i])))
1266 plats->itself.set_to_bottom ();
1267 plats->ctxlat.set_to_bottom ();
1268 set_agg_lats_to_bottom (plats);
1269 plats->bits_lattice.set_to_bottom ();
1270 plats->m_value_range.set_to_bottom ();
1272 else
1274 plats->m_value_range.init ();
1275 if (variable)
1276 set_all_contains_variable (plats);
1280 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1281 if (ie->indirect_info->polymorphic
1282 && ie->indirect_info->param_index >= 0)
1284 gcc_checking_assert (ie->indirect_info->param_index >= 0);
1285 ipa_get_parm_lattices (info,
1286 ie->indirect_info->param_index)->virt_call = 1;
1290 /* Return the result of a (possibly arithmetic) operation on the constant
1291 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1292 the type of the parameter to which the result is passed. Return
1293 NULL_TREE if that cannot be determined or be considered an
1294 interprocedural invariant. */
1296 static tree
1297 ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
1298 tree res_type)
1300 tree res;
1302 if (opcode == NOP_EXPR)
1303 return input;
1304 if (!is_gimple_ip_invariant (input))
1305 return NULL_TREE;
1307 if (!res_type)
1309 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1310 res_type = boolean_type_node;
1311 else if (expr_type_first_operand_type_p (opcode))
1312 res_type = TREE_TYPE (input);
1313 else
1314 return NULL_TREE;
1317 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1318 res = fold_unary (opcode, res_type, input);
1319 else
1320 res = fold_binary (opcode, res_type, input, operand);
1322 if (res && !is_gimple_ip_invariant (res))
1323 return NULL_TREE;
1325 return res;
1328 /* Return the result of a (possibly arithmetic) pass through jump function
1329 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1330 to which the result is passed. Return NULL_TREE if that cannot be
1331 determined or be considered an interprocedural invariant. */
1333 static tree
1334 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1335 tree res_type)
1337 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
1338 input,
1339 ipa_get_jf_pass_through_operand (jfunc),
1340 res_type);
1343 /* Return the result of an ancestor jump function JFUNC on the constant value
1344 INPUT. Return NULL_TREE if that cannot be determined. */
1346 static tree
1347 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
1349 gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
1350 if (TREE_CODE (input) == ADDR_EXPR)
1352 tree t = TREE_OPERAND (input, 0);
1353 t = build_ref_for_offset (EXPR_LOCATION (t), t,
1354 ipa_get_jf_ancestor_offset (jfunc), false,
1355 ptr_type_node, NULL, false);
1356 return build_fold_addr_expr (t);
1358 else
1359 return NULL_TREE;
1362 /* Determine whether JFUNC evaluates to a single known constant value and if
1363 so, return it. Otherwise return NULL. INFO describes the caller node or
1364 the one it is inlined to, so that pass-through jump functions can be
1365 evaluated. PARM_TYPE is the type of the parameter to which the result is
1366 passed. */
1368 tree
1369 ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
1370 tree parm_type)
1372 if (jfunc->type == IPA_JF_CONST)
1373 return ipa_get_jf_constant (jfunc);
1374 else if (jfunc->type == IPA_JF_PASS_THROUGH
1375 || jfunc->type == IPA_JF_ANCESTOR)
1377 tree input;
1378 int idx;
1380 if (jfunc->type == IPA_JF_PASS_THROUGH)
1381 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1382 else
1383 idx = ipa_get_jf_ancestor_formal_id (jfunc);
1385 if (info->ipcp_orig_node)
1386 input = info->known_csts[idx];
1387 else
1389 ipcp_lattice<tree> *lat;
1391 if (!info->lattices
1392 || idx >= ipa_get_param_count (info))
1393 return NULL_TREE;
1394 lat = ipa_get_scalar_lat (info, idx);
1395 if (!lat->is_single_const ())
1396 return NULL_TREE;
1397 input = lat->values->value;
1400 if (!input)
1401 return NULL_TREE;
1403 if (jfunc->type == IPA_JF_PASS_THROUGH)
1404 return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
1405 else
1406 return ipa_get_jf_ancestor_result (jfunc, input);
1408 else
1409 return NULL_TREE;
1412 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1413 that INFO describes the caller node or the one it is inlined to, CS is the
1414 call graph edge corresponding to JFUNC and CSIDX index of the described
1415 parameter. */
1417 ipa_polymorphic_call_context
1418 ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
1419 ipa_jump_func *jfunc)
1421 ipa_edge_args *args = IPA_EDGE_REF (cs);
1422 ipa_polymorphic_call_context ctx;
1423 ipa_polymorphic_call_context *edge_ctx
1424 = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
1426 if (edge_ctx && !edge_ctx->useless_p ())
1427 ctx = *edge_ctx;
1429 if (jfunc->type == IPA_JF_PASS_THROUGH
1430 || jfunc->type == IPA_JF_ANCESTOR)
1432 ipa_polymorphic_call_context srcctx;
1433 int srcidx;
1434 bool type_preserved = true;
1435 if (jfunc->type == IPA_JF_PASS_THROUGH)
1437 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1438 return ctx;
1439 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1440 srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
1442 else
1444 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1445 srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
1447 if (info->ipcp_orig_node)
1449 if (info->known_contexts.exists ())
1450 srcctx = info->known_contexts[srcidx];
1452 else
1454 if (!info->lattices
1455 || srcidx >= ipa_get_param_count (info))
1456 return ctx;
1457 ipcp_lattice<ipa_polymorphic_call_context> *lat;
1458 lat = ipa_get_poly_ctx_lat (info, srcidx);
1459 if (!lat->is_single_const ())
1460 return ctx;
1461 srcctx = lat->values->value;
1463 if (srcctx.useless_p ())
1464 return ctx;
1465 if (jfunc->type == IPA_JF_ANCESTOR)
1466 srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1467 if (!type_preserved)
1468 srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1469 srcctx.combine_with (ctx);
1470 return srcctx;
1473 return ctx;
1476 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1477 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1478 the result is a range or an anti-range. */
1480 static bool
1481 ipa_vr_operation_and_type_effects (value_range *dst_vr,
1482 value_range *src_vr,
1483 enum tree_code operation,
1484 tree dst_type, tree src_type)
1486 range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1487 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1488 return false;
1489 return true;
1492 /* Determine value_range of JFUNC given that INFO describes the caller node or
1493 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1494 and PARM_TYPE of the parameter. */
1496 value_range
1497 ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
1498 ipa_jump_func *jfunc, tree parm_type)
1500 value_range vr;
1501 return vr;
1502 if (jfunc->m_vr)
1503 ipa_vr_operation_and_type_effects (&vr,
1504 jfunc->m_vr,
1505 NOP_EXPR, parm_type,
1506 jfunc->m_vr->type ());
1507 if (vr.singleton_p ())
1508 return vr;
1509 if (jfunc->type == IPA_JF_PASS_THROUGH)
1511 int idx;
1512 ipcp_transformation *sum
1513 = ipcp_get_transformation_summary (cs->caller->inlined_to
1514 ? cs->caller->inlined_to
1515 : cs->caller);
1516 if (!sum || !sum->m_vr)
1517 return vr;
1519 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1521 if (!(*sum->m_vr)[idx].known)
1522 return vr;
1523 tree vr_type = ipa_get_type (info, idx);
1524 value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
1525 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
1526 (*sum->m_vr)[idx].type);
1528 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1530 if (TREE_CODE_CLASS (operation) == tcc_unary)
1532 value_range res;
1534 if (ipa_vr_operation_and_type_effects (&res,
1535 &srcvr,
1536 operation, parm_type,
1537 vr_type))
1538 vr.intersect (res);
1540 else
1542 value_range op_res, res;
1543 tree op = ipa_get_jf_pass_through_operand (jfunc);
1544 value_range op_vr (op, op);
1546 range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
1547 if (ipa_vr_operation_and_type_effects (&res,
1548 &op_res,
1549 NOP_EXPR, parm_type,
1550 vr_type))
1551 vr.intersect (res);
1554 return vr;
1557 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1558 parameter with the given INDEX. */
1560 static tree
1561 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
1562 int index)
1564 struct ipa_agg_replacement_value *aggval;
1566 aggval = ipa_get_agg_replacements_for_node (node);
1567 while (aggval)
1569 if (aggval->offset == offset
1570 && aggval->index == index)
1571 return aggval->value;
1572 aggval = aggval->next;
1574 return NULL_TREE;
1577 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1578 single known constant value and if so, return it. Otherwise return NULL.
1579 NODE and INFO describes the caller node or the one it is inlined to, and
1580 its related info. */
1582 static tree
1583 ipa_agg_value_from_node (class ipa_node_params *info,
1584 struct cgraph_node *node,
1585 struct ipa_agg_jf_item *item)
1587 tree value = NULL_TREE;
1588 int src_idx;
1590 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
1591 return NULL_TREE;
1593 if (item->jftype == IPA_JF_CONST)
1594 return item->value.constant;
1596 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
1597 || item->jftype == IPA_JF_LOAD_AGG);
1599 src_idx = item->value.pass_through.formal_id;
1601 if (info->ipcp_orig_node)
1603 if (item->jftype == IPA_JF_PASS_THROUGH)
1604 value = info->known_csts[src_idx];
1605 else
1606 value = get_clone_agg_value (node, item->value.load_agg.offset,
1607 src_idx);
1609 else if (info->lattices)
1611 class ipcp_param_lattices *src_plats
1612 = ipa_get_parm_lattices (info, src_idx);
1614 if (item->jftype == IPA_JF_PASS_THROUGH)
1616 struct ipcp_lattice<tree> *lat = &src_plats->itself;
1618 if (!lat->is_single_const ())
1619 return NULL_TREE;
1621 value = lat->values->value;
1623 else if (src_plats->aggs
1624 && !src_plats->aggs_bottom
1625 && !src_plats->aggs_contain_variable
1626 && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
1628 struct ipcp_agg_lattice *aglat;
1630 for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
1632 if (aglat->offset > item->value.load_agg.offset)
1633 break;
1635 if (aglat->offset == item->value.load_agg.offset)
1637 if (aglat->is_single_const ())
1638 value = aglat->values->value;
1639 break;
1645 if (!value)
1646 return NULL_TREE;
1648 if (item->jftype == IPA_JF_LOAD_AGG)
1650 tree load_type = item->value.load_agg.type;
1651 tree value_type = TREE_TYPE (value);
1653 /* Ensure value type is compatible with load type. */
1654 if (!useless_type_conversion_p (load_type, value_type))
1655 return NULL_TREE;
1658 return ipa_get_jf_arith_result (item->value.pass_through.operation,
1659 value,
1660 item->value.pass_through.operand,
1661 item->type);
1664 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1665 an aggregate and if so, return it. Otherwise return an empty set. NODE
1666 and INFO describes the caller node or the one it is inlined to, and its
1667 related info. */
1669 struct ipa_agg_value_set
1670 ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node,
1671 struct ipa_agg_jump_function *agg_jfunc)
1673 struct ipa_agg_value_set agg;
1674 struct ipa_agg_jf_item *item;
1675 int i;
1677 agg.items = vNULL;
1678 agg.by_ref = agg_jfunc->by_ref;
1680 FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item)
1682 tree value = ipa_agg_value_from_node (info, node, item);
1684 if (value)
1686 struct ipa_agg_value value_item;
1688 value_item.offset = item->offset;
1689 value_item.value = value;
1691 agg.items.safe_push (value_item);
1694 return agg;
1697 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1698 bottom, not containing a variable component and without any known value at
1699 the same time. */
1701 DEBUG_FUNCTION void
1702 ipcp_verify_propagated_values (void)
1704 struct cgraph_node *node;
1706 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1708 class ipa_node_params *info = IPA_NODE_REF (node);
1709 if (!opt_for_fn (node->decl, flag_ipa_cp)
1710 || !opt_for_fn (node->decl, optimize))
1711 continue;
1712 int i, count = ipa_get_param_count (info);
1714 for (i = 0; i < count; i++)
1716 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
1718 if (!lat->bottom
1719 && !lat->contains_variable
1720 && lat->values_count == 0)
1722 if (dump_file)
1724 symtab->dump (dump_file);
1725 fprintf (dump_file, "\nIPA lattices after constant "
1726 "propagation, before gcc_unreachable:\n");
1727 print_all_lattices (dump_file, true, false);
1730 gcc_unreachable ();
1736 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1738 static bool
1739 values_equal_for_ipcp_p (tree x, tree y)
1741 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
1743 if (x == y)
1744 return true;
1746 if (TREE_CODE (x) == ADDR_EXPR
1747 && TREE_CODE (y) == ADDR_EXPR
1748 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
1749 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
1750 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
1751 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
1752 else
1753 return operand_equal_p (x, y, 0);
1756 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1758 static bool
1759 values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
1760 ipa_polymorphic_call_context y)
1762 return x.equal_to (y);
1766 /* Add a new value source to the value represented by THIS, marking that a
1767 value comes from edge CS and (if the underlying jump function is a
1768 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1769 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1770 scalar value of the parameter itself or the offset within an aggregate. */
1772 template <typename valtype>
1773 void
1774 ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
1775 int src_idx, HOST_WIDE_INT offset)
1777 ipcp_value_source<valtype> *src;
1779 src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
1780 src->offset = offset;
1781 src->cs = cs;
1782 src->val = src_val;
1783 src->index = src_idx;
1785 src->next = sources;
1786 sources = src;
1789 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1790 SOURCE and clear all other fields. */
1792 static ipcp_value<tree> *
1793 allocate_and_init_ipcp_value (tree source)
1795 ipcp_value<tree> *val;
1797 val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>();
1798 val->value = source;
1799 return val;
1802 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1803 value to SOURCE and clear all other fields. */
1805 static ipcp_value<ipa_polymorphic_call_context> *
1806 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source)
1808 ipcp_value<ipa_polymorphic_call_context> *val;
1810 // TODO
1811 val = new (ipcp_poly_ctx_values_pool.allocate ())
1812 ipcp_value<ipa_polymorphic_call_context>();
1813 val->value = source;
1814 return val;
1817 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1818 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1819 meaning. OFFSET -1 means the source is scalar and not a part of an
1820 aggregate. */
1822 template <typename valtype>
1823 bool
1824 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1825 ipcp_value<valtype> *src_val,
1826 int src_idx, HOST_WIDE_INT offset)
1828 ipcp_value<valtype> *val;
1830 if (bottom)
1831 return false;
1833 for (val = values; val; val = val->next)
1834 if (values_equal_for_ipcp_p (val->value, newval))
1836 if (ipa_edge_within_scc (cs))
1838 ipcp_value_source<valtype> *s;
1839 for (s = val->sources; s; s = s->next)
1840 if (s->cs == cs)
1841 break;
1842 if (s)
1843 return false;
1846 val->add_source (cs, src_val, src_idx, offset);
1847 return false;
1850 if (values_count == param_ipa_cp_value_list_size)
1852 /* We can only free sources, not the values themselves, because sources
1853 of other values in this SCC might point to them. */
1854 for (val = values; val; val = val->next)
1856 while (val->sources)
1858 ipcp_value_source<valtype> *src = val->sources;
1859 val->sources = src->next;
1860 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
1864 values = NULL;
1865 return set_to_bottom ();
1868 values_count++;
1869 val = allocate_and_init_ipcp_value (newval);
1870 val->add_source (cs, src_val, src_idx, offset);
1871 val->next = values;
1872 values = val;
1873 return true;
1876 /* Propagate values through an arithmetic transformation described by a jump
1877 function associated with edge CS, taking values from SRC_LAT and putting
1878 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
1879 OPND2 is a constant value if transformation is a binary operation.
1880 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
1881 a part of the aggregate. SRC_IDX is the index of the source parameter.
1882 RES_TYPE is the value type of result being propagated into. Return true if
1883 DEST_LAT changed. */
1885 static bool
1886 propagate_vals_across_arith_jfunc (cgraph_edge *cs,
1887 enum tree_code opcode,
1888 tree opnd1_type,
1889 tree opnd2,
1890 ipcp_lattice<tree> *src_lat,
1891 ipcp_lattice<tree> *dest_lat,
1892 HOST_WIDE_INT src_offset,
1893 int src_idx,
1894 tree res_type)
1896 ipcp_value<tree> *src_val;
1897 bool ret = false;
1899 /* Do not create new values when propagating within an SCC because if there
1900 are arithmetic functions with circular dependencies, there is infinite
1901 number of them and we would just make lattices bottom. If this condition
1902 is ever relaxed we have to detect self-feeding recursive calls in
1903 cgraph_edge_brings_value_p in a smarter way. */
1904 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
1905 ret = dest_lat->set_contains_variable ();
1906 else
1907 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1909 tree opnd1 = src_val->value;
1910 tree cstval = NULL_TREE;
1912 /* Skip source values that is incompatible with specified type. */
1913 if (!opnd1_type
1914 || useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
1915 cstval = ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
1917 if (cstval)
1918 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
1919 src_offset);
1920 else
1921 ret |= dest_lat->set_contains_variable ();
1924 return ret;
1927 /* Propagate values through a pass-through jump function JFUNC associated with
1928 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1929 is the index of the source parameter. PARM_TYPE is the type of the
1930 parameter to which the result is passed. */
1932 static bool
1933 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
1934 ipcp_lattice<tree> *src_lat,
1935 ipcp_lattice<tree> *dest_lat, int src_idx,
1936 tree parm_type)
1938 return propagate_vals_across_arith_jfunc (cs,
1939 ipa_get_jf_pass_through_operation (jfunc),
1940 NULL_TREE,
1941 ipa_get_jf_pass_through_operand (jfunc),
1942 src_lat, dest_lat, -1, src_idx, parm_type);
1945 /* Propagate values through an ancestor jump function JFUNC associated with
1946 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1947 is the index of the source parameter. */
1949 static bool
1950 propagate_vals_across_ancestor (struct cgraph_edge *cs,
1951 struct ipa_jump_func *jfunc,
1952 ipcp_lattice<tree> *src_lat,
1953 ipcp_lattice<tree> *dest_lat, int src_idx)
1955 ipcp_value<tree> *src_val;
1956 bool ret = false;
1958 if (ipa_edge_within_scc (cs))
1959 return dest_lat->set_contains_variable ();
1961 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1963 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
1965 if (t)
1966 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
1967 else
1968 ret |= dest_lat->set_contains_variable ();
1971 return ret;
1974 /* Propagate scalar values across jump function JFUNC that is associated with
1975 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
1976 parameter to which the result is passed. */
1978 static bool
1979 propagate_scalar_across_jump_function (struct cgraph_edge *cs,
1980 struct ipa_jump_func *jfunc,
1981 ipcp_lattice<tree> *dest_lat,
1982 tree param_type)
1984 if (dest_lat->bottom)
1985 return false;
1987 if (jfunc->type == IPA_JF_CONST)
1989 tree val = ipa_get_jf_constant (jfunc);
1990 return dest_lat->add_value (val, cs, NULL, 0);
1992 else if (jfunc->type == IPA_JF_PASS_THROUGH
1993 || jfunc->type == IPA_JF_ANCESTOR)
1995 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1996 ipcp_lattice<tree> *src_lat;
1997 int src_idx;
1998 bool ret;
2000 if (jfunc->type == IPA_JF_PASS_THROUGH)
2001 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2002 else
2003 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2005 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
2006 if (src_lat->bottom)
2007 return dest_lat->set_contains_variable ();
2009 /* If we would need to clone the caller and cannot, do not propagate. */
2010 if (!ipcp_versionable_function_p (cs->caller)
2011 && (src_lat->contains_variable
2012 || (src_lat->values_count > 1)))
2013 return dest_lat->set_contains_variable ();
2015 if (jfunc->type == IPA_JF_PASS_THROUGH)
2016 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
2017 dest_lat, src_idx, param_type);
2018 else
2019 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
2020 src_idx);
2022 if (src_lat->contains_variable)
2023 ret |= dest_lat->set_contains_variable ();
2025 return ret;
2028 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2029 use it for indirect inlining), we should propagate them too. */
2030 return dest_lat->set_contains_variable ();
2033 /* Propagate scalar values across jump function JFUNC that is associated with
2034 edge CS and describes argument IDX and put the values into DEST_LAT. */
2036 static bool
2037 propagate_context_across_jump_function (cgraph_edge *cs,
2038 ipa_jump_func *jfunc, int idx,
2039 ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
2041 ipa_edge_args *args = IPA_EDGE_REF (cs);
2042 if (dest_lat->bottom)
2043 return false;
2044 bool ret = false;
2045 bool added_sth = false;
2046 bool type_preserved = true;
2048 ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
2049 = ipa_get_ith_polymorhic_call_context (args, idx);
2051 if (edge_ctx_ptr)
2052 edge_ctx = *edge_ctx_ptr;
2054 if (jfunc->type == IPA_JF_PASS_THROUGH
2055 || jfunc->type == IPA_JF_ANCESTOR)
2057 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2058 int src_idx;
2059 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
2061 /* TODO: Once we figure out how to propagate speculations, it will
2062 probably be a good idea to switch to speculation if type_preserved is
2063 not set instead of punting. */
2064 if (jfunc->type == IPA_JF_PASS_THROUGH)
2066 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
2067 goto prop_fail;
2068 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
2069 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2071 else
2073 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
2074 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2077 src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
2078 /* If we would need to clone the caller and cannot, do not propagate. */
2079 if (!ipcp_versionable_function_p (cs->caller)
2080 && (src_lat->contains_variable
2081 || (src_lat->values_count > 1)))
2082 goto prop_fail;
2084 ipcp_value<ipa_polymorphic_call_context> *src_val;
2085 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2087 ipa_polymorphic_call_context cur = src_val->value;
2089 if (!type_preserved)
2090 cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
2091 if (jfunc->type == IPA_JF_ANCESTOR)
2092 cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
2093 /* TODO: In cases we know how the context is going to be used,
2094 we can improve the result by passing proper OTR_TYPE. */
2095 cur.combine_with (edge_ctx);
2096 if (!cur.useless_p ())
2098 if (src_lat->contains_variable
2099 && !edge_ctx.equal_to (cur))
2100 ret |= dest_lat->set_contains_variable ();
2101 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
2102 added_sth = true;
2107 prop_fail:
2108 if (!added_sth)
2110 if (!edge_ctx.useless_p ())
2111 ret |= dest_lat->add_value (edge_ctx, cs);
2112 else
2113 ret |= dest_lat->set_contains_variable ();
2116 return ret;
2119 /* Propagate bits across jfunc that is associated with
2120 edge cs and update dest_lattice accordingly. */
2122 bool
2123 propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
2124 ipa_jump_func *jfunc,
2125 ipcp_bits_lattice *dest_lattice)
2127 if (dest_lattice->bottom_p ())
2128 return false;
2130 enum availability availability;
2131 cgraph_node *callee = cs->callee->function_symbol (&availability);
2132 class ipa_node_params *callee_info = IPA_NODE_REF (callee);
2133 tree parm_type = ipa_get_type (callee_info, idx);
2135 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2136 transform for these cases. Similarly, we can have bad type mismatches
2137 with LTO, avoid doing anything with those too. */
2138 if (!parm_type
2139 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
2141 if (dump_file && (dump_flags & TDF_DETAILS))
2142 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
2143 "param %i of %s is NULL or unsuitable for bits propagation\n",
2144 idx, cs->callee->name ());
2146 return dest_lattice->set_to_bottom ();
2149 unsigned precision = TYPE_PRECISION (parm_type);
2150 signop sgn = TYPE_SIGN (parm_type);
2152 if (jfunc->type == IPA_JF_PASS_THROUGH
2153 || jfunc->type == IPA_JF_ANCESTOR)
2155 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2156 tree operand = NULL_TREE;
2157 enum tree_code code;
2158 unsigned src_idx;
2160 if (jfunc->type == IPA_JF_PASS_THROUGH)
2162 code = ipa_get_jf_pass_through_operation (jfunc);
2163 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2164 if (code != NOP_EXPR)
2165 operand = ipa_get_jf_pass_through_operand (jfunc);
2167 else
2169 code = POINTER_PLUS_EXPR;
2170 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2171 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
2172 operand = build_int_cstu (size_type_node, offset);
2175 class ipcp_param_lattices *src_lats
2176 = ipa_get_parm_lattices (caller_info, src_idx);
2178 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2179 for eg consider:
2180 int f(int x)
2182 g (x & 0xff);
2184 Assume lattice for x is bottom, however we can still propagate
2185 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2186 and we store it in jump function during analysis stage. */
2188 if (src_lats->bits_lattice.bottom_p ()
2189 && jfunc->bits)
2190 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2191 precision);
2192 else
2193 return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
2194 code, operand);
2197 else if (jfunc->type == IPA_JF_ANCESTOR)
2198 return dest_lattice->set_to_bottom ();
2199 else if (jfunc->bits)
2200 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2201 precision);
2202 else
2203 return dest_lattice->set_to_bottom ();
2206 /* Propagate value range across jump function JFUNC that is associated with
2207 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2208 accordingly. */
2210 static bool
2211 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
2212 class ipcp_param_lattices *dest_plats,
2213 tree param_type)
2215 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
2217 if (dest_lat->bottom_p ())
2218 return false;
2220 if (!param_type
2221 || (!INTEGRAL_TYPE_P (param_type)
2222 && !POINTER_TYPE_P (param_type)))
2223 return dest_lat->set_to_bottom ();
2225 if (jfunc->type == IPA_JF_PASS_THROUGH)
2227 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
2228 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2229 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2230 class ipcp_param_lattices *src_lats
2231 = ipa_get_parm_lattices (caller_info, src_idx);
2232 tree operand_type = ipa_get_type (caller_info, src_idx);
2234 if (src_lats->m_value_range.bottom_p ())
2235 return dest_lat->set_to_bottom ();
2237 value_range vr;
2238 if (TREE_CODE_CLASS (operation) == tcc_unary)
2240 ipa_vr_operation_and_type_effects (&vr,
2241 &src_lats->m_value_range.m_vr,
2242 operation, param_type,
2243 operand_type);
2245 /* A crude way to prevent unbounded number of value range updates
2246 in SCC components. We should allow limited number of updates within
2247 SCC, too. */
2248 else if (!ipa_edge_within_scc (cs))
2250 tree op = ipa_get_jf_pass_through_operand (jfunc);
2251 value_range op_vr (op, op);
2252 value_range op_res,res;
2254 range_fold_binary_expr (&op_res, operation, operand_type,
2255 &src_lats->m_value_range.m_vr, &op_vr);
2256 ipa_vr_operation_and_type_effects (&vr,
2257 &op_res,
2258 NOP_EXPR, param_type,
2259 operand_type);
2261 if (!vr.undefined_p () && !vr.varying_p ())
2263 if (jfunc->m_vr)
2265 value_range jvr;
2266 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2267 NOP_EXPR,
2268 param_type,
2269 jfunc->m_vr->type ()))
2270 vr.intersect (*jfunc->m_vr);
2272 return dest_lat->meet_with (&vr);
2275 else if (jfunc->type == IPA_JF_CONST)
2277 tree val = ipa_get_jf_constant (jfunc);
2278 if (TREE_CODE (val) == INTEGER_CST)
2280 val = fold_convert (param_type, val);
2281 if (TREE_OVERFLOW_P (val))
2282 val = drop_tree_overflow (val);
2284 value_range tmpvr (val, val);
2285 return dest_lat->meet_with (&tmpvr);
2289 value_range vr;
2290 if (jfunc->m_vr
2291 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
2292 param_type,
2293 jfunc->m_vr->type ()))
2294 return dest_lat->meet_with (&vr);
2295 else
2296 return dest_lat->set_to_bottom ();
2299 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2300 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2301 other cases, return false). If there are no aggregate items, set
2302 aggs_by_ref to NEW_AGGS_BY_REF. */
2304 static bool
2305 set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
2306 bool new_aggs_by_ref)
2308 if (dest_plats->aggs)
2310 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
2312 set_agg_lats_to_bottom (dest_plats);
2313 return true;
2316 else
2317 dest_plats->aggs_by_ref = new_aggs_by_ref;
2318 return false;
2321 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2322 already existing lattice for the given OFFSET and SIZE, marking all skipped
2323 lattices as containing variable and checking for overlaps. If there is no
2324 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2325 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2326 unless there are too many already. If there are two many, return false. If
2327 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2328 skipped lattices were newly marked as containing variable, set *CHANGE to
2329 true. */
2331 static bool
2332 merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
2333 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
2334 struct ipcp_agg_lattice ***aglat,
2335 bool pre_existing, bool *change)
2337 gcc_checking_assert (offset >= 0);
2339 while (**aglat && (**aglat)->offset < offset)
2341 if ((**aglat)->offset + (**aglat)->size > offset)
2343 set_agg_lats_to_bottom (dest_plats);
2344 return false;
2346 *change |= (**aglat)->set_contains_variable ();
2347 *aglat = &(**aglat)->next;
2350 if (**aglat && (**aglat)->offset == offset)
2352 if ((**aglat)->size != val_size)
2354 set_agg_lats_to_bottom (dest_plats);
2355 return false;
2357 gcc_assert (!(**aglat)->next
2358 || (**aglat)->next->offset >= offset + val_size);
2359 return true;
2361 else
2363 struct ipcp_agg_lattice *new_al;
2365 if (**aglat && (**aglat)->offset < offset + val_size)
2367 set_agg_lats_to_bottom (dest_plats);
2368 return false;
2370 if (dest_plats->aggs_count == param_ipa_max_agg_items)
2371 return false;
2372 dest_plats->aggs_count++;
2373 new_al = ipcp_agg_lattice_pool.allocate ();
2374 memset (new_al, 0, sizeof (*new_al));
2376 new_al->offset = offset;
2377 new_al->size = val_size;
2378 new_al->contains_variable = pre_existing;
2380 new_al->next = **aglat;
2381 **aglat = new_al;
2382 return true;
2386 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2387 containing an unknown value. */
2389 static bool
2390 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
2392 bool ret = false;
2393 while (aglat)
2395 ret |= aglat->set_contains_variable ();
2396 aglat = aglat->next;
2398 return ret;
2401 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2402 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2403 parameter used for lattice value sources. Return true if DEST_PLATS changed
2404 in any way. */
2406 static bool
2407 merge_aggregate_lattices (struct cgraph_edge *cs,
2408 class ipcp_param_lattices *dest_plats,
2409 class ipcp_param_lattices *src_plats,
2410 int src_idx, HOST_WIDE_INT offset_delta)
2412 bool pre_existing = dest_plats->aggs != NULL;
2413 struct ipcp_agg_lattice **dst_aglat;
2414 bool ret = false;
2416 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
2417 return true;
2418 if (src_plats->aggs_bottom)
2419 return set_agg_lats_contain_variable (dest_plats);
2420 if (src_plats->aggs_contain_variable)
2421 ret |= set_agg_lats_contain_variable (dest_plats);
2422 dst_aglat = &dest_plats->aggs;
2424 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2425 src_aglat;
2426 src_aglat = src_aglat->next)
2428 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2430 if (new_offset < 0)
2431 continue;
2432 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
2433 &dst_aglat, pre_existing, &ret))
2435 struct ipcp_agg_lattice *new_al = *dst_aglat;
2437 dst_aglat = &(*dst_aglat)->next;
2438 if (src_aglat->bottom)
2440 ret |= new_al->set_contains_variable ();
2441 continue;
2443 if (src_aglat->contains_variable)
2444 ret |= new_al->set_contains_variable ();
2445 for (ipcp_value<tree> *val = src_aglat->values;
2446 val;
2447 val = val->next)
2448 ret |= new_al->add_value (val->value, cs, val, src_idx,
2449 src_aglat->offset);
2451 else if (dest_plats->aggs_bottom)
2452 return true;
2454 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
2455 return ret;
2458 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2459 pass-through JFUNC and if so, whether it has conform and conforms to the
2460 rules about propagating values passed by reference. */
2462 static bool
2463 agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
2464 struct ipa_jump_func *jfunc)
2466 return src_plats->aggs
2467 && (!src_plats->aggs_by_ref
2468 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2471 /* Propagate values through ITEM, jump function for a part of an aggregate,
2472 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2473 associated with the jump function. Return true if AGLAT changed in any
2474 way. */
2476 static bool
2477 propagate_aggregate_lattice (struct cgraph_edge *cs,
2478 struct ipa_agg_jf_item *item,
2479 struct ipcp_agg_lattice *aglat)
2481 class ipa_node_params *caller_info;
2482 class ipcp_param_lattices *src_plats;
2483 struct ipcp_lattice<tree> *src_lat;
2484 HOST_WIDE_INT src_offset;
2485 int src_idx;
2486 tree load_type;
2487 bool ret;
2489 if (item->jftype == IPA_JF_CONST)
2491 tree value = item->value.constant;
2493 gcc_checking_assert (is_gimple_ip_invariant (value));
2494 return aglat->add_value (value, cs, NULL, 0);
2497 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2498 || item->jftype == IPA_JF_LOAD_AGG);
2500 caller_info = IPA_NODE_REF (cs->caller);
2501 src_idx = item->value.pass_through.formal_id;
2502 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2504 if (item->jftype == IPA_JF_PASS_THROUGH)
2506 load_type = NULL_TREE;
2507 src_lat = &src_plats->itself;
2508 src_offset = -1;
2510 else
2512 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
2513 struct ipcp_agg_lattice *src_aglat;
2515 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
2516 if (src_aglat->offset >= load_offset)
2517 break;
2519 load_type = item->value.load_agg.type;
2520 if (!src_aglat
2521 || src_aglat->offset > load_offset
2522 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
2523 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
2524 return aglat->set_contains_variable ();
2526 src_lat = src_aglat;
2527 src_offset = load_offset;
2530 if (src_lat->bottom
2531 || (!ipcp_versionable_function_p (cs->caller)
2532 && !src_lat->is_single_const ()))
2533 return aglat->set_contains_variable ();
2535 ret = propagate_vals_across_arith_jfunc (cs,
2536 item->value.pass_through.operation,
2537 load_type,
2538 item->value.pass_through.operand,
2539 src_lat, aglat,
2540 src_offset,
2541 src_idx,
2542 item->type);
2544 if (src_lat->contains_variable)
2545 ret |= aglat->set_contains_variable ();
2547 return ret;
2550 /* Propagate scalar values across jump function JFUNC that is associated with
2551 edge CS and put the values into DEST_LAT. */
2553 static bool
2554 propagate_aggs_across_jump_function (struct cgraph_edge *cs,
2555 struct ipa_jump_func *jfunc,
2556 class ipcp_param_lattices *dest_plats)
2558 bool ret = false;
2560 if (dest_plats->aggs_bottom)
2561 return false;
2563 if (jfunc->type == IPA_JF_PASS_THROUGH
2564 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2566 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2567 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2568 class ipcp_param_lattices *src_plats;
2570 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2571 if (agg_pass_through_permissible_p (src_plats, jfunc))
2573 /* Currently we do not produce clobber aggregate jump
2574 functions, replace with merging when we do. */
2575 gcc_assert (!jfunc->agg.items);
2576 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
2577 src_idx, 0);
2579 else
2580 ret |= set_agg_lats_contain_variable (dest_plats);
2582 else if (jfunc->type == IPA_JF_ANCESTOR
2583 && ipa_get_jf_ancestor_agg_preserved (jfunc))
2585 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2586 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2587 class ipcp_param_lattices *src_plats;
2589 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2590 if (src_plats->aggs && src_plats->aggs_by_ref)
2592 /* Currently we do not produce clobber aggregate jump
2593 functions, replace with merging when we do. */
2594 gcc_assert (!jfunc->agg.items);
2595 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
2596 ipa_get_jf_ancestor_offset (jfunc));
2598 else if (!src_plats->aggs_by_ref)
2599 ret |= set_agg_lats_to_bottom (dest_plats);
2600 else
2601 ret |= set_agg_lats_contain_variable (dest_plats);
2603 else if (jfunc->agg.items)
2605 bool pre_existing = dest_plats->aggs != NULL;
2606 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
2607 struct ipa_agg_jf_item *item;
2608 int i;
2610 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
2611 return true;
2613 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2615 HOST_WIDE_INT val_size;
2617 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
2618 continue;
2619 val_size = tree_to_shwi (TYPE_SIZE (item->type));
2621 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
2622 &aglat, pre_existing, &ret))
2624 ret |= propagate_aggregate_lattice (cs, item, *aglat);
2625 aglat = &(*aglat)->next;
2627 else if (dest_plats->aggs_bottom)
2628 return true;
2631 ret |= set_chain_of_aglats_contains_variable (*aglat);
2633 else
2634 ret |= set_agg_lats_contain_variable (dest_plats);
2636 return ret;
2639 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2640 non-thunk) destination, the call passes through a thunk. */
2642 static bool
2643 call_passes_through_thunk_p (cgraph_edge *cs)
2645 cgraph_node *alias_or_thunk = cs->callee;
2646 while (alias_or_thunk->alias)
2647 alias_or_thunk = alias_or_thunk->get_alias_target ();
2648 return alias_or_thunk->thunk.thunk_p;
2651 /* Propagate constants from the caller to the callee of CS. INFO describes the
2652 caller. */
2654 static bool
2655 propagate_constants_across_call (struct cgraph_edge *cs)
2657 class ipa_node_params *callee_info;
2658 enum availability availability;
2659 cgraph_node *callee;
2660 class ipa_edge_args *args;
2661 bool ret = false;
2662 int i, args_count, parms_count;
2664 callee = cs->callee->function_symbol (&availability);
2665 if (!callee->definition)
2666 return false;
2667 gcc_checking_assert (callee->has_gimple_body_p ());
2668 callee_info = IPA_NODE_REF (callee);
2669 if (!callee_info)
2670 return false;
2672 args = IPA_EDGE_REF (cs);
2673 parms_count = ipa_get_param_count (callee_info);
2674 if (parms_count == 0)
2675 return false;
2676 if (!args
2677 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
2678 || !opt_for_fn (cs->caller->decl, optimize))
2680 for (i = 0; i < parms_count; i++)
2681 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2682 i));
2683 return ret;
2685 args_count = ipa_get_cs_argument_count (args);
2687 /* If this call goes through a thunk we must not propagate to the first (0th)
2688 parameter. However, we might need to uncover a thunk from below a series
2689 of aliases first. */
2690 if (call_passes_through_thunk_p (cs))
2692 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2693 0));
2694 i = 1;
2696 else
2697 i = 0;
2699 for (; (i < args_count) && (i < parms_count); i++)
2701 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
2702 class ipcp_param_lattices *dest_plats;
2703 tree param_type = ipa_get_type (callee_info, i);
2705 dest_plats = ipa_get_parm_lattices (callee_info, i);
2706 if (availability == AVAIL_INTERPOSABLE)
2707 ret |= set_all_contains_variable (dest_plats);
2708 else
2710 ret |= propagate_scalar_across_jump_function (cs, jump_func,
2711 &dest_plats->itself,
2712 param_type);
2713 ret |= propagate_context_across_jump_function (cs, jump_func, i,
2714 &dest_plats->ctxlat);
2716 |= propagate_bits_across_jump_function (cs, i, jump_func,
2717 &dest_plats->bits_lattice);
2718 ret |= propagate_aggs_across_jump_function (cs, jump_func,
2719 dest_plats);
2720 if (opt_for_fn (callee->decl, flag_ipa_vrp))
2721 ret |= propagate_vr_across_jump_function (cs, jump_func,
2722 dest_plats, param_type);
2723 else
2724 ret |= dest_plats->m_value_range.set_to_bottom ();
2727 for (; i < parms_count; i++)
2728 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
2730 return ret;
2733 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2734 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2735 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2737 static tree
2738 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
2739 vec<tree> known_csts,
2740 vec<ipa_polymorphic_call_context> known_contexts,
2741 vec<ipa_agg_value_set> known_aggs,
2742 struct ipa_agg_replacement_value *agg_reps,
2743 bool *speculative)
2745 int param_index = ie->indirect_info->param_index;
2746 HOST_WIDE_INT anc_offset;
2747 tree t;
2748 tree target = NULL;
2750 *speculative = false;
2752 if (param_index == -1
2753 || known_csts.length () <= (unsigned int) param_index)
2754 return NULL_TREE;
2756 if (!ie->indirect_info->polymorphic)
2758 tree t;
2760 if (ie->indirect_info->agg_contents)
2762 t = NULL;
2763 if (agg_reps && ie->indirect_info->guaranteed_unmodified)
2765 while (agg_reps)
2767 if (agg_reps->index == param_index
2768 && agg_reps->offset == ie->indirect_info->offset
2769 && agg_reps->by_ref == ie->indirect_info->by_ref)
2771 t = agg_reps->value;
2772 break;
2774 agg_reps = agg_reps->next;
2777 if (!t)
2779 struct ipa_agg_value_set *agg;
2780 if (known_aggs.length () > (unsigned int) param_index)
2781 agg = &known_aggs[param_index];
2782 else
2783 agg = NULL;
2784 bool from_global_constant;
2785 t = ipa_find_agg_cst_for_param (agg, known_csts[param_index],
2786 ie->indirect_info->offset,
2787 ie->indirect_info->by_ref,
2788 &from_global_constant);
2789 if (t
2790 && !from_global_constant
2791 && !ie->indirect_info->guaranteed_unmodified)
2792 t = NULL_TREE;
2795 else
2796 t = known_csts[param_index];
2798 if (t
2799 && TREE_CODE (t) == ADDR_EXPR
2800 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
2801 return TREE_OPERAND (t, 0);
2802 else
2803 return NULL_TREE;
2806 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
2807 return NULL_TREE;
2809 gcc_assert (!ie->indirect_info->agg_contents);
2810 anc_offset = ie->indirect_info->offset;
2812 t = NULL;
2814 /* Try to work out value of virtual table pointer value in replacements. */
2815 if (!t && agg_reps && !ie->indirect_info->by_ref)
2817 while (agg_reps)
2819 if (agg_reps->index == param_index
2820 && agg_reps->offset == ie->indirect_info->offset
2821 && agg_reps->by_ref)
2823 t = agg_reps->value;
2824 break;
2826 agg_reps = agg_reps->next;
2830 /* Try to work out value of virtual table pointer value in known
2831 aggregate values. */
2832 if (!t && known_aggs.length () > (unsigned int) param_index
2833 && !ie->indirect_info->by_ref)
2835 struct ipa_agg_value_set *agg = &known_aggs[param_index];
2836 t = ipa_find_agg_cst_for_param (agg, known_csts[param_index],
2837 ie->indirect_info->offset, true);
2840 /* If we found the virtual table pointer, lookup the target. */
2841 if (t)
2843 tree vtable;
2844 unsigned HOST_WIDE_INT offset;
2845 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
2847 bool can_refer;
2848 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2849 vtable, offset, &can_refer);
2850 if (can_refer)
2852 if (!target
2853 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
2854 || !possible_polymorphic_call_target_p
2855 (ie, cgraph_node::get (target)))
2857 /* Do not speculate builtin_unreachable, it is stupid! */
2858 if (ie->indirect_info->vptr_changed)
2859 return NULL;
2860 target = ipa_impossible_devirt_target (ie, target);
2862 *speculative = ie->indirect_info->vptr_changed;
2863 if (!*speculative)
2864 return target;
2869 /* Do we know the constant value of pointer? */
2870 if (!t)
2871 t = known_csts[param_index];
2873 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
2875 ipa_polymorphic_call_context context;
2876 if (known_contexts.length () > (unsigned int) param_index)
2878 context = known_contexts[param_index];
2879 context.offset_by (anc_offset);
2880 if (ie->indirect_info->vptr_changed)
2881 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2882 ie->indirect_info->otr_type);
2883 if (t)
2885 ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
2886 (t, ie->indirect_info->otr_type, anc_offset);
2887 if (!ctx2.useless_p ())
2888 context.combine_with (ctx2, ie->indirect_info->otr_type);
2891 else if (t)
2893 context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
2894 anc_offset);
2895 if (ie->indirect_info->vptr_changed)
2896 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2897 ie->indirect_info->otr_type);
2899 else
2900 return NULL_TREE;
2902 vec <cgraph_node *>targets;
2903 bool final;
2905 targets = possible_polymorphic_call_targets
2906 (ie->indirect_info->otr_type,
2907 ie->indirect_info->otr_token,
2908 context, &final);
2909 if (!final || targets.length () > 1)
2911 struct cgraph_node *node;
2912 if (*speculative)
2913 return target;
2914 if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
2915 || ie->speculative || !ie->maybe_hot_p ())
2916 return NULL;
2917 node = try_speculative_devirtualization (ie->indirect_info->otr_type,
2918 ie->indirect_info->otr_token,
2919 context);
2920 if (node)
2922 *speculative = true;
2923 target = node->decl;
2925 else
2926 return NULL;
2928 else
2930 *speculative = false;
2931 if (targets.length () == 1)
2932 target = targets[0]->decl;
2933 else
2934 target = ipa_impossible_devirt_target (ie, NULL_TREE);
2937 if (target && !possible_polymorphic_call_target_p (ie,
2938 cgraph_node::get (target)))
2940 if (*speculative)
2941 return NULL;
2942 target = ipa_impossible_devirt_target (ie, target);
2945 return target;
2949 /* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
2950 KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
2951 return the destination. */
2953 tree
2954 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
2955 vec<tree> known_csts,
2956 vec<ipa_polymorphic_call_context> known_contexts,
2957 vec<ipa_agg_value_set> known_aggs,
2958 bool *speculative)
2960 return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2961 known_aggs, NULL, speculative);
2964 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
2965 and KNOWN_CONTEXTS. */
2967 static int
2968 devirtualization_time_bonus (struct cgraph_node *node,
2969 vec<tree> known_csts,
2970 vec<ipa_polymorphic_call_context> known_contexts,
2971 vec<ipa_agg_value_set> known_aggs)
2973 struct cgraph_edge *ie;
2974 int res = 0;
2976 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
2978 struct cgraph_node *callee;
2979 class ipa_fn_summary *isummary;
2980 enum availability avail;
2981 tree target;
2982 bool speculative;
2984 target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts,
2985 known_aggs, &speculative);
2986 if (!target)
2987 continue;
2989 /* Only bare minimum benefit for clearly un-inlineable targets. */
2990 res += 1;
2991 callee = cgraph_node::get (target);
2992 if (!callee || !callee->definition)
2993 continue;
2994 callee = callee->function_symbol (&avail);
2995 if (avail < AVAIL_AVAILABLE)
2996 continue;
2997 isummary = ipa_fn_summaries->get (callee);
2998 if (!isummary->inlinable)
2999 continue;
3001 int size = ipa_size_summaries->get (callee)->size;
3002 /* FIXME: The values below need re-considering and perhaps also
3003 integrating into the cost metrics, at lest in some very basic way. */
3004 int max_inline_insns_auto
3005 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3006 if (size <= max_inline_insns_auto / 4)
3007 res += 31 / ((int)speculative + 1);
3008 else if (size <= max_inline_insns_auto / 2)
3009 res += 15 / ((int)speculative + 1);
3010 else if (size <= max_inline_insns_auto
3011 || DECL_DECLARED_INLINE_P (callee->decl))
3012 res += 7 / ((int)speculative + 1);
3015 return res;
3018 /* Return time bonus incurred because of HINTS. */
3020 static int
3021 hint_time_bonus (ipa_hints hints)
3023 int result = 0;
3024 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
3025 result += param_ipa_cp_loop_hint_bonus;
3026 return result;
3029 /* If there is a reason to penalize the function described by INFO in the
3030 cloning goodness evaluation, do so. */
3032 static inline int64_t
3033 incorporate_penalties (ipa_node_params *info, int64_t evaluation)
3035 if (info->node_within_scc)
3036 evaluation = (evaluation
3037 * (100 - param_ipa_cp_recursion_penalty)) / 100;
3039 if (info->node_calling_single_call)
3040 evaluation = (evaluation
3041 * (100 - param_ipa_cp_single_call_penalty))
3042 / 100;
3044 return evaluation;
3047 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3048 and SIZE_COST and with the sum of frequencies of incoming edges to the
3049 potential new clone in FREQUENCIES. */
3051 static bool
3052 good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
3053 int freq_sum, profile_count count_sum, int size_cost)
3055 if (time_benefit == 0
3056 || !opt_for_fn (node->decl, flag_ipa_cp_clone)
3057 || node->optimize_for_size_p ())
3058 return false;
3060 gcc_assert (size_cost > 0);
3062 class ipa_node_params *info = IPA_NODE_REF (node);
3063 if (max_count > profile_count::zero ())
3065 int factor = RDIV (count_sum.probability_in
3066 (max_count).to_reg_br_prob_base ()
3067 * 1000, REG_BR_PROB_BASE);
3068 int64_t evaluation = (((int64_t) time_benefit * factor)
3069 / size_cost);
3070 evaluation = incorporate_penalties (info, evaluation);
3072 if (dump_file && (dump_flags & TDF_DETAILS))
3074 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
3075 "size: %i, count_sum: ", time_benefit, size_cost);
3076 count_sum.dump (dump_file);
3077 fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64
3078 ", threshold: %i\n",
3079 info->node_within_scc ? ", scc" : "",
3080 info->node_calling_single_call ? ", single_call" : "",
3081 evaluation, param_ipa_cp_eval_threshold);
3084 return evaluation >= param_ipa_cp_eval_threshold;
3086 else
3088 int64_t evaluation = (((int64_t) time_benefit * freq_sum)
3089 / size_cost);
3090 evaluation = incorporate_penalties (info, evaluation);
3092 if (dump_file && (dump_flags & TDF_DETAILS))
3093 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
3094 "size: %i, freq_sum: %i%s%s) -> evaluation: "
3095 "%" PRId64 ", threshold: %i\n",
3096 time_benefit, size_cost, freq_sum,
3097 info->node_within_scc ? ", scc" : "",
3098 info->node_calling_single_call ? ", single_call" : "",
3099 evaluation, param_ipa_cp_eval_threshold);
3101 return evaluation >= param_ipa_cp_eval_threshold;
3105 /* Return all context independent values from aggregate lattices in PLATS in a
3106 vector. Return NULL if there are none. */
3108 static vec<ipa_agg_value>
3109 context_independent_aggregate_values (class ipcp_param_lattices *plats)
3111 vec<ipa_agg_value> res = vNULL;
3113 if (plats->aggs_bottom
3114 || plats->aggs_contain_variable
3115 || plats->aggs_count == 0)
3116 return vNULL;
3118 for (struct ipcp_agg_lattice *aglat = plats->aggs;
3119 aglat;
3120 aglat = aglat->next)
3121 if (aglat->is_single_const ())
3123 struct ipa_agg_value item;
3124 item.offset = aglat->offset;
3125 item.value = aglat->values->value;
3126 res.safe_push (item);
3128 return res;
3131 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
3132 populate them with values of parameters that are known independent of the
3133 context. INFO describes the function. If REMOVABLE_PARAMS_COST is
3134 non-NULL, the movement cost of all removable parameters will be stored in
3135 it. */
3137 static bool
3138 gather_context_independent_values (class ipa_node_params *info,
3139 vec<tree> *known_csts,
3140 vec<ipa_polymorphic_call_context>
3141 *known_contexts,
3142 vec<ipa_agg_value_set> *known_aggs,
3143 int *removable_params_cost)
3145 int i, count = ipa_get_param_count (info);
3146 bool ret = false;
3148 known_csts->create (0);
3149 known_contexts->create (0);
3150 known_csts->safe_grow_cleared (count);
3151 known_contexts->safe_grow_cleared (count);
3152 if (known_aggs)
3154 known_aggs->create (0);
3155 known_aggs->safe_grow_cleared (count);
3158 if (removable_params_cost)
3159 *removable_params_cost = 0;
3161 for (i = 0; i < count; i++)
3163 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3164 ipcp_lattice<tree> *lat = &plats->itself;
3166 if (lat->is_single_const ())
3168 ipcp_value<tree> *val = lat->values;
3169 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3170 (*known_csts)[i] = val->value;
3171 if (removable_params_cost)
3172 *removable_params_cost
3173 += estimate_move_cost (TREE_TYPE (val->value), false);
3174 ret = true;
3176 else if (removable_params_cost
3177 && !ipa_is_param_used (info, i))
3178 *removable_params_cost
3179 += ipa_get_param_move_cost (info, i);
3181 if (!ipa_is_param_used (info, i))
3182 continue;
3184 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3185 /* Do not account known context as reason for cloning. We can see
3186 if it permits devirtualization. */
3187 if (ctxlat->is_single_const ())
3188 (*known_contexts)[i] = ctxlat->values->value;
3190 if (known_aggs)
3192 vec<ipa_agg_value> agg_items;
3193 struct ipa_agg_value_set *agg;
3195 agg_items = context_independent_aggregate_values (plats);
3196 agg = &(*known_aggs)[i];
3197 agg->items = agg_items;
3198 agg->by_ref = plats->aggs_by_ref;
3199 ret |= !agg_items.is_empty ();
3203 return ret;
3206 /* Perform time and size measurement of NODE with the context given in
3207 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
3208 given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
3209 all context-independent removable parameters and EST_MOVE_COST of estimated
3210 movement of the considered parameter and store it into VAL. */
3212 static void
3213 perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
3214 vec<ipa_polymorphic_call_context> known_contexts,
3215 vec<ipa_agg_value_set> known_aggs,
3216 int removable_params_cost,
3217 int est_move_cost, ipcp_value_base *val)
3219 int size, time_benefit;
3220 sreal time, base_time;
3221 ipa_hints hints;
3223 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
3224 known_aggs, &size, &time,
3225 &base_time, &hints);
3226 base_time -= time;
3227 if (base_time > 65535)
3228 base_time = 65535;
3230 /* Extern inline functions have no cloning local time benefits because they
3231 will be inlined anyway. The only reason to clone them is if it enables
3232 optimization in any of the functions they call. */
3233 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3234 time_benefit = 0;
3235 else
3236 time_benefit = base_time.to_int ()
3237 + devirtualization_time_bonus (node, known_csts, known_contexts,
3238 known_aggs)
3239 + hint_time_bonus (hints)
3240 + removable_params_cost + est_move_cost;
3242 gcc_checking_assert (size >=0);
3243 /* The inliner-heuristics based estimates may think that in certain
3244 contexts some functions do not have any size at all but we want
3245 all specializations to have at least a tiny cost, not least not to
3246 divide by zero. */
3247 if (size == 0)
3248 size = 1;
3250 val->local_time_benefit = time_benefit;
3251 val->local_size_cost = size;
3254 /* Iterate over known values of parameters of NODE and estimate the local
3255 effects in terms of time and size they have. */
3257 static void
3258 estimate_local_effects (struct cgraph_node *node)
3260 class ipa_node_params *info = IPA_NODE_REF (node);
3261 int i, count = ipa_get_param_count (info);
3262 vec<tree> known_csts;
3263 vec<ipa_polymorphic_call_context> known_contexts;
3264 vec<ipa_agg_value_set> known_aggs;
3265 bool always_const;
3266 int removable_params_cost;
3268 if (!count || !ipcp_versionable_function_p (node))
3269 return;
3271 if (dump_file && (dump_flags & TDF_DETAILS))
3272 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
3274 always_const = gather_context_independent_values (info, &known_csts,
3275 &known_contexts, &known_aggs,
3276 &removable_params_cost);
3277 int devirt_bonus = devirtualization_time_bonus (node, known_csts,
3278 known_contexts, known_aggs);
3279 if (always_const || devirt_bonus
3280 || (removable_params_cost && node->can_change_signature))
3282 struct caller_statistics stats;
3283 ipa_hints hints;
3284 sreal time, base_time;
3285 int size;
3287 init_caller_stats (&stats);
3288 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3289 false);
3290 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
3291 known_aggs, &size, &time,
3292 &base_time, &hints);
3293 time -= devirt_bonus;
3294 time -= hint_time_bonus (hints);
3295 time -= removable_params_cost;
3296 size -= stats.n_calls * removable_params_cost;
3298 if (dump_file)
3299 fprintf (dump_file, " - context independent values, size: %i, "
3300 "time_benefit: %f\n", size, (base_time - time).to_double ());
3302 if (size <= 0 || node->local)
3304 info->do_clone_for_all_contexts = true;
3306 if (dump_file)
3307 fprintf (dump_file, " Decided to specialize for all "
3308 "known contexts, code not going to grow.\n");
3310 else if (good_cloning_opportunity_p (node,
3311 MIN ((base_time - time).to_int (),
3312 65536),
3313 stats.freq_sum, stats.count_sum,
3314 size))
3316 if (size + overall_size <= max_new_size)
3318 info->do_clone_for_all_contexts = true;
3319 overall_size += size;
3321 if (dump_file)
3322 fprintf (dump_file, " Decided to specialize for all "
3323 "known contexts, growth deemed beneficial.\n");
3325 else if (dump_file && (dump_flags & TDF_DETAILS))
3326 fprintf (dump_file, " Not cloning for all contexts because "
3327 "max_new_size would be reached with %li.\n",
3328 size + overall_size);
3330 else if (dump_file && (dump_flags & TDF_DETAILS))
3331 fprintf (dump_file, " Not cloning for all contexts because "
3332 "!good_cloning_opportunity_p.\n");
3336 for (i = 0; i < count; i++)
3338 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3339 ipcp_lattice<tree> *lat = &plats->itself;
3340 ipcp_value<tree> *val;
3342 if (lat->bottom
3343 || !lat->values
3344 || known_csts[i])
3345 continue;
3347 for (val = lat->values; val; val = val->next)
3349 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3350 known_csts[i] = val->value;
3352 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
3353 perform_estimation_of_a_value (node, known_csts, known_contexts,
3354 known_aggs,
3355 removable_params_cost, emc, val);
3357 if (dump_file && (dump_flags & TDF_DETAILS))
3359 fprintf (dump_file, " - estimates for value ");
3360 print_ipcp_constant_value (dump_file, val->value);
3361 fprintf (dump_file, " for ");
3362 ipa_dump_param (dump_file, info, i);
3363 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
3364 val->local_time_benefit, val->local_size_cost);
3367 known_csts[i] = NULL_TREE;
3370 for (i = 0; i < count; i++)
3372 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3374 if (!plats->virt_call)
3375 continue;
3377 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3378 ipcp_value<ipa_polymorphic_call_context> *val;
3380 if (ctxlat->bottom
3381 || !ctxlat->values
3382 || !known_contexts[i].useless_p ())
3383 continue;
3385 for (val = ctxlat->values; val; val = val->next)
3387 known_contexts[i] = val->value;
3388 perform_estimation_of_a_value (node, known_csts, known_contexts,
3389 known_aggs,
3390 removable_params_cost, 0, val);
3392 if (dump_file && (dump_flags & TDF_DETAILS))
3394 fprintf (dump_file, " - estimates for polymorphic context ");
3395 print_ipcp_constant_value (dump_file, val->value);
3396 fprintf (dump_file, " for ");
3397 ipa_dump_param (dump_file, info, i);
3398 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
3399 val->local_time_benefit, val->local_size_cost);
3402 known_contexts[i] = ipa_polymorphic_call_context ();
3405 for (i = 0; i < count; i++)
3407 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3408 struct ipa_agg_value_set *agg;
3409 struct ipcp_agg_lattice *aglat;
3411 if (plats->aggs_bottom || !plats->aggs)
3412 continue;
3414 agg = &known_aggs[i];
3415 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3417 ipcp_value<tree> *val;
3418 if (aglat->bottom || !aglat->values
3419 /* If the following is true, the one value is in known_aggs. */
3420 || (!plats->aggs_contain_variable
3421 && aglat->is_single_const ()))
3422 continue;
3424 for (val = aglat->values; val; val = val->next)
3426 struct ipa_agg_value item;
3428 item.offset = aglat->offset;
3429 item.value = val->value;
3430 agg->items.safe_push (item);
3432 perform_estimation_of_a_value (node, known_csts, known_contexts,
3433 known_aggs,
3434 removable_params_cost, 0, val);
3436 if (dump_file && (dump_flags & TDF_DETAILS))
3438 fprintf (dump_file, " - estimates for value ");
3439 print_ipcp_constant_value (dump_file, val->value);
3440 fprintf (dump_file, " for ");
3441 ipa_dump_param (dump_file, info, i);
3442 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3443 "]: time_benefit: %i, size: %i\n",
3444 plats->aggs_by_ref ? "ref " : "",
3445 aglat->offset,
3446 val->local_time_benefit, val->local_size_cost);
3449 agg->items.pop ();
3454 known_csts.release ();
3455 known_contexts.release ();
3456 ipa_release_agg_values (known_aggs);
3460 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3461 topological sort of values. */
3463 template <typename valtype>
3464 void
3465 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
3467 ipcp_value_source<valtype> *src;
3469 if (cur_val->dfs)
3470 return;
3472 dfs_counter++;
3473 cur_val->dfs = dfs_counter;
3474 cur_val->low_link = dfs_counter;
3476 cur_val->topo_next = stack;
3477 stack = cur_val;
3478 cur_val->on_stack = true;
3480 for (src = cur_val->sources; src; src = src->next)
3481 if (src->val)
3483 if (src->val->dfs == 0)
3485 add_val (src->val);
3486 if (src->val->low_link < cur_val->low_link)
3487 cur_val->low_link = src->val->low_link;
3489 else if (src->val->on_stack
3490 && src->val->dfs < cur_val->low_link)
3491 cur_val->low_link = src->val->dfs;
3494 if (cur_val->dfs == cur_val->low_link)
3496 ipcp_value<valtype> *v, *scc_list = NULL;
3500 v = stack;
3501 stack = v->topo_next;
3502 v->on_stack = false;
3504 v->scc_next = scc_list;
3505 scc_list = v;
3507 while (v != cur_val);
3509 cur_val->topo_next = values_topo;
3510 values_topo = cur_val;
3514 /* Add all values in lattices associated with NODE to the topological sort if
3515 they are not there yet. */
3517 static void
3518 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
3520 class ipa_node_params *info = IPA_NODE_REF (node);
3521 int i, count = ipa_get_param_count (info);
3523 for (i = 0; i < count; i++)
3525 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3526 ipcp_lattice<tree> *lat = &plats->itself;
3527 struct ipcp_agg_lattice *aglat;
3529 if (!lat->bottom)
3531 ipcp_value<tree> *val;
3532 for (val = lat->values; val; val = val->next)
3533 topo->constants.add_val (val);
3536 if (!plats->aggs_bottom)
3537 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3538 if (!aglat->bottom)
3540 ipcp_value<tree> *val;
3541 for (val = aglat->values; val; val = val->next)
3542 topo->constants.add_val (val);
3545 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3546 if (!ctxlat->bottom)
3548 ipcp_value<ipa_polymorphic_call_context> *ctxval;
3549 for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
3550 topo->contexts.add_val (ctxval);
3555 /* One pass of constants propagation along the call graph edges, from callers
3556 to callees (requires topological ordering in TOPO), iterate over strongly
3557 connected components. */
3559 static void
3560 propagate_constants_topo (class ipa_topo_info *topo)
3562 int i;
3564 for (i = topo->nnodes - 1; i >= 0; i--)
3566 unsigned j;
3567 struct cgraph_node *v, *node = topo->order[i];
3568 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
3570 /* First, iteratively propagate within the strongly connected component
3571 until all lattices stabilize. */
3572 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3573 if (v->has_gimple_body_p ())
3575 if (opt_for_fn (v->decl, flag_ipa_cp)
3576 && opt_for_fn (v->decl, optimize))
3577 push_node_to_stack (topo, v);
3578 /* When V is not optimized, we can not push it to stack, but
3579 still we need to set all its callees lattices to bottom. */
3580 else
3582 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
3583 propagate_constants_across_call (cs);
3587 v = pop_node_from_stack (topo);
3588 while (v)
3590 struct cgraph_edge *cs;
3592 for (cs = v->callees; cs; cs = cs->next_callee)
3593 if (ipa_edge_within_scc (cs))
3595 IPA_NODE_REF (v)->node_within_scc = true;
3596 if (propagate_constants_across_call (cs))
3597 push_node_to_stack (topo, cs->callee->function_symbol ());
3599 v = pop_node_from_stack (topo);
3602 /* Afterwards, propagate along edges leading out of the SCC, calculates
3603 the local effects of the discovered constants and all valid values to
3604 their topological sort. */
3605 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3606 if (v->has_gimple_body_p ()
3607 && opt_for_fn (v->decl, flag_ipa_cp)
3608 && opt_for_fn (v->decl, optimize))
3610 struct cgraph_edge *cs;
3612 estimate_local_effects (v);
3613 add_all_node_vals_to_toposort (v, topo);
3614 for (cs = v->callees; cs; cs = cs->next_callee)
3615 if (!ipa_edge_within_scc (cs))
3616 propagate_constants_across_call (cs);
3618 cycle_nodes.release ();
3623 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3624 the bigger one if otherwise. */
3626 static int
3627 safe_add (int a, int b)
3629 if (a > INT_MAX/2 || b > INT_MAX/2)
3630 return a > b ? a : b;
3631 else
3632 return a + b;
3636 /* Propagate the estimated effects of individual values along the topological
3637 from the dependent values to those they depend on. */
3639 template <typename valtype>
3640 void
3641 value_topo_info<valtype>::propagate_effects ()
3643 ipcp_value<valtype> *base;
3645 for (base = values_topo; base; base = base->topo_next)
3647 ipcp_value_source<valtype> *src;
3648 ipcp_value<valtype> *val;
3649 int time = 0, size = 0;
3651 for (val = base; val; val = val->scc_next)
3653 time = safe_add (time,
3654 val->local_time_benefit + val->prop_time_benefit);
3655 size = safe_add (size, val->local_size_cost + val->prop_size_cost);
3658 for (val = base; val; val = val->scc_next)
3659 for (src = val->sources; src; src = src->next)
3660 if (src->val
3661 && src->cs->maybe_hot_p ())
3663 src->val->prop_time_benefit = safe_add (time,
3664 src->val->prop_time_benefit);
3665 src->val->prop_size_cost = safe_add (size,
3666 src->val->prop_size_cost);
3672 /* Propagate constants, polymorphic contexts and their effects from the
3673 summaries interprocedurally. */
3675 static void
3676 ipcp_propagate_stage (class ipa_topo_info *topo)
3678 struct cgraph_node *node;
3680 if (dump_file)
3681 fprintf (dump_file, "\n Propagating constants:\n\n");
3683 max_count = profile_count::uninitialized ();
3685 FOR_EACH_DEFINED_FUNCTION (node)
3687 if (node->has_gimple_body_p ()
3688 && opt_for_fn (node->decl, flag_ipa_cp)
3689 && opt_for_fn (node->decl, optimize))
3691 class ipa_node_params *info = IPA_NODE_REF (node);
3692 determine_versionability (node, info);
3693 info->lattices = XCNEWVEC (class ipcp_param_lattices,
3694 ipa_get_param_count (info));
3695 initialize_node_lattices (node);
3697 ipa_size_summary *s = ipa_size_summaries->get (node);
3698 if (node->definition && !node->alias && s != NULL)
3699 overall_size += s->self_size;
3700 max_count = max_count.max (node->count.ipa ());
3703 max_new_size = overall_size;
3704 if (max_new_size < param_large_unit_insns)
3705 max_new_size = param_large_unit_insns;
3706 max_new_size += max_new_size * param_ipcp_unit_growth / 100 + 1;
3708 if (dump_file)
3709 fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
3710 overall_size, max_new_size);
3712 propagate_constants_topo (topo);
3713 if (flag_checking)
3714 ipcp_verify_propagated_values ();
3715 topo->constants.propagate_effects ();
3716 topo->contexts.propagate_effects ();
3718 if (dump_file)
3720 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
3721 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
3725 /* Discover newly direct outgoing edges from NODE which is a new clone with
3726 known KNOWN_CSTS and make them direct. */
3728 static void
3729 ipcp_discover_new_direct_edges (struct cgraph_node *node,
3730 vec<tree> known_csts,
3731 vec<ipa_polymorphic_call_context>
3732 known_contexts,
3733 struct ipa_agg_replacement_value *aggvals)
3735 struct cgraph_edge *ie, *next_ie;
3736 bool found = false;
3738 for (ie = node->indirect_calls; ie; ie = next_ie)
3740 tree target;
3741 bool speculative;
3743 next_ie = ie->next_callee;
3744 target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
3745 vNULL, aggvals, &speculative);
3746 if (target)
3748 bool agg_contents = ie->indirect_info->agg_contents;
3749 bool polymorphic = ie->indirect_info->polymorphic;
3750 int param_index = ie->indirect_info->param_index;
3751 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
3752 speculative);
3753 found = true;
3755 if (cs && !agg_contents && !polymorphic)
3757 class ipa_node_params *info = IPA_NODE_REF (node);
3758 int c = ipa_get_controlled_uses (info, param_index);
3759 if (c != IPA_UNDESCRIBED_USE)
3761 struct ipa_ref *to_del;
3763 c--;
3764 ipa_set_controlled_uses (info, param_index, c);
3765 if (dump_file && (dump_flags & TDF_DETAILS))
3766 fprintf (dump_file, " controlled uses count of param "
3767 "%i bumped down to %i\n", param_index, c);
3768 if (c == 0
3769 && (to_del = node->find_reference (cs->callee, NULL, 0)))
3771 if (dump_file && (dump_flags & TDF_DETAILS))
3772 fprintf (dump_file, " and even removing its "
3773 "cloning-created reference\n");
3774 to_del->remove_reference ();
3780 /* Turning calls to direct calls will improve overall summary. */
3781 if (found)
3782 ipa_update_overall_fn_summary (node);
3785 class edge_clone_summary;
3786 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
3788 /* Edge clone summary. */
3790 class edge_clone_summary
3792 public:
3793 /* Default constructor. */
3794 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
3796 /* Default destructor. */
3797 ~edge_clone_summary ()
3799 if (prev_clone)
3800 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
3801 if (next_clone)
3802 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
3805 cgraph_edge *prev_clone;
3806 cgraph_edge *next_clone;
3809 class edge_clone_summary_t:
3810 public call_summary <edge_clone_summary *>
3812 public:
3813 edge_clone_summary_t (symbol_table *symtab):
3814 call_summary <edge_clone_summary *> (symtab)
3816 m_initialize_when_cloning = true;
3819 virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
3820 edge_clone_summary *src_data,
3821 edge_clone_summary *dst_data);
3824 /* Edge duplication hook. */
3826 void
3827 edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
3828 edge_clone_summary *src_data,
3829 edge_clone_summary *dst_data)
3831 if (src_data->next_clone)
3832 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
3833 dst_data->prev_clone = src_edge;
3834 dst_data->next_clone = src_data->next_clone;
3835 src_data->next_clone = dst_edge;
3838 /* Return true is NODE is DEST or its clone for all contexts. */
3840 static bool
3841 same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
3843 if (node == dest)
3844 return true;
3846 class ipa_node_params *info = IPA_NODE_REF (node);
3847 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
3850 /* Return true if edge CS does bring about the value described by SRC to
3851 DEST_VAL of node DEST or its clone for all contexts. */
3853 static bool
3854 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
3855 cgraph_node *dest, ipcp_value<tree> *dest_val)
3857 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3858 enum availability availability;
3859 cgraph_node *real_dest = cs->callee->function_symbol (&availability);
3861 if (availability <= AVAIL_INTERPOSABLE
3862 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
3863 || caller_info->node_dead)
3864 return false;
3866 if (!src->val)
3867 return true;
3869 if (caller_info->ipcp_orig_node)
3871 tree t;
3872 if (src->offset == -1)
3873 t = caller_info->known_csts[src->index];
3874 else
3875 t = get_clone_agg_value (cs->caller, src->offset, src->index);
3876 return (t != NULL_TREE
3877 && values_equal_for_ipcp_p (src->val->value, t));
3879 else
3881 /* At the moment we do not propagate over arithmetic jump functions in
3882 SCCs, so it is safe to detect self-feeding recursive calls in this
3883 way. */
3884 if (src->val == dest_val)
3885 return true;
3887 struct ipcp_agg_lattice *aglat;
3888 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3889 src->index);
3890 if (src->offset == -1)
3891 return (plats->itself.is_single_const ()
3892 && values_equal_for_ipcp_p (src->val->value,
3893 plats->itself.values->value));
3894 else
3896 if (plats->aggs_bottom || plats->aggs_contain_variable)
3897 return false;
3898 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3899 if (aglat->offset == src->offset)
3900 return (aglat->is_single_const ()
3901 && values_equal_for_ipcp_p (src->val->value,
3902 aglat->values->value));
3904 return false;
3908 /* Return true if edge CS does bring about the value described by SRC to
3909 DST_VAL of node DEST or its clone for all contexts. */
3911 static bool
3912 cgraph_edge_brings_value_p (cgraph_edge *cs,
3913 ipcp_value_source<ipa_polymorphic_call_context> *src,
3914 cgraph_node *dest,
3915 ipcp_value<ipa_polymorphic_call_context> *)
3917 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3918 enum availability avail;
3919 cgraph_node *real_dest = cs->callee->function_symbol (&avail);
3921 if (avail <= AVAIL_INTERPOSABLE
3922 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
3923 || caller_info->node_dead)
3924 return false;
3925 if (!src->val)
3926 return true;
3928 if (caller_info->ipcp_orig_node)
3929 return (caller_info->known_contexts.length () > (unsigned) src->index)
3930 && values_equal_for_ipcp_p (src->val->value,
3931 caller_info->known_contexts[src->index]);
3933 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3934 src->index);
3935 return plats->ctxlat.is_single_const ()
3936 && values_equal_for_ipcp_p (src->val->value,
3937 plats->ctxlat.values->value);
3940 /* Get the next clone in the linked list of clones of an edge. */
3942 static inline struct cgraph_edge *
3943 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
3945 edge_clone_summary *s = edge_clone_summaries->get (cs);
3946 return s != NULL ? s->next_clone : NULL;
3949 /* Given VAL that is intended for DEST, iterate over all its sources and if any
3950 of them is viable and hot, return true. In that case, for those that still
3951 hold, add their edge frequency and their number into *FREQUENCY and
3952 *CALLER_COUNT respectively. */
3954 template <typename valtype>
3955 static bool
3956 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
3957 int *freq_sum,
3958 profile_count *count_sum, int *caller_count)
3960 ipcp_value_source<valtype> *src;
3961 int freq = 0, count = 0;
3962 profile_count cnt = profile_count::zero ();
3963 bool hot = false;
3964 bool non_self_recursive = false;
3966 for (src = val->sources; src; src = src->next)
3968 struct cgraph_edge *cs = src->cs;
3969 while (cs)
3971 if (cgraph_edge_brings_value_p (cs, src, dest, val))
3973 count++;
3974 freq += cs->frequency ();
3975 if (cs->count.ipa ().initialized_p ())
3976 cnt += cs->count.ipa ();
3977 hot |= cs->maybe_hot_p ();
3978 if (cs->caller != dest)
3979 non_self_recursive = true;
3981 cs = get_next_cgraph_edge_clone (cs);
3985 /* If the only edges bringing a value are self-recursive ones, do not bother
3986 evaluating it. */
3987 if (!non_self_recursive)
3988 return false;
3990 *freq_sum = freq;
3991 *count_sum = cnt;
3992 *caller_count = count;
3993 return hot;
3996 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
3997 is assumed their number is known and equal to CALLER_COUNT. */
3999 template <typename valtype>
4000 static vec<cgraph_edge *>
4001 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
4002 int caller_count)
4004 ipcp_value_source<valtype> *src;
4005 vec<cgraph_edge *> ret;
4007 ret.create (caller_count);
4008 for (src = val->sources; src; src = src->next)
4010 struct cgraph_edge *cs = src->cs;
4011 while (cs)
4013 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4014 ret.quick_push (cs);
4015 cs = get_next_cgraph_edge_clone (cs);
4019 return ret;
4022 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4023 Return it or NULL if for some reason it cannot be created. */
4025 static struct ipa_replace_map *
4026 get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
4028 struct ipa_replace_map *replace_map;
4031 replace_map = ggc_alloc<ipa_replace_map> ();
4032 if (dump_file)
4034 fprintf (dump_file, " replacing ");
4035 ipa_dump_param (dump_file, info, parm_num);
4037 fprintf (dump_file, " with const ");
4038 print_generic_expr (dump_file, value);
4039 fprintf (dump_file, "\n");
4041 replace_map->parm_num = parm_num;
4042 replace_map->new_tree = value;
4043 return replace_map;
4046 /* Dump new profiling counts */
4048 static void
4049 dump_profile_updates (struct cgraph_node *orig_node,
4050 struct cgraph_node *new_node)
4052 struct cgraph_edge *cs;
4054 fprintf (dump_file, " setting count of the specialized node to ");
4055 new_node->count.dump (dump_file);
4056 fprintf (dump_file, "\n");
4057 for (cs = new_node->callees; cs; cs = cs->next_callee)
4059 fprintf (dump_file, " edge to %s has count ",
4060 cs->callee->name ());
4061 cs->count.dump (dump_file);
4062 fprintf (dump_file, "\n");
4065 fprintf (dump_file, " setting count of the original node to ");
4066 orig_node->count.dump (dump_file);
4067 fprintf (dump_file, "\n");
4068 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4070 fprintf (dump_file, " edge to %s is left with ",
4071 cs->callee->name ());
4072 cs->count.dump (dump_file);
4073 fprintf (dump_file, "\n");
4077 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4078 their profile information to reflect this. */
4080 static void
4081 update_profiling_info (struct cgraph_node *orig_node,
4082 struct cgraph_node *new_node)
4084 struct cgraph_edge *cs;
4085 struct caller_statistics stats;
4086 profile_count new_sum, orig_sum;
4087 profile_count remainder, orig_node_count = orig_node->count;
4089 if (!(orig_node_count.ipa () > profile_count::zero ()))
4090 return;
4092 init_caller_stats (&stats);
4093 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4094 false);
4095 orig_sum = stats.count_sum;
4096 init_caller_stats (&stats);
4097 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4098 false);
4099 new_sum = stats.count_sum;
4101 if (orig_node_count < orig_sum + new_sum)
4103 if (dump_file)
4105 fprintf (dump_file, " Problem: node %s has too low count ",
4106 orig_node->dump_name ());
4107 orig_node_count.dump (dump_file);
4108 fprintf (dump_file, "while the sum of incoming count is ");
4109 (orig_sum + new_sum).dump (dump_file);
4110 fprintf (dump_file, "\n");
4113 orig_node_count = (orig_sum + new_sum).apply_scale (12, 10);
4114 if (dump_file)
4116 fprintf (dump_file, " proceeding by pretending it was ");
4117 orig_node_count.dump (dump_file);
4118 fprintf (dump_file, "\n");
4122 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
4123 - new_sum.ipa ());
4124 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
4125 orig_node->count = remainder;
4127 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_node_count);
4128 for (cs = new_node->callees; cs; cs = cs->next_callee)
4129 cs->count = cs->count.apply_scale (new_sum, orig_node_count);
4131 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
4132 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4133 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4135 if (dump_file)
4136 dump_profile_updates (orig_node, new_node);
4139 /* Update the respective profile of specialized NEW_NODE and the original
4140 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4141 have been redirected to the specialized version. */
4143 static void
4144 update_specialized_profile (struct cgraph_node *new_node,
4145 struct cgraph_node *orig_node,
4146 profile_count redirected_sum)
4148 struct cgraph_edge *cs;
4149 profile_count new_node_count, orig_node_count = orig_node->count;
4151 if (dump_file)
4153 fprintf (dump_file, " the sum of counts of redirected edges is ");
4154 redirected_sum.dump (dump_file);
4155 fprintf (dump_file, "\n");
4157 if (!(orig_node_count > profile_count::zero ()))
4158 return;
4160 gcc_assert (orig_node_count >= redirected_sum);
4162 new_node_count = new_node->count;
4163 new_node->count += redirected_sum;
4164 orig_node->count -= redirected_sum;
4166 for (cs = new_node->callees; cs; cs = cs->next_callee)
4167 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
4169 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4171 profile_count dec = cs->count.apply_scale (redirected_sum,
4172 orig_node_count);
4173 cs->count -= dec;
4176 if (dump_file)
4177 dump_profile_updates (orig_node, new_node);
4180 /* Return true if we would like to remove a parameter from NODE when cloning it
4181 with KNOWN_CSTS scalar constants. */
4183 static bool
4184 want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
4186 auto_vec<bool, 16> surviving;
4187 bool filled_vec = false;
4188 ipa_node_params *info = IPA_NODE_REF (node);
4189 int i, count = ipa_get_param_count (info);
4191 for (i = 0; i < count; i++)
4193 if (!known_csts[i] && ipa_is_param_used (info, i))
4194 continue;
4196 if (!filled_vec)
4198 if (!node->clone.param_adjustments)
4199 return true;
4200 node->clone.param_adjustments->get_surviving_params (&surviving);
4201 filled_vec = true;
4203 if (surviving.length() < (unsigned) i && surviving[i])
4204 return true;
4206 return false;
4209 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4210 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4211 redirect all edges in CALLERS to it. */
4213 static struct cgraph_node *
4214 create_specialized_node (struct cgraph_node *node,
4215 vec<tree> known_csts,
4216 vec<ipa_polymorphic_call_context> known_contexts,
4217 struct ipa_agg_replacement_value *aggvals,
4218 vec<cgraph_edge *> callers)
4220 class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
4221 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
4222 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
4223 struct ipa_agg_replacement_value *av;
4224 struct cgraph_node *new_node;
4225 int i, count = ipa_get_param_count (info);
4226 ipa_param_adjustments *old_adjustments = node->clone.param_adjustments;
4227 ipa_param_adjustments *new_adjustments;
4228 gcc_assert (!info->ipcp_orig_node);
4229 gcc_assert (node->can_change_signature
4230 || !old_adjustments);
4232 if (old_adjustments)
4234 /* At the moment all IPA optimizations should use the number of
4235 parameters of the prevailing decl as the m_always_copy_start.
4236 Handling any other value would complicate the code below, so for the
4237 time bing let's only assert it is so. */
4238 gcc_assert (old_adjustments->m_always_copy_start == count
4239 || old_adjustments->m_always_copy_start < 0);
4240 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
4241 for (i = 0; i < old_adj_count; i++)
4243 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
4244 if (!node->can_change_signature
4245 || old_adj->op != IPA_PARAM_OP_COPY
4246 || (!known_csts[old_adj->base_index]
4247 && ipa_is_param_used (info, old_adj->base_index)))
4249 ipa_adjusted_param new_adj = *old_adj;
4251 new_adj.prev_clone_adjustment = true;
4252 new_adj.prev_clone_index = i;
4253 vec_safe_push (new_params, new_adj);
4256 bool skip_return = old_adjustments->m_skip_return;
4257 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4258 ipa_param_adjustments (new_params, count,
4259 skip_return));
4261 else if (node->can_change_signature
4262 && want_remove_some_param_p (node, known_csts))
4264 ipa_adjusted_param adj;
4265 memset (&adj, 0, sizeof (adj));
4266 adj.op = IPA_PARAM_OP_COPY;
4267 for (i = 0; i < count; i++)
4268 if (!known_csts[i] && ipa_is_param_used (info, i))
4270 adj.base_index = i;
4271 adj.prev_clone_index = i;
4272 vec_safe_push (new_params, adj);
4274 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4275 ipa_param_adjustments (new_params, count, false));
4277 else
4278 new_adjustments = NULL;
4280 replace_trees = vec_safe_copy (node->clone.tree_map);
4281 for (i = 0; i < count; i++)
4283 tree t = known_csts[i];
4284 if (t)
4286 struct ipa_replace_map *replace_map;
4288 gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
4289 replace_map = get_replacement_map (info, t, i);
4290 if (replace_map)
4291 vec_safe_push (replace_trees, replace_map);
4294 auto_vec<cgraph_edge *, 2> self_recursive_calls;
4295 for (i = callers.length () - 1; i >= 0; i--)
4297 cgraph_edge *cs = callers[i];
4298 if (cs->caller == node)
4300 self_recursive_calls.safe_push (cs);
4301 callers.unordered_remove (i);
4305 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
4306 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4307 node->decl)));
4308 new_node = node->create_virtual_clone (callers, replace_trees,
4309 new_adjustments, "constprop",
4310 suffix_counter);
4311 suffix_counter++;
4313 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
4314 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
4316 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
4317 /* Cloned edges can disappear during cloning as speculation can be
4318 resolved, check that we have one and that it comes from the last
4319 cloning. */
4320 if (cs && cs->caller == new_node)
4321 cs->redirect_callee_duplicating_thunks (new_node);
4322 /* Any future code that would make more than one clone of an outgoing
4323 edge would confuse this mechanism, so let's check that does not
4324 happen. */
4325 gcc_checking_assert (!cs
4326 || !get_next_cgraph_edge_clone (cs)
4327 || get_next_cgraph_edge_clone (cs)->caller != new_node);
4329 if (have_self_recursive_calls)
4330 new_node->expand_all_artificial_thunks ();
4332 ipa_set_node_agg_value_chain (new_node, aggvals);
4333 for (av = aggvals; av; av = av->next)
4334 new_node->maybe_create_reference (av->value, NULL);
4336 if (dump_file && (dump_flags & TDF_DETAILS))
4338 fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ());
4339 if (known_contexts.exists ())
4341 for (i = 0; i < count; i++)
4342 if (!known_contexts[i].useless_p ())
4344 fprintf (dump_file, " known ctx %i is ", i);
4345 known_contexts[i].dump (dump_file);
4348 if (aggvals)
4349 ipa_dump_agg_replacement_values (dump_file, aggvals);
4351 ipa_check_create_node_params ();
4352 update_profiling_info (node, new_node);
4353 new_info = IPA_NODE_REF (new_node);
4354 new_info->ipcp_orig_node = node;
4355 new_node->ipcp_clone = true;
4356 new_info->known_csts = known_csts;
4357 new_info->known_contexts = known_contexts;
4359 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
4361 callers.release ();
4362 return new_node;
4365 /* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
4366 simple no-operation pass-through function to itself. */
4368 static bool
4369 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i)
4371 enum availability availability;
4372 if (cs->caller == cs->callee->function_symbol (&availability)
4373 && availability > AVAIL_INTERPOSABLE
4374 && jfunc->type == IPA_JF_PASS_THROUGH
4375 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR
4376 && ipa_get_jf_pass_through_formal_id (jfunc) == i)
4377 return true;
4378 return false;
4381 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
4382 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
4384 static void
4385 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
4386 vec<tree> known_csts,
4387 vec<cgraph_edge *> callers)
4389 class ipa_node_params *info = IPA_NODE_REF (node);
4390 int i, count = ipa_get_param_count (info);
4392 for (i = 0; i < count; i++)
4394 struct cgraph_edge *cs;
4395 tree newval = NULL_TREE;
4396 int j;
4397 bool first = true;
4398 tree type = ipa_get_type (info, i);
4400 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
4401 continue;
4403 FOR_EACH_VEC_ELT (callers, j, cs)
4405 struct ipa_jump_func *jump_func;
4406 tree t;
4408 if (IPA_NODE_REF (cs->caller)->node_dead)
4409 continue;
4411 if (!IPA_EDGE_REF (cs)
4412 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
4413 || (i == 0
4414 && call_passes_through_thunk_p (cs)))
4416 newval = NULL_TREE;
4417 break;
4419 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
4420 if (self_recursive_pass_through_p (cs, jump_func, i))
4421 continue;
4423 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func, type);
4424 if (!t
4425 || (newval
4426 && !values_equal_for_ipcp_p (t, newval))
4427 || (!first && !newval))
4429 newval = NULL_TREE;
4430 break;
4432 else
4433 newval = t;
4434 first = false;
4437 if (newval)
4439 if (dump_file && (dump_flags & TDF_DETAILS))
4441 fprintf (dump_file, " adding an extra known scalar value ");
4442 print_ipcp_constant_value (dump_file, newval);
4443 fprintf (dump_file, " for ");
4444 ipa_dump_param (dump_file, info, i);
4445 fprintf (dump_file, "\n");
4448 known_csts[i] = newval;
4453 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4454 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4455 CALLERS. */
4457 static void
4458 find_more_contexts_for_caller_subset (cgraph_node *node,
4459 vec<ipa_polymorphic_call_context>
4460 *known_contexts,
4461 vec<cgraph_edge *> callers)
4463 ipa_node_params *info = IPA_NODE_REF (node);
4464 int i, count = ipa_get_param_count (info);
4466 for (i = 0; i < count; i++)
4468 cgraph_edge *cs;
4470 if (ipa_get_poly_ctx_lat (info, i)->bottom
4471 || (known_contexts->exists ()
4472 && !(*known_contexts)[i].useless_p ()))
4473 continue;
4475 ipa_polymorphic_call_context newval;
4476 bool first = true;
4477 int j;
4479 FOR_EACH_VEC_ELT (callers, j, cs)
4481 if (!IPA_EDGE_REF (cs)
4482 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
4483 return;
4484 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
4486 ipa_polymorphic_call_context ctx;
4487 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
4488 jfunc);
4489 if (first)
4491 newval = ctx;
4492 first = false;
4494 else
4495 newval.meet_with (ctx);
4496 if (newval.useless_p ())
4497 break;
4500 if (!newval.useless_p ())
4502 if (dump_file && (dump_flags & TDF_DETAILS))
4504 fprintf (dump_file, " adding an extra known polymorphic "
4505 "context ");
4506 print_ipcp_constant_value (dump_file, newval);
4507 fprintf (dump_file, " for ");
4508 ipa_dump_param (dump_file, info, i);
4509 fprintf (dump_file, "\n");
4512 if (!known_contexts->exists ())
4513 known_contexts->safe_grow_cleared (ipa_get_param_count (info));
4514 (*known_contexts)[i] = newval;
4520 /* Go through PLATS and create a vector of values consisting of values and
4521 offsets (minus OFFSET) of lattices that contain only a single value. */
4523 static vec<ipa_agg_value>
4524 copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
4526 vec<ipa_agg_value> res = vNULL;
4528 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4529 return vNULL;
4531 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
4532 if (aglat->is_single_const ())
4534 struct ipa_agg_value ti;
4535 ti.offset = aglat->offset - offset;
4536 ti.value = aglat->values->value;
4537 res.safe_push (ti);
4539 return res;
4542 /* Intersect all values in INTER with single value lattices in PLATS (while
4543 subtracting OFFSET). */
4545 static void
4546 intersect_with_plats (class ipcp_param_lattices *plats,
4547 vec<ipa_agg_value> *inter,
4548 HOST_WIDE_INT offset)
4550 struct ipcp_agg_lattice *aglat;
4551 struct ipa_agg_value *item;
4552 int k;
4554 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4556 inter->release ();
4557 return;
4560 aglat = plats->aggs;
4561 FOR_EACH_VEC_ELT (*inter, k, item)
4563 bool found = false;
4564 if (!item->value)
4565 continue;
4566 while (aglat)
4568 if (aglat->offset - offset > item->offset)
4569 break;
4570 if (aglat->offset - offset == item->offset)
4572 gcc_checking_assert (item->value);
4573 if (aglat->is_single_const ()
4574 && values_equal_for_ipcp_p (item->value,
4575 aglat->values->value))
4576 found = true;
4577 break;
4579 aglat = aglat->next;
4581 if (!found)
4582 item->value = NULL_TREE;
4586 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4587 vector result while subtracting OFFSET from the individual value offsets. */
4589 static vec<ipa_agg_value>
4590 agg_replacements_to_vector (struct cgraph_node *node, int index,
4591 HOST_WIDE_INT offset)
4593 struct ipa_agg_replacement_value *av;
4594 vec<ipa_agg_value> res = vNULL;
4596 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
4597 if (av->index == index
4598 && (av->offset - offset) >= 0)
4600 struct ipa_agg_value item;
4601 gcc_checking_assert (av->value);
4602 item.offset = av->offset - offset;
4603 item.value = av->value;
4604 res.safe_push (item);
4607 return res;
4610 /* Intersect all values in INTER with those that we have already scheduled to
4611 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4612 (while subtracting OFFSET). */
4614 static void
4615 intersect_with_agg_replacements (struct cgraph_node *node, int index,
4616 vec<ipa_agg_value> *inter,
4617 HOST_WIDE_INT offset)
4619 struct ipa_agg_replacement_value *srcvals;
4620 struct ipa_agg_value *item;
4621 int i;
4623 srcvals = ipa_get_agg_replacements_for_node (node);
4624 if (!srcvals)
4626 inter->release ();
4627 return;
4630 FOR_EACH_VEC_ELT (*inter, i, item)
4632 struct ipa_agg_replacement_value *av;
4633 bool found = false;
4634 if (!item->value)
4635 continue;
4636 for (av = srcvals; av; av = av->next)
4638 gcc_checking_assert (av->value);
4639 if (av->index == index
4640 && av->offset - offset == item->offset)
4642 if (values_equal_for_ipcp_p (item->value, av->value))
4643 found = true;
4644 break;
4647 if (!found)
4648 item->value = NULL_TREE;
4652 /* Intersect values in INTER with aggregate values that come along edge CS to
4653 parameter number INDEX and return it. If INTER does not actually exist yet,
4654 copy all incoming values to it. If we determine we ended up with no values
4655 whatsoever, return a released vector. */
4657 static vec<ipa_agg_value>
4658 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
4659 vec<ipa_agg_value> inter)
4661 struct ipa_jump_func *jfunc;
4662 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
4663 if (jfunc->type == IPA_JF_PASS_THROUGH
4664 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4666 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4667 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
4669 if (caller_info->ipcp_orig_node)
4671 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
4672 class ipcp_param_lattices *orig_plats;
4673 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
4674 src_idx);
4675 if (agg_pass_through_permissible_p (orig_plats, jfunc))
4677 if (!inter.exists ())
4678 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
4679 else
4680 intersect_with_agg_replacements (cs->caller, src_idx,
4681 &inter, 0);
4683 else
4685 inter.release ();
4686 return vNULL;
4689 else
4691 class ipcp_param_lattices *src_plats;
4692 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
4693 if (agg_pass_through_permissible_p (src_plats, jfunc))
4695 /* Currently we do not produce clobber aggregate jump
4696 functions, adjust when we do. */
4697 gcc_checking_assert (!jfunc->agg.items);
4698 if (!inter.exists ())
4699 inter = copy_plats_to_inter (src_plats, 0);
4700 else
4701 intersect_with_plats (src_plats, &inter, 0);
4703 else
4705 inter.release ();
4706 return vNULL;
4710 else if (jfunc->type == IPA_JF_ANCESTOR
4711 && ipa_get_jf_ancestor_agg_preserved (jfunc))
4713 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4714 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
4715 class ipcp_param_lattices *src_plats;
4716 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
4718 if (caller_info->ipcp_orig_node)
4720 if (!inter.exists ())
4721 inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
4722 else
4723 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
4724 delta);
4726 else
4728 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
4729 /* Currently we do not produce clobber aggregate jump
4730 functions, adjust when we do. */
4731 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
4732 if (!inter.exists ())
4733 inter = copy_plats_to_inter (src_plats, delta);
4734 else
4735 intersect_with_plats (src_plats, &inter, delta);
4738 else if (jfunc->agg.items)
4740 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4741 struct ipa_agg_value *item;
4742 int k;
4744 if (!inter.exists ())
4745 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
4747 struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
4748 tree value = ipa_agg_value_from_node (caller_info, cs->caller,
4749 agg_item);
4750 if (value)
4752 struct ipa_agg_value agg_value;
4754 agg_value.offset = agg_item->offset;
4755 agg_value.value = value;
4757 inter.safe_push (agg_value);
4760 else
4761 FOR_EACH_VEC_ELT (inter, k, item)
4763 int l = 0;
4764 bool found = false;
4766 if (!item->value)
4767 continue;
4769 while ((unsigned) l < jfunc->agg.items->length ())
4771 struct ipa_agg_jf_item *ti;
4772 ti = &(*jfunc->agg.items)[l];
4773 if (ti->offset > item->offset)
4774 break;
4775 if (ti->offset == item->offset)
4777 tree value = ipa_agg_value_from_node (caller_info,
4778 cs->caller, ti);
4779 if (value
4780 && values_equal_for_ipcp_p (item->value, value))
4781 found = true;
4782 break;
4784 l++;
4786 if (!found)
4787 item->value = NULL;
4790 else
4792 inter.release ();
4793 return vNULL;
4795 return inter;
4798 /* Look at edges in CALLERS and collect all known aggregate values that arrive
4799 from all of them. */
4801 static struct ipa_agg_replacement_value *
4802 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
4803 vec<cgraph_edge *> callers)
4805 class ipa_node_params *dest_info = IPA_NODE_REF (node);
4806 struct ipa_agg_replacement_value *res;
4807 struct ipa_agg_replacement_value **tail = &res;
4808 struct cgraph_edge *cs;
4809 int i, j, count = ipa_get_param_count (dest_info);
4811 FOR_EACH_VEC_ELT (callers, j, cs)
4813 if (!IPA_EDGE_REF (cs))
4815 count = 0;
4816 break;
4818 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
4819 if (c < count)
4820 count = c;
4823 for (i = 0; i < count; i++)
4825 struct cgraph_edge *cs;
4826 vec<ipa_agg_value> inter = vNULL;
4827 struct ipa_agg_value *item;
4828 class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
4829 int j;
4831 /* Among other things, the following check should deal with all by_ref
4832 mismatches. */
4833 if (plats->aggs_bottom)
4834 continue;
4836 FOR_EACH_VEC_ELT (callers, j, cs)
4838 struct ipa_jump_func *jfunc
4839 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
4840 if (self_recursive_pass_through_p (cs, jfunc, i)
4841 && (!plats->aggs_by_ref
4842 || ipa_get_jf_pass_through_agg_preserved (jfunc)))
4843 continue;
4844 inter = intersect_aggregates_with_edge (cs, i, inter);
4846 if (!inter.exists ())
4847 goto next_param;
4850 FOR_EACH_VEC_ELT (inter, j, item)
4852 struct ipa_agg_replacement_value *v;
4854 if (!item->value)
4855 continue;
4857 v = ggc_alloc<ipa_agg_replacement_value> ();
4858 v->index = i;
4859 v->offset = item->offset;
4860 v->value = item->value;
4861 v->by_ref = plats->aggs_by_ref;
4862 *tail = v;
4863 tail = &v->next;
4866 next_param:
4867 if (inter.exists ())
4868 inter.release ();
4870 *tail = NULL;
4871 return res;
4874 /* Determine whether CS also brings all scalar values that the NODE is
4875 specialized for. */
4877 static bool
4878 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
4879 struct cgraph_node *node)
4881 class ipa_node_params *dest_info = IPA_NODE_REF (node);
4882 int count = ipa_get_param_count (dest_info);
4883 class ipa_node_params *caller_info;
4884 class ipa_edge_args *args;
4885 int i;
4887 caller_info = IPA_NODE_REF (cs->caller);
4888 args = IPA_EDGE_REF (cs);
4889 for (i = 0; i < count; i++)
4891 struct ipa_jump_func *jump_func;
4892 tree val, t;
4894 val = dest_info->known_csts[i];
4895 if (!val)
4896 continue;
4898 if (i >= ipa_get_cs_argument_count (args))
4899 return false;
4900 jump_func = ipa_get_ith_jump_func (args, i);
4901 t = ipa_value_from_jfunc (caller_info, jump_func,
4902 ipa_get_type (dest_info, i));
4903 if (!t || !values_equal_for_ipcp_p (val, t))
4904 return false;
4906 return true;
4909 /* Determine whether CS also brings all aggregate values that NODE is
4910 specialized for. */
4911 static bool
4912 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
4913 struct cgraph_node *node)
4915 class ipa_node_params *orig_node_info;
4916 struct ipa_agg_replacement_value *aggval;
4917 int i, ec, count;
4919 aggval = ipa_get_agg_replacements_for_node (node);
4920 if (!aggval)
4921 return true;
4923 count = ipa_get_param_count (IPA_NODE_REF (node));
4924 ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
4925 if (ec < count)
4926 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4927 if (aggval->index >= ec)
4928 return false;
4930 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
4932 for (i = 0; i < count; i++)
4934 static vec<ipa_agg_value> values = vNULL;
4935 class ipcp_param_lattices *plats;
4936 bool interesting = false;
4937 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4938 if (aggval->index == i)
4940 interesting = true;
4941 break;
4943 if (!interesting)
4944 continue;
4946 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
4947 if (plats->aggs_bottom)
4948 return false;
4950 values = intersect_aggregates_with_edge (cs, i, values);
4951 if (!values.exists ())
4952 return false;
4954 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4955 if (aggval->index == i)
4957 struct ipa_agg_value *item;
4958 int j;
4959 bool found = false;
4960 FOR_EACH_VEC_ELT (values, j, item)
4961 if (item->value
4962 && item->offset == av->offset
4963 && values_equal_for_ipcp_p (item->value, av->value))
4965 found = true;
4966 break;
4968 if (!found)
4970 values.release ();
4971 return false;
4975 return true;
4978 /* Given an original NODE and a VAL for which we have already created a
4979 specialized clone, look whether there are incoming edges that still lead
4980 into the old node but now also bring the requested value and also conform to
4981 all other criteria such that they can be redirected the special node.
4982 This function can therefore redirect the final edge in a SCC. */
4984 template <typename valtype>
4985 static void
4986 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
4988 ipcp_value_source<valtype> *src;
4989 profile_count redirected_sum = profile_count::zero ();
4991 for (src = val->sources; src; src = src->next)
4993 struct cgraph_edge *cs = src->cs;
4994 while (cs)
4996 if (cgraph_edge_brings_value_p (cs, src, node, val)
4997 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
4998 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
5000 if (dump_file)
5001 fprintf (dump_file, " - adding an extra caller %s of %s\n",
5002 cs->caller->dump_name (),
5003 val->spec_node->dump_name ());
5005 cs->redirect_callee_duplicating_thunks (val->spec_node);
5006 val->spec_node->expand_all_artificial_thunks ();
5007 if (cs->count.ipa ().initialized_p ())
5008 redirected_sum = redirected_sum + cs->count.ipa ();
5010 cs = get_next_cgraph_edge_clone (cs);
5014 if (redirected_sum.nonzero_p ())
5015 update_specialized_profile (val->spec_node, node, redirected_sum);
5018 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5020 static bool
5021 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
5023 ipa_polymorphic_call_context *ctx;
5024 int i;
5026 FOR_EACH_VEC_ELT (known_contexts, i, ctx)
5027 if (!ctx->useless_p ())
5028 return true;
5029 return false;
5032 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5034 static vec<ipa_polymorphic_call_context>
5035 copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
5037 if (known_contexts_useful_p (known_contexts))
5038 return known_contexts.copy ();
5039 else
5040 return vNULL;
5043 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX. If
5044 non-empty, replace KNOWN_CONTEXTS with its copy too. */
5046 static void
5047 modify_known_vectors_with_val (vec<tree> *known_csts,
5048 vec<ipa_polymorphic_call_context> *known_contexts,
5049 ipcp_value<tree> *val,
5050 int index)
5052 *known_csts = known_csts->copy ();
5053 *known_contexts = copy_useful_known_contexts (*known_contexts);
5054 (*known_csts)[index] = val->value;
5057 /* Replace KNOWN_CSTS with its copy. Also copy KNOWN_CONTEXTS and modify the
5058 copy according to VAL and INDEX. */
5060 static void
5061 modify_known_vectors_with_val (vec<tree> *known_csts,
5062 vec<ipa_polymorphic_call_context> *known_contexts,
5063 ipcp_value<ipa_polymorphic_call_context> *val,
5064 int index)
5066 *known_csts = known_csts->copy ();
5067 *known_contexts = known_contexts->copy ();
5068 (*known_contexts)[index] = val->value;
5071 /* Return true if OFFSET indicates this was not an aggregate value or there is
5072 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5073 AGGVALS list. */
5075 DEBUG_FUNCTION bool
5076 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
5077 int index, HOST_WIDE_INT offset, tree value)
5079 if (offset == -1)
5080 return true;
5082 while (aggvals)
5084 if (aggvals->index == index
5085 && aggvals->offset == offset
5086 && values_equal_for_ipcp_p (aggvals->value, value))
5087 return true;
5088 aggvals = aggvals->next;
5090 return false;
5093 /* Return true if offset is minus one because source of a polymorphic context
5094 cannot be an aggregate value. */
5096 DEBUG_FUNCTION bool
5097 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
5098 int , HOST_WIDE_INT offset,
5099 ipa_polymorphic_call_context)
5101 return offset == -1;
5104 /* Decide whether to create a special version of NODE for value VAL of parameter
5105 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
5106 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
5107 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
5109 template <typename valtype>
5110 static bool
5111 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
5112 ipcp_value<valtype> *val, vec<tree> known_csts,
5113 vec<ipa_polymorphic_call_context> known_contexts)
5115 struct ipa_agg_replacement_value *aggvals;
5116 int freq_sum, caller_count;
5117 profile_count count_sum;
5118 vec<cgraph_edge *> callers;
5120 if (val->spec_node)
5122 perhaps_add_new_callers (node, val);
5123 return false;
5125 else if (val->local_size_cost + overall_size > max_new_size)
5127 if (dump_file && (dump_flags & TDF_DETAILS))
5128 fprintf (dump_file, " Ignoring candidate value because "
5129 "max_new_size would be reached with %li.\n",
5130 val->local_size_cost + overall_size);
5131 return false;
5133 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
5134 &caller_count))
5135 return false;
5137 if (dump_file && (dump_flags & TDF_DETAILS))
5139 fprintf (dump_file, " - considering value ");
5140 print_ipcp_constant_value (dump_file, val->value);
5141 fprintf (dump_file, " for ");
5142 ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
5143 if (offset != -1)
5144 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
5145 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
5148 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
5149 freq_sum, count_sum,
5150 val->local_size_cost)
5151 && !good_cloning_opportunity_p (node,
5152 val->local_time_benefit
5153 + val->prop_time_benefit,
5154 freq_sum, count_sum,
5155 val->local_size_cost
5156 + val->prop_size_cost))
5157 return false;
5159 if (dump_file)
5160 fprintf (dump_file, " Creating a specialized node of %s.\n",
5161 node->dump_name ());
5163 callers = gather_edges_for_value (val, node, caller_count);
5164 if (offset == -1)
5165 modify_known_vectors_with_val (&known_csts, &known_contexts, val, index);
5166 else
5168 known_csts = known_csts.copy ();
5169 known_contexts = copy_useful_known_contexts (known_contexts);
5171 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5172 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5173 aggvals = find_aggregate_values_for_callers_subset (node, callers);
5174 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
5175 offset, val->value));
5176 val->spec_node = create_specialized_node (node, known_csts, known_contexts,
5177 aggvals, callers);
5178 overall_size += val->local_size_cost;
5180 /* TODO: If for some lattice there is only one other known value
5181 left, make a special node for it too. */
5183 return true;
5186 /* Decide whether and what specialized clones of NODE should be created. */
5188 static bool
5189 decide_whether_version_node (struct cgraph_node *node)
5191 class ipa_node_params *info = IPA_NODE_REF (node);
5192 int i, count = ipa_get_param_count (info);
5193 vec<tree> known_csts;
5194 vec<ipa_polymorphic_call_context> known_contexts;
5195 bool ret = false;
5197 if (count == 0)
5198 return false;
5200 if (dump_file && (dump_flags & TDF_DETAILS))
5201 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
5202 node->dump_name ());
5204 gather_context_independent_values (info, &known_csts, &known_contexts,
5205 NULL, NULL);
5207 for (i = 0; i < count;i++)
5209 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5210 ipcp_lattice<tree> *lat = &plats->itself;
5211 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
5213 if (!lat->bottom
5214 && !known_csts[i])
5216 ipcp_value<tree> *val;
5217 for (val = lat->values; val; val = val->next)
5218 ret |= decide_about_value (node, i, -1, val, known_csts,
5219 known_contexts);
5222 if (!plats->aggs_bottom)
5224 struct ipcp_agg_lattice *aglat;
5225 ipcp_value<tree> *val;
5226 for (aglat = plats->aggs; aglat; aglat = aglat->next)
5227 if (!aglat->bottom && aglat->values
5228 /* If the following is false, the one value is in
5229 known_aggs. */
5230 && (plats->aggs_contain_variable
5231 || !aglat->is_single_const ()))
5232 for (val = aglat->values; val; val = val->next)
5233 ret |= decide_about_value (node, i, aglat->offset, val,
5234 known_csts, known_contexts);
5237 if (!ctxlat->bottom
5238 && known_contexts[i].useless_p ())
5240 ipcp_value<ipa_polymorphic_call_context> *val;
5241 for (val = ctxlat->values; val; val = val->next)
5242 ret |= decide_about_value (node, i, -1, val, known_csts,
5243 known_contexts);
5246 info = IPA_NODE_REF (node);
5249 if (info->do_clone_for_all_contexts)
5251 struct cgraph_node *clone;
5252 vec<cgraph_edge *> callers;
5254 if (dump_file)
5255 fprintf (dump_file, " - Creating a specialized node of %s "
5256 "for all known contexts.\n", node->dump_name ());
5258 callers = node->collect_callers ();
5259 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5260 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5261 ipa_agg_replacement_value *aggvals
5262 = find_aggregate_values_for_callers_subset (node, callers);
5264 if (!known_contexts_useful_p (known_contexts))
5266 known_contexts.release ();
5267 known_contexts = vNULL;
5269 clone = create_specialized_node (node, known_csts, known_contexts,
5270 aggvals, callers);
5271 info = IPA_NODE_REF (node);
5272 info->do_clone_for_all_contexts = false;
5273 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
5274 ret = true;
5276 else
5278 known_csts.release ();
5279 known_contexts.release ();
5282 return ret;
5285 /* Transitively mark all callees of NODE within the same SCC as not dead. */
5287 static void
5288 spread_undeadness (struct cgraph_node *node)
5290 struct cgraph_edge *cs;
5292 for (cs = node->callees; cs; cs = cs->next_callee)
5293 if (ipa_edge_within_scc (cs))
5295 struct cgraph_node *callee;
5296 class ipa_node_params *info;
5298 callee = cs->callee->function_symbol (NULL);
5299 info = IPA_NODE_REF (callee);
5301 if (info && info->node_dead)
5303 info->node_dead = 0;
5304 spread_undeadness (callee);
5309 /* Return true if NODE has a caller from outside of its SCC that is not
5310 dead. Worker callback for cgraph_for_node_and_aliases. */
5312 static bool
5313 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
5314 void *data ATTRIBUTE_UNUSED)
5316 struct cgraph_edge *cs;
5318 for (cs = node->callers; cs; cs = cs->next_caller)
5319 if (cs->caller->thunk.thunk_p
5320 && cs->caller->call_for_symbol_thunks_and_aliases
5321 (has_undead_caller_from_outside_scc_p, NULL, true))
5322 return true;
5323 else if (!ipa_edge_within_scc (cs)
5324 && !IPA_NODE_REF (cs->caller)->node_dead)
5325 return true;
5326 return false;
5330 /* Identify nodes within the same SCC as NODE which are no longer needed
5331 because of new clones and will be removed as unreachable. */
5333 static void
5334 identify_dead_nodes (struct cgraph_node *node)
5336 struct cgraph_node *v;
5337 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5338 if (v->local
5339 && IPA_NODE_REF (v)
5340 && !v->call_for_symbol_thunks_and_aliases
5341 (has_undead_caller_from_outside_scc_p, NULL, true))
5342 IPA_NODE_REF (v)->node_dead = 1;
5344 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5345 if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
5346 spread_undeadness (v);
5348 if (dump_file && (dump_flags & TDF_DETAILS))
5350 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5351 if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
5352 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
5356 /* The decision stage. Iterate over the topological order of call graph nodes
5357 TOPO and make specialized clones if deemed beneficial. */
5359 static void
5360 ipcp_decision_stage (class ipa_topo_info *topo)
5362 int i;
5364 if (dump_file)
5365 fprintf (dump_file, "\nIPA decision stage:\n\n");
5367 for (i = topo->nnodes - 1; i >= 0; i--)
5369 struct cgraph_node *node = topo->order[i];
5370 bool change = false, iterate = true;
5372 while (iterate)
5374 struct cgraph_node *v;
5375 iterate = false;
5376 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5377 if (v->has_gimple_body_p ()
5378 && ipcp_versionable_function_p (v))
5379 iterate |= decide_whether_version_node (v);
5381 change |= iterate;
5383 if (change)
5384 identify_dead_nodes (node);
5388 /* Look up all the bits information that we have discovered and copy it over
5389 to the transformation summary. */
5391 static void
5392 ipcp_store_bits_results (void)
5394 cgraph_node *node;
5396 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5398 ipa_node_params *info = IPA_NODE_REF (node);
5399 bool dumped_sth = false;
5400 bool found_useful_result = false;
5402 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
5404 if (dump_file)
5405 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
5406 "; -fipa-bit-cp: disabled.\n",
5407 node->name ());
5408 continue;
5411 if (info->ipcp_orig_node)
5412 info = IPA_NODE_REF (info->ipcp_orig_node);
5414 unsigned count = ipa_get_param_count (info);
5415 for (unsigned i = 0; i < count; i++)
5417 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5418 if (plats->bits_lattice.constant_p ())
5420 found_useful_result = true;
5421 break;
5425 if (!found_useful_result)
5426 continue;
5428 ipcp_transformation_initialize ();
5429 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5430 vec_safe_reserve_exact (ts->bits, count);
5432 for (unsigned i = 0; i < count; i++)
5434 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5435 ipa_bits *jfbits;
5437 if (plats->bits_lattice.constant_p ())
5438 jfbits
5439 = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
5440 plats->bits_lattice.get_mask ());
5441 else
5442 jfbits = NULL;
5444 ts->bits->quick_push (jfbits);
5445 if (!dump_file || !jfbits)
5446 continue;
5447 if (!dumped_sth)
5449 fprintf (dump_file, "Propagated bits info for function %s:\n",
5450 node->dump_name ());
5451 dumped_sth = true;
5453 fprintf (dump_file, " param %i: value = ", i);
5454 print_hex (jfbits->value, dump_file);
5455 fprintf (dump_file, ", mask = ");
5456 print_hex (jfbits->mask, dump_file);
5457 fprintf (dump_file, "\n");
5462 /* Look up all VR information that we have discovered and copy it over
5463 to the transformation summary. */
5465 static void
5466 ipcp_store_vr_results (void)
5468 cgraph_node *node;
5470 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5472 ipa_node_params *info = IPA_NODE_REF (node);
5473 bool found_useful_result = false;
5475 if (!opt_for_fn (node->decl, flag_ipa_vrp))
5477 if (dump_file)
5478 fprintf (dump_file, "Not considering %s for VR discovery "
5479 "and propagate; -fipa-ipa-vrp: disabled.\n",
5480 node->name ());
5481 continue;
5484 if (info->ipcp_orig_node)
5485 info = IPA_NODE_REF (info->ipcp_orig_node);
5487 unsigned count = ipa_get_param_count (info);
5488 for (unsigned i = 0; i < count; i++)
5490 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5491 if (!plats->m_value_range.bottom_p ()
5492 && !plats->m_value_range.top_p ())
5494 found_useful_result = true;
5495 break;
5498 if (!found_useful_result)
5499 continue;
5501 ipcp_transformation_initialize ();
5502 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5503 vec_safe_reserve_exact (ts->m_vr, count);
5505 for (unsigned i = 0; i < count; i++)
5507 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5508 ipa_vr vr;
5510 if (!plats->m_value_range.bottom_p ()
5511 && !plats->m_value_range.top_p ())
5513 vr.known = true;
5514 vr.type = plats->m_value_range.m_vr.kind ();
5515 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
5516 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
5518 else
5520 vr.known = false;
5521 vr.type = VR_VARYING;
5522 vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
5524 ts->m_vr->quick_push (vr);
5529 /* The IPCP driver. */
5531 static unsigned int
5532 ipcp_driver (void)
5534 class ipa_topo_info topo;
5536 if (edge_clone_summaries == NULL)
5537 edge_clone_summaries = new edge_clone_summary_t (symtab);
5539 ipa_check_create_node_params ();
5540 ipa_check_create_edge_args ();
5541 clone_num_suffixes = new hash_map<const char *, unsigned>;
5543 if (dump_file)
5545 fprintf (dump_file, "\nIPA structures before propagation:\n");
5546 if (dump_flags & TDF_DETAILS)
5547 ipa_print_all_params (dump_file);
5548 ipa_print_all_jump_functions (dump_file);
5551 /* Topological sort. */
5552 build_toporder_info (&topo);
5553 /* Do the interprocedural propagation. */
5554 ipcp_propagate_stage (&topo);
5555 /* Decide what constant propagation and cloning should be performed. */
5556 ipcp_decision_stage (&topo);
5557 /* Store results of bits propagation. */
5558 ipcp_store_bits_results ();
5559 /* Store results of value range propagation. */
5560 ipcp_store_vr_results ();
5562 /* Free all IPCP structures. */
5563 delete clone_num_suffixes;
5564 free_toporder_info (&topo);
5565 delete edge_clone_summaries;
5566 edge_clone_summaries = NULL;
5567 ipa_free_all_structures_after_ipa_cp ();
5568 if (dump_file)
5569 fprintf (dump_file, "\nIPA constant propagation end\n");
5570 return 0;
5573 /* Initialization and computation of IPCP data structures. This is the initial
5574 intraprocedural analysis of functions, which gathers information to be
5575 propagated later on. */
5577 static void
5578 ipcp_generate_summary (void)
5580 struct cgraph_node *node;
5582 if (dump_file)
5583 fprintf (dump_file, "\nIPA constant propagation start:\n");
5584 ipa_register_cgraph_hooks ();
5586 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5587 ipa_analyze_node (node);
5590 /* Write ipcp summary for nodes in SET. */
5592 static void
5593 ipcp_write_summary (void)
5595 ipa_prop_write_jump_functions ();
5598 /* Read ipcp summary. */
5600 static void
5601 ipcp_read_summary (void)
5603 ipa_prop_read_jump_functions ();
5606 namespace {
5608 const pass_data pass_data_ipa_cp =
5610 IPA_PASS, /* type */
5611 "cp", /* name */
5612 OPTGROUP_NONE, /* optinfo_flags */
5613 TV_IPA_CONSTANT_PROP, /* tv_id */
5614 0, /* properties_required */
5615 0, /* properties_provided */
5616 0, /* properties_destroyed */
5617 0, /* todo_flags_start */
5618 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
5621 class pass_ipa_cp : public ipa_opt_pass_d
5623 public:
5624 pass_ipa_cp (gcc::context *ctxt)
5625 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
5626 ipcp_generate_summary, /* generate_summary */
5627 ipcp_write_summary, /* write_summary */
5628 ipcp_read_summary, /* read_summary */
5629 ipcp_write_transformation_summaries, /*
5630 write_optimization_summary */
5631 ipcp_read_transformation_summaries, /*
5632 read_optimization_summary */
5633 NULL, /* stmt_fixup */
5634 0, /* function_transform_todo_flags_start */
5635 ipcp_transform_function, /* function_transform */
5636 NULL) /* variable_transform */
5639 /* opt_pass methods: */
5640 virtual bool gate (function *)
5642 /* FIXME: We should remove the optimize check after we ensure we never run
5643 IPA passes when not optimizing. */
5644 return (flag_ipa_cp && optimize) || in_lto_p;
5647 virtual unsigned int execute (function *) { return ipcp_driver (); }
5649 }; // class pass_ipa_cp
5651 } // anon namespace
5653 ipa_opt_pass_d *
5654 make_pass_ipa_cp (gcc::context *ctxt)
5656 return new pass_ipa_cp (ctxt);
5659 /* Reset all state within ipa-cp.c so that we can rerun the compiler
5660 within the same process. For use by toplev::finalize. */
5662 void
5663 ipa_cp_c_finalize (void)
5665 max_count = profile_count::uninitialized ();
5666 overall_size = 0;
5667 max_new_size = 0;
5668 ipcp_free_transformation_sum ();