testsuite: localclass2 require LTO
[official-gcc.git] / gcc / ipa-cp.c
blobc3ee71e16e1d5f0235b3f6d938e38de26f1c89e2
1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
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"
126 #include "dbgcnt.h"
127 #include "symtab-clones.h"
129 template <typename valtype> class ipcp_value;
131 /* Describes a particular source for an IPA-CP value. */
133 template <typename valtype>
134 struct ipcp_value_source
136 public:
137 /* Aggregate offset of the source, negative if the source is scalar value of
138 the argument itself. */
139 HOST_WIDE_INT offset;
140 /* The incoming edge that brought the value. */
141 cgraph_edge *cs;
142 /* If the jump function that resulted into his value was a pass-through or an
143 ancestor, this is the ipcp_value of the caller from which the described
144 value has been derived. Otherwise it is NULL. */
145 ipcp_value<valtype> *val;
146 /* Next pointer in a linked list of sources of a value. */
147 ipcp_value_source *next;
148 /* If the jump function that resulted into his value was a pass-through or an
149 ancestor, this is the index of the parameter of the caller the jump
150 function references. */
151 int index;
154 /* Common ancestor for all ipcp_value instantiations. */
156 class ipcp_value_base
158 public:
159 /* Time benefit and that specializing the function for this value would bring
160 about in this function alone. */
161 sreal local_time_benefit;
162 /* Time benefit that specializing the function for this value can bring about
163 in it's callees. */
164 sreal prop_time_benefit;
165 /* Size cost that specializing the function for this value would bring about
166 in this function alone. */
167 int local_size_cost;
168 /* Size cost that specializing the function for this value can bring about in
169 it's callees. */
170 int prop_size_cost;
172 ipcp_value_base ()
173 : local_time_benefit (0), prop_time_benefit (0),
174 local_size_cost (0), prop_size_cost (0) {}
177 /* Describes one particular value stored in struct ipcp_lattice. */
179 template <typename valtype>
180 class ipcp_value : public ipcp_value_base
182 public:
183 /* The actual value for the given parameter. */
184 valtype value;
185 /* The list of sources from which this value originates. */
186 ipcp_value_source <valtype> *sources;
187 /* Next pointers in a linked list of all values in a lattice. */
188 ipcp_value *next;
189 /* Next pointers in a linked list of values in a strongly connected component
190 of values. */
191 ipcp_value *scc_next;
192 /* Next pointers in a linked list of SCCs of values sorted topologically
193 according their sources. */
194 ipcp_value *topo_next;
195 /* A specialized node created for this value, NULL if none has been (so far)
196 created. */
197 cgraph_node *spec_node;
198 /* Depth first search number and low link for topological sorting of
199 values. */
200 int dfs, low_link;
201 /* True if this value is currently on the topo-sort stack. */
202 bool on_stack;
204 ipcp_value()
205 : sources (0), next (0), scc_next (0), topo_next (0),
206 spec_node (0), dfs (0), low_link (0), on_stack (false) {}
208 void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
209 HOST_WIDE_INT offset);
212 /* Lattice describing potential values of a formal parameter of a function, or
213 a part of an aggregate. TOP is represented by a lattice with zero values
214 and with contains_variable and bottom flags cleared. BOTTOM is represented
215 by a lattice with the bottom flag set. In that case, values and
216 contains_variable flag should be disregarded. */
218 template <typename valtype>
219 struct ipcp_lattice
221 public:
222 /* The list of known values and types in this lattice. Note that values are
223 not deallocated if a lattice is set to bottom because there may be value
224 sources referencing them. */
225 ipcp_value<valtype> *values;
226 /* Number of known values and types in this lattice. */
227 int values_count;
228 /* The lattice contains a variable component (in addition to values). */
229 bool contains_variable;
230 /* The value of the lattice is bottom (i.e. variable and unusable for any
231 propagation). */
232 bool bottom;
234 inline bool is_single_const ();
235 inline bool set_to_bottom ();
236 inline bool set_contains_variable ();
237 bool add_value (valtype newval, cgraph_edge *cs,
238 ipcp_value<valtype> *src_val = NULL,
239 int src_idx = 0, HOST_WIDE_INT offset = -1,
240 ipcp_value<valtype> **val_p = NULL,
241 bool unlimited = false);
242 void print (FILE * f, bool dump_sources, bool dump_benefits);
245 /* Lattice of tree values with an offset to describe a part of an
246 aggregate. */
248 struct ipcp_agg_lattice : public ipcp_lattice<tree>
250 public:
251 /* Offset that is being described by this lattice. */
252 HOST_WIDE_INT offset;
253 /* Size so that we don't have to re-compute it every time we traverse the
254 list. Must correspond to TYPE_SIZE of all lat values. */
255 HOST_WIDE_INT size;
256 /* Next element of the linked list. */
257 struct ipcp_agg_lattice *next;
260 /* Lattice of known bits, only capable of holding one value.
261 Bitwise constant propagation propagates which bits of a
262 value are constant.
263 For eg:
264 int f(int x)
266 return some_op (x);
269 int f1(int y)
271 if (cond)
272 return f (y & 0xff);
273 else
274 return f (y & 0xf);
277 In the above case, the param 'x' will always have all
278 the bits (except the bits in lsb) set to 0.
279 Hence the mask of 'x' would be 0xff. The mask
280 reflects that the bits in lsb are unknown.
281 The actual propagated value is given by m_value & ~m_mask. */
283 class ipcp_bits_lattice
285 public:
286 bool bottom_p () { return m_lattice_val == IPA_BITS_VARYING; }
287 bool top_p () { return m_lattice_val == IPA_BITS_UNDEFINED; }
288 bool constant_p () { return m_lattice_val == IPA_BITS_CONSTANT; }
289 bool set_to_bottom ();
290 bool set_to_constant (widest_int, widest_int);
292 widest_int get_value () { return m_value; }
293 widest_int get_mask () { return m_mask; }
295 bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
296 enum tree_code, tree);
298 bool meet_with (widest_int, widest_int, unsigned);
300 void print (FILE *);
302 private:
303 enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
305 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
306 If a bit in mask is set to 0, then the corresponding bit in
307 value is known to be constant. */
308 widest_int m_value, m_mask;
310 bool meet_with_1 (widest_int, widest_int, unsigned);
311 void get_value_and_mask (tree, widest_int *, widest_int *);
314 /* Lattice of value ranges. */
316 class ipcp_vr_lattice
318 public:
319 value_range m_vr;
321 inline bool bottom_p () const;
322 inline bool top_p () const;
323 inline bool set_to_bottom ();
324 bool meet_with (const value_range *p_vr);
325 bool meet_with (const ipcp_vr_lattice &other);
326 void init () { gcc_assert (m_vr.undefined_p ()); }
327 void print (FILE * f);
329 private:
330 bool meet_with_1 (const value_range *other_vr);
333 /* Structure containing lattices for a parameter itself and for pieces of
334 aggregates that are passed in the parameter or by a reference in a parameter
335 plus some other useful flags. */
337 class ipcp_param_lattices
339 public:
340 /* Lattice describing the value of the parameter itself. */
341 ipcp_lattice<tree> itself;
342 /* Lattice describing the polymorphic contexts of a parameter. */
343 ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
344 /* Lattices describing aggregate parts. */
345 ipcp_agg_lattice *aggs;
346 /* Lattice describing known bits. */
347 ipcp_bits_lattice bits_lattice;
348 /* Lattice describing value range. */
349 ipcp_vr_lattice m_value_range;
350 /* Number of aggregate lattices */
351 int aggs_count;
352 /* True if aggregate data were passed by reference (as opposed to by
353 value). */
354 bool aggs_by_ref;
355 /* All aggregate lattices contain a variable component (in addition to
356 values). */
357 bool aggs_contain_variable;
358 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
359 for any propagation). */
360 bool aggs_bottom;
362 /* There is a virtual call based on this parameter. */
363 bool virt_call;
366 /* Allocation pools for values and their sources in ipa-cp. */
368 object_allocator<ipcp_value<tree> > ipcp_cst_values_pool
369 ("IPA-CP constant values");
371 object_allocator<ipcp_value<ipa_polymorphic_call_context> >
372 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
374 object_allocator<ipcp_value_source<tree> > ipcp_sources_pool
375 ("IPA-CP value sources");
377 object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
378 ("IPA_CP aggregate lattices");
380 /* Maximal count found in program. */
382 static profile_count max_count;
384 /* Original overall size of the program. */
386 static long overall_size, orig_overall_size;
388 /* Node name to unique clone suffix number map. */
389 static hash_map<const char *, unsigned> *clone_num_suffixes;
391 /* Return the param lattices structure corresponding to the Ith formal
392 parameter of the function described by INFO. */
393 static inline class ipcp_param_lattices *
394 ipa_get_parm_lattices (class ipa_node_params *info, int i)
396 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
397 gcc_checking_assert (!info->ipcp_orig_node);
398 gcc_checking_assert (info->lattices);
399 return &(info->lattices[i]);
402 /* Return the lattice corresponding to the scalar value of the Ith formal
403 parameter of the function described by INFO. */
404 static inline ipcp_lattice<tree> *
405 ipa_get_scalar_lat (class ipa_node_params *info, int i)
407 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
408 return &plats->itself;
411 /* Return the lattice corresponding to the scalar value of the Ith formal
412 parameter of the function described by INFO. */
413 static inline ipcp_lattice<ipa_polymorphic_call_context> *
414 ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
416 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
417 return &plats->ctxlat;
420 /* Return whether LAT is a lattice with a single constant and without an
421 undefined value. */
423 template <typename valtype>
424 inline bool
425 ipcp_lattice<valtype>::is_single_const ()
427 if (bottom || contains_variable || values_count != 1)
428 return false;
429 else
430 return true;
433 /* Print V which is extracted from a value in a lattice to F. */
435 static void
436 print_ipcp_constant_value (FILE * f, tree v)
438 if (TREE_CODE (v) == ADDR_EXPR
439 && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
441 fprintf (f, "& ");
442 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)));
444 else
445 print_generic_expr (f, v);
448 /* Print V which is extracted from a value in a lattice to F. */
450 static void
451 print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
453 v.dump(f, false);
456 /* Print a lattice LAT to F. */
458 template <typename valtype>
459 void
460 ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
462 ipcp_value<valtype> *val;
463 bool prev = false;
465 if (bottom)
467 fprintf (f, "BOTTOM\n");
468 return;
471 if (!values_count && !contains_variable)
473 fprintf (f, "TOP\n");
474 return;
477 if (contains_variable)
479 fprintf (f, "VARIABLE");
480 prev = true;
481 if (dump_benefits)
482 fprintf (f, "\n");
485 for (val = values; val; val = val->next)
487 if (dump_benefits && prev)
488 fprintf (f, " ");
489 else if (!dump_benefits && prev)
490 fprintf (f, ", ");
491 else
492 prev = true;
494 print_ipcp_constant_value (f, val->value);
496 if (dump_sources)
498 ipcp_value_source<valtype> *s;
500 fprintf (f, " [from:");
501 for (s = val->sources; s; s = s->next)
502 fprintf (f, " %i(%f)", s->cs->caller->order,
503 s->cs->sreal_frequency ().to_double ());
504 fprintf (f, "]");
507 if (dump_benefits)
508 fprintf (f, " [loc_time: %g, loc_size: %i, "
509 "prop_time: %g, prop_size: %i]\n",
510 val->local_time_benefit.to_double (), val->local_size_cost,
511 val->prop_time_benefit.to_double (), val->prop_size_cost);
513 if (!dump_benefits)
514 fprintf (f, "\n");
517 void
518 ipcp_bits_lattice::print (FILE *f)
520 if (top_p ())
521 fprintf (f, " Bits unknown (TOP)\n");
522 else if (bottom_p ())
523 fprintf (f, " Bits unusable (BOTTOM)\n");
524 else
526 fprintf (f, " Bits: value = "); print_hex (get_value (), f);
527 fprintf (f, ", mask = "); print_hex (get_mask (), f);
528 fprintf (f, "\n");
532 /* Print value range lattice to F. */
534 void
535 ipcp_vr_lattice::print (FILE * f)
537 dump_value_range (f, &m_vr);
540 /* Print all ipcp_lattices of all functions to F. */
542 static void
543 print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
545 struct cgraph_node *node;
546 int i, count;
548 fprintf (f, "\nLattices:\n");
549 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
551 class ipa_node_params *info;
553 info = IPA_NODE_REF (node);
554 /* Skip unoptimized functions and constprop clones since we don't make
555 lattices for them. */
556 if (!info || info->ipcp_orig_node)
557 continue;
558 fprintf (f, " Node: %s:\n", node->dump_name ());
559 count = ipa_get_param_count (info);
560 for (i = 0; i < count; i++)
562 struct ipcp_agg_lattice *aglat;
563 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
564 fprintf (f, " param [%d]: ", i);
565 plats->itself.print (f, dump_sources, dump_benefits);
566 fprintf (f, " ctxs: ");
567 plats->ctxlat.print (f, dump_sources, dump_benefits);
568 plats->bits_lattice.print (f);
569 fprintf (f, " ");
570 plats->m_value_range.print (f);
571 fprintf (f, "\n");
572 if (plats->virt_call)
573 fprintf (f, " virt_call flag set\n");
575 if (plats->aggs_bottom)
577 fprintf (f, " AGGS BOTTOM\n");
578 continue;
580 if (plats->aggs_contain_variable)
581 fprintf (f, " AGGS VARIABLE\n");
582 for (aglat = plats->aggs; aglat; aglat = aglat->next)
584 fprintf (f, " %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
585 plats->aggs_by_ref ? "ref " : "", aglat->offset);
586 aglat->print (f, dump_sources, dump_benefits);
592 /* Determine whether it is at all technically possible to create clones of NODE
593 and store this information in the ipa_node_params structure associated
594 with NODE. */
596 static void
597 determine_versionability (struct cgraph_node *node,
598 class ipa_node_params *info)
600 const char *reason = NULL;
602 /* There are a number of generic reasons functions cannot be versioned. We
603 also cannot remove parameters if there are type attributes such as fnspec
604 present. */
605 if (node->alias || node->thunk)
606 reason = "alias or thunk";
607 else if (!node->versionable)
608 reason = "not a tree_versionable_function";
609 else if (node->get_availability () <= AVAIL_INTERPOSABLE)
610 reason = "insufficient body availability";
611 else if (!opt_for_fn (node->decl, optimize)
612 || !opt_for_fn (node->decl, flag_ipa_cp))
613 reason = "non-optimized function";
614 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
616 /* Ideally we should clone the SIMD clones themselves and create
617 vector copies of them, so IPA-cp and SIMD clones can happily
618 coexist, but that may not be worth the effort. */
619 reason = "function has SIMD clones";
621 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)))
623 /* Ideally we should clone the target clones themselves and create
624 copies of them, so IPA-cp and target clones can happily
625 coexist, but that may not be worth the effort. */
626 reason = "function target_clones attribute";
628 /* Don't clone decls local to a comdat group; it breaks and for C++
629 decloned constructors, inlining is always better anyway. */
630 else if (node->comdat_local_p ())
631 reason = "comdat-local function";
632 else if (node->calls_comdat_local)
634 /* TODO: call is versionable if we make sure that all
635 callers are inside of a comdat group. */
636 reason = "calls comdat-local function";
639 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
640 work only when inlined. Cloning them may still lead to better code
641 because ipa-cp will not give up on cloning further. If the function is
642 external this however leads to wrong code because we may end up producing
643 offline copy of the function. */
644 if (DECL_EXTERNAL (node->decl))
645 for (cgraph_edge *edge = node->callees; !reason && edge;
646 edge = edge->next_callee)
647 if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
649 if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
650 reason = "external function which calls va_arg_pack";
651 if (DECL_FUNCTION_CODE (edge->callee->decl)
652 == BUILT_IN_VA_ARG_PACK_LEN)
653 reason = "external function which calls va_arg_pack_len";
656 if (reason && dump_file && !node->alias && !node->thunk)
657 fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
658 node->dump_name (), reason);
660 info->versionable = (reason == NULL);
663 /* Return true if it is at all technically possible to create clones of a
664 NODE. */
666 static bool
667 ipcp_versionable_function_p (struct cgraph_node *node)
669 return IPA_NODE_REF (node) && IPA_NODE_REF (node)->versionable;
672 /* Structure holding accumulated information about callers of a node. */
674 struct caller_statistics
676 profile_count count_sum;
677 sreal freq_sum;
678 int n_calls, n_hot_calls;
681 /* Initialize fields of STAT to zeroes. */
683 static inline void
684 init_caller_stats (struct caller_statistics *stats)
686 stats->count_sum = profile_count::zero ();
687 stats->n_calls = 0;
688 stats->n_hot_calls = 0;
689 stats->freq_sum = 0;
692 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
693 non-thunk incoming edges to NODE. */
695 static bool
696 gather_caller_stats (struct cgraph_node *node, void *data)
698 struct caller_statistics *stats = (struct caller_statistics *) data;
699 struct cgraph_edge *cs;
701 for (cs = node->callers; cs; cs = cs->next_caller)
702 if (!cs->caller->thunk)
704 if (cs->count.ipa ().initialized_p ())
705 stats->count_sum += cs->count.ipa ();
706 stats->freq_sum += cs->sreal_frequency ();
707 stats->n_calls++;
708 if (cs->maybe_hot_p ())
709 stats->n_hot_calls ++;
711 return false;
715 /* Return true if this NODE is viable candidate for cloning. */
717 static bool
718 ipcp_cloning_candidate_p (struct cgraph_node *node)
720 struct caller_statistics stats;
722 gcc_checking_assert (node->has_gimple_body_p ());
724 if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
726 if (dump_file)
727 fprintf (dump_file, "Not considering %s for cloning; "
728 "-fipa-cp-clone disabled.\n",
729 node->dump_name ());
730 return false;
733 if (node->optimize_for_size_p ())
735 if (dump_file)
736 fprintf (dump_file, "Not considering %s for cloning; "
737 "optimizing it for size.\n",
738 node->dump_name ());
739 return false;
742 init_caller_stats (&stats);
743 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
745 if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
747 if (dump_file)
748 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
749 node->dump_name ());
750 return true;
753 /* When profile is available and function is hot, propagate into it even if
754 calls seems cold; constant propagation can improve function's speed
755 significantly. */
756 if (max_count > profile_count::zero ())
758 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
760 if (dump_file)
761 fprintf (dump_file, "Considering %s for cloning; "
762 "usually called directly.\n",
763 node->dump_name ());
764 return true;
767 if (!stats.n_hot_calls)
769 if (dump_file)
770 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
771 node->dump_name ());
772 return false;
774 if (dump_file)
775 fprintf (dump_file, "Considering %s for cloning.\n",
776 node->dump_name ());
777 return true;
780 template <typename valtype>
781 class value_topo_info
783 public:
784 /* Head of the linked list of topologically sorted values. */
785 ipcp_value<valtype> *values_topo;
786 /* Stack for creating SCCs, represented by a linked list too. */
787 ipcp_value<valtype> *stack;
788 /* Counter driving the algorithm in add_val_to_toposort. */
789 int dfs_counter;
791 value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
793 void add_val (ipcp_value<valtype> *cur_val);
794 void propagate_effects ();
797 /* Arrays representing a topological ordering of call graph nodes and a stack
798 of nodes used during constant propagation and also data required to perform
799 topological sort of values and propagation of benefits in the determined
800 order. */
802 class ipa_topo_info
804 public:
805 /* Array with obtained topological order of cgraph nodes. */
806 struct cgraph_node **order;
807 /* Stack of cgraph nodes used during propagation within SCC until all values
808 in the SCC stabilize. */
809 struct cgraph_node **stack;
810 int nnodes, stack_top;
812 value_topo_info<tree> constants;
813 value_topo_info<ipa_polymorphic_call_context> contexts;
815 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
816 constants ()
820 /* Skip edges from and to nodes without ipa_cp enabled.
821 Ignore not available symbols. */
823 static bool
824 ignore_edge_p (cgraph_edge *e)
826 enum availability avail;
827 cgraph_node *ultimate_target
828 = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
830 return (avail <= AVAIL_INTERPOSABLE
831 || !opt_for_fn (ultimate_target->decl, optimize)
832 || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
835 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
837 static void
838 build_toporder_info (class ipa_topo_info *topo)
840 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
841 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
843 gcc_checking_assert (topo->stack_top == 0);
844 topo->nnodes = ipa_reduced_postorder (topo->order, true,
845 ignore_edge_p);
848 /* Free information about strongly connected components and the arrays in
849 TOPO. */
851 static void
852 free_toporder_info (class ipa_topo_info *topo)
854 ipa_free_postorder_info ();
855 free (topo->order);
856 free (topo->stack);
859 /* Add NODE to the stack in TOPO, unless it is already there. */
861 static inline void
862 push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
864 class ipa_node_params *info = IPA_NODE_REF (node);
865 if (info->node_enqueued)
866 return;
867 info->node_enqueued = 1;
868 topo->stack[topo->stack_top++] = node;
871 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
872 is empty. */
874 static struct cgraph_node *
875 pop_node_from_stack (class ipa_topo_info *topo)
877 if (topo->stack_top)
879 struct cgraph_node *node;
880 topo->stack_top--;
881 node = topo->stack[topo->stack_top];
882 IPA_NODE_REF (node)->node_enqueued = 0;
883 return node;
885 else
886 return NULL;
889 /* Set lattice LAT to bottom and return true if it previously was not set as
890 such. */
892 template <typename valtype>
893 inline bool
894 ipcp_lattice<valtype>::set_to_bottom ()
896 bool ret = !bottom;
897 bottom = true;
898 return ret;
901 /* Mark lattice as containing an unknown value and return true if it previously
902 was not marked as such. */
904 template <typename valtype>
905 inline bool
906 ipcp_lattice<valtype>::set_contains_variable ()
908 bool ret = !contains_variable;
909 contains_variable = true;
910 return ret;
913 /* Set all aggregate lattices in PLATS to bottom and return true if they were
914 not previously set as such. */
916 static inline bool
917 set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
919 bool ret = !plats->aggs_bottom;
920 plats->aggs_bottom = true;
921 return ret;
924 /* Mark all aggregate lattices in PLATS as containing an unknown value and
925 return true if they were not previously marked as such. */
927 static inline bool
928 set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
930 bool ret = !plats->aggs_contain_variable;
931 plats->aggs_contain_variable = true;
932 return ret;
935 bool
936 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
938 return meet_with_1 (&other.m_vr);
941 /* Meet the current value of the lattice with value range described by VR
942 lattice. */
944 bool
945 ipcp_vr_lattice::meet_with (const value_range *p_vr)
947 return meet_with_1 (p_vr);
950 /* Meet the current value of the lattice with value range described by
951 OTHER_VR lattice. Return TRUE if anything changed. */
953 bool
954 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
956 if (bottom_p ())
957 return false;
959 if (other_vr->varying_p ())
960 return set_to_bottom ();
962 value_range save (m_vr);
963 m_vr.union_ (other_vr);
964 return !m_vr.equal_p (save);
967 /* Return true if value range information in the lattice is yet unknown. */
969 bool
970 ipcp_vr_lattice::top_p () const
972 return m_vr.undefined_p ();
975 /* Return true if value range information in the lattice is known to be
976 unusable. */
978 bool
979 ipcp_vr_lattice::bottom_p () const
981 return m_vr.varying_p ();
984 /* Set value range information in the lattice to bottom. Return true if it
985 previously was in a different state. */
987 bool
988 ipcp_vr_lattice::set_to_bottom ()
990 if (m_vr.varying_p ())
991 return false;
992 /* ?? We create all sorts of VARYING ranges for floats, structures,
993 and other types which we cannot handle as ranges. We should
994 probably avoid handling them throughout the pass, but it's easier
995 to create a sensible VARYING here and let the lattice
996 propagate. */
997 m_vr.set_varying (integer_type_node);
998 return true;
1001 /* Set lattice value to bottom, if it already isn't the case. */
1003 bool
1004 ipcp_bits_lattice::set_to_bottom ()
1006 if (bottom_p ())
1007 return false;
1008 m_lattice_val = IPA_BITS_VARYING;
1009 m_value = 0;
1010 m_mask = -1;
1011 return true;
1014 /* Set to constant if it isn't already. Only meant to be called
1015 when switching state from TOP. */
1017 bool
1018 ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask)
1020 gcc_assert (top_p ());
1021 m_lattice_val = IPA_BITS_CONSTANT;
1022 m_value = wi::bit_and (wi::bit_not (mask), value);
1023 m_mask = mask;
1024 return true;
1027 /* Convert operand to value, mask form. */
1029 void
1030 ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_int *maskp)
1032 wide_int get_nonzero_bits (const_tree);
1034 if (TREE_CODE (operand) == INTEGER_CST)
1036 *valuep = wi::to_widest (operand);
1037 *maskp = 0;
1039 else
1041 *valuep = 0;
1042 *maskp = -1;
1046 /* Meet operation, similar to ccp_lattice_meet, we xor values
1047 if this->value, value have different values at same bit positions, we want
1048 to drop that bit to varying. Return true if mask is changed.
1049 This function assumes that the lattice value is in CONSTANT state */
1051 bool
1052 ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask,
1053 unsigned precision)
1055 gcc_assert (constant_p ());
1057 widest_int old_mask = m_mask;
1058 m_mask = (m_mask | mask) | (m_value ^ value);
1059 m_value &= ~m_mask;
1061 if (wi::sext (m_mask, precision) == -1)
1062 return set_to_bottom ();
1064 return m_mask != old_mask;
1067 /* Meet the bits lattice with operand
1068 described by <value, mask, sgn, precision. */
1070 bool
1071 ipcp_bits_lattice::meet_with (widest_int value, widest_int mask,
1072 unsigned precision)
1074 if (bottom_p ())
1075 return false;
1077 if (top_p ())
1079 if (wi::sext (mask, precision) == -1)
1080 return set_to_bottom ();
1081 return set_to_constant (value, mask);
1084 return meet_with_1 (value, mask, precision);
1087 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1088 if code is binary operation or bit_value_unop (other) if code is unary op.
1089 In the case when code is nop_expr, no adjustment is required. */
1091 bool
1092 ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
1093 signop sgn, enum tree_code code, tree operand)
1095 if (other.bottom_p ())
1096 return set_to_bottom ();
1098 if (bottom_p () || other.top_p ())
1099 return false;
1101 widest_int adjusted_value, adjusted_mask;
1103 if (TREE_CODE_CLASS (code) == tcc_binary)
1105 tree type = TREE_TYPE (operand);
1106 widest_int o_value, o_mask;
1107 get_value_and_mask (operand, &o_value, &o_mask);
1109 bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask,
1110 sgn, precision, other.get_value (), other.get_mask (),
1111 TYPE_SIGN (type), TYPE_PRECISION (type), o_value, o_mask);
1113 if (wi::sext (adjusted_mask, precision) == -1)
1114 return set_to_bottom ();
1117 else if (TREE_CODE_CLASS (code) == tcc_unary)
1119 bit_value_unop (code, sgn, precision, &adjusted_value,
1120 &adjusted_mask, sgn, precision, other.get_value (),
1121 other.get_mask ());
1123 if (wi::sext (adjusted_mask, precision) == -1)
1124 return set_to_bottom ();
1127 else
1128 return set_to_bottom ();
1130 if (top_p ())
1132 if (wi::sext (adjusted_mask, precision) == -1)
1133 return set_to_bottom ();
1134 return set_to_constant (adjusted_value, adjusted_mask);
1136 else
1137 return meet_with_1 (adjusted_value, adjusted_mask, precision);
1140 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1141 return true is any of them has not been marked as such so far. */
1143 static inline bool
1144 set_all_contains_variable (class ipcp_param_lattices *plats)
1146 bool ret;
1147 ret = plats->itself.set_contains_variable ();
1148 ret |= plats->ctxlat.set_contains_variable ();
1149 ret |= set_agg_lats_contain_variable (plats);
1150 ret |= plats->bits_lattice.set_to_bottom ();
1151 ret |= plats->m_value_range.set_to_bottom ();
1152 return ret;
1155 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1156 points to by the number of callers to NODE. */
1158 static bool
1159 count_callers (cgraph_node *node, void *data)
1161 int *caller_count = (int *) data;
1163 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
1164 /* Local thunks can be handled transparently, but if the thunk cannot
1165 be optimized out, count it as a real use. */
1166 if (!cs->caller->thunk || !cs->caller->local)
1167 ++*caller_count;
1168 return false;
1171 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1172 the one caller of some other node. Set the caller's corresponding flag. */
1174 static bool
1175 set_single_call_flag (cgraph_node *node, void *)
1177 cgraph_edge *cs = node->callers;
1178 /* Local thunks can be handled transparently, skip them. */
1179 while (cs && cs->caller->thunk && cs->caller->local)
1180 cs = cs->next_caller;
1181 if (cs && IPA_NODE_REF (cs->caller))
1183 IPA_NODE_REF (cs->caller)->node_calling_single_call = true;
1184 return true;
1186 return false;
1189 /* Initialize ipcp_lattices. */
1191 static void
1192 initialize_node_lattices (struct cgraph_node *node)
1194 class ipa_node_params *info = IPA_NODE_REF (node);
1195 struct cgraph_edge *ie;
1196 bool disable = false, variable = false;
1197 int i;
1199 gcc_checking_assert (node->has_gimple_body_p ());
1201 if (!ipa_get_param_count (info))
1202 disable = true;
1203 else if (node->local)
1205 int caller_count = 0;
1206 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
1207 true);
1208 gcc_checking_assert (caller_count > 0);
1209 if (caller_count == 1)
1210 node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
1211 NULL, true);
1213 else
1215 /* When cloning is allowed, we can assume that externally visible
1216 functions are not called. We will compensate this by cloning
1217 later. */
1218 if (ipcp_versionable_function_p (node)
1219 && ipcp_cloning_candidate_p (node))
1220 variable = true;
1221 else
1222 disable = true;
1225 if (dump_file && (dump_flags & TDF_DETAILS)
1226 && !node->alias && !node->thunk)
1228 fprintf (dump_file, "Initializing lattices of %s\n",
1229 node->dump_name ());
1230 if (disable || variable)
1231 fprintf (dump_file, " Marking all lattices as %s\n",
1232 disable ? "BOTTOM" : "VARIABLE");
1235 auto_vec<bool, 16> surviving_params;
1236 bool pre_modified = false;
1238 clone_info *cinfo = clone_info::get (node);
1240 if (!disable && cinfo && cinfo->param_adjustments)
1242 /* At the moment all IPA optimizations should use the number of
1243 parameters of the prevailing decl as the m_always_copy_start.
1244 Handling any other value would complicate the code below, so for the
1245 time bing let's only assert it is so. */
1246 gcc_assert ((cinfo->param_adjustments->m_always_copy_start
1247 == ipa_get_param_count (info))
1248 || cinfo->param_adjustments->m_always_copy_start < 0);
1250 pre_modified = true;
1251 cinfo->param_adjustments->get_surviving_params (&surviving_params);
1253 if (dump_file && (dump_flags & TDF_DETAILS)
1254 && !node->alias && !node->thunk)
1256 bool first = true;
1257 for (int j = 0; j < ipa_get_param_count (info); j++)
1259 if (j < (int) surviving_params.length ()
1260 && surviving_params[j])
1261 continue;
1262 if (first)
1264 fprintf (dump_file,
1265 " The following parameters are dead on arrival:");
1266 first = false;
1268 fprintf (dump_file, " %u", j);
1270 if (!first)
1271 fprintf (dump_file, "\n");
1275 for (i = 0; i < ipa_get_param_count (info); i++)
1277 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
1278 if (disable
1279 || (pre_modified && (surviving_params.length () <= (unsigned) i
1280 || !surviving_params[i])))
1282 plats->itself.set_to_bottom ();
1283 plats->ctxlat.set_to_bottom ();
1284 set_agg_lats_to_bottom (plats);
1285 plats->bits_lattice.set_to_bottom ();
1286 plats->m_value_range.m_vr = value_range ();
1287 plats->m_value_range.set_to_bottom ();
1289 else
1291 plats->m_value_range.init ();
1292 if (variable)
1293 set_all_contains_variable (plats);
1297 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1298 if (ie->indirect_info->polymorphic
1299 && ie->indirect_info->param_index >= 0)
1301 gcc_checking_assert (ie->indirect_info->param_index >= 0);
1302 ipa_get_parm_lattices (info,
1303 ie->indirect_info->param_index)->virt_call = 1;
1307 /* Return the result of a (possibly arithmetic) operation on the constant
1308 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1309 the type of the parameter to which the result is passed. Return
1310 NULL_TREE if that cannot be determined or be considered an
1311 interprocedural invariant. */
1313 static tree
1314 ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
1315 tree res_type)
1317 tree res;
1319 if (opcode == NOP_EXPR)
1320 return input;
1321 if (!is_gimple_ip_invariant (input))
1322 return NULL_TREE;
1324 if (!res_type)
1326 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1327 res_type = boolean_type_node;
1328 else if (expr_type_first_operand_type_p (opcode))
1329 res_type = TREE_TYPE (input);
1330 else
1331 return NULL_TREE;
1334 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1335 res = fold_unary (opcode, res_type, input);
1336 else
1337 res = fold_binary (opcode, res_type, input, operand);
1339 if (res && !is_gimple_ip_invariant (res))
1340 return NULL_TREE;
1342 return res;
1345 /* Return the result of a (possibly arithmetic) pass through jump function
1346 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1347 to which the result is passed. Return NULL_TREE if that cannot be
1348 determined or be considered an interprocedural invariant. */
1350 static tree
1351 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1352 tree res_type)
1354 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
1355 input,
1356 ipa_get_jf_pass_through_operand (jfunc),
1357 res_type);
1360 /* Return the result of an ancestor jump function JFUNC on the constant value
1361 INPUT. Return NULL_TREE if that cannot be determined. */
1363 static tree
1364 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
1366 gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
1367 if (TREE_CODE (input) == ADDR_EXPR)
1369 gcc_checking_assert (is_gimple_ip_invariant_address (input));
1370 poly_int64 off = ipa_get_jf_ancestor_offset (jfunc);
1371 if (known_eq (off, 0))
1372 return input;
1373 poly_int64 byte_offset = exact_div (off, BITS_PER_UNIT);
1374 return build1 (ADDR_EXPR, TREE_TYPE (input),
1375 fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (input)), input,
1376 build_int_cst (ptr_type_node, byte_offset)));
1378 else
1379 return NULL_TREE;
1382 /* Determine whether JFUNC evaluates to a single known constant value and if
1383 so, return it. Otherwise return NULL. INFO describes the caller node or
1384 the one it is inlined to, so that pass-through jump functions can be
1385 evaluated. PARM_TYPE is the type of the parameter to which the result is
1386 passed. */
1388 tree
1389 ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
1390 tree parm_type)
1392 if (jfunc->type == IPA_JF_CONST)
1393 return ipa_get_jf_constant (jfunc);
1394 else if (jfunc->type == IPA_JF_PASS_THROUGH
1395 || jfunc->type == IPA_JF_ANCESTOR)
1397 tree input;
1398 int idx;
1400 if (jfunc->type == IPA_JF_PASS_THROUGH)
1401 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1402 else
1403 idx = ipa_get_jf_ancestor_formal_id (jfunc);
1405 if (info->ipcp_orig_node)
1406 input = info->known_csts[idx];
1407 else
1409 ipcp_lattice<tree> *lat;
1411 if (!info->lattices
1412 || idx >= ipa_get_param_count (info))
1413 return NULL_TREE;
1414 lat = ipa_get_scalar_lat (info, idx);
1415 if (!lat->is_single_const ())
1416 return NULL_TREE;
1417 input = lat->values->value;
1420 if (!input)
1421 return NULL_TREE;
1423 if (jfunc->type == IPA_JF_PASS_THROUGH)
1424 return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
1425 else
1426 return ipa_get_jf_ancestor_result (jfunc, input);
1428 else
1429 return NULL_TREE;
1432 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1433 that INFO describes the caller node or the one it is inlined to, CS is the
1434 call graph edge corresponding to JFUNC and CSIDX index of the described
1435 parameter. */
1437 ipa_polymorphic_call_context
1438 ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
1439 ipa_jump_func *jfunc)
1441 ipa_edge_args *args = IPA_EDGE_REF (cs);
1442 ipa_polymorphic_call_context ctx;
1443 ipa_polymorphic_call_context *edge_ctx
1444 = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
1446 if (edge_ctx && !edge_ctx->useless_p ())
1447 ctx = *edge_ctx;
1449 if (jfunc->type == IPA_JF_PASS_THROUGH
1450 || jfunc->type == IPA_JF_ANCESTOR)
1452 ipa_polymorphic_call_context srcctx;
1453 int srcidx;
1454 bool type_preserved = true;
1455 if (jfunc->type == IPA_JF_PASS_THROUGH)
1457 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1458 return ctx;
1459 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1460 srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
1462 else
1464 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1465 srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
1467 if (info->ipcp_orig_node)
1469 if (info->known_contexts.exists ())
1470 srcctx = info->known_contexts[srcidx];
1472 else
1474 if (!info->lattices
1475 || srcidx >= ipa_get_param_count (info))
1476 return ctx;
1477 ipcp_lattice<ipa_polymorphic_call_context> *lat;
1478 lat = ipa_get_poly_ctx_lat (info, srcidx);
1479 if (!lat->is_single_const ())
1480 return ctx;
1481 srcctx = lat->values->value;
1483 if (srcctx.useless_p ())
1484 return ctx;
1485 if (jfunc->type == IPA_JF_ANCESTOR)
1486 srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1487 if (!type_preserved)
1488 srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1489 srcctx.combine_with (ctx);
1490 return srcctx;
1493 return ctx;
1496 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1497 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1498 the result is a range or an anti-range. */
1500 static bool
1501 ipa_vr_operation_and_type_effects (value_range *dst_vr,
1502 value_range *src_vr,
1503 enum tree_code operation,
1504 tree dst_type, tree src_type)
1506 range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1507 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1508 return false;
1509 return true;
1512 /* Determine value_range of JFUNC given that INFO describes the caller node or
1513 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1514 and PARM_TYPE of the parameter. */
1516 value_range
1517 ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
1518 ipa_jump_func *jfunc, tree parm_type)
1520 value_range vr;
1521 return vr;
1522 if (jfunc->m_vr)
1523 ipa_vr_operation_and_type_effects (&vr,
1524 jfunc->m_vr,
1525 NOP_EXPR, parm_type,
1526 jfunc->m_vr->type ());
1527 if (vr.singleton_p ())
1528 return vr;
1529 if (jfunc->type == IPA_JF_PASS_THROUGH)
1531 int idx;
1532 ipcp_transformation *sum
1533 = ipcp_get_transformation_summary (cs->caller->inlined_to
1534 ? cs->caller->inlined_to
1535 : cs->caller);
1536 if (!sum || !sum->m_vr)
1537 return vr;
1539 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1541 if (!(*sum->m_vr)[idx].known)
1542 return vr;
1543 tree vr_type = ipa_get_type (info, idx);
1544 value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
1545 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
1546 (*sum->m_vr)[idx].type);
1548 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1550 if (TREE_CODE_CLASS (operation) == tcc_unary)
1552 value_range res;
1554 if (ipa_vr_operation_and_type_effects (&res,
1555 &srcvr,
1556 operation, parm_type,
1557 vr_type))
1558 vr.intersect (res);
1560 else
1562 value_range op_res, res;
1563 tree op = ipa_get_jf_pass_through_operand (jfunc);
1564 value_range op_vr (op, op);
1566 range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
1567 if (ipa_vr_operation_and_type_effects (&res,
1568 &op_res,
1569 NOP_EXPR, parm_type,
1570 vr_type))
1571 vr.intersect (res);
1574 return vr;
1577 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1578 parameter with the given INDEX. */
1580 static tree
1581 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
1582 int index)
1584 struct ipa_agg_replacement_value *aggval;
1586 aggval = ipa_get_agg_replacements_for_node (node);
1587 while (aggval)
1589 if (aggval->offset == offset
1590 && aggval->index == index)
1591 return aggval->value;
1592 aggval = aggval->next;
1594 return NULL_TREE;
1597 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1598 single known constant value and if so, return it. Otherwise return NULL.
1599 NODE and INFO describes the caller node or the one it is inlined to, and
1600 its related info. */
1602 static tree
1603 ipa_agg_value_from_node (class ipa_node_params *info,
1604 struct cgraph_node *node,
1605 struct ipa_agg_jf_item *item)
1607 tree value = NULL_TREE;
1608 int src_idx;
1610 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
1611 return NULL_TREE;
1613 if (item->jftype == IPA_JF_CONST)
1614 return item->value.constant;
1616 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
1617 || item->jftype == IPA_JF_LOAD_AGG);
1619 src_idx = item->value.pass_through.formal_id;
1621 if (info->ipcp_orig_node)
1623 if (item->jftype == IPA_JF_PASS_THROUGH)
1624 value = info->known_csts[src_idx];
1625 else
1626 value = get_clone_agg_value (node, item->value.load_agg.offset,
1627 src_idx);
1629 else if (info->lattices)
1631 class ipcp_param_lattices *src_plats
1632 = ipa_get_parm_lattices (info, src_idx);
1634 if (item->jftype == IPA_JF_PASS_THROUGH)
1636 struct ipcp_lattice<tree> *lat = &src_plats->itself;
1638 if (!lat->is_single_const ())
1639 return NULL_TREE;
1641 value = lat->values->value;
1643 else if (src_plats->aggs
1644 && !src_plats->aggs_bottom
1645 && !src_plats->aggs_contain_variable
1646 && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
1648 struct ipcp_agg_lattice *aglat;
1650 for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
1652 if (aglat->offset > item->value.load_agg.offset)
1653 break;
1655 if (aglat->offset == item->value.load_agg.offset)
1657 if (aglat->is_single_const ())
1658 value = aglat->values->value;
1659 break;
1665 if (!value)
1666 return NULL_TREE;
1668 if (item->jftype == IPA_JF_LOAD_AGG)
1670 tree load_type = item->value.load_agg.type;
1671 tree value_type = TREE_TYPE (value);
1673 /* Ensure value type is compatible with load type. */
1674 if (!useless_type_conversion_p (load_type, value_type))
1675 return NULL_TREE;
1678 return ipa_get_jf_arith_result (item->value.pass_through.operation,
1679 value,
1680 item->value.pass_through.operand,
1681 item->type);
1684 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1685 an aggregate and if so, return it. Otherwise return an empty set. NODE
1686 and INFO describes the caller node or the one it is inlined to, and its
1687 related info. */
1689 struct ipa_agg_value_set
1690 ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node,
1691 struct ipa_agg_jump_function *agg_jfunc)
1693 struct ipa_agg_value_set agg;
1694 struct ipa_agg_jf_item *item;
1695 int i;
1697 agg.items = vNULL;
1698 agg.by_ref = agg_jfunc->by_ref;
1700 FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item)
1702 tree value = ipa_agg_value_from_node (info, node, item);
1704 if (value)
1706 struct ipa_agg_value value_item;
1708 value_item.offset = item->offset;
1709 value_item.value = value;
1711 agg.items.safe_push (value_item);
1714 return agg;
1717 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1718 bottom, not containing a variable component and without any known value at
1719 the same time. */
1721 DEBUG_FUNCTION void
1722 ipcp_verify_propagated_values (void)
1724 struct cgraph_node *node;
1726 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1728 class ipa_node_params *info = IPA_NODE_REF (node);
1729 if (!opt_for_fn (node->decl, flag_ipa_cp)
1730 || !opt_for_fn (node->decl, optimize))
1731 continue;
1732 int i, count = ipa_get_param_count (info);
1734 for (i = 0; i < count; i++)
1736 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
1738 if (!lat->bottom
1739 && !lat->contains_variable
1740 && lat->values_count == 0)
1742 if (dump_file)
1744 symtab->dump (dump_file);
1745 fprintf (dump_file, "\nIPA lattices after constant "
1746 "propagation, before gcc_unreachable:\n");
1747 print_all_lattices (dump_file, true, false);
1750 gcc_unreachable ();
1756 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1758 static bool
1759 values_equal_for_ipcp_p (tree x, tree y)
1761 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
1763 if (x == y)
1764 return true;
1766 if (TREE_CODE (x) == ADDR_EXPR
1767 && TREE_CODE (y) == ADDR_EXPR
1768 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
1769 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
1770 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
1771 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
1772 else
1773 return operand_equal_p (x, y, 0);
1776 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1778 static bool
1779 values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
1780 ipa_polymorphic_call_context y)
1782 return x.equal_to (y);
1786 /* Add a new value source to the value represented by THIS, marking that a
1787 value comes from edge CS and (if the underlying jump function is a
1788 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1789 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1790 scalar value of the parameter itself or the offset within an aggregate. */
1792 template <typename valtype>
1793 void
1794 ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
1795 int src_idx, HOST_WIDE_INT offset)
1797 ipcp_value_source<valtype> *src;
1799 src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
1800 src->offset = offset;
1801 src->cs = cs;
1802 src->val = src_val;
1803 src->index = src_idx;
1805 src->next = sources;
1806 sources = src;
1809 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1810 SOURCE and clear all other fields. */
1812 static ipcp_value<tree> *
1813 allocate_and_init_ipcp_value (tree source)
1815 ipcp_value<tree> *val;
1817 val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>();
1818 val->value = source;
1819 return val;
1822 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1823 value to SOURCE and clear all other fields. */
1825 static ipcp_value<ipa_polymorphic_call_context> *
1826 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source)
1828 ipcp_value<ipa_polymorphic_call_context> *val;
1830 // TODO
1831 val = new (ipcp_poly_ctx_values_pool.allocate ())
1832 ipcp_value<ipa_polymorphic_call_context>();
1833 val->value = source;
1834 return val;
1837 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1838 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1839 meaning. OFFSET -1 means the source is scalar and not a part of an
1840 aggregate. If non-NULL, VAL_P records address of existing or newly added
1841 ipcp_value. UNLIMITED means whether value count should not exceed the limit
1842 given by PARAM_IPA_CP_VALUE_LIST_SIZE. */
1844 template <typename valtype>
1845 bool
1846 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1847 ipcp_value<valtype> *src_val,
1848 int src_idx, HOST_WIDE_INT offset,
1849 ipcp_value<valtype> **val_p,
1850 bool unlimited)
1852 ipcp_value<valtype> *val, *last_val = NULL;
1854 if (val_p)
1855 *val_p = NULL;
1857 if (bottom)
1858 return false;
1860 for (val = values; val; last_val = val, val = val->next)
1861 if (values_equal_for_ipcp_p (val->value, newval))
1863 if (val_p)
1864 *val_p = val;
1866 if (ipa_edge_within_scc (cs))
1868 ipcp_value_source<valtype> *s;
1869 for (s = val->sources; s; s = s->next)
1870 if (s->cs == cs && s->val == src_val)
1871 break;
1872 if (s)
1873 return false;
1876 val->add_source (cs, src_val, src_idx, offset);
1877 return false;
1880 if (!unlimited && values_count == opt_for_fn (cs->caller->decl,
1881 param_ipa_cp_value_list_size))
1883 /* We can only free sources, not the values themselves, because sources
1884 of other values in this SCC might point to them. */
1885 for (val = values; val; val = val->next)
1887 while (val->sources)
1889 ipcp_value_source<valtype> *src = val->sources;
1890 val->sources = src->next;
1891 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
1894 values = NULL;
1895 return set_to_bottom ();
1898 values_count++;
1899 val = allocate_and_init_ipcp_value (newval);
1900 val->add_source (cs, src_val, src_idx, offset);
1901 val->next = NULL;
1903 /* Add the new value to end of value list, which can reduce iterations
1904 of propagation stage for recursive function. */
1905 if (last_val)
1906 last_val->next = val;
1907 else
1908 values = val;
1910 if (val_p)
1911 *val_p = val;
1913 return true;
1916 /* Return true, if a ipcp_value VAL is orginated from parameter value of
1917 self-feeding recursive function via some kind of pass-through jump
1918 function. */
1920 static bool
1921 self_recursively_generated_p (ipcp_value<tree> *val)
1923 class ipa_node_params *info = NULL;
1925 for (ipcp_value_source<tree> *src = val->sources; src; src = src->next)
1927 cgraph_edge *cs = src->cs;
1929 if (!src->val || cs->caller != cs->callee->function_symbol ())
1930 return false;
1932 if (src->val == val)
1933 continue;
1935 if (!info)
1936 info = IPA_NODE_REF (cs->caller);
1938 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info,
1939 src->index);
1940 ipcp_lattice<tree> *src_lat;
1941 ipcp_value<tree> *src_val;
1943 if (src->offset == -1)
1944 src_lat = &plats->itself;
1945 else
1947 struct ipcp_agg_lattice *src_aglat;
1949 for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next)
1950 if (src_aglat->offset == src->offset)
1951 break;
1953 if (!src_aglat)
1954 return false;
1956 src_lat = src_aglat;
1959 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1960 if (src_val == val)
1961 break;
1963 if (!src_val)
1964 return false;
1967 return true;
1970 /* A helper function that returns result of operation specified by OPCODE on
1971 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1972 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
1973 acting as its second operand. If non-NULL, RES_TYPE is expected type of
1974 the result. */
1976 static tree
1977 get_val_across_arith_op (enum tree_code opcode,
1978 tree opnd1_type,
1979 tree opnd2,
1980 ipcp_value<tree> *src_val,
1981 tree res_type)
1983 tree opnd1 = src_val->value;
1985 /* Skip source values that is incompatible with specified type. */
1986 if (opnd1_type
1987 && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
1988 return NULL_TREE;
1990 return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
1993 /* Propagate values through an arithmetic transformation described by a jump
1994 function associated with edge CS, taking values from SRC_LAT and putting
1995 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
1996 OPND2 is a constant value if transformation is a binary operation.
1997 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
1998 a part of the aggregate. SRC_IDX is the index of the source parameter.
1999 RES_TYPE is the value type of result being propagated into. Return true if
2000 DEST_LAT changed. */
2002 static bool
2003 propagate_vals_across_arith_jfunc (cgraph_edge *cs,
2004 enum tree_code opcode,
2005 tree opnd1_type,
2006 tree opnd2,
2007 ipcp_lattice<tree> *src_lat,
2008 ipcp_lattice<tree> *dest_lat,
2009 HOST_WIDE_INT src_offset,
2010 int src_idx,
2011 tree res_type)
2013 ipcp_value<tree> *src_val;
2014 bool ret = false;
2016 /* Due to circular dependencies, propagating within an SCC through arithmetic
2017 transformation would create infinite number of values. But for
2018 self-feeding recursive function, we could allow propagation in a limited
2019 count, and this can enable a simple kind of recursive function versioning.
2020 For other scenario, we would just make lattices bottom. */
2021 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
2023 int i;
2025 int max_recursive_depth = opt_for_fn(cs->caller->decl,
2026 param_ipa_cp_max_recursive_depth);
2027 if (src_lat != dest_lat || max_recursive_depth < 1)
2028 return dest_lat->set_contains_variable ();
2030 /* No benefit if recursive execution is in low probability. */
2031 if (cs->sreal_frequency () * 100
2032 <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
2033 param_ipa_cp_min_recursive_probability))
2034 return dest_lat->set_contains_variable ();
2036 auto_vec<ipcp_value<tree> *, 8> val_seeds;
2038 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2040 /* Now we do not use self-recursively generated value as propagation
2041 source, this is absolutely conservative, but could avoid explosion
2042 of lattice's value space, especially when one recursive function
2043 calls another recursive. */
2044 if (self_recursively_generated_p (src_val))
2046 ipcp_value_source<tree> *s;
2048 /* If the lattice has already been propagated for the call site,
2049 no need to do that again. */
2050 for (s = src_val->sources; s; s = s->next)
2051 if (s->cs == cs)
2052 return dest_lat->set_contains_variable ();
2054 else
2055 val_seeds.safe_push (src_val);
2058 gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
2060 /* Recursively generate lattice values with a limited count. */
2061 FOR_EACH_VEC_ELT (val_seeds, i, src_val)
2063 for (int j = 1; j < max_recursive_depth; j++)
2065 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2066 src_val, res_type);
2067 if (!cstval)
2068 break;
2070 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2071 src_offset, &src_val, true);
2072 gcc_checking_assert (src_val);
2075 ret |= dest_lat->set_contains_variable ();
2077 else
2078 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2080 /* Now we do not use self-recursively generated value as propagation
2081 source, otherwise it is easy to make value space of normal lattice
2082 overflow. */
2083 if (self_recursively_generated_p (src_val))
2085 ret |= dest_lat->set_contains_variable ();
2086 continue;
2089 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2090 src_val, res_type);
2091 if (cstval)
2092 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2093 src_offset);
2094 else
2095 ret |= dest_lat->set_contains_variable ();
2098 return ret;
2101 /* Propagate values through a pass-through jump function JFUNC associated with
2102 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2103 is the index of the source parameter. PARM_TYPE is the type of the
2104 parameter to which the result is passed. */
2106 static bool
2107 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
2108 ipcp_lattice<tree> *src_lat,
2109 ipcp_lattice<tree> *dest_lat, int src_idx,
2110 tree parm_type)
2112 return propagate_vals_across_arith_jfunc (cs,
2113 ipa_get_jf_pass_through_operation (jfunc),
2114 NULL_TREE,
2115 ipa_get_jf_pass_through_operand (jfunc),
2116 src_lat, dest_lat, -1, src_idx, parm_type);
2119 /* Propagate values through an ancestor jump function JFUNC associated with
2120 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2121 is the index of the source parameter. */
2123 static bool
2124 propagate_vals_across_ancestor (struct cgraph_edge *cs,
2125 struct ipa_jump_func *jfunc,
2126 ipcp_lattice<tree> *src_lat,
2127 ipcp_lattice<tree> *dest_lat, int src_idx)
2129 ipcp_value<tree> *src_val;
2130 bool ret = false;
2132 if (ipa_edge_within_scc (cs))
2133 return dest_lat->set_contains_variable ();
2135 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2137 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
2139 if (t)
2140 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
2141 else
2142 ret |= dest_lat->set_contains_variable ();
2145 return ret;
2148 /* Propagate scalar values across jump function JFUNC that is associated with
2149 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2150 parameter to which the result is passed. */
2152 static bool
2153 propagate_scalar_across_jump_function (struct cgraph_edge *cs,
2154 struct ipa_jump_func *jfunc,
2155 ipcp_lattice<tree> *dest_lat,
2156 tree param_type)
2158 if (dest_lat->bottom)
2159 return false;
2161 if (jfunc->type == IPA_JF_CONST)
2163 tree val = ipa_get_jf_constant (jfunc);
2164 return dest_lat->add_value (val, cs, NULL, 0);
2166 else if (jfunc->type == IPA_JF_PASS_THROUGH
2167 || jfunc->type == IPA_JF_ANCESTOR)
2169 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2170 ipcp_lattice<tree> *src_lat;
2171 int src_idx;
2172 bool ret;
2174 if (jfunc->type == IPA_JF_PASS_THROUGH)
2175 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2176 else
2177 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2179 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
2180 if (src_lat->bottom)
2181 return dest_lat->set_contains_variable ();
2183 /* If we would need to clone the caller and cannot, do not propagate. */
2184 if (!ipcp_versionable_function_p (cs->caller)
2185 && (src_lat->contains_variable
2186 || (src_lat->values_count > 1)))
2187 return dest_lat->set_contains_variable ();
2189 if (jfunc->type == IPA_JF_PASS_THROUGH)
2190 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
2191 dest_lat, src_idx, param_type);
2192 else
2193 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
2194 src_idx);
2196 if (src_lat->contains_variable)
2197 ret |= dest_lat->set_contains_variable ();
2199 return ret;
2202 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2203 use it for indirect inlining), we should propagate them too. */
2204 return dest_lat->set_contains_variable ();
2207 /* Propagate scalar values across jump function JFUNC that is associated with
2208 edge CS and describes argument IDX and put the values into DEST_LAT. */
2210 static bool
2211 propagate_context_across_jump_function (cgraph_edge *cs,
2212 ipa_jump_func *jfunc, int idx,
2213 ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
2215 ipa_edge_args *args = IPA_EDGE_REF (cs);
2216 if (dest_lat->bottom)
2217 return false;
2218 bool ret = false;
2219 bool added_sth = false;
2220 bool type_preserved = true;
2222 ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
2223 = ipa_get_ith_polymorhic_call_context (args, idx);
2225 if (edge_ctx_ptr)
2226 edge_ctx = *edge_ctx_ptr;
2228 if (jfunc->type == IPA_JF_PASS_THROUGH
2229 || jfunc->type == IPA_JF_ANCESTOR)
2231 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2232 int src_idx;
2233 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
2235 /* TODO: Once we figure out how to propagate speculations, it will
2236 probably be a good idea to switch to speculation if type_preserved is
2237 not set instead of punting. */
2238 if (jfunc->type == IPA_JF_PASS_THROUGH)
2240 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
2241 goto prop_fail;
2242 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
2243 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2245 else
2247 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
2248 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2251 src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
2252 /* If we would need to clone the caller and cannot, do not propagate. */
2253 if (!ipcp_versionable_function_p (cs->caller)
2254 && (src_lat->contains_variable
2255 || (src_lat->values_count > 1)))
2256 goto prop_fail;
2258 ipcp_value<ipa_polymorphic_call_context> *src_val;
2259 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2261 ipa_polymorphic_call_context cur = src_val->value;
2263 if (!type_preserved)
2264 cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
2265 if (jfunc->type == IPA_JF_ANCESTOR)
2266 cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
2267 /* TODO: In cases we know how the context is going to be used,
2268 we can improve the result by passing proper OTR_TYPE. */
2269 cur.combine_with (edge_ctx);
2270 if (!cur.useless_p ())
2272 if (src_lat->contains_variable
2273 && !edge_ctx.equal_to (cur))
2274 ret |= dest_lat->set_contains_variable ();
2275 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
2276 added_sth = true;
2281 prop_fail:
2282 if (!added_sth)
2284 if (!edge_ctx.useless_p ())
2285 ret |= dest_lat->add_value (edge_ctx, cs);
2286 else
2287 ret |= dest_lat->set_contains_variable ();
2290 return ret;
2293 /* Propagate bits across jfunc that is associated with
2294 edge cs and update dest_lattice accordingly. */
2296 bool
2297 propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
2298 ipa_jump_func *jfunc,
2299 ipcp_bits_lattice *dest_lattice)
2301 if (dest_lattice->bottom_p ())
2302 return false;
2304 enum availability availability;
2305 cgraph_node *callee = cs->callee->function_symbol (&availability);
2306 class ipa_node_params *callee_info = IPA_NODE_REF (callee);
2307 tree parm_type = ipa_get_type (callee_info, idx);
2309 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2310 transform for these cases. Similarly, we can have bad type mismatches
2311 with LTO, avoid doing anything with those too. */
2312 if (!parm_type
2313 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
2315 if (dump_file && (dump_flags & TDF_DETAILS))
2316 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
2317 "param %i of %s is NULL or unsuitable for bits propagation\n",
2318 idx, cs->callee->dump_name ());
2320 return dest_lattice->set_to_bottom ();
2323 unsigned precision = TYPE_PRECISION (parm_type);
2324 signop sgn = TYPE_SIGN (parm_type);
2326 if (jfunc->type == IPA_JF_PASS_THROUGH
2327 || jfunc->type == IPA_JF_ANCESTOR)
2329 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2330 tree operand = NULL_TREE;
2331 enum tree_code code;
2332 unsigned src_idx;
2334 if (jfunc->type == IPA_JF_PASS_THROUGH)
2336 code = ipa_get_jf_pass_through_operation (jfunc);
2337 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2338 if (code != NOP_EXPR)
2339 operand = ipa_get_jf_pass_through_operand (jfunc);
2341 else
2343 code = POINTER_PLUS_EXPR;
2344 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2345 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
2346 operand = build_int_cstu (size_type_node, offset);
2349 class ipcp_param_lattices *src_lats
2350 = ipa_get_parm_lattices (caller_info, src_idx);
2352 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2353 for eg consider:
2354 int f(int x)
2356 g (x & 0xff);
2358 Assume lattice for x is bottom, however we can still propagate
2359 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2360 and we store it in jump function during analysis stage. */
2362 if (src_lats->bits_lattice.bottom_p ()
2363 && jfunc->bits)
2364 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2365 precision);
2366 else
2367 return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
2368 code, operand);
2371 else if (jfunc->type == IPA_JF_ANCESTOR)
2372 return dest_lattice->set_to_bottom ();
2373 else if (jfunc->bits)
2374 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2375 precision);
2376 else
2377 return dest_lattice->set_to_bottom ();
2380 /* Propagate value range across jump function JFUNC that is associated with
2381 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2382 accordingly. */
2384 static bool
2385 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
2386 class ipcp_param_lattices *dest_plats,
2387 tree param_type)
2389 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
2391 if (dest_lat->bottom_p ())
2392 return false;
2394 if (!param_type
2395 || (!INTEGRAL_TYPE_P (param_type)
2396 && !POINTER_TYPE_P (param_type)))
2397 return dest_lat->set_to_bottom ();
2399 if (jfunc->type == IPA_JF_PASS_THROUGH)
2401 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
2402 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2403 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2404 class ipcp_param_lattices *src_lats
2405 = ipa_get_parm_lattices (caller_info, src_idx);
2406 tree operand_type = ipa_get_type (caller_info, src_idx);
2408 if (src_lats->m_value_range.bottom_p ())
2409 return dest_lat->set_to_bottom ();
2411 value_range vr;
2412 if (TREE_CODE_CLASS (operation) == tcc_unary)
2413 ipa_vr_operation_and_type_effects (&vr,
2414 &src_lats->m_value_range.m_vr,
2415 operation, param_type,
2416 operand_type);
2417 /* A crude way to prevent unbounded number of value range updates
2418 in SCC components. We should allow limited number of updates within
2419 SCC, too. */
2420 else if (!ipa_edge_within_scc (cs))
2422 tree op = ipa_get_jf_pass_through_operand (jfunc);
2423 value_range op_vr (op, op);
2424 value_range op_res,res;
2426 range_fold_binary_expr (&op_res, operation, operand_type,
2427 &src_lats->m_value_range.m_vr, &op_vr);
2428 ipa_vr_operation_and_type_effects (&vr,
2429 &op_res,
2430 NOP_EXPR, param_type,
2431 operand_type);
2433 if (!vr.undefined_p () && !vr.varying_p ())
2435 if (jfunc->m_vr)
2437 value_range jvr;
2438 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2439 NOP_EXPR,
2440 param_type,
2441 jfunc->m_vr->type ()))
2442 vr.intersect (jvr);
2444 return dest_lat->meet_with (&vr);
2447 else if (jfunc->type == IPA_JF_CONST)
2449 tree val = ipa_get_jf_constant (jfunc);
2450 if (TREE_CODE (val) == INTEGER_CST)
2452 val = fold_convert (param_type, val);
2453 if (TREE_OVERFLOW_P (val))
2454 val = drop_tree_overflow (val);
2456 value_range tmpvr (val, val);
2457 return dest_lat->meet_with (&tmpvr);
2461 value_range vr;
2462 if (jfunc->m_vr
2463 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
2464 param_type,
2465 jfunc->m_vr->type ()))
2466 return dest_lat->meet_with (&vr);
2467 else
2468 return dest_lat->set_to_bottom ();
2471 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2472 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2473 other cases, return false). If there are no aggregate items, set
2474 aggs_by_ref to NEW_AGGS_BY_REF. */
2476 static bool
2477 set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
2478 bool new_aggs_by_ref)
2480 if (dest_plats->aggs)
2482 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
2484 set_agg_lats_to_bottom (dest_plats);
2485 return true;
2488 else
2489 dest_plats->aggs_by_ref = new_aggs_by_ref;
2490 return false;
2493 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2494 already existing lattice for the given OFFSET and SIZE, marking all skipped
2495 lattices as containing variable and checking for overlaps. If there is no
2496 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2497 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2498 unless there are too many already. If there are two many, return false. If
2499 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2500 skipped lattices were newly marked as containing variable, set *CHANGE to
2501 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2503 static bool
2504 merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
2505 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
2506 struct ipcp_agg_lattice ***aglat,
2507 bool pre_existing, bool *change, int max_agg_items)
2509 gcc_checking_assert (offset >= 0);
2511 while (**aglat && (**aglat)->offset < offset)
2513 if ((**aglat)->offset + (**aglat)->size > offset)
2515 set_agg_lats_to_bottom (dest_plats);
2516 return false;
2518 *change |= (**aglat)->set_contains_variable ();
2519 *aglat = &(**aglat)->next;
2522 if (**aglat && (**aglat)->offset == offset)
2524 if ((**aglat)->size != val_size)
2526 set_agg_lats_to_bottom (dest_plats);
2527 return false;
2529 gcc_assert (!(**aglat)->next
2530 || (**aglat)->next->offset >= offset + val_size);
2531 return true;
2533 else
2535 struct ipcp_agg_lattice *new_al;
2537 if (**aglat && (**aglat)->offset < offset + val_size)
2539 set_agg_lats_to_bottom (dest_plats);
2540 return false;
2542 if (dest_plats->aggs_count == max_agg_items)
2543 return false;
2544 dest_plats->aggs_count++;
2545 new_al = ipcp_agg_lattice_pool.allocate ();
2546 memset (new_al, 0, sizeof (*new_al));
2548 new_al->offset = offset;
2549 new_al->size = val_size;
2550 new_al->contains_variable = pre_existing;
2552 new_al->next = **aglat;
2553 **aglat = new_al;
2554 return true;
2558 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2559 containing an unknown value. */
2561 static bool
2562 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
2564 bool ret = false;
2565 while (aglat)
2567 ret |= aglat->set_contains_variable ();
2568 aglat = aglat->next;
2570 return ret;
2573 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2574 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2575 parameter used for lattice value sources. Return true if DEST_PLATS changed
2576 in any way. */
2578 static bool
2579 merge_aggregate_lattices (struct cgraph_edge *cs,
2580 class ipcp_param_lattices *dest_plats,
2581 class ipcp_param_lattices *src_plats,
2582 int src_idx, HOST_WIDE_INT offset_delta)
2584 bool pre_existing = dest_plats->aggs != NULL;
2585 struct ipcp_agg_lattice **dst_aglat;
2586 bool ret = false;
2588 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
2589 return true;
2590 if (src_plats->aggs_bottom)
2591 return set_agg_lats_contain_variable (dest_plats);
2592 if (src_plats->aggs_contain_variable)
2593 ret |= set_agg_lats_contain_variable (dest_plats);
2594 dst_aglat = &dest_plats->aggs;
2596 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2597 param_ipa_max_agg_items);
2598 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2599 src_aglat;
2600 src_aglat = src_aglat->next)
2602 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2604 if (new_offset < 0)
2605 continue;
2606 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
2607 &dst_aglat, pre_existing, &ret, max_agg_items))
2609 struct ipcp_agg_lattice *new_al = *dst_aglat;
2611 dst_aglat = &(*dst_aglat)->next;
2612 if (src_aglat->bottom)
2614 ret |= new_al->set_contains_variable ();
2615 continue;
2617 if (src_aglat->contains_variable)
2618 ret |= new_al->set_contains_variable ();
2619 for (ipcp_value<tree> *val = src_aglat->values;
2620 val;
2621 val = val->next)
2622 ret |= new_al->add_value (val->value, cs, val, src_idx,
2623 src_aglat->offset);
2625 else if (dest_plats->aggs_bottom)
2626 return true;
2628 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
2629 return ret;
2632 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2633 pass-through JFUNC and if so, whether it has conform and conforms to the
2634 rules about propagating values passed by reference. */
2636 static bool
2637 agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
2638 struct ipa_jump_func *jfunc)
2640 return src_plats->aggs
2641 && (!src_plats->aggs_by_ref
2642 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2645 /* Propagate values through ITEM, jump function for a part of an aggregate,
2646 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2647 associated with the jump function. Return true if AGLAT changed in any
2648 way. */
2650 static bool
2651 propagate_aggregate_lattice (struct cgraph_edge *cs,
2652 struct ipa_agg_jf_item *item,
2653 struct ipcp_agg_lattice *aglat)
2655 class ipa_node_params *caller_info;
2656 class ipcp_param_lattices *src_plats;
2657 struct ipcp_lattice<tree> *src_lat;
2658 HOST_WIDE_INT src_offset;
2659 int src_idx;
2660 tree load_type;
2661 bool ret;
2663 if (item->jftype == IPA_JF_CONST)
2665 tree value = item->value.constant;
2667 gcc_checking_assert (is_gimple_ip_invariant (value));
2668 return aglat->add_value (value, cs, NULL, 0);
2671 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2672 || item->jftype == IPA_JF_LOAD_AGG);
2674 caller_info = IPA_NODE_REF (cs->caller);
2675 src_idx = item->value.pass_through.formal_id;
2676 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2678 if (item->jftype == IPA_JF_PASS_THROUGH)
2680 load_type = NULL_TREE;
2681 src_lat = &src_plats->itself;
2682 src_offset = -1;
2684 else
2686 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
2687 struct ipcp_agg_lattice *src_aglat;
2689 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
2690 if (src_aglat->offset >= load_offset)
2691 break;
2693 load_type = item->value.load_agg.type;
2694 if (!src_aglat
2695 || src_aglat->offset > load_offset
2696 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
2697 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
2698 return aglat->set_contains_variable ();
2700 src_lat = src_aglat;
2701 src_offset = load_offset;
2704 if (src_lat->bottom
2705 || (!ipcp_versionable_function_p (cs->caller)
2706 && !src_lat->is_single_const ()))
2707 return aglat->set_contains_variable ();
2709 ret = propagate_vals_across_arith_jfunc (cs,
2710 item->value.pass_through.operation,
2711 load_type,
2712 item->value.pass_through.operand,
2713 src_lat, aglat,
2714 src_offset,
2715 src_idx,
2716 item->type);
2718 if (src_lat->contains_variable)
2719 ret |= aglat->set_contains_variable ();
2721 return ret;
2724 /* Propagate scalar values across jump function JFUNC that is associated with
2725 edge CS and put the values into DEST_LAT. */
2727 static bool
2728 propagate_aggs_across_jump_function (struct cgraph_edge *cs,
2729 struct ipa_jump_func *jfunc,
2730 class ipcp_param_lattices *dest_plats)
2732 bool ret = false;
2734 if (dest_plats->aggs_bottom)
2735 return false;
2737 if (jfunc->type == IPA_JF_PASS_THROUGH
2738 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2740 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2741 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2742 class ipcp_param_lattices *src_plats;
2744 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2745 if (agg_pass_through_permissible_p (src_plats, jfunc))
2747 /* Currently we do not produce clobber aggregate jump
2748 functions, replace with merging when we do. */
2749 gcc_assert (!jfunc->agg.items);
2750 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
2751 src_idx, 0);
2752 return ret;
2755 else if (jfunc->type == IPA_JF_ANCESTOR
2756 && ipa_get_jf_ancestor_agg_preserved (jfunc))
2758 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2759 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2760 class ipcp_param_lattices *src_plats;
2762 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2763 if (src_plats->aggs && src_plats->aggs_by_ref)
2765 /* Currently we do not produce clobber aggregate jump
2766 functions, replace with merging when we do. */
2767 gcc_assert (!jfunc->agg.items);
2768 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
2769 ipa_get_jf_ancestor_offset (jfunc));
2771 else if (!src_plats->aggs_by_ref)
2772 ret |= set_agg_lats_to_bottom (dest_plats);
2773 else
2774 ret |= set_agg_lats_contain_variable (dest_plats);
2775 return ret;
2778 if (jfunc->agg.items)
2780 bool pre_existing = dest_plats->aggs != NULL;
2781 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
2782 struct ipa_agg_jf_item *item;
2783 int i;
2785 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
2786 return true;
2788 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2789 param_ipa_max_agg_items);
2790 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2792 HOST_WIDE_INT val_size;
2794 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
2795 continue;
2796 val_size = tree_to_shwi (TYPE_SIZE (item->type));
2798 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
2799 &aglat, pre_existing, &ret, max_agg_items))
2801 ret |= propagate_aggregate_lattice (cs, item, *aglat);
2802 aglat = &(*aglat)->next;
2804 else if (dest_plats->aggs_bottom)
2805 return true;
2808 ret |= set_chain_of_aglats_contains_variable (*aglat);
2810 else
2811 ret |= set_agg_lats_contain_variable (dest_plats);
2813 return ret;
2816 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2817 non-thunk) destination, the call passes through a thunk. */
2819 static bool
2820 call_passes_through_thunk (cgraph_edge *cs)
2822 cgraph_node *alias_or_thunk = cs->callee;
2823 while (alias_or_thunk->alias)
2824 alias_or_thunk = alias_or_thunk->get_alias_target ();
2825 return alias_or_thunk->thunk;
2828 /* Propagate constants from the caller to the callee of CS. INFO describes the
2829 caller. */
2831 static bool
2832 propagate_constants_across_call (struct cgraph_edge *cs)
2834 class ipa_node_params *callee_info;
2835 enum availability availability;
2836 cgraph_node *callee;
2837 class ipa_edge_args *args;
2838 bool ret = false;
2839 int i, args_count, parms_count;
2841 callee = cs->callee->function_symbol (&availability);
2842 if (!callee->definition)
2843 return false;
2844 gcc_checking_assert (callee->has_gimple_body_p ());
2845 callee_info = IPA_NODE_REF (callee);
2846 if (!callee_info)
2847 return false;
2849 args = IPA_EDGE_REF (cs);
2850 parms_count = ipa_get_param_count (callee_info);
2851 if (parms_count == 0)
2852 return false;
2853 if (!args
2854 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
2855 || !opt_for_fn (cs->caller->decl, optimize))
2857 for (i = 0; i < parms_count; i++)
2858 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2859 i));
2860 return ret;
2862 args_count = ipa_get_cs_argument_count (args);
2864 /* If this call goes through a thunk we must not propagate to the first (0th)
2865 parameter. However, we might need to uncover a thunk from below a series
2866 of aliases first. */
2867 if (call_passes_through_thunk (cs))
2869 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2870 0));
2871 i = 1;
2873 else
2874 i = 0;
2876 for (; (i < args_count) && (i < parms_count); i++)
2878 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
2879 class ipcp_param_lattices *dest_plats;
2880 tree param_type = ipa_get_type (callee_info, i);
2882 dest_plats = ipa_get_parm_lattices (callee_info, i);
2883 if (availability == AVAIL_INTERPOSABLE)
2884 ret |= set_all_contains_variable (dest_plats);
2885 else
2887 ret |= propagate_scalar_across_jump_function (cs, jump_func,
2888 &dest_plats->itself,
2889 param_type);
2890 ret |= propagate_context_across_jump_function (cs, jump_func, i,
2891 &dest_plats->ctxlat);
2893 |= propagate_bits_across_jump_function (cs, i, jump_func,
2894 &dest_plats->bits_lattice);
2895 ret |= propagate_aggs_across_jump_function (cs, jump_func,
2896 dest_plats);
2897 if (opt_for_fn (callee->decl, flag_ipa_vrp))
2898 ret |= propagate_vr_across_jump_function (cs, jump_func,
2899 dest_plats, param_type);
2900 else
2901 ret |= dest_plats->m_value_range.set_to_bottom ();
2904 for (; i < parms_count; i++)
2905 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
2907 return ret;
2910 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2911 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2912 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2914 static tree
2915 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
2916 vec<tree> known_csts,
2917 vec<ipa_polymorphic_call_context> known_contexts,
2918 vec<ipa_agg_value_set> known_aggs,
2919 struct ipa_agg_replacement_value *agg_reps,
2920 bool *speculative)
2922 int param_index = ie->indirect_info->param_index;
2923 HOST_WIDE_INT anc_offset;
2924 tree t = NULL;
2925 tree target = NULL;
2927 *speculative = false;
2929 if (param_index == -1)
2930 return NULL_TREE;
2932 if (!ie->indirect_info->polymorphic)
2934 tree t = NULL;
2936 if (ie->indirect_info->agg_contents)
2938 t = NULL;
2939 if (agg_reps && ie->indirect_info->guaranteed_unmodified)
2941 while (agg_reps)
2943 if (agg_reps->index == param_index
2944 && agg_reps->offset == ie->indirect_info->offset
2945 && agg_reps->by_ref == ie->indirect_info->by_ref)
2947 t = agg_reps->value;
2948 break;
2950 agg_reps = agg_reps->next;
2953 if (!t)
2955 struct ipa_agg_value_set *agg;
2956 if (known_aggs.length () > (unsigned int) param_index)
2957 agg = &known_aggs[param_index];
2958 else
2959 agg = NULL;
2960 bool from_global_constant;
2961 t = ipa_find_agg_cst_for_param (agg,
2962 (unsigned) param_index
2963 < known_csts.length ()
2964 ? known_csts[param_index]
2965 : NULL,
2966 ie->indirect_info->offset,
2967 ie->indirect_info->by_ref,
2968 &from_global_constant);
2969 if (t
2970 && !from_global_constant
2971 && !ie->indirect_info->guaranteed_unmodified)
2972 t = NULL_TREE;
2975 else if ((unsigned) param_index < known_csts.length ())
2976 t = known_csts[param_index];
2978 if (t
2979 && TREE_CODE (t) == ADDR_EXPR
2980 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
2981 return TREE_OPERAND (t, 0);
2982 else
2983 return NULL_TREE;
2986 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
2987 return NULL_TREE;
2989 gcc_assert (!ie->indirect_info->agg_contents);
2990 anc_offset = ie->indirect_info->offset;
2992 t = NULL;
2994 /* Try to work out value of virtual table pointer value in replacements. */
2995 if (!t && agg_reps && !ie->indirect_info->by_ref)
2997 while (agg_reps)
2999 if (agg_reps->index == param_index
3000 && agg_reps->offset == ie->indirect_info->offset
3001 && agg_reps->by_ref)
3003 t = agg_reps->value;
3004 break;
3006 agg_reps = agg_reps->next;
3010 /* Try to work out value of virtual table pointer value in known
3011 aggregate values. */
3012 if (!t && known_aggs.length () > (unsigned int) param_index
3013 && !ie->indirect_info->by_ref)
3015 struct ipa_agg_value_set *agg = &known_aggs[param_index];
3016 t = ipa_find_agg_cst_for_param (agg,
3017 (unsigned) param_index
3018 < known_csts.length ()
3019 ? known_csts[param_index] : NULL,
3020 ie->indirect_info->offset, true);
3023 /* If we found the virtual table pointer, lookup the target. */
3024 if (t)
3026 tree vtable;
3027 unsigned HOST_WIDE_INT offset;
3028 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
3030 bool can_refer;
3031 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3032 vtable, offset, &can_refer);
3033 if (can_refer)
3035 if (!target
3036 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
3037 || !possible_polymorphic_call_target_p
3038 (ie, cgraph_node::get (target)))
3040 /* Do not speculate builtin_unreachable, it is stupid! */
3041 if (ie->indirect_info->vptr_changed)
3042 return NULL;
3043 target = ipa_impossible_devirt_target (ie, target);
3045 *speculative = ie->indirect_info->vptr_changed;
3046 if (!*speculative)
3047 return target;
3052 /* Do we know the constant value of pointer? */
3053 if (!t && (unsigned) param_index < known_csts.length ())
3054 t = known_csts[param_index];
3056 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
3058 ipa_polymorphic_call_context context;
3059 if (known_contexts.length () > (unsigned int) param_index)
3061 context = known_contexts[param_index];
3062 context.offset_by (anc_offset);
3063 if (ie->indirect_info->vptr_changed)
3064 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3065 ie->indirect_info->otr_type);
3066 if (t)
3068 ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
3069 (t, ie->indirect_info->otr_type, anc_offset);
3070 if (!ctx2.useless_p ())
3071 context.combine_with (ctx2, ie->indirect_info->otr_type);
3074 else if (t)
3076 context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
3077 anc_offset);
3078 if (ie->indirect_info->vptr_changed)
3079 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3080 ie->indirect_info->otr_type);
3082 else
3083 return NULL_TREE;
3085 vec <cgraph_node *>targets;
3086 bool final;
3088 targets = possible_polymorphic_call_targets
3089 (ie->indirect_info->otr_type,
3090 ie->indirect_info->otr_token,
3091 context, &final);
3092 if (!final || targets.length () > 1)
3094 struct cgraph_node *node;
3095 if (*speculative)
3096 return target;
3097 if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3098 || ie->speculative || !ie->maybe_hot_p ())
3099 return NULL;
3100 node = try_speculative_devirtualization (ie->indirect_info->otr_type,
3101 ie->indirect_info->otr_token,
3102 context);
3103 if (node)
3105 *speculative = true;
3106 target = node->decl;
3108 else
3109 return NULL;
3111 else
3113 *speculative = false;
3114 if (targets.length () == 1)
3115 target = targets[0]->decl;
3116 else
3117 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3120 if (target && !possible_polymorphic_call_target_p (ie,
3121 cgraph_node::get (target)))
3123 if (*speculative)
3124 return NULL;
3125 target = ipa_impossible_devirt_target (ie, target);
3128 return target;
3131 /* If an indirect edge IE can be turned into a direct one based on data in
3132 AVALS, return the destination. Store into *SPECULATIVE a boolean determinig
3133 whether the discovered target is only speculative guess. */
3135 tree
3136 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
3137 ipa_call_arg_values *avals,
3138 bool *speculative)
3140 return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3141 avals->m_known_contexts,
3142 avals->m_known_aggs,
3143 NULL, speculative);
3146 /* The same functionality as above overloaded for ipa_auto_call_arg_values. */
3148 tree
3149 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
3150 ipa_auto_call_arg_values *avals,
3151 bool *speculative)
3153 return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3154 avals->m_known_contexts,
3155 avals->m_known_aggs,
3156 NULL, speculative);
3159 /* Calculate devirtualization time bonus for NODE, assuming we know information
3160 about arguments stored in AVALS. */
3162 static int
3163 devirtualization_time_bonus (struct cgraph_node *node,
3164 ipa_auto_call_arg_values *avals)
3166 struct cgraph_edge *ie;
3167 int res = 0;
3169 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
3171 struct cgraph_node *callee;
3172 class ipa_fn_summary *isummary;
3173 enum availability avail;
3174 tree target;
3175 bool speculative;
3177 target = ipa_get_indirect_edge_target (ie, avals, &speculative);
3178 if (!target)
3179 continue;
3181 /* Only bare minimum benefit for clearly un-inlineable targets. */
3182 res += 1;
3183 callee = cgraph_node::get (target);
3184 if (!callee || !callee->definition)
3185 continue;
3186 callee = callee->function_symbol (&avail);
3187 if (avail < AVAIL_AVAILABLE)
3188 continue;
3189 isummary = ipa_fn_summaries->get (callee);
3190 if (!isummary || !isummary->inlinable)
3191 continue;
3193 int size = ipa_size_summaries->get (callee)->size;
3194 /* FIXME: The values below need re-considering and perhaps also
3195 integrating into the cost metrics, at lest in some very basic way. */
3196 int max_inline_insns_auto
3197 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3198 if (size <= max_inline_insns_auto / 4)
3199 res += 31 / ((int)speculative + 1);
3200 else if (size <= max_inline_insns_auto / 2)
3201 res += 15 / ((int)speculative + 1);
3202 else if (size <= max_inline_insns_auto
3203 || DECL_DECLARED_INLINE_P (callee->decl))
3204 res += 7 / ((int)speculative + 1);
3207 return res;
3210 /* Return time bonus incurred because of hints stored in ESTIMATES. */
3212 static int
3213 hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates)
3215 int result = 0;
3216 ipa_hints hints = estimates.hints;
3217 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
3218 result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3220 sreal bonus_for_one = opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3222 if (hints & INLINE_HINT_loop_iterations)
3223 result += (estimates.loops_with_known_iterations * bonus_for_one).to_int ();
3225 if (hints & INLINE_HINT_loop_stride)
3226 result += (estimates.loops_with_known_strides * bonus_for_one).to_int ();
3228 return result;
3231 /* If there is a reason to penalize the function described by INFO in the
3232 cloning goodness evaluation, do so. */
3234 static inline sreal
3235 incorporate_penalties (cgraph_node *node, ipa_node_params *info,
3236 sreal evaluation)
3238 if (info->node_within_scc && !info->node_is_self_scc)
3239 evaluation = (evaluation
3240 * (100 - opt_for_fn (node->decl,
3241 param_ipa_cp_recursion_penalty))) / 100;
3243 if (info->node_calling_single_call)
3244 evaluation = (evaluation
3245 * (100 - opt_for_fn (node->decl,
3246 param_ipa_cp_single_call_penalty)))
3247 / 100;
3249 return evaluation;
3252 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3253 and SIZE_COST and with the sum of frequencies of incoming edges to the
3254 potential new clone in FREQUENCIES. */
3256 static bool
3257 good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit,
3258 sreal freq_sum, profile_count count_sum,
3259 int size_cost)
3261 if (time_benefit == 0
3262 || !opt_for_fn (node->decl, flag_ipa_cp_clone)
3263 || node->optimize_for_size_p ())
3264 return false;
3266 gcc_assert (size_cost > 0);
3267 if (size_cost == INT_MAX)
3269 if (dump_file && (dump_flags & TDF_DETAILS))
3270 fprintf (dump_file, " good_cloning_opportunity_p returning "
3271 "false because of size overflow.\n");
3272 return false;
3275 class ipa_node_params *info = IPA_NODE_REF (node);
3276 int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
3277 if (max_count > profile_count::zero ())
3280 sreal factor = count_sum.probability_in (max_count).to_sreal ();
3281 sreal evaluation = (time_benefit * factor) / size_cost;
3282 evaluation = incorporate_penalties (node, info, evaluation);
3283 evaluation *= 1000;
3285 if (dump_file && (dump_flags & TDF_DETAILS))
3287 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3288 "size: %i, count_sum: ", time_benefit.to_double (),
3289 size_cost);
3290 count_sum.dump (dump_file);
3291 fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n",
3292 info->node_within_scc
3293 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3294 info->node_calling_single_call ? ", single_call" : "",
3295 evaluation.to_double (), eval_threshold);
3298 return evaluation.to_int () >= eval_threshold;
3300 else
3302 sreal evaluation = (time_benefit * freq_sum) / size_cost;
3303 evaluation = incorporate_penalties (node, info, evaluation);
3304 evaluation *= 1000;
3306 if (dump_file && (dump_flags & TDF_DETAILS))
3307 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3308 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
3309 "threshold: %i\n",
3310 time_benefit.to_double (), size_cost, freq_sum.to_double (),
3311 info->node_within_scc
3312 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3313 info->node_calling_single_call ? ", single_call" : "",
3314 evaluation.to_double (), eval_threshold);
3316 return evaluation.to_int () >= eval_threshold;
3320 /* Return all context independent values from aggregate lattices in PLATS in a
3321 vector. Return NULL if there are none. */
3323 static vec<ipa_agg_value>
3324 context_independent_aggregate_values (class ipcp_param_lattices *plats)
3326 vec<ipa_agg_value> res = vNULL;
3328 if (plats->aggs_bottom
3329 || plats->aggs_contain_variable
3330 || plats->aggs_count == 0)
3331 return vNULL;
3333 for (struct ipcp_agg_lattice *aglat = plats->aggs;
3334 aglat;
3335 aglat = aglat->next)
3336 if (aglat->is_single_const ())
3338 struct ipa_agg_value item;
3339 item.offset = aglat->offset;
3340 item.value = aglat->values->value;
3341 res.safe_push (item);
3343 return res;
3346 /* Grow vectors in AVALS and fill them with information about values of
3347 parameters that are known to be independent of the context. Only calculate
3348 m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If
3349 REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
3350 parameters will be stored in it.
3352 TODO: Also grow context independent value range vectors. */
3354 static bool
3355 gather_context_independent_values (class ipa_node_params *info,
3356 ipa_auto_call_arg_values *avals,
3357 bool calculate_aggs,
3358 int *removable_params_cost)
3360 int i, count = ipa_get_param_count (info);
3361 bool ret = false;
3363 avals->m_known_vals.safe_grow_cleared (count, true);
3364 avals->m_known_contexts.safe_grow_cleared (count, true);
3365 if (calculate_aggs)
3366 avals->m_known_aggs.safe_grow_cleared (count, true);
3368 if (removable_params_cost)
3369 *removable_params_cost = 0;
3371 for (i = 0; i < count; i++)
3373 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3374 ipcp_lattice<tree> *lat = &plats->itself;
3376 if (lat->is_single_const ())
3378 ipcp_value<tree> *val = lat->values;
3379 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3380 avals->m_known_vals[i] = val->value;
3381 if (removable_params_cost)
3382 *removable_params_cost
3383 += estimate_move_cost (TREE_TYPE (val->value), false);
3384 ret = true;
3386 else if (removable_params_cost
3387 && !ipa_is_param_used (info, i))
3388 *removable_params_cost
3389 += ipa_get_param_move_cost (info, i);
3391 if (!ipa_is_param_used (info, i))
3392 continue;
3394 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3395 /* Do not account known context as reason for cloning. We can see
3396 if it permits devirtualization. */
3397 if (ctxlat->is_single_const ())
3398 avals->m_known_contexts[i] = ctxlat->values->value;
3400 if (calculate_aggs)
3402 vec<ipa_agg_value> agg_items;
3403 struct ipa_agg_value_set *agg;
3405 agg_items = context_independent_aggregate_values (plats);
3406 agg = &avals->m_known_aggs[i];
3407 agg->items = agg_items;
3408 agg->by_ref = plats->aggs_by_ref;
3409 ret |= !agg_items.is_empty ();
3413 return ret;
3416 /* Perform time and size measurement of NODE with the context given in AVALS,
3417 calculate the benefit compared to the node without specialization and store
3418 it into VAL. Take into account REMOVABLE_PARAMS_COST of all
3419 context-independent or unused removable parameters and EST_MOVE_COST, the
3420 estimated movement of the considered parameter. */
3422 static void
3423 perform_estimation_of_a_value (cgraph_node *node,
3424 ipa_auto_call_arg_values *avals,
3425 int removable_params_cost, int est_move_cost,
3426 ipcp_value_base *val)
3428 sreal time_benefit;
3429 ipa_call_estimates estimates;
3431 estimate_ipcp_clone_size_and_time (node, avals, &estimates);
3433 /* Extern inline functions have no cloning local time benefits because they
3434 will be inlined anyway. The only reason to clone them is if it enables
3435 optimization in any of the functions they call. */
3436 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3437 time_benefit = 0;
3438 else
3439 time_benefit = (estimates.nonspecialized_time - estimates.time)
3440 + (devirtualization_time_bonus (node, avals)
3441 + hint_time_bonus (node, estimates)
3442 + removable_params_cost + est_move_cost);
3444 int size = estimates.size;
3445 gcc_checking_assert (size >=0);
3446 /* The inliner-heuristics based estimates may think that in certain
3447 contexts some functions do not have any size at all but we want
3448 all specializations to have at least a tiny cost, not least not to
3449 divide by zero. */
3450 if (size == 0)
3451 size = 1;
3453 val->local_time_benefit = time_benefit;
3454 val->local_size_cost = size;
3457 /* Get the overall limit oof growth based on parameters extracted from growth.
3458 it does not really make sense to mix functions with different overall growth
3459 limits but it is possible and if it happens, we do not want to select one
3460 limit at random. */
3462 static long
3463 get_max_overall_size (cgraph_node *node)
3465 long max_new_size = orig_overall_size;
3466 long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns);
3467 if (max_new_size < large_unit)
3468 max_new_size = large_unit;
3469 int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
3470 max_new_size += max_new_size * unit_growth / 100 + 1;
3471 return max_new_size;
3474 /* Iterate over known values of parameters of NODE and estimate the local
3475 effects in terms of time and size they have. */
3477 static void
3478 estimate_local_effects (struct cgraph_node *node)
3480 class ipa_node_params *info = IPA_NODE_REF (node);
3481 int i, count = ipa_get_param_count (info);
3482 bool always_const;
3483 int removable_params_cost;
3485 if (!count || !ipcp_versionable_function_p (node))
3486 return;
3488 if (dump_file && (dump_flags & TDF_DETAILS))
3489 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
3491 ipa_auto_call_arg_values avals;
3492 always_const = gather_context_independent_values (info, &avals, true,
3493 &removable_params_cost);
3494 int devirt_bonus = devirtualization_time_bonus (node, &avals);
3495 if (always_const || devirt_bonus
3496 || (removable_params_cost && node->can_change_signature))
3498 struct caller_statistics stats;
3499 ipa_call_estimates estimates;
3501 init_caller_stats (&stats);
3502 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3503 false);
3504 estimate_ipcp_clone_size_and_time (node, &avals, &estimates);
3505 sreal time = estimates.nonspecialized_time - estimates.time;
3506 time += devirt_bonus;
3507 time += hint_time_bonus (node, estimates);
3508 time += removable_params_cost;
3509 int size = estimates.size - stats.n_calls * removable_params_cost;
3511 if (dump_file)
3512 fprintf (dump_file, " - context independent values, size: %i, "
3513 "time_benefit: %f\n", size, (time).to_double ());
3515 if (size <= 0 || node->local)
3517 info->do_clone_for_all_contexts = true;
3519 if (dump_file)
3520 fprintf (dump_file, " Decided to specialize for all "
3521 "known contexts, code not going to grow.\n");
3523 else if (good_cloning_opportunity_p (node, time, stats.freq_sum,
3524 stats.count_sum, size))
3526 if (size + overall_size <= get_max_overall_size (node))
3528 info->do_clone_for_all_contexts = true;
3529 overall_size += size;
3531 if (dump_file)
3532 fprintf (dump_file, " Decided to specialize for all "
3533 "known contexts, growth (to %li) deemed "
3534 "beneficial.\n", overall_size);
3536 else if (dump_file && (dump_flags & TDF_DETAILS))
3537 fprintf (dump_file, " Not cloning for all contexts because "
3538 "maximum unit size would be reached with %li.\n",
3539 size + overall_size);
3541 else if (dump_file && (dump_flags & TDF_DETAILS))
3542 fprintf (dump_file, " Not cloning for all contexts because "
3543 "!good_cloning_opportunity_p.\n");
3547 for (i = 0; i < count; i++)
3549 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3550 ipcp_lattice<tree> *lat = &plats->itself;
3551 ipcp_value<tree> *val;
3553 if (lat->bottom
3554 || !lat->values
3555 || avals.m_known_vals[i])
3556 continue;
3558 for (val = lat->values; val; val = val->next)
3560 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3561 avals.m_known_vals[i] = val->value;
3563 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
3564 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3565 emc, val);
3567 if (dump_file && (dump_flags & TDF_DETAILS))
3569 fprintf (dump_file, " - estimates for value ");
3570 print_ipcp_constant_value (dump_file, val->value);
3571 fprintf (dump_file, " for ");
3572 ipa_dump_param (dump_file, info, i);
3573 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3574 val->local_time_benefit.to_double (),
3575 val->local_size_cost);
3578 avals.m_known_vals[i] = NULL_TREE;
3581 for (i = 0; i < count; i++)
3583 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3585 if (!plats->virt_call)
3586 continue;
3588 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3589 ipcp_value<ipa_polymorphic_call_context> *val;
3591 if (ctxlat->bottom
3592 || !ctxlat->values
3593 || !avals.m_known_contexts[i].useless_p ())
3594 continue;
3596 for (val = ctxlat->values; val; val = val->next)
3598 avals.m_known_contexts[i] = val->value;
3599 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3600 0, val);
3602 if (dump_file && (dump_flags & TDF_DETAILS))
3604 fprintf (dump_file, " - estimates for polymorphic context ");
3605 print_ipcp_constant_value (dump_file, val->value);
3606 fprintf (dump_file, " for ");
3607 ipa_dump_param (dump_file, info, i);
3608 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3609 val->local_time_benefit.to_double (),
3610 val->local_size_cost);
3613 avals.m_known_contexts[i] = ipa_polymorphic_call_context ();
3616 for (i = 0; i < count; i++)
3618 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3620 if (plats->aggs_bottom || !plats->aggs)
3621 continue;
3623 ipa_agg_value_set *agg = &avals.m_known_aggs[i];
3624 for (ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
3626 ipcp_value<tree> *val;
3627 if (aglat->bottom || !aglat->values
3628 /* If the following is true, the one value is in known_aggs. */
3629 || (!plats->aggs_contain_variable
3630 && aglat->is_single_const ()))
3631 continue;
3633 for (val = aglat->values; val; val = val->next)
3635 struct ipa_agg_value item;
3637 item.offset = aglat->offset;
3638 item.value = val->value;
3639 agg->items.safe_push (item);
3641 perform_estimation_of_a_value (node, &avals,
3642 removable_params_cost, 0, val);
3644 if (dump_file && (dump_flags & TDF_DETAILS))
3646 fprintf (dump_file, " - estimates for value ");
3647 print_ipcp_constant_value (dump_file, val->value);
3648 fprintf (dump_file, " for ");
3649 ipa_dump_param (dump_file, info, i);
3650 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3651 "]: time_benefit: %g, size: %i\n",
3652 plats->aggs_by_ref ? "ref " : "",
3653 aglat->offset,
3654 val->local_time_benefit.to_double (),
3655 val->local_size_cost);
3658 agg->items.pop ();
3665 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3666 topological sort of values. */
3668 template <typename valtype>
3669 void
3670 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
3672 ipcp_value_source<valtype> *src;
3674 if (cur_val->dfs)
3675 return;
3677 dfs_counter++;
3678 cur_val->dfs = dfs_counter;
3679 cur_val->low_link = dfs_counter;
3681 cur_val->topo_next = stack;
3682 stack = cur_val;
3683 cur_val->on_stack = true;
3685 for (src = cur_val->sources; src; src = src->next)
3686 if (src->val)
3688 if (src->val->dfs == 0)
3690 add_val (src->val);
3691 if (src->val->low_link < cur_val->low_link)
3692 cur_val->low_link = src->val->low_link;
3694 else if (src->val->on_stack
3695 && src->val->dfs < cur_val->low_link)
3696 cur_val->low_link = src->val->dfs;
3699 if (cur_val->dfs == cur_val->low_link)
3701 ipcp_value<valtype> *v, *scc_list = NULL;
3705 v = stack;
3706 stack = v->topo_next;
3707 v->on_stack = false;
3709 v->scc_next = scc_list;
3710 scc_list = v;
3712 while (v != cur_val);
3714 cur_val->topo_next = values_topo;
3715 values_topo = cur_val;
3719 /* Add all values in lattices associated with NODE to the topological sort if
3720 they are not there yet. */
3722 static void
3723 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
3725 class ipa_node_params *info = IPA_NODE_REF (node);
3726 int i, count = ipa_get_param_count (info);
3728 for (i = 0; i < count; i++)
3730 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3731 ipcp_lattice<tree> *lat = &plats->itself;
3732 struct ipcp_agg_lattice *aglat;
3734 if (!lat->bottom)
3736 ipcp_value<tree> *val;
3737 for (val = lat->values; val; val = val->next)
3738 topo->constants.add_val (val);
3741 if (!plats->aggs_bottom)
3742 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3743 if (!aglat->bottom)
3745 ipcp_value<tree> *val;
3746 for (val = aglat->values; val; val = val->next)
3747 topo->constants.add_val (val);
3750 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3751 if (!ctxlat->bottom)
3753 ipcp_value<ipa_polymorphic_call_context> *ctxval;
3754 for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
3755 topo->contexts.add_val (ctxval);
3760 /* One pass of constants propagation along the call graph edges, from callers
3761 to callees (requires topological ordering in TOPO), iterate over strongly
3762 connected components. */
3764 static void
3765 propagate_constants_topo (class ipa_topo_info *topo)
3767 int i;
3769 for (i = topo->nnodes - 1; i >= 0; i--)
3771 unsigned j;
3772 struct cgraph_node *v, *node = topo->order[i];
3773 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
3775 /* First, iteratively propagate within the strongly connected component
3776 until all lattices stabilize. */
3777 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3778 if (v->has_gimple_body_p ())
3780 if (opt_for_fn (v->decl, flag_ipa_cp)
3781 && opt_for_fn (v->decl, optimize))
3782 push_node_to_stack (topo, v);
3783 /* When V is not optimized, we can not push it to stack, but
3784 still we need to set all its callees lattices to bottom. */
3785 else
3787 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
3788 propagate_constants_across_call (cs);
3792 v = pop_node_from_stack (topo);
3793 while (v)
3795 struct cgraph_edge *cs;
3796 class ipa_node_params *info = NULL;
3797 bool self_scc = true;
3799 for (cs = v->callees; cs; cs = cs->next_callee)
3800 if (ipa_edge_within_scc (cs))
3802 cgraph_node *callee = cs->callee->function_symbol ();
3804 if (v != callee)
3805 self_scc = false;
3807 if (!info)
3809 info = IPA_NODE_REF (v);
3810 info->node_within_scc = true;
3813 if (propagate_constants_across_call (cs))
3814 push_node_to_stack (topo, callee);
3817 if (info)
3818 info->node_is_self_scc = self_scc;
3820 v = pop_node_from_stack (topo);
3823 /* Afterwards, propagate along edges leading out of the SCC, calculates
3824 the local effects of the discovered constants and all valid values to
3825 their topological sort. */
3826 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3827 if (v->has_gimple_body_p ()
3828 && opt_for_fn (v->decl, flag_ipa_cp)
3829 && opt_for_fn (v->decl, optimize))
3831 struct cgraph_edge *cs;
3833 estimate_local_effects (v);
3834 add_all_node_vals_to_toposort (v, topo);
3835 for (cs = v->callees; cs; cs = cs->next_callee)
3836 if (!ipa_edge_within_scc (cs))
3837 propagate_constants_across_call (cs);
3839 cycle_nodes.release ();
3844 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3845 INT_MAX. */
3847 static int
3848 safe_add (int a, int b)
3850 if (a > INT_MAX/2 || b > INT_MAX/2)
3851 return INT_MAX;
3852 else
3853 return a + b;
3857 /* Propagate the estimated effects of individual values along the topological
3858 from the dependent values to those they depend on. */
3860 template <typename valtype>
3861 void
3862 value_topo_info<valtype>::propagate_effects ()
3864 ipcp_value<valtype> *base;
3866 for (base = values_topo; base; base = base->topo_next)
3868 ipcp_value_source<valtype> *src;
3869 ipcp_value<valtype> *val;
3870 sreal time = 0;
3871 int size = 0;
3873 for (val = base; val; val = val->scc_next)
3875 time = time + val->local_time_benefit + val->prop_time_benefit;
3876 size = safe_add (size, safe_add (val->local_size_cost,
3877 val->prop_size_cost));
3880 for (val = base; val; val = val->scc_next)
3881 for (src = val->sources; src; src = src->next)
3882 if (src->val
3883 && src->cs->maybe_hot_p ())
3885 src->val->prop_time_benefit = time + src->val->prop_time_benefit;
3886 src->val->prop_size_cost = safe_add (size,
3887 src->val->prop_size_cost);
3893 /* Propagate constants, polymorphic contexts and their effects from the
3894 summaries interprocedurally. */
3896 static void
3897 ipcp_propagate_stage (class ipa_topo_info *topo)
3899 struct cgraph_node *node;
3901 if (dump_file)
3902 fprintf (dump_file, "\n Propagating constants:\n\n");
3904 max_count = profile_count::uninitialized ();
3906 FOR_EACH_DEFINED_FUNCTION (node)
3908 if (node->has_gimple_body_p ()
3909 && opt_for_fn (node->decl, flag_ipa_cp)
3910 && opt_for_fn (node->decl, optimize))
3912 class ipa_node_params *info = IPA_NODE_REF (node);
3913 determine_versionability (node, info);
3915 unsigned nlattices = ipa_get_param_count (info);
3916 void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
3917 info->lattices = new (chunk) ipcp_param_lattices[nlattices];
3918 initialize_node_lattices (node);
3920 ipa_size_summary *s = ipa_size_summaries->get (node);
3921 if (node->definition && !node->alias && s != NULL)
3922 overall_size += s->self_size;
3923 max_count = max_count.max (node->count.ipa ());
3926 orig_overall_size = overall_size;
3928 if (dump_file)
3929 fprintf (dump_file, "\noverall_size: %li\n", overall_size);
3931 propagate_constants_topo (topo);
3932 if (flag_checking)
3933 ipcp_verify_propagated_values ();
3934 topo->constants.propagate_effects ();
3935 topo->contexts.propagate_effects ();
3937 if (dump_file)
3939 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
3940 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
3944 /* Discover newly direct outgoing edges from NODE which is a new clone with
3945 known KNOWN_CSTS and make them direct. */
3947 static void
3948 ipcp_discover_new_direct_edges (struct cgraph_node *node,
3949 vec<tree> known_csts,
3950 vec<ipa_polymorphic_call_context>
3951 known_contexts,
3952 struct ipa_agg_replacement_value *aggvals)
3954 struct cgraph_edge *ie, *next_ie;
3955 bool found = false;
3957 for (ie = node->indirect_calls; ie; ie = next_ie)
3959 tree target;
3960 bool speculative;
3962 next_ie = ie->next_callee;
3963 target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
3964 vNULL, aggvals, &speculative);
3965 if (target)
3967 bool agg_contents = ie->indirect_info->agg_contents;
3968 bool polymorphic = ie->indirect_info->polymorphic;
3969 int param_index = ie->indirect_info->param_index;
3970 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
3971 speculative);
3972 found = true;
3974 if (cs && !agg_contents && !polymorphic)
3976 class ipa_node_params *info = IPA_NODE_REF (node);
3977 int c = ipa_get_controlled_uses (info, param_index);
3978 if (c != IPA_UNDESCRIBED_USE)
3980 struct ipa_ref *to_del;
3982 c--;
3983 ipa_set_controlled_uses (info, param_index, c);
3984 if (dump_file && (dump_flags & TDF_DETAILS))
3985 fprintf (dump_file, " controlled uses count of param "
3986 "%i bumped down to %i\n", param_index, c);
3987 if (c == 0
3988 && (to_del = node->find_reference (cs->callee, NULL, 0)))
3990 if (dump_file && (dump_flags & TDF_DETAILS))
3991 fprintf (dump_file, " and even removing its "
3992 "cloning-created reference\n");
3993 to_del->remove_reference ();
3999 /* Turning calls to direct calls will improve overall summary. */
4000 if (found)
4001 ipa_update_overall_fn_summary (node);
4004 class edge_clone_summary;
4005 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
4007 /* Edge clone summary. */
4009 class edge_clone_summary
4011 public:
4012 /* Default constructor. */
4013 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
4015 /* Default destructor. */
4016 ~edge_clone_summary ()
4018 if (prev_clone)
4019 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
4020 if (next_clone)
4021 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
4024 cgraph_edge *prev_clone;
4025 cgraph_edge *next_clone;
4028 class edge_clone_summary_t:
4029 public call_summary <edge_clone_summary *>
4031 public:
4032 edge_clone_summary_t (symbol_table *symtab):
4033 call_summary <edge_clone_summary *> (symtab)
4035 m_initialize_when_cloning = true;
4038 virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4039 edge_clone_summary *src_data,
4040 edge_clone_summary *dst_data);
4043 /* Edge duplication hook. */
4045 void
4046 edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4047 edge_clone_summary *src_data,
4048 edge_clone_summary *dst_data)
4050 if (src_data->next_clone)
4051 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
4052 dst_data->prev_clone = src_edge;
4053 dst_data->next_clone = src_data->next_clone;
4054 src_data->next_clone = dst_edge;
4057 /* Return true is CS calls DEST or its clone for all contexts. When
4058 ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
4059 edges from/to an all-context clone. */
4061 static bool
4062 calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest,
4063 bool allow_recursion_to_clone)
4065 enum availability availability;
4066 cgraph_node *callee = cs->callee->function_symbol (&availability);
4068 if (availability <= AVAIL_INTERPOSABLE)
4069 return false;
4070 if (callee == dest)
4071 return true;
4072 if (!allow_recursion_to_clone && cs->caller == callee)
4073 return false;
4075 class ipa_node_params *info = IPA_NODE_REF (callee);
4076 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
4079 /* Return true if edge CS does bring about the value described by SRC to
4080 DEST_VAL of node DEST or its clone for all contexts. */
4082 static bool
4083 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
4084 cgraph_node *dest, ipcp_value<tree> *dest_val)
4086 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4088 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val)
4089 || caller_info->node_dead)
4090 return false;
4092 if (!src->val)
4093 return true;
4095 if (caller_info->ipcp_orig_node)
4097 tree t;
4098 if (src->offset == -1)
4099 t = caller_info->known_csts[src->index];
4100 else
4101 t = get_clone_agg_value (cs->caller, src->offset, src->index);
4102 return (t != NULL_TREE
4103 && values_equal_for_ipcp_p (src->val->value, t));
4105 else
4107 if (src->val == dest_val)
4108 return true;
4110 struct ipcp_agg_lattice *aglat;
4111 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4112 src->index);
4113 if (src->offset == -1)
4114 return (plats->itself.is_single_const ()
4115 && values_equal_for_ipcp_p (src->val->value,
4116 plats->itself.values->value));
4117 else
4119 if (plats->aggs_bottom || plats->aggs_contain_variable)
4120 return false;
4121 for (aglat = plats->aggs; aglat; aglat = aglat->next)
4122 if (aglat->offset == src->offset)
4123 return (aglat->is_single_const ()
4124 && values_equal_for_ipcp_p (src->val->value,
4125 aglat->values->value));
4127 return false;
4131 /* Return true if edge CS does bring about the value described by SRC to
4132 DST_VAL of node DEST or its clone for all contexts. */
4134 static bool
4135 cgraph_edge_brings_value_p (cgraph_edge *cs,
4136 ipcp_value_source<ipa_polymorphic_call_context> *src,
4137 cgraph_node *dest,
4138 ipcp_value<ipa_polymorphic_call_context> *)
4140 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4142 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true)
4143 || caller_info->node_dead)
4144 return false;
4145 if (!src->val)
4146 return true;
4148 if (caller_info->ipcp_orig_node)
4149 return (caller_info->known_contexts.length () > (unsigned) src->index)
4150 && values_equal_for_ipcp_p (src->val->value,
4151 caller_info->known_contexts[src->index]);
4153 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4154 src->index);
4155 return plats->ctxlat.is_single_const ()
4156 && values_equal_for_ipcp_p (src->val->value,
4157 plats->ctxlat.values->value);
4160 /* Get the next clone in the linked list of clones of an edge. */
4162 static inline struct cgraph_edge *
4163 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
4165 edge_clone_summary *s = edge_clone_summaries->get (cs);
4166 return s != NULL ? s->next_clone : NULL;
4169 /* Given VAL that is intended for DEST, iterate over all its sources and if any
4170 of them is viable and hot, return true. In that case, for those that still
4171 hold, add their edge frequency and their number into *FREQUENCY and
4172 *CALLER_COUNT respectively. */
4174 template <typename valtype>
4175 static bool
4176 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
4177 sreal *freq_sum, profile_count *count_sum,
4178 int *caller_count)
4180 ipcp_value_source<valtype> *src;
4181 sreal freq = 0;
4182 int count = 0;
4183 profile_count cnt = profile_count::zero ();
4184 bool hot = false;
4185 bool non_self_recursive = false;
4187 for (src = val->sources; src; src = src->next)
4189 struct cgraph_edge *cs = src->cs;
4190 while (cs)
4192 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4194 count++;
4195 freq += cs->sreal_frequency ();
4196 if (cs->count.ipa ().initialized_p ())
4197 cnt += cs->count.ipa ();
4198 hot |= cs->maybe_hot_p ();
4199 if (cs->caller != dest)
4200 non_self_recursive = true;
4202 cs = get_next_cgraph_edge_clone (cs);
4206 /* If the only edges bringing a value are self-recursive ones, do not bother
4207 evaluating it. */
4208 if (!non_self_recursive)
4209 return false;
4211 *freq_sum = freq;
4212 *count_sum = cnt;
4213 *caller_count = count;
4215 if (!hot && IPA_NODE_REF (dest)->node_within_scc)
4217 struct cgraph_edge *cs;
4219 /* Cold non-SCC source edge could trigger hot recursive execution of
4220 function. Consider the case as hot and rely on following cost model
4221 computation to further select right one. */
4222 for (cs = dest->callers; cs; cs = cs->next_caller)
4223 if (cs->caller == dest && cs->maybe_hot_p ())
4224 return true;
4227 return hot;
4230 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4231 to let a non-self-recursive caller be the first element. Thus, we can
4232 simplify intersecting operations on values that arrive from all of these
4233 callers, especially when there exists self-recursive call. Return true if
4234 this kind of adjustment is possible. */
4236 static bool
4237 adjust_callers_for_value_intersection (vec<cgraph_edge *> callers,
4238 cgraph_node *node)
4240 for (unsigned i = 0; i < callers.length (); i++)
4242 cgraph_edge *cs = callers[i];
4244 if (cs->caller != node)
4246 if (i > 0)
4248 callers[i] = callers[0];
4249 callers[0] = cs;
4251 return true;
4254 return false;
4257 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
4258 is assumed their number is known and equal to CALLER_COUNT. */
4260 template <typename valtype>
4261 static vec<cgraph_edge *>
4262 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
4263 int caller_count)
4265 ipcp_value_source<valtype> *src;
4266 vec<cgraph_edge *> ret;
4268 ret.create (caller_count);
4269 for (src = val->sources; src; src = src->next)
4271 struct cgraph_edge *cs = src->cs;
4272 while (cs)
4274 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4275 ret.quick_push (cs);
4276 cs = get_next_cgraph_edge_clone (cs);
4280 if (caller_count > 1)
4281 adjust_callers_for_value_intersection (ret, dest);
4283 return ret;
4286 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4287 Return it or NULL if for some reason it cannot be created. */
4289 static struct ipa_replace_map *
4290 get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
4292 struct ipa_replace_map *replace_map;
4294 replace_map = ggc_alloc<ipa_replace_map> ();
4295 if (dump_file)
4297 fprintf (dump_file, " replacing ");
4298 ipa_dump_param (dump_file, info, parm_num);
4300 fprintf (dump_file, " with const ");
4301 print_generic_expr (dump_file, value);
4302 fprintf (dump_file, "\n");
4304 replace_map->parm_num = parm_num;
4305 replace_map->new_tree = value;
4306 return replace_map;
4309 /* Dump new profiling counts */
4311 static void
4312 dump_profile_updates (struct cgraph_node *orig_node,
4313 struct cgraph_node *new_node)
4315 struct cgraph_edge *cs;
4317 fprintf (dump_file, " setting count of the specialized node to ");
4318 new_node->count.dump (dump_file);
4319 fprintf (dump_file, "\n");
4320 for (cs = new_node->callees; cs; cs = cs->next_callee)
4322 fprintf (dump_file, " edge to %s has count ",
4323 cs->callee->dump_name ());
4324 cs->count.dump (dump_file);
4325 fprintf (dump_file, "\n");
4328 fprintf (dump_file, " setting count of the original node to ");
4329 orig_node->count.dump (dump_file);
4330 fprintf (dump_file, "\n");
4331 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4333 fprintf (dump_file, " edge to %s is left with ",
4334 cs->callee->dump_name ());
4335 cs->count.dump (dump_file);
4336 fprintf (dump_file, "\n");
4340 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4341 their profile information to reflect this. */
4343 static void
4344 update_profiling_info (struct cgraph_node *orig_node,
4345 struct cgraph_node *new_node)
4347 struct cgraph_edge *cs;
4348 struct caller_statistics stats;
4349 profile_count new_sum, orig_sum;
4350 profile_count remainder, orig_node_count = orig_node->count;
4351 profile_count orig_new_node_count = new_node->count;
4353 if (!(orig_node_count.ipa () > profile_count::zero ()))
4354 return;
4356 init_caller_stats (&stats);
4357 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4358 false);
4359 orig_sum = stats.count_sum;
4360 init_caller_stats (&stats);
4361 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4362 false);
4363 new_sum = stats.count_sum;
4365 if (orig_node_count < orig_sum + new_sum)
4367 if (dump_file)
4369 fprintf (dump_file, " Problem: node %s has too low count ",
4370 orig_node->dump_name ());
4371 orig_node_count.dump (dump_file);
4372 fprintf (dump_file, "while the sum of incoming count is ");
4373 (orig_sum + new_sum).dump (dump_file);
4374 fprintf (dump_file, "\n");
4377 orig_node_count = (orig_sum + new_sum).apply_scale (12, 10);
4378 if (dump_file)
4380 fprintf (dump_file, " proceeding by pretending it was ");
4381 orig_node_count.dump (dump_file);
4382 fprintf (dump_file, "\n");
4386 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
4387 - new_sum.ipa ());
4389 /* With partial train run we do not want to assume that original's
4390 count is zero whenever we redurect all executed edges to clone.
4391 Simply drop profile to local one in this case. */
4392 if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
4393 && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
4394 && flag_profile_partial_training)
4395 remainder = remainder.guessed_local ();
4397 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
4398 new_node->count = new_sum;
4399 orig_node->count = remainder;
4401 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
4402 for (cs = new_node->callees; cs; cs = cs->next_callee)
4403 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4404 for (cs = new_node->indirect_calls; cs; cs = cs->next_callee)
4405 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4407 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
4408 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4409 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4410 for (cs = orig_node->indirect_calls; cs; cs = cs->next_callee)
4411 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4413 if (dump_file)
4414 dump_profile_updates (orig_node, new_node);
4417 /* Update the respective profile of specialized NEW_NODE and the original
4418 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4419 have been redirected to the specialized version. */
4421 static void
4422 update_specialized_profile (struct cgraph_node *new_node,
4423 struct cgraph_node *orig_node,
4424 profile_count redirected_sum)
4426 struct cgraph_edge *cs;
4427 profile_count new_node_count, orig_node_count = orig_node->count;
4429 if (dump_file)
4431 fprintf (dump_file, " the sum of counts of redirected edges is ");
4432 redirected_sum.dump (dump_file);
4433 fprintf (dump_file, "\n");
4435 if (!(orig_node_count > profile_count::zero ()))
4436 return;
4438 gcc_assert (orig_node_count >= redirected_sum);
4440 new_node_count = new_node->count;
4441 new_node->count += redirected_sum;
4442 orig_node->count -= redirected_sum;
4444 for (cs = new_node->callees; cs; cs = cs->next_callee)
4445 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
4447 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4449 profile_count dec = cs->count.apply_scale (redirected_sum,
4450 orig_node_count);
4451 cs->count -= dec;
4454 if (dump_file)
4455 dump_profile_updates (orig_node, new_node);
4458 /* Return true if we would like to remove a parameter from NODE when cloning it
4459 with KNOWN_CSTS scalar constants. */
4461 static bool
4462 want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
4464 auto_vec<bool, 16> surviving;
4465 bool filled_vec = false;
4466 ipa_node_params *info = IPA_NODE_REF (node);
4467 int i, count = ipa_get_param_count (info);
4469 for (i = 0; i < count; i++)
4471 if (!known_csts[i] && ipa_is_param_used (info, i))
4472 continue;
4474 if (!filled_vec)
4476 clone_info *info = clone_info::get (node);
4477 if (!info || !info->param_adjustments)
4478 return true;
4479 info->param_adjustments->get_surviving_params (&surviving);
4480 filled_vec = true;
4482 if (surviving.length() < (unsigned) i && surviving[i])
4483 return true;
4485 return false;
4488 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4489 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4490 redirect all edges in CALLERS to it. */
4492 static struct cgraph_node *
4493 create_specialized_node (struct cgraph_node *node,
4494 vec<tree> known_csts,
4495 vec<ipa_polymorphic_call_context> known_contexts,
4496 struct ipa_agg_replacement_value *aggvals,
4497 vec<cgraph_edge *> callers)
4499 class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
4500 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
4501 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
4502 struct ipa_agg_replacement_value *av;
4503 struct cgraph_node *new_node;
4504 int i, count = ipa_get_param_count (info);
4505 clone_info *cinfo = clone_info::get (node);
4506 ipa_param_adjustments *old_adjustments = cinfo
4507 ? cinfo->param_adjustments : NULL;
4508 ipa_param_adjustments *new_adjustments;
4509 gcc_assert (!info->ipcp_orig_node);
4510 gcc_assert (node->can_change_signature
4511 || !old_adjustments);
4513 if (old_adjustments)
4515 /* At the moment all IPA optimizations should use the number of
4516 parameters of the prevailing decl as the m_always_copy_start.
4517 Handling any other value would complicate the code below, so for the
4518 time bing let's only assert it is so. */
4519 gcc_assert (old_adjustments->m_always_copy_start == count
4520 || old_adjustments->m_always_copy_start < 0);
4521 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
4522 for (i = 0; i < old_adj_count; i++)
4524 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
4525 if (!node->can_change_signature
4526 || old_adj->op != IPA_PARAM_OP_COPY
4527 || (!known_csts[old_adj->base_index]
4528 && ipa_is_param_used (info, old_adj->base_index)))
4530 ipa_adjusted_param new_adj = *old_adj;
4532 new_adj.prev_clone_adjustment = true;
4533 new_adj.prev_clone_index = i;
4534 vec_safe_push (new_params, new_adj);
4537 bool skip_return = old_adjustments->m_skip_return;
4538 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4539 ipa_param_adjustments (new_params, count,
4540 skip_return));
4542 else if (node->can_change_signature
4543 && want_remove_some_param_p (node, known_csts))
4545 ipa_adjusted_param adj;
4546 memset (&adj, 0, sizeof (adj));
4547 adj.op = IPA_PARAM_OP_COPY;
4548 for (i = 0; i < count; i++)
4549 if (!known_csts[i] && ipa_is_param_used (info, i))
4551 adj.base_index = i;
4552 adj.prev_clone_index = i;
4553 vec_safe_push (new_params, adj);
4555 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4556 ipa_param_adjustments (new_params, count, false));
4558 else
4559 new_adjustments = NULL;
4561 replace_trees = cinfo ? vec_safe_copy (cinfo->tree_map) : NULL;
4562 for (i = 0; i < count; i++)
4564 tree t = known_csts[i];
4565 if (t)
4567 struct ipa_replace_map *replace_map;
4569 gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
4570 replace_map = get_replacement_map (info, t, i);
4571 if (replace_map)
4572 vec_safe_push (replace_trees, replace_map);
4575 auto_vec<cgraph_edge *, 2> self_recursive_calls;
4576 for (i = callers.length () - 1; i >= 0; i--)
4578 cgraph_edge *cs = callers[i];
4579 if (cs->caller == node)
4581 self_recursive_calls.safe_push (cs);
4582 callers.unordered_remove (i);
4586 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
4587 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4588 node->decl)));
4589 new_node = node->create_virtual_clone (callers, replace_trees,
4590 new_adjustments, "constprop",
4591 suffix_counter);
4592 suffix_counter++;
4594 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
4595 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
4597 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
4598 /* Cloned edges can disappear during cloning as speculation can be
4599 resolved, check that we have one and that it comes from the last
4600 cloning. */
4601 if (cs && cs->caller == new_node)
4602 cs->redirect_callee_duplicating_thunks (new_node);
4603 /* Any future code that would make more than one clone of an outgoing
4604 edge would confuse this mechanism, so let's check that does not
4605 happen. */
4606 gcc_checking_assert (!cs
4607 || !get_next_cgraph_edge_clone (cs)
4608 || get_next_cgraph_edge_clone (cs)->caller != new_node);
4610 if (have_self_recursive_calls)
4611 new_node->expand_all_artificial_thunks ();
4613 ipa_set_node_agg_value_chain (new_node, aggvals);
4614 for (av = aggvals; av; av = av->next)
4615 new_node->maybe_create_reference (av->value, NULL);
4617 if (dump_file && (dump_flags & TDF_DETAILS))
4619 fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ());
4620 if (known_contexts.exists ())
4622 for (i = 0; i < count; i++)
4623 if (!known_contexts[i].useless_p ())
4625 fprintf (dump_file, " known ctx %i is ", i);
4626 known_contexts[i].dump (dump_file);
4629 if (aggvals)
4630 ipa_dump_agg_replacement_values (dump_file, aggvals);
4632 ipa_check_create_node_params ();
4633 update_profiling_info (node, new_node);
4634 new_info = IPA_NODE_REF (new_node);
4635 new_info->ipcp_orig_node = node;
4636 new_node->ipcp_clone = true;
4637 new_info->known_csts = known_csts;
4638 new_info->known_contexts = known_contexts;
4640 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
4642 callers.release ();
4643 return new_node;
4646 /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
4647 pass-through function to itself when the cgraph_node involved is not an
4648 IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
4649 no-operation pass-through. */
4651 static bool
4652 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
4653 bool simple = true)
4655 enum availability availability;
4656 if (cs->caller == cs->callee->function_symbol (&availability)
4657 && availability > AVAIL_INTERPOSABLE
4658 && jfunc->type == IPA_JF_PASS_THROUGH
4659 && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4660 && ipa_get_jf_pass_through_formal_id (jfunc) == i
4661 && IPA_NODE_REF (cs->caller)
4662 && !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
4663 return true;
4664 return false;
4667 /* Return true if JFUNC, which describes a part of an aggregate represented or
4668 pointed to by the i-th parameter of call CS, is a pass-through function to
4669 itself when the cgraph_node involved is not an IPA-CP clone.. When
4670 SIMPLE is true, further check if JFUNC is a simple no-operation
4671 pass-through. */
4673 static bool
4674 self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
4675 int i, bool simple = true)
4677 enum availability availability;
4678 if (cs->caller == cs->callee->function_symbol (&availability)
4679 && availability > AVAIL_INTERPOSABLE
4680 && jfunc->jftype == IPA_JF_LOAD_AGG
4681 && jfunc->offset == jfunc->value.load_agg.offset
4682 && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
4683 && jfunc->value.pass_through.formal_id == i
4684 && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)
4685 && IPA_NODE_REF (cs->caller)
4686 && !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
4687 return true;
4688 return false;
4691 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
4692 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
4694 static void
4695 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
4696 vec<tree> known_csts,
4697 vec<cgraph_edge *> callers)
4699 class ipa_node_params *info = IPA_NODE_REF (node);
4700 int i, count = ipa_get_param_count (info);
4702 for (i = 0; i < count; i++)
4704 struct cgraph_edge *cs;
4705 tree newval = NULL_TREE;
4706 int j;
4707 bool first = true;
4708 tree type = ipa_get_type (info, i);
4710 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
4711 continue;
4713 FOR_EACH_VEC_ELT (callers, j, cs)
4715 struct ipa_jump_func *jump_func;
4716 tree t;
4718 if (!IPA_EDGE_REF (cs)
4719 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
4720 || (i == 0
4721 && call_passes_through_thunk (cs)))
4723 newval = NULL_TREE;
4724 break;
4726 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
4728 /* Besides simple pass-through jump function, arithmetic jump
4729 function could also introduce argument-direct-pass-through for
4730 self-feeding recursive call. For example,
4732 fn (int i)
4734 fn (i & 1);
4737 Given that i is 0, recursive propagation via (i & 1) also gets
4738 0. */
4739 if (self_recursive_pass_through_p (cs, jump_func, i, false))
4741 gcc_assert (newval);
4742 t = ipa_get_jf_arith_result (
4743 ipa_get_jf_pass_through_operation (jump_func),
4744 newval,
4745 ipa_get_jf_pass_through_operand (jump_func),
4746 type);
4748 else
4749 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func,
4750 type);
4751 if (!t
4752 || (newval
4753 && !values_equal_for_ipcp_p (t, newval))
4754 || (!first && !newval))
4756 newval = NULL_TREE;
4757 break;
4759 else
4760 newval = t;
4761 first = false;
4764 if (newval)
4766 if (dump_file && (dump_flags & TDF_DETAILS))
4768 fprintf (dump_file, " adding an extra known scalar value ");
4769 print_ipcp_constant_value (dump_file, newval);
4770 fprintf (dump_file, " for ");
4771 ipa_dump_param (dump_file, info, i);
4772 fprintf (dump_file, "\n");
4775 known_csts[i] = newval;
4780 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4781 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4782 CALLERS. */
4784 static void
4785 find_more_contexts_for_caller_subset (cgraph_node *node,
4786 vec<ipa_polymorphic_call_context>
4787 *known_contexts,
4788 vec<cgraph_edge *> callers)
4790 ipa_node_params *info = IPA_NODE_REF (node);
4791 int i, count = ipa_get_param_count (info);
4793 for (i = 0; i < count; i++)
4795 cgraph_edge *cs;
4797 if (ipa_get_poly_ctx_lat (info, i)->bottom
4798 || (known_contexts->exists ()
4799 && !(*known_contexts)[i].useless_p ()))
4800 continue;
4802 ipa_polymorphic_call_context newval;
4803 bool first = true;
4804 int j;
4806 FOR_EACH_VEC_ELT (callers, j, cs)
4808 if (!IPA_EDGE_REF (cs)
4809 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
4810 return;
4811 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
4813 ipa_polymorphic_call_context ctx;
4814 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
4815 jfunc);
4816 if (first)
4818 newval = ctx;
4819 first = false;
4821 else
4822 newval.meet_with (ctx);
4823 if (newval.useless_p ())
4824 break;
4827 if (!newval.useless_p ())
4829 if (dump_file && (dump_flags & TDF_DETAILS))
4831 fprintf (dump_file, " adding an extra known polymorphic "
4832 "context ");
4833 print_ipcp_constant_value (dump_file, newval);
4834 fprintf (dump_file, " for ");
4835 ipa_dump_param (dump_file, info, i);
4836 fprintf (dump_file, "\n");
4839 if (!known_contexts->exists ())
4840 known_contexts->safe_grow_cleared (ipa_get_param_count (info),
4841 true);
4842 (*known_contexts)[i] = newval;
4848 /* Go through PLATS and create a vector of values consisting of values and
4849 offsets (minus OFFSET) of lattices that contain only a single value. */
4851 static vec<ipa_agg_value>
4852 copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
4854 vec<ipa_agg_value> res = vNULL;
4856 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4857 return vNULL;
4859 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
4860 if (aglat->is_single_const ())
4862 struct ipa_agg_value ti;
4863 ti.offset = aglat->offset - offset;
4864 ti.value = aglat->values->value;
4865 res.safe_push (ti);
4867 return res;
4870 /* Intersect all values in INTER with single value lattices in PLATS (while
4871 subtracting OFFSET). */
4873 static void
4874 intersect_with_plats (class ipcp_param_lattices *plats,
4875 vec<ipa_agg_value> *inter,
4876 HOST_WIDE_INT offset)
4878 struct ipcp_agg_lattice *aglat;
4879 struct ipa_agg_value *item;
4880 int k;
4882 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4884 inter->release ();
4885 return;
4888 aglat = plats->aggs;
4889 FOR_EACH_VEC_ELT (*inter, k, item)
4891 bool found = false;
4892 if (!item->value)
4893 continue;
4894 while (aglat)
4896 if (aglat->offset - offset > item->offset)
4897 break;
4898 if (aglat->offset - offset == item->offset)
4900 if (aglat->is_single_const ())
4902 tree value = aglat->values->value;
4904 if (values_equal_for_ipcp_p (item->value, value))
4905 found = true;
4907 break;
4909 aglat = aglat->next;
4911 if (!found)
4912 item->value = NULL_TREE;
4916 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4917 vector result while subtracting OFFSET from the individual value offsets. */
4919 static vec<ipa_agg_value>
4920 agg_replacements_to_vector (struct cgraph_node *node, int index,
4921 HOST_WIDE_INT offset)
4923 struct ipa_agg_replacement_value *av;
4924 vec<ipa_agg_value> res = vNULL;
4926 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
4927 if (av->index == index
4928 && (av->offset - offset) >= 0)
4930 struct ipa_agg_value item;
4931 gcc_checking_assert (av->value);
4932 item.offset = av->offset - offset;
4933 item.value = av->value;
4934 res.safe_push (item);
4937 return res;
4940 /* Intersect all values in INTER with those that we have already scheduled to
4941 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4942 (while subtracting OFFSET). */
4944 static void
4945 intersect_with_agg_replacements (struct cgraph_node *node, int index,
4946 vec<ipa_agg_value> *inter,
4947 HOST_WIDE_INT offset)
4949 struct ipa_agg_replacement_value *srcvals;
4950 struct ipa_agg_value *item;
4951 int i;
4953 srcvals = ipa_get_agg_replacements_for_node (node);
4954 if (!srcvals)
4956 inter->release ();
4957 return;
4960 FOR_EACH_VEC_ELT (*inter, i, item)
4962 struct ipa_agg_replacement_value *av;
4963 bool found = false;
4964 if (!item->value)
4965 continue;
4966 for (av = srcvals; av; av = av->next)
4968 gcc_checking_assert (av->value);
4969 if (av->index == index
4970 && av->offset - offset == item->offset)
4972 if (values_equal_for_ipcp_p (item->value, av->value))
4973 found = true;
4974 break;
4977 if (!found)
4978 item->value = NULL_TREE;
4982 /* Intersect values in INTER with aggregate values that come along edge CS to
4983 parameter number INDEX and return it. If INTER does not actually exist yet,
4984 copy all incoming values to it. If we determine we ended up with no values
4985 whatsoever, return a released vector. */
4987 static vec<ipa_agg_value>
4988 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
4989 vec<ipa_agg_value> inter)
4991 struct ipa_jump_func *jfunc;
4992 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
4993 if (jfunc->type == IPA_JF_PASS_THROUGH
4994 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4996 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4997 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
4999 if (caller_info->ipcp_orig_node)
5001 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
5002 class ipcp_param_lattices *orig_plats;
5003 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
5004 src_idx);
5005 if (agg_pass_through_permissible_p (orig_plats, jfunc))
5007 if (!inter.exists ())
5008 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
5009 else
5010 intersect_with_agg_replacements (cs->caller, src_idx,
5011 &inter, 0);
5012 return inter;
5015 else
5017 class ipcp_param_lattices *src_plats;
5018 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
5019 if (agg_pass_through_permissible_p (src_plats, jfunc))
5021 /* Currently we do not produce clobber aggregate jump
5022 functions, adjust when we do. */
5023 gcc_checking_assert (!jfunc->agg.items);
5024 if (!inter.exists ())
5025 inter = copy_plats_to_inter (src_plats, 0);
5026 else
5027 intersect_with_plats (src_plats, &inter, 0);
5028 return inter;
5032 else if (jfunc->type == IPA_JF_ANCESTOR
5033 && ipa_get_jf_ancestor_agg_preserved (jfunc))
5035 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5036 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
5037 class ipcp_param_lattices *src_plats;
5038 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
5040 if (caller_info->ipcp_orig_node)
5042 if (!inter.exists ())
5043 inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
5044 else
5045 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
5046 delta);
5048 else
5050 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
5051 /* Currently we do not produce clobber aggregate jump
5052 functions, adjust when we do. */
5053 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
5054 if (!inter.exists ())
5055 inter = copy_plats_to_inter (src_plats, delta);
5056 else
5057 intersect_with_plats (src_plats, &inter, delta);
5059 return inter;
5062 if (jfunc->agg.items)
5064 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5065 struct ipa_agg_value *item;
5066 int k;
5068 if (!inter.exists ())
5069 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
5071 struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
5072 tree value = ipa_agg_value_from_node (caller_info, cs->caller,
5073 agg_item);
5074 if (value)
5076 struct ipa_agg_value agg_value;
5078 agg_value.value = value;
5079 agg_value.offset = agg_item->offset;
5080 inter.safe_push (agg_value);
5083 else
5084 FOR_EACH_VEC_ELT (inter, k, item)
5086 int l = 0;
5087 bool found = false;
5089 if (!item->value)
5090 continue;
5092 while ((unsigned) l < jfunc->agg.items->length ())
5094 struct ipa_agg_jf_item *ti;
5095 ti = &(*jfunc->agg.items)[l];
5096 if (ti->offset > item->offset)
5097 break;
5098 if (ti->offset == item->offset)
5100 tree value;
5102 /* Besides simple pass-through aggregate jump function,
5103 arithmetic aggregate jump function could also bring
5104 same aggregate value as parameter passed-in for
5105 self-feeding recursive call. For example,
5107 fn (int *i)
5109 int j = *i & 1;
5110 fn (&j);
5113 Given that *i is 0, recursive propagation via (*i & 1)
5114 also gets 0. */
5115 if (self_recursive_agg_pass_through_p (cs, ti, index,
5116 false))
5117 value = ipa_get_jf_arith_result (
5118 ti->value.pass_through.operation,
5119 item->value,
5120 ti->value.pass_through.operand,
5121 ti->type);
5122 else
5123 value = ipa_agg_value_from_node (caller_info,
5124 cs->caller, ti);
5126 if (value && values_equal_for_ipcp_p (item->value, value))
5127 found = true;
5128 break;
5130 l++;
5132 if (!found)
5133 item->value = NULL;
5136 else
5138 inter.release ();
5139 return vNULL;
5141 return inter;
5144 /* Look at edges in CALLERS and collect all known aggregate values that arrive
5145 from all of them. */
5147 static struct ipa_agg_replacement_value *
5148 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
5149 vec<cgraph_edge *> callers)
5151 class ipa_node_params *dest_info = IPA_NODE_REF (node);
5152 struct ipa_agg_replacement_value *res;
5153 struct ipa_agg_replacement_value **tail = &res;
5154 struct cgraph_edge *cs;
5155 int i, j, count = ipa_get_param_count (dest_info);
5157 FOR_EACH_VEC_ELT (callers, j, cs)
5159 if (!IPA_EDGE_REF (cs))
5161 count = 0;
5162 break;
5164 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5165 if (c < count)
5166 count = c;
5169 for (i = 0; i < count; i++)
5171 struct cgraph_edge *cs;
5172 vec<ipa_agg_value> inter = vNULL;
5173 struct ipa_agg_value *item;
5174 class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
5175 int j;
5177 /* Among other things, the following check should deal with all by_ref
5178 mismatches. */
5179 if (plats->aggs_bottom)
5180 continue;
5182 FOR_EACH_VEC_ELT (callers, j, cs)
5184 struct ipa_jump_func *jfunc
5185 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
5186 if (self_recursive_pass_through_p (cs, jfunc, i)
5187 && (!plats->aggs_by_ref
5188 || ipa_get_jf_pass_through_agg_preserved (jfunc)))
5189 continue;
5190 inter = intersect_aggregates_with_edge (cs, i, inter);
5192 if (!inter.exists ())
5193 goto next_param;
5196 FOR_EACH_VEC_ELT (inter, j, item)
5198 struct ipa_agg_replacement_value *v;
5200 if (!item->value)
5201 continue;
5203 v = ggc_alloc<ipa_agg_replacement_value> ();
5204 v->index = i;
5205 v->offset = item->offset;
5206 v->value = item->value;
5207 v->by_ref = plats->aggs_by_ref;
5208 *tail = v;
5209 tail = &v->next;
5212 next_param:
5213 if (inter.exists ())
5214 inter.release ();
5216 *tail = NULL;
5217 return res;
5220 /* Determine whether CS also brings all scalar values that the NODE is
5221 specialized for. */
5223 static bool
5224 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
5225 struct cgraph_node *node)
5227 class ipa_node_params *dest_info = IPA_NODE_REF (node);
5228 int count = ipa_get_param_count (dest_info);
5229 class ipa_node_params *caller_info;
5230 class ipa_edge_args *args;
5231 int i;
5233 caller_info = IPA_NODE_REF (cs->caller);
5234 args = IPA_EDGE_REF (cs);
5235 for (i = 0; i < count; i++)
5237 struct ipa_jump_func *jump_func;
5238 tree val, t;
5240 val = dest_info->known_csts[i];
5241 if (!val)
5242 continue;
5244 if (i >= ipa_get_cs_argument_count (args))
5245 return false;
5246 jump_func = ipa_get_ith_jump_func (args, i);
5247 t = ipa_value_from_jfunc (caller_info, jump_func,
5248 ipa_get_type (dest_info, i));
5249 if (!t || !values_equal_for_ipcp_p (val, t))
5250 return false;
5252 return true;
5255 /* Determine whether CS also brings all aggregate values that NODE is
5256 specialized for. */
5257 static bool
5258 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
5259 struct cgraph_node *node)
5261 class ipa_node_params *orig_node_info;
5262 struct ipa_agg_replacement_value *aggval;
5263 int i, ec, count;
5265 aggval = ipa_get_agg_replacements_for_node (node);
5266 if (!aggval)
5267 return true;
5269 count = ipa_get_param_count (IPA_NODE_REF (node));
5270 ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5271 if (ec < count)
5272 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5273 if (aggval->index >= ec)
5274 return false;
5276 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
5278 for (i = 0; i < count; i++)
5280 class ipcp_param_lattices *plats;
5281 bool interesting = false;
5282 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5283 if (aggval->index == i)
5285 interesting = true;
5286 break;
5288 if (!interesting)
5289 continue;
5291 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
5292 if (plats->aggs_bottom)
5293 return false;
5295 vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL);
5296 if (!values.exists ())
5297 return false;
5299 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5300 if (aggval->index == i)
5302 struct ipa_agg_value *item;
5303 int j;
5304 bool found = false;
5305 FOR_EACH_VEC_ELT (values, j, item)
5306 if (item->value
5307 && item->offset == av->offset
5308 && values_equal_for_ipcp_p (item->value, av->value))
5310 found = true;
5311 break;
5313 if (!found)
5315 values.release ();
5316 return false;
5319 values.release ();
5321 return true;
5324 /* Given an original NODE and a VAL for which we have already created a
5325 specialized clone, look whether there are incoming edges that still lead
5326 into the old node but now also bring the requested value and also conform to
5327 all other criteria such that they can be redirected the special node.
5328 This function can therefore redirect the final edge in a SCC. */
5330 template <typename valtype>
5331 static void
5332 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
5334 ipcp_value_source<valtype> *src;
5335 profile_count redirected_sum = profile_count::zero ();
5337 for (src = val->sources; src; src = src->next)
5339 struct cgraph_edge *cs = src->cs;
5340 while (cs)
5342 if (cgraph_edge_brings_value_p (cs, src, node, val)
5343 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
5344 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
5346 if (dump_file)
5347 fprintf (dump_file, " - adding an extra caller %s of %s\n",
5348 cs->caller->dump_name (),
5349 val->spec_node->dump_name ());
5351 cs->redirect_callee_duplicating_thunks (val->spec_node);
5352 val->spec_node->expand_all_artificial_thunks ();
5353 if (cs->count.ipa ().initialized_p ())
5354 redirected_sum = redirected_sum + cs->count.ipa ();
5356 cs = get_next_cgraph_edge_clone (cs);
5360 if (redirected_sum.nonzero_p ())
5361 update_specialized_profile (val->spec_node, node, redirected_sum);
5364 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5366 static bool
5367 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
5369 ipa_polymorphic_call_context *ctx;
5370 int i;
5372 FOR_EACH_VEC_ELT (known_contexts, i, ctx)
5373 if (!ctx->useless_p ())
5374 return true;
5375 return false;
5378 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5380 static vec<ipa_polymorphic_call_context>
5381 copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
5383 if (known_contexts_useful_p (known_contexts))
5384 return known_contexts.copy ();
5385 else
5386 return vNULL;
5389 /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
5390 according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its
5391 copy too. */
5393 static void
5394 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
5395 vec<tree> *known_csts,
5396 vec<ipa_polymorphic_call_context> *known_contexts,
5397 ipcp_value<tree> *val, int index)
5399 *known_csts = avals->m_known_vals.copy ();
5400 *known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
5401 (*known_csts)[index] = val->value;
5404 /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy
5405 contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
5406 INDEX. */
5408 static void
5409 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
5410 vec<tree> *known_csts,
5411 vec<ipa_polymorphic_call_context> *known_contexts,
5412 ipcp_value<ipa_polymorphic_call_context> *val,
5413 int index)
5415 *known_csts = avals->m_known_vals.copy ();
5416 *known_contexts = avals->m_known_contexts.copy ();
5417 (*known_contexts)[index] = val->value;
5420 /* Return true if OFFSET indicates this was not an aggregate value or there is
5421 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5422 AGGVALS list. */
5424 DEBUG_FUNCTION bool
5425 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
5426 int index, HOST_WIDE_INT offset, tree value)
5428 if (offset == -1)
5429 return true;
5431 while (aggvals)
5433 if (aggvals->index == index
5434 && aggvals->offset == offset
5435 && values_equal_for_ipcp_p (aggvals->value, value))
5436 return true;
5437 aggvals = aggvals->next;
5439 return false;
5442 /* Return true if offset is minus one because source of a polymorphic context
5443 cannot be an aggregate value. */
5445 DEBUG_FUNCTION bool
5446 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
5447 int , HOST_WIDE_INT offset,
5448 ipa_polymorphic_call_context)
5450 return offset == -1;
5453 /* Decide whether to create a special version of NODE for value VAL of
5454 parameter at the given INDEX. If OFFSET is -1, the value is for the
5455 parameter itself, otherwise it is stored at the given OFFSET of the
5456 parameter. AVALS describes the other already known values. */
5458 template <typename valtype>
5459 static bool
5460 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
5461 ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals)
5463 struct ipa_agg_replacement_value *aggvals;
5464 int caller_count;
5465 sreal freq_sum;
5466 profile_count count_sum;
5467 vec<cgraph_edge *> callers;
5469 if (val->spec_node)
5471 perhaps_add_new_callers (node, val);
5472 return false;
5474 else if (val->local_size_cost + overall_size > get_max_overall_size (node))
5476 if (dump_file && (dump_flags & TDF_DETAILS))
5477 fprintf (dump_file, " Ignoring candidate value because "
5478 "maximum unit size would be reached with %li.\n",
5479 val->local_size_cost + overall_size);
5480 return false;
5482 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
5483 &caller_count))
5484 return false;
5486 if (!dbg_cnt (ipa_cp_values))
5487 return false;
5489 if (dump_file && (dump_flags & TDF_DETAILS))
5491 fprintf (dump_file, " - considering value ");
5492 print_ipcp_constant_value (dump_file, val->value);
5493 fprintf (dump_file, " for ");
5494 ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
5495 if (offset != -1)
5496 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
5497 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
5500 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
5501 freq_sum, count_sum,
5502 val->local_size_cost)
5503 && !good_cloning_opportunity_p (node,
5504 val->local_time_benefit
5505 + val->prop_time_benefit,
5506 freq_sum, count_sum,
5507 safe_add (val->local_size_cost,
5508 val->prop_size_cost)))
5509 return false;
5511 if (dump_file)
5512 fprintf (dump_file, " Creating a specialized node of %s.\n",
5513 node->dump_name ());
5515 vec<tree> known_csts;
5516 vec<ipa_polymorphic_call_context> known_contexts;
5518 callers = gather_edges_for_value (val, node, caller_count);
5519 if (offset == -1)
5520 copy_known_vectors_add_val (avals, &known_csts, &known_contexts, val, index);
5521 else
5523 known_csts = avals->m_known_vals.copy ();
5524 known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
5526 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5527 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5528 aggvals = find_aggregate_values_for_callers_subset (node, callers);
5529 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
5530 offset, val->value));
5531 val->spec_node = create_specialized_node (node, known_csts, known_contexts,
5532 aggvals, callers);
5533 overall_size += val->local_size_cost;
5534 if (dump_file && (dump_flags & TDF_DETAILS))
5535 fprintf (dump_file, " overall size reached %li\n",
5536 overall_size);
5538 /* TODO: If for some lattice there is only one other known value
5539 left, make a special node for it too. */
5541 return true;
5544 /* Decide whether and what specialized clones of NODE should be created. */
5546 static bool
5547 decide_whether_version_node (struct cgraph_node *node)
5549 class ipa_node_params *info = IPA_NODE_REF (node);
5550 int i, count = ipa_get_param_count (info);
5551 bool ret = false;
5553 if (count == 0)
5554 return false;
5556 if (dump_file && (dump_flags & TDF_DETAILS))
5557 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
5558 node->dump_name ());
5560 ipa_auto_call_arg_values avals;
5561 gather_context_independent_values (info, &avals, false, NULL);
5563 for (i = 0; i < count;i++)
5565 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5566 ipcp_lattice<tree> *lat = &plats->itself;
5567 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
5569 if (!lat->bottom
5570 && !avals.m_known_vals[i])
5572 ipcp_value<tree> *val;
5573 for (val = lat->values; val; val = val->next)
5574 ret |= decide_about_value (node, i, -1, val, &avals);
5577 if (!plats->aggs_bottom)
5579 struct ipcp_agg_lattice *aglat;
5580 ipcp_value<tree> *val;
5581 for (aglat = plats->aggs; aglat; aglat = aglat->next)
5582 if (!aglat->bottom && aglat->values
5583 /* If the following is false, the one value has been considered
5584 for cloning for all contexts. */
5585 && (plats->aggs_contain_variable
5586 || !aglat->is_single_const ()))
5587 for (val = aglat->values; val; val = val->next)
5588 ret |= decide_about_value (node, i, aglat->offset, val, &avals);
5591 if (!ctxlat->bottom
5592 && avals.m_known_contexts[i].useless_p ())
5594 ipcp_value<ipa_polymorphic_call_context> *val;
5595 for (val = ctxlat->values; val; val = val->next)
5596 ret |= decide_about_value (node, i, -1, val, &avals);
5599 info = IPA_NODE_REF (node);
5602 if (info->do_clone_for_all_contexts)
5604 if (!dbg_cnt (ipa_cp_values))
5606 info->do_clone_for_all_contexts = false;
5607 return ret;
5610 struct cgraph_node *clone;
5611 vec<cgraph_edge *> callers = node->collect_callers ();
5613 for (int i = callers.length () - 1; i >= 0; i--)
5615 cgraph_edge *cs = callers[i];
5616 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5618 if (caller_info && caller_info->node_dead)
5619 callers.unordered_remove (i);
5622 if (!adjust_callers_for_value_intersection (callers, node))
5624 /* If node is not called by anyone, or all its caller edges are
5625 self-recursive, the node is not really in use, no need to do
5626 cloning. */
5627 callers.release ();
5628 info->do_clone_for_all_contexts = false;
5629 return ret;
5632 if (dump_file)
5633 fprintf (dump_file, " - Creating a specialized node of %s "
5634 "for all known contexts.\n", node->dump_name ());
5636 vec<tree> known_csts = avals.m_known_vals.copy ();
5637 vec<ipa_polymorphic_call_context> known_contexts
5638 = copy_useful_known_contexts (avals.m_known_contexts);
5639 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5640 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5641 ipa_agg_replacement_value *aggvals
5642 = find_aggregate_values_for_callers_subset (node, callers);
5644 if (!known_contexts_useful_p (known_contexts))
5646 known_contexts.release ();
5647 known_contexts = vNULL;
5649 clone = create_specialized_node (node, known_csts, known_contexts,
5650 aggvals, callers);
5651 info = IPA_NODE_REF (node);
5652 info->do_clone_for_all_contexts = false;
5653 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
5654 ret = true;
5657 return ret;
5660 /* Transitively mark all callees of NODE within the same SCC as not dead. */
5662 static void
5663 spread_undeadness (struct cgraph_node *node)
5665 struct cgraph_edge *cs;
5667 for (cs = node->callees; cs; cs = cs->next_callee)
5668 if (ipa_edge_within_scc (cs))
5670 struct cgraph_node *callee;
5671 class ipa_node_params *info;
5673 callee = cs->callee->function_symbol (NULL);
5674 info = IPA_NODE_REF (callee);
5676 if (info && info->node_dead)
5678 info->node_dead = 0;
5679 spread_undeadness (callee);
5684 /* Return true if NODE has a caller from outside of its SCC that is not
5685 dead. Worker callback for cgraph_for_node_and_aliases. */
5687 static bool
5688 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
5689 void *data ATTRIBUTE_UNUSED)
5691 struct cgraph_edge *cs;
5693 for (cs = node->callers; cs; cs = cs->next_caller)
5694 if (cs->caller->thunk
5695 && cs->caller->call_for_symbol_thunks_and_aliases
5696 (has_undead_caller_from_outside_scc_p, NULL, true))
5697 return true;
5698 else if (!ipa_edge_within_scc (cs)
5699 && (!IPA_NODE_REF (cs->caller) /* Unoptimized caller. */
5700 || !IPA_NODE_REF (cs->caller)->node_dead))
5701 return true;
5702 return false;
5706 /* Identify nodes within the same SCC as NODE which are no longer needed
5707 because of new clones and will be removed as unreachable. */
5709 static void
5710 identify_dead_nodes (struct cgraph_node *node)
5712 struct cgraph_node *v;
5713 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5714 if (v->local
5715 && IPA_NODE_REF (v)
5716 && !v->call_for_symbol_thunks_and_aliases
5717 (has_undead_caller_from_outside_scc_p, NULL, true))
5718 IPA_NODE_REF (v)->node_dead = 1;
5720 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5721 if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
5722 spread_undeadness (v);
5724 if (dump_file && (dump_flags & TDF_DETAILS))
5726 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5727 if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
5728 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
5732 /* The decision stage. Iterate over the topological order of call graph nodes
5733 TOPO and make specialized clones if deemed beneficial. */
5735 static void
5736 ipcp_decision_stage (class ipa_topo_info *topo)
5738 int i;
5740 if (dump_file)
5741 fprintf (dump_file, "\nIPA decision stage:\n\n");
5743 for (i = topo->nnodes - 1; i >= 0; i--)
5745 struct cgraph_node *node = topo->order[i];
5746 bool change = false, iterate = true;
5748 while (iterate)
5750 struct cgraph_node *v;
5751 iterate = false;
5752 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5753 if (v->has_gimple_body_p ()
5754 && ipcp_versionable_function_p (v))
5755 iterate |= decide_whether_version_node (v);
5757 change |= iterate;
5759 if (change)
5760 identify_dead_nodes (node);
5764 /* Look up all the bits information that we have discovered and copy it over
5765 to the transformation summary. */
5767 static void
5768 ipcp_store_bits_results (void)
5770 cgraph_node *node;
5772 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5774 ipa_node_params *info = IPA_NODE_REF (node);
5775 bool dumped_sth = false;
5776 bool found_useful_result = false;
5778 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
5780 if (dump_file)
5781 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
5782 "; -fipa-bit-cp: disabled.\n",
5783 node->dump_name ());
5784 continue;
5787 if (info->ipcp_orig_node)
5788 info = IPA_NODE_REF (info->ipcp_orig_node);
5789 if (!info->lattices)
5790 /* Newly expanded artificial thunks do not have lattices. */
5791 continue;
5793 unsigned count = ipa_get_param_count (info);
5794 for (unsigned i = 0; i < count; i++)
5796 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5797 if (plats->bits_lattice.constant_p ())
5799 found_useful_result = true;
5800 break;
5804 if (!found_useful_result)
5805 continue;
5807 ipcp_transformation_initialize ();
5808 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5809 vec_safe_reserve_exact (ts->bits, count);
5811 for (unsigned i = 0; i < count; i++)
5813 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5814 ipa_bits *jfbits;
5816 if (plats->bits_lattice.constant_p ())
5818 jfbits
5819 = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
5820 plats->bits_lattice.get_mask ());
5821 if (!dbg_cnt (ipa_cp_bits))
5822 jfbits = NULL;
5824 else
5825 jfbits = NULL;
5827 ts->bits->quick_push (jfbits);
5828 if (!dump_file || !jfbits)
5829 continue;
5830 if (!dumped_sth)
5832 fprintf (dump_file, "Propagated bits info for function %s:\n",
5833 node->dump_name ());
5834 dumped_sth = true;
5836 fprintf (dump_file, " param %i: value = ", i);
5837 print_hex (jfbits->value, dump_file);
5838 fprintf (dump_file, ", mask = ");
5839 print_hex (jfbits->mask, dump_file);
5840 fprintf (dump_file, "\n");
5845 /* Look up all VR information that we have discovered and copy it over
5846 to the transformation summary. */
5848 static void
5849 ipcp_store_vr_results (void)
5851 cgraph_node *node;
5853 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5855 ipa_node_params *info = IPA_NODE_REF (node);
5856 bool found_useful_result = false;
5858 if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
5860 if (dump_file)
5861 fprintf (dump_file, "Not considering %s for VR discovery "
5862 "and propagate; -fipa-ipa-vrp: disabled.\n",
5863 node->dump_name ());
5864 continue;
5867 if (info->ipcp_orig_node)
5868 info = IPA_NODE_REF (info->ipcp_orig_node);
5869 if (!info->lattices)
5870 /* Newly expanded artificial thunks do not have lattices. */
5871 continue;
5873 unsigned count = ipa_get_param_count (info);
5874 for (unsigned i = 0; i < count; i++)
5876 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5877 if (!plats->m_value_range.bottom_p ()
5878 && !plats->m_value_range.top_p ())
5880 found_useful_result = true;
5881 break;
5884 if (!found_useful_result)
5885 continue;
5887 ipcp_transformation_initialize ();
5888 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5889 vec_safe_reserve_exact (ts->m_vr, count);
5891 for (unsigned i = 0; i < count; i++)
5893 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5894 ipa_vr vr;
5896 if (!plats->m_value_range.bottom_p ()
5897 && !plats->m_value_range.top_p ()
5898 && dbg_cnt (ipa_cp_vr))
5900 vr.known = true;
5901 vr.type = plats->m_value_range.m_vr.kind ();
5902 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
5903 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
5905 else
5907 vr.known = false;
5908 vr.type = VR_VARYING;
5909 vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
5911 ts->m_vr->quick_push (vr);
5916 /* The IPCP driver. */
5918 static unsigned int
5919 ipcp_driver (void)
5921 class ipa_topo_info topo;
5923 if (edge_clone_summaries == NULL)
5924 edge_clone_summaries = new edge_clone_summary_t (symtab);
5926 ipa_check_create_node_params ();
5927 ipa_check_create_edge_args ();
5928 clone_num_suffixes = new hash_map<const char *, unsigned>;
5930 if (dump_file)
5932 fprintf (dump_file, "\nIPA structures before propagation:\n");
5933 if (dump_flags & TDF_DETAILS)
5934 ipa_print_all_params (dump_file);
5935 ipa_print_all_jump_functions (dump_file);
5938 /* Topological sort. */
5939 build_toporder_info (&topo);
5940 /* Do the interprocedural propagation. */
5941 ipcp_propagate_stage (&topo);
5942 /* Decide what constant propagation and cloning should be performed. */
5943 ipcp_decision_stage (&topo);
5944 /* Store results of bits propagation. */
5945 ipcp_store_bits_results ();
5946 /* Store results of value range propagation. */
5947 ipcp_store_vr_results ();
5949 /* Free all IPCP structures. */
5950 delete clone_num_suffixes;
5951 free_toporder_info (&topo);
5952 delete edge_clone_summaries;
5953 edge_clone_summaries = NULL;
5954 ipa_free_all_structures_after_ipa_cp ();
5955 if (dump_file)
5956 fprintf (dump_file, "\nIPA constant propagation end\n");
5957 return 0;
5960 /* Initialization and computation of IPCP data structures. This is the initial
5961 intraprocedural analysis of functions, which gathers information to be
5962 propagated later on. */
5964 static void
5965 ipcp_generate_summary (void)
5967 struct cgraph_node *node;
5969 if (dump_file)
5970 fprintf (dump_file, "\nIPA constant propagation start:\n");
5971 ipa_register_cgraph_hooks ();
5973 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5974 ipa_analyze_node (node);
5977 namespace {
5979 const pass_data pass_data_ipa_cp =
5981 IPA_PASS, /* type */
5982 "cp", /* name */
5983 OPTGROUP_NONE, /* optinfo_flags */
5984 TV_IPA_CONSTANT_PROP, /* tv_id */
5985 0, /* properties_required */
5986 0, /* properties_provided */
5987 0, /* properties_destroyed */
5988 0, /* todo_flags_start */
5989 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
5992 class pass_ipa_cp : public ipa_opt_pass_d
5994 public:
5995 pass_ipa_cp (gcc::context *ctxt)
5996 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
5997 ipcp_generate_summary, /* generate_summary */
5998 NULL, /* write_summary */
5999 NULL, /* read_summary */
6000 ipcp_write_transformation_summaries, /*
6001 write_optimization_summary */
6002 ipcp_read_transformation_summaries, /*
6003 read_optimization_summary */
6004 NULL, /* stmt_fixup */
6005 0, /* function_transform_todo_flags_start */
6006 ipcp_transform_function, /* function_transform */
6007 NULL) /* variable_transform */
6010 /* opt_pass methods: */
6011 virtual bool gate (function *)
6013 /* FIXME: We should remove the optimize check after we ensure we never run
6014 IPA passes when not optimizing. */
6015 return (flag_ipa_cp && optimize) || in_lto_p;
6018 virtual unsigned int execute (function *) { return ipcp_driver (); }
6020 }; // class pass_ipa_cp
6022 } // anon namespace
6024 ipa_opt_pass_d *
6025 make_pass_ipa_cp (gcc::context *ctxt)
6027 return new pass_ipa_cp (ctxt);
6030 /* Reset all state within ipa-cp.c so that we can rerun the compiler
6031 within the same process. For use by toplev::finalize. */
6033 void
6034 ipa_cp_c_finalize (void)
6036 max_count = profile_count::uninitialized ();
6037 overall_size = 0;
6038 orig_overall_size = 0;
6039 ipcp_free_transformation_sum ();