aix: Switch AIX configurtion to DWARF2 debugging
[official-gcc.git] / gcc / ipa-cp.c
blob6041f75d8242ccf49fbdaffadd0a7886fb6065fe
1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
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 || !ipa_get_type (info, i)
1280 || (pre_modified && (surviving_params.length () <= (unsigned) i
1281 || !surviving_params[i])))
1283 plats->itself.set_to_bottom ();
1284 plats->ctxlat.set_to_bottom ();
1285 set_agg_lats_to_bottom (plats);
1286 plats->bits_lattice.set_to_bottom ();
1287 plats->m_value_range.m_vr = value_range ();
1288 plats->m_value_range.set_to_bottom ();
1290 else
1292 plats->m_value_range.init ();
1293 if (variable)
1294 set_all_contains_variable (plats);
1298 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1299 if (ie->indirect_info->polymorphic
1300 && ie->indirect_info->param_index >= 0)
1302 gcc_checking_assert (ie->indirect_info->param_index >= 0);
1303 ipa_get_parm_lattices (info,
1304 ie->indirect_info->param_index)->virt_call = 1;
1308 /* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
1309 PARAM_TYPE. */
1311 static bool
1312 ipacp_value_safe_for_type (tree param_type, tree value)
1314 tree val_type = TREE_TYPE (value);
1315 if (param_type == val_type
1316 || useless_type_conversion_p (param_type, val_type)
1317 || fold_convertible_p (param_type, value))
1318 return true;
1319 else
1320 return false;
1323 /* Return true iff X and Y should be considered equal values by IPA-CP. */
1325 static bool
1326 values_equal_for_ipcp_p (tree x, tree y)
1328 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
1330 if (x == y)
1331 return true;
1333 if (TREE_CODE (x) == ADDR_EXPR
1334 && TREE_CODE (y) == ADDR_EXPR
1335 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
1336 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
1337 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
1338 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
1339 else
1340 return operand_equal_p (x, y, 0);
1343 /* Return the result of a (possibly arithmetic) operation on the constant
1344 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1345 the type of the parameter to which the result is passed. Return
1346 NULL_TREE if that cannot be determined or be considered an
1347 interprocedural invariant. */
1349 static tree
1350 ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
1351 tree res_type)
1353 tree res;
1355 if (opcode == NOP_EXPR)
1356 return input;
1357 if (!is_gimple_ip_invariant (input))
1358 return NULL_TREE;
1360 if (opcode == ASSERT_EXPR)
1362 if (values_equal_for_ipcp_p (input, operand))
1363 return input;
1364 else
1365 return NULL_TREE;
1368 if (!res_type)
1370 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1371 res_type = boolean_type_node;
1372 else if (expr_type_first_operand_type_p (opcode))
1373 res_type = TREE_TYPE (input);
1374 else
1375 return NULL_TREE;
1378 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1379 res = fold_unary (opcode, res_type, input);
1380 else
1381 res = fold_binary (opcode, res_type, input, operand);
1383 if (res && !is_gimple_ip_invariant (res))
1384 return NULL_TREE;
1386 return res;
1389 /* Return the result of a (possibly arithmetic) pass through jump function
1390 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1391 to which the result is passed. Return NULL_TREE if that cannot be
1392 determined or be considered an interprocedural invariant. */
1394 static tree
1395 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1396 tree res_type)
1398 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
1399 input,
1400 ipa_get_jf_pass_through_operand (jfunc),
1401 res_type);
1404 /* Return the result of an ancestor jump function JFUNC on the constant value
1405 INPUT. Return NULL_TREE if that cannot be determined. */
1407 static tree
1408 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
1410 gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
1411 if (TREE_CODE (input) == ADDR_EXPR)
1413 gcc_checking_assert (is_gimple_ip_invariant_address (input));
1414 poly_int64 off = ipa_get_jf_ancestor_offset (jfunc);
1415 if (known_eq (off, 0))
1416 return input;
1417 poly_int64 byte_offset = exact_div (off, BITS_PER_UNIT);
1418 return build1 (ADDR_EXPR, TREE_TYPE (input),
1419 fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (input)), input,
1420 build_int_cst (ptr_type_node, byte_offset)));
1422 else
1423 return NULL_TREE;
1426 /* Determine whether JFUNC evaluates to a single known constant value and if
1427 so, return it. Otherwise return NULL. INFO describes the caller node or
1428 the one it is inlined to, so that pass-through jump functions can be
1429 evaluated. PARM_TYPE is the type of the parameter to which the result is
1430 passed. */
1432 tree
1433 ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
1434 tree parm_type)
1436 if (jfunc->type == IPA_JF_CONST)
1437 return ipa_get_jf_constant (jfunc);
1438 else if (jfunc->type == IPA_JF_PASS_THROUGH
1439 || jfunc->type == IPA_JF_ANCESTOR)
1441 tree input;
1442 int idx;
1444 if (jfunc->type == IPA_JF_PASS_THROUGH)
1445 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1446 else
1447 idx = ipa_get_jf_ancestor_formal_id (jfunc);
1449 if (info->ipcp_orig_node)
1450 input = info->known_csts[idx];
1451 else
1453 ipcp_lattice<tree> *lat;
1455 if (!info->lattices
1456 || idx >= ipa_get_param_count (info))
1457 return NULL_TREE;
1458 lat = ipa_get_scalar_lat (info, idx);
1459 if (!lat->is_single_const ())
1460 return NULL_TREE;
1461 input = lat->values->value;
1464 if (!input)
1465 return NULL_TREE;
1467 if (jfunc->type == IPA_JF_PASS_THROUGH)
1468 return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
1469 else
1470 return ipa_get_jf_ancestor_result (jfunc, input);
1472 else
1473 return NULL_TREE;
1476 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1477 that INFO describes the caller node or the one it is inlined to, CS is the
1478 call graph edge corresponding to JFUNC and CSIDX index of the described
1479 parameter. */
1481 ipa_polymorphic_call_context
1482 ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
1483 ipa_jump_func *jfunc)
1485 ipa_edge_args *args = IPA_EDGE_REF (cs);
1486 ipa_polymorphic_call_context ctx;
1487 ipa_polymorphic_call_context *edge_ctx
1488 = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
1490 if (edge_ctx && !edge_ctx->useless_p ())
1491 ctx = *edge_ctx;
1493 if (jfunc->type == IPA_JF_PASS_THROUGH
1494 || jfunc->type == IPA_JF_ANCESTOR)
1496 ipa_polymorphic_call_context srcctx;
1497 int srcidx;
1498 bool type_preserved = true;
1499 if (jfunc->type == IPA_JF_PASS_THROUGH)
1501 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1502 return ctx;
1503 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1504 srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
1506 else
1508 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1509 srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
1511 if (info->ipcp_orig_node)
1513 if (info->known_contexts.exists ())
1514 srcctx = info->known_contexts[srcidx];
1516 else
1518 if (!info->lattices
1519 || srcidx >= ipa_get_param_count (info))
1520 return ctx;
1521 ipcp_lattice<ipa_polymorphic_call_context> *lat;
1522 lat = ipa_get_poly_ctx_lat (info, srcidx);
1523 if (!lat->is_single_const ())
1524 return ctx;
1525 srcctx = lat->values->value;
1527 if (srcctx.useless_p ())
1528 return ctx;
1529 if (jfunc->type == IPA_JF_ANCESTOR)
1530 srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1531 if (!type_preserved)
1532 srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1533 srcctx.combine_with (ctx);
1534 return srcctx;
1537 return ctx;
1540 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1541 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1542 the result is a range or an anti-range. */
1544 static bool
1545 ipa_vr_operation_and_type_effects (value_range *dst_vr,
1546 value_range *src_vr,
1547 enum tree_code operation,
1548 tree dst_type, tree src_type)
1550 range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1551 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1552 return false;
1553 return true;
1556 /* Determine value_range of JFUNC given that INFO describes the caller node or
1557 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1558 and PARM_TYPE of the parameter. */
1560 value_range
1561 ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
1562 ipa_jump_func *jfunc, tree parm_type)
1564 value_range vr;
1565 return vr;
1566 if (jfunc->m_vr)
1567 ipa_vr_operation_and_type_effects (&vr,
1568 jfunc->m_vr,
1569 NOP_EXPR, parm_type,
1570 jfunc->m_vr->type ());
1571 if (vr.singleton_p ())
1572 return vr;
1573 if (jfunc->type == IPA_JF_PASS_THROUGH)
1575 int idx;
1576 ipcp_transformation *sum
1577 = ipcp_get_transformation_summary (cs->caller->inlined_to
1578 ? cs->caller->inlined_to
1579 : cs->caller);
1580 if (!sum || !sum->m_vr)
1581 return vr;
1583 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1585 if (!(*sum->m_vr)[idx].known)
1586 return vr;
1587 tree vr_type = ipa_get_type (info, idx);
1588 value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
1589 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
1590 (*sum->m_vr)[idx].type);
1592 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1594 if (TREE_CODE_CLASS (operation) == tcc_unary)
1596 value_range res;
1598 if (ipa_vr_operation_and_type_effects (&res,
1599 &srcvr,
1600 operation, parm_type,
1601 vr_type))
1602 vr.intersect (res);
1604 else
1606 value_range op_res, res;
1607 tree op = ipa_get_jf_pass_through_operand (jfunc);
1608 value_range op_vr (op, op);
1610 range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
1611 if (ipa_vr_operation_and_type_effects (&res,
1612 &op_res,
1613 NOP_EXPR, parm_type,
1614 vr_type))
1615 vr.intersect (res);
1618 return vr;
1621 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
1622 parameter with the given INDEX. */
1624 static tree
1625 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
1626 int index)
1628 struct ipa_agg_replacement_value *aggval;
1630 aggval = ipa_get_agg_replacements_for_node (node);
1631 while (aggval)
1633 if (aggval->offset == offset
1634 && aggval->index == index)
1635 return aggval->value;
1636 aggval = aggval->next;
1638 return NULL_TREE;
1641 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1642 single known constant value and if so, return it. Otherwise return NULL.
1643 NODE and INFO describes the caller node or the one it is inlined to, and
1644 its related info. */
1646 static tree
1647 ipa_agg_value_from_node (class ipa_node_params *info,
1648 struct cgraph_node *node,
1649 struct ipa_agg_jf_item *item)
1651 tree value = NULL_TREE;
1652 int src_idx;
1654 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
1655 return NULL_TREE;
1657 if (item->jftype == IPA_JF_CONST)
1658 return item->value.constant;
1660 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
1661 || item->jftype == IPA_JF_LOAD_AGG);
1663 src_idx = item->value.pass_through.formal_id;
1665 if (info->ipcp_orig_node)
1667 if (item->jftype == IPA_JF_PASS_THROUGH)
1668 value = info->known_csts[src_idx];
1669 else
1670 value = get_clone_agg_value (node, item->value.load_agg.offset,
1671 src_idx);
1673 else if (info->lattices)
1675 class ipcp_param_lattices *src_plats
1676 = ipa_get_parm_lattices (info, src_idx);
1678 if (item->jftype == IPA_JF_PASS_THROUGH)
1680 struct ipcp_lattice<tree> *lat = &src_plats->itself;
1682 if (!lat->is_single_const ())
1683 return NULL_TREE;
1685 value = lat->values->value;
1687 else if (src_plats->aggs
1688 && !src_plats->aggs_bottom
1689 && !src_plats->aggs_contain_variable
1690 && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
1692 struct ipcp_agg_lattice *aglat;
1694 for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
1696 if (aglat->offset > item->value.load_agg.offset)
1697 break;
1699 if (aglat->offset == item->value.load_agg.offset)
1701 if (aglat->is_single_const ())
1702 value = aglat->values->value;
1703 break;
1709 if (!value)
1710 return NULL_TREE;
1712 if (item->jftype == IPA_JF_LOAD_AGG)
1714 tree load_type = item->value.load_agg.type;
1715 tree value_type = TREE_TYPE (value);
1717 /* Ensure value type is compatible with load type. */
1718 if (!useless_type_conversion_p (load_type, value_type))
1719 return NULL_TREE;
1722 return ipa_get_jf_arith_result (item->value.pass_through.operation,
1723 value,
1724 item->value.pass_through.operand,
1725 item->type);
1728 /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
1729 an aggregate and if so, return it. Otherwise return an empty set. NODE
1730 and INFO describes the caller node or the one it is inlined to, and its
1731 related info. */
1733 struct ipa_agg_value_set
1734 ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node,
1735 struct ipa_agg_jump_function *agg_jfunc)
1737 struct ipa_agg_value_set agg;
1738 struct ipa_agg_jf_item *item;
1739 int i;
1741 agg.items = vNULL;
1742 agg.by_ref = agg_jfunc->by_ref;
1744 FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item)
1746 tree value = ipa_agg_value_from_node (info, node, item);
1748 if (value)
1750 struct ipa_agg_value value_item;
1752 value_item.offset = item->offset;
1753 value_item.value = value;
1755 agg.items.safe_push (value_item);
1758 return agg;
1761 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1762 bottom, not containing a variable component and without any known value at
1763 the same time. */
1765 DEBUG_FUNCTION void
1766 ipcp_verify_propagated_values (void)
1768 struct cgraph_node *node;
1770 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1772 class ipa_node_params *info = IPA_NODE_REF (node);
1773 if (!opt_for_fn (node->decl, flag_ipa_cp)
1774 || !opt_for_fn (node->decl, optimize))
1775 continue;
1776 int i, count = ipa_get_param_count (info);
1778 for (i = 0; i < count; i++)
1780 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
1782 if (!lat->bottom
1783 && !lat->contains_variable
1784 && lat->values_count == 0)
1786 if (dump_file)
1788 symtab->dump (dump_file);
1789 fprintf (dump_file, "\nIPA lattices after constant "
1790 "propagation, before gcc_unreachable:\n");
1791 print_all_lattices (dump_file, true, false);
1794 gcc_unreachable ();
1800 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
1802 static bool
1803 values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
1804 ipa_polymorphic_call_context y)
1806 return x.equal_to (y);
1810 /* Add a new value source to the value represented by THIS, marking that a
1811 value comes from edge CS and (if the underlying jump function is a
1812 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1813 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1814 scalar value of the parameter itself or the offset within an aggregate. */
1816 template <typename valtype>
1817 void
1818 ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
1819 int src_idx, HOST_WIDE_INT offset)
1821 ipcp_value_source<valtype> *src;
1823 src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
1824 src->offset = offset;
1825 src->cs = cs;
1826 src->val = src_val;
1827 src->index = src_idx;
1829 src->next = sources;
1830 sources = src;
1833 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1834 SOURCE and clear all other fields. */
1836 static ipcp_value<tree> *
1837 allocate_and_init_ipcp_value (tree source)
1839 ipcp_value<tree> *val;
1841 val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>();
1842 val->value = source;
1843 return val;
1846 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1847 value to SOURCE and clear all other fields. */
1849 static ipcp_value<ipa_polymorphic_call_context> *
1850 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source)
1852 ipcp_value<ipa_polymorphic_call_context> *val;
1854 // TODO
1855 val = new (ipcp_poly_ctx_values_pool.allocate ())
1856 ipcp_value<ipa_polymorphic_call_context>();
1857 val->value = source;
1858 return val;
1861 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1862 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1863 meaning. OFFSET -1 means the source is scalar and not a part of an
1864 aggregate. If non-NULL, VAL_P records address of existing or newly added
1865 ipcp_value. UNLIMITED means whether value count should not exceed the limit
1866 given by PARAM_IPA_CP_VALUE_LIST_SIZE. */
1868 template <typename valtype>
1869 bool
1870 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1871 ipcp_value<valtype> *src_val,
1872 int src_idx, HOST_WIDE_INT offset,
1873 ipcp_value<valtype> **val_p,
1874 bool unlimited)
1876 ipcp_value<valtype> *val, *last_val = NULL;
1878 if (val_p)
1879 *val_p = NULL;
1881 if (bottom)
1882 return false;
1884 for (val = values; val; last_val = val, val = val->next)
1885 if (values_equal_for_ipcp_p (val->value, newval))
1887 if (val_p)
1888 *val_p = val;
1890 if (ipa_edge_within_scc (cs))
1892 ipcp_value_source<valtype> *s;
1893 for (s = val->sources; s; s = s->next)
1894 if (s->cs == cs && s->val == src_val)
1895 break;
1896 if (s)
1897 return false;
1900 val->add_source (cs, src_val, src_idx, offset);
1901 return false;
1904 if (!unlimited && values_count == opt_for_fn (cs->caller->decl,
1905 param_ipa_cp_value_list_size))
1907 /* We can only free sources, not the values themselves, because sources
1908 of other values in this SCC might point to them. */
1909 for (val = values; val; val = val->next)
1911 while (val->sources)
1913 ipcp_value_source<valtype> *src = val->sources;
1914 val->sources = src->next;
1915 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
1918 values = NULL;
1919 return set_to_bottom ();
1922 values_count++;
1923 val = allocate_and_init_ipcp_value (newval);
1924 val->add_source (cs, src_val, src_idx, offset);
1925 val->next = NULL;
1927 /* Add the new value to end of value list, which can reduce iterations
1928 of propagation stage for recursive function. */
1929 if (last_val)
1930 last_val->next = val;
1931 else
1932 values = val;
1934 if (val_p)
1935 *val_p = val;
1937 return true;
1940 /* Return true, if a ipcp_value VAL is orginated from parameter value of
1941 self-feeding recursive function via some kind of pass-through jump
1942 function. */
1944 static bool
1945 self_recursively_generated_p (ipcp_value<tree> *val)
1947 class ipa_node_params *info = NULL;
1949 for (ipcp_value_source<tree> *src = val->sources; src; src = src->next)
1951 cgraph_edge *cs = src->cs;
1953 if (!src->val || cs->caller != cs->callee->function_symbol ())
1954 return false;
1956 if (src->val == val)
1957 continue;
1959 if (!info)
1960 info = IPA_NODE_REF (cs->caller);
1962 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info,
1963 src->index);
1964 ipcp_lattice<tree> *src_lat;
1965 ipcp_value<tree> *src_val;
1967 if (src->offset == -1)
1968 src_lat = &plats->itself;
1969 else
1971 struct ipcp_agg_lattice *src_aglat;
1973 for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next)
1974 if (src_aglat->offset == src->offset)
1975 break;
1977 if (!src_aglat)
1978 return false;
1980 src_lat = src_aglat;
1983 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1984 if (src_val == val)
1985 break;
1987 if (!src_val)
1988 return false;
1991 return true;
1994 /* A helper function that returns result of operation specified by OPCODE on
1995 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1996 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
1997 acting as its second operand. If non-NULL, RES_TYPE is expected type of
1998 the result. */
2000 static tree
2001 get_val_across_arith_op (enum tree_code opcode,
2002 tree opnd1_type,
2003 tree opnd2,
2004 ipcp_value<tree> *src_val,
2005 tree res_type)
2007 tree opnd1 = src_val->value;
2009 /* Skip source values that is incompatible with specified type. */
2010 if (opnd1_type
2011 && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
2012 return NULL_TREE;
2014 return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
2017 /* Propagate values through an arithmetic transformation described by a jump
2018 function associated with edge CS, taking values from SRC_LAT and putting
2019 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
2020 OPND2 is a constant value if transformation is a binary operation.
2021 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
2022 a part of the aggregate. SRC_IDX is the index of the source parameter.
2023 RES_TYPE is the value type of result being propagated into. Return true if
2024 DEST_LAT changed. */
2026 static bool
2027 propagate_vals_across_arith_jfunc (cgraph_edge *cs,
2028 enum tree_code opcode,
2029 tree opnd1_type,
2030 tree opnd2,
2031 ipcp_lattice<tree> *src_lat,
2032 ipcp_lattice<tree> *dest_lat,
2033 HOST_WIDE_INT src_offset,
2034 int src_idx,
2035 tree res_type)
2037 ipcp_value<tree> *src_val;
2038 bool ret = false;
2040 /* Due to circular dependencies, propagating within an SCC through arithmetic
2041 transformation would create infinite number of values. But for
2042 self-feeding recursive function, we could allow propagation in a limited
2043 count, and this can enable a simple kind of recursive function versioning.
2044 For other scenario, we would just make lattices bottom. */
2045 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
2047 int i;
2049 int max_recursive_depth = opt_for_fn(cs->caller->decl,
2050 param_ipa_cp_max_recursive_depth);
2051 if (src_lat != dest_lat || max_recursive_depth < 1)
2052 return dest_lat->set_contains_variable ();
2054 /* No benefit if recursive execution is in low probability. */
2055 if (cs->sreal_frequency () * 100
2056 <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
2057 param_ipa_cp_min_recursive_probability))
2058 return dest_lat->set_contains_variable ();
2060 auto_vec<ipcp_value<tree> *, 8> val_seeds;
2062 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2064 /* Now we do not use self-recursively generated value as propagation
2065 source, this is absolutely conservative, but could avoid explosion
2066 of lattice's value space, especially when one recursive function
2067 calls another recursive. */
2068 if (self_recursively_generated_p (src_val))
2070 ipcp_value_source<tree> *s;
2072 /* If the lattice has already been propagated for the call site,
2073 no need to do that again. */
2074 for (s = src_val->sources; s; s = s->next)
2075 if (s->cs == cs)
2076 return dest_lat->set_contains_variable ();
2078 else
2079 val_seeds.safe_push (src_val);
2082 gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
2084 /* Recursively generate lattice values with a limited count. */
2085 FOR_EACH_VEC_ELT (val_seeds, i, src_val)
2087 for (int j = 1; j < max_recursive_depth; j++)
2089 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2090 src_val, res_type);
2091 if (!cstval
2092 || !ipacp_value_safe_for_type (res_type, cstval))
2093 break;
2095 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2096 src_offset, &src_val, true);
2097 gcc_checking_assert (src_val);
2100 ret |= dest_lat->set_contains_variable ();
2102 else
2103 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2105 /* Now we do not use self-recursively generated value as propagation
2106 source, otherwise it is easy to make value space of normal lattice
2107 overflow. */
2108 if (self_recursively_generated_p (src_val))
2110 ret |= dest_lat->set_contains_variable ();
2111 continue;
2114 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2115 src_val, res_type);
2116 if (cstval
2117 && ipacp_value_safe_for_type (res_type, cstval))
2118 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2119 src_offset);
2120 else
2121 ret |= dest_lat->set_contains_variable ();
2124 return ret;
2127 /* Propagate values through a pass-through jump function JFUNC associated with
2128 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2129 is the index of the source parameter. PARM_TYPE is the type of the
2130 parameter to which the result is passed. */
2132 static bool
2133 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
2134 ipcp_lattice<tree> *src_lat,
2135 ipcp_lattice<tree> *dest_lat, int src_idx,
2136 tree parm_type)
2138 return propagate_vals_across_arith_jfunc (cs,
2139 ipa_get_jf_pass_through_operation (jfunc),
2140 NULL_TREE,
2141 ipa_get_jf_pass_through_operand (jfunc),
2142 src_lat, dest_lat, -1, src_idx, parm_type);
2145 /* Propagate values through an ancestor jump function JFUNC associated with
2146 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2147 is the index of the source parameter. */
2149 static bool
2150 propagate_vals_across_ancestor (struct cgraph_edge *cs,
2151 struct ipa_jump_func *jfunc,
2152 ipcp_lattice<tree> *src_lat,
2153 ipcp_lattice<tree> *dest_lat, int src_idx,
2154 tree param_type)
2156 ipcp_value<tree> *src_val;
2157 bool ret = false;
2159 if (ipa_edge_within_scc (cs))
2160 return dest_lat->set_contains_variable ();
2162 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2164 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
2166 if (t && ipacp_value_safe_for_type (param_type, t))
2167 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
2168 else
2169 ret |= dest_lat->set_contains_variable ();
2172 return ret;
2175 /* Propagate scalar values across jump function JFUNC that is associated with
2176 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2177 parameter to which the result is passed. */
2179 static bool
2180 propagate_scalar_across_jump_function (struct cgraph_edge *cs,
2181 struct ipa_jump_func *jfunc,
2182 ipcp_lattice<tree> *dest_lat,
2183 tree param_type)
2185 if (dest_lat->bottom)
2186 return false;
2188 if (jfunc->type == IPA_JF_CONST)
2190 tree val = ipa_get_jf_constant (jfunc);
2191 if (ipacp_value_safe_for_type (param_type, val))
2192 return dest_lat->add_value (val, cs, NULL, 0);
2193 else
2194 return dest_lat->set_contains_variable ();
2196 else if (jfunc->type == IPA_JF_PASS_THROUGH
2197 || jfunc->type == IPA_JF_ANCESTOR)
2199 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2200 ipcp_lattice<tree> *src_lat;
2201 int src_idx;
2202 bool ret;
2204 if (jfunc->type == IPA_JF_PASS_THROUGH)
2205 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2206 else
2207 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2209 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
2210 if (src_lat->bottom)
2211 return dest_lat->set_contains_variable ();
2213 /* If we would need to clone the caller and cannot, do not propagate. */
2214 if (!ipcp_versionable_function_p (cs->caller)
2215 && (src_lat->contains_variable
2216 || (src_lat->values_count > 1)))
2217 return dest_lat->set_contains_variable ();
2219 if (jfunc->type == IPA_JF_PASS_THROUGH)
2220 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
2221 dest_lat, src_idx,
2222 param_type);
2223 else
2224 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
2225 src_idx, param_type);
2227 if (src_lat->contains_variable)
2228 ret |= dest_lat->set_contains_variable ();
2230 return ret;
2233 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2234 use it for indirect inlining), we should propagate them too. */
2235 return dest_lat->set_contains_variable ();
2238 /* Propagate scalar values across jump function JFUNC that is associated with
2239 edge CS and describes argument IDX and put the values into DEST_LAT. */
2241 static bool
2242 propagate_context_across_jump_function (cgraph_edge *cs,
2243 ipa_jump_func *jfunc, int idx,
2244 ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
2246 ipa_edge_args *args = IPA_EDGE_REF (cs);
2247 if (dest_lat->bottom)
2248 return false;
2249 bool ret = false;
2250 bool added_sth = false;
2251 bool type_preserved = true;
2253 ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
2254 = ipa_get_ith_polymorhic_call_context (args, idx);
2256 if (edge_ctx_ptr)
2257 edge_ctx = *edge_ctx_ptr;
2259 if (jfunc->type == IPA_JF_PASS_THROUGH
2260 || jfunc->type == IPA_JF_ANCESTOR)
2262 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2263 int src_idx;
2264 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
2266 /* TODO: Once we figure out how to propagate speculations, it will
2267 probably be a good idea to switch to speculation if type_preserved is
2268 not set instead of punting. */
2269 if (jfunc->type == IPA_JF_PASS_THROUGH)
2271 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
2272 goto prop_fail;
2273 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
2274 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2276 else
2278 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
2279 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2282 src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
2283 /* If we would need to clone the caller and cannot, do not propagate. */
2284 if (!ipcp_versionable_function_p (cs->caller)
2285 && (src_lat->contains_variable
2286 || (src_lat->values_count > 1)))
2287 goto prop_fail;
2289 ipcp_value<ipa_polymorphic_call_context> *src_val;
2290 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2292 ipa_polymorphic_call_context cur = src_val->value;
2294 if (!type_preserved)
2295 cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
2296 if (jfunc->type == IPA_JF_ANCESTOR)
2297 cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
2298 /* TODO: In cases we know how the context is going to be used,
2299 we can improve the result by passing proper OTR_TYPE. */
2300 cur.combine_with (edge_ctx);
2301 if (!cur.useless_p ())
2303 if (src_lat->contains_variable
2304 && !edge_ctx.equal_to (cur))
2305 ret |= dest_lat->set_contains_variable ();
2306 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
2307 added_sth = true;
2312 prop_fail:
2313 if (!added_sth)
2315 if (!edge_ctx.useless_p ())
2316 ret |= dest_lat->add_value (edge_ctx, cs);
2317 else
2318 ret |= dest_lat->set_contains_variable ();
2321 return ret;
2324 /* Propagate bits across jfunc that is associated with
2325 edge cs and update dest_lattice accordingly. */
2327 bool
2328 propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
2329 ipa_jump_func *jfunc,
2330 ipcp_bits_lattice *dest_lattice)
2332 if (dest_lattice->bottom_p ())
2333 return false;
2335 enum availability availability;
2336 cgraph_node *callee = cs->callee->function_symbol (&availability);
2337 class ipa_node_params *callee_info = IPA_NODE_REF (callee);
2338 tree parm_type = ipa_get_type (callee_info, idx);
2340 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2341 transform for these cases. Similarly, we can have bad type mismatches
2342 with LTO, avoid doing anything with those too. */
2343 if (!parm_type
2344 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
2346 if (dump_file && (dump_flags & TDF_DETAILS))
2347 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
2348 "param %i of %s is NULL or unsuitable for bits propagation\n",
2349 idx, cs->callee->dump_name ());
2351 return dest_lattice->set_to_bottom ();
2354 unsigned precision = TYPE_PRECISION (parm_type);
2355 signop sgn = TYPE_SIGN (parm_type);
2357 if (jfunc->type == IPA_JF_PASS_THROUGH
2358 || jfunc->type == IPA_JF_ANCESTOR)
2360 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2361 tree operand = NULL_TREE;
2362 enum tree_code code;
2363 unsigned src_idx;
2365 if (jfunc->type == IPA_JF_PASS_THROUGH)
2367 code = ipa_get_jf_pass_through_operation (jfunc);
2368 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2369 if (code != NOP_EXPR)
2370 operand = ipa_get_jf_pass_through_operand (jfunc);
2372 else
2374 code = POINTER_PLUS_EXPR;
2375 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2376 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
2377 operand = build_int_cstu (size_type_node, offset);
2380 class ipcp_param_lattices *src_lats
2381 = ipa_get_parm_lattices (caller_info, src_idx);
2383 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2384 for eg consider:
2385 int f(int x)
2387 g (x & 0xff);
2389 Assume lattice for x is bottom, however we can still propagate
2390 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2391 and we store it in jump function during analysis stage. */
2393 if (src_lats->bits_lattice.bottom_p ()
2394 && jfunc->bits)
2395 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2396 precision);
2397 else
2398 return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
2399 code, operand);
2402 else if (jfunc->type == IPA_JF_ANCESTOR)
2403 return dest_lattice->set_to_bottom ();
2404 else if (jfunc->bits)
2405 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2406 precision);
2407 else
2408 return dest_lattice->set_to_bottom ();
2411 /* Propagate value range across jump function JFUNC that is associated with
2412 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2413 accordingly. */
2415 static bool
2416 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
2417 class ipcp_param_lattices *dest_plats,
2418 tree param_type)
2420 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
2422 if (dest_lat->bottom_p ())
2423 return false;
2425 if (!param_type
2426 || (!INTEGRAL_TYPE_P (param_type)
2427 && !POINTER_TYPE_P (param_type)))
2428 return dest_lat->set_to_bottom ();
2430 if (jfunc->type == IPA_JF_PASS_THROUGH)
2432 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
2433 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2434 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2435 class ipcp_param_lattices *src_lats
2436 = ipa_get_parm_lattices (caller_info, src_idx);
2437 tree operand_type = ipa_get_type (caller_info, src_idx);
2439 if (src_lats->m_value_range.bottom_p ())
2440 return dest_lat->set_to_bottom ();
2442 value_range vr;
2443 if (TREE_CODE_CLASS (operation) == tcc_unary)
2444 ipa_vr_operation_and_type_effects (&vr,
2445 &src_lats->m_value_range.m_vr,
2446 operation, param_type,
2447 operand_type);
2448 /* A crude way to prevent unbounded number of value range updates
2449 in SCC components. We should allow limited number of updates within
2450 SCC, too. */
2451 else if (!ipa_edge_within_scc (cs))
2453 tree op = ipa_get_jf_pass_through_operand (jfunc);
2454 value_range op_vr (op, op);
2455 value_range op_res,res;
2457 range_fold_binary_expr (&op_res, operation, operand_type,
2458 &src_lats->m_value_range.m_vr, &op_vr);
2459 ipa_vr_operation_and_type_effects (&vr,
2460 &op_res,
2461 NOP_EXPR, param_type,
2462 operand_type);
2464 if (!vr.undefined_p () && !vr.varying_p ())
2466 if (jfunc->m_vr)
2468 value_range jvr;
2469 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2470 NOP_EXPR,
2471 param_type,
2472 jfunc->m_vr->type ()))
2473 vr.intersect (jvr);
2475 return dest_lat->meet_with (&vr);
2478 else if (jfunc->type == IPA_JF_CONST)
2480 tree val = ipa_get_jf_constant (jfunc);
2481 if (TREE_CODE (val) == INTEGER_CST)
2483 val = fold_convert (param_type, val);
2484 if (TREE_OVERFLOW_P (val))
2485 val = drop_tree_overflow (val);
2487 value_range tmpvr (val, val);
2488 return dest_lat->meet_with (&tmpvr);
2492 value_range vr;
2493 if (jfunc->m_vr
2494 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
2495 param_type,
2496 jfunc->m_vr->type ()))
2497 return dest_lat->meet_with (&vr);
2498 else
2499 return dest_lat->set_to_bottom ();
2502 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2503 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2504 other cases, return false). If there are no aggregate items, set
2505 aggs_by_ref to NEW_AGGS_BY_REF. */
2507 static bool
2508 set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
2509 bool new_aggs_by_ref)
2511 if (dest_plats->aggs)
2513 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
2515 set_agg_lats_to_bottom (dest_plats);
2516 return true;
2519 else
2520 dest_plats->aggs_by_ref = new_aggs_by_ref;
2521 return false;
2524 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2525 already existing lattice for the given OFFSET and SIZE, marking all skipped
2526 lattices as containing variable and checking for overlaps. If there is no
2527 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2528 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2529 unless there are too many already. If there are two many, return false. If
2530 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2531 skipped lattices were newly marked as containing variable, set *CHANGE to
2532 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2534 static bool
2535 merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
2536 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
2537 struct ipcp_agg_lattice ***aglat,
2538 bool pre_existing, bool *change, int max_agg_items)
2540 gcc_checking_assert (offset >= 0);
2542 while (**aglat && (**aglat)->offset < offset)
2544 if ((**aglat)->offset + (**aglat)->size > offset)
2546 set_agg_lats_to_bottom (dest_plats);
2547 return false;
2549 *change |= (**aglat)->set_contains_variable ();
2550 *aglat = &(**aglat)->next;
2553 if (**aglat && (**aglat)->offset == offset)
2555 if ((**aglat)->size != val_size)
2557 set_agg_lats_to_bottom (dest_plats);
2558 return false;
2560 gcc_assert (!(**aglat)->next
2561 || (**aglat)->next->offset >= offset + val_size);
2562 return true;
2564 else
2566 struct ipcp_agg_lattice *new_al;
2568 if (**aglat && (**aglat)->offset < offset + val_size)
2570 set_agg_lats_to_bottom (dest_plats);
2571 return false;
2573 if (dest_plats->aggs_count == max_agg_items)
2574 return false;
2575 dest_plats->aggs_count++;
2576 new_al = ipcp_agg_lattice_pool.allocate ();
2577 memset (new_al, 0, sizeof (*new_al));
2579 new_al->offset = offset;
2580 new_al->size = val_size;
2581 new_al->contains_variable = pre_existing;
2583 new_al->next = **aglat;
2584 **aglat = new_al;
2585 return true;
2589 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2590 containing an unknown value. */
2592 static bool
2593 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
2595 bool ret = false;
2596 while (aglat)
2598 ret |= aglat->set_contains_variable ();
2599 aglat = aglat->next;
2601 return ret;
2604 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2605 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2606 parameter used for lattice value sources. Return true if DEST_PLATS changed
2607 in any way. */
2609 static bool
2610 merge_aggregate_lattices (struct cgraph_edge *cs,
2611 class ipcp_param_lattices *dest_plats,
2612 class ipcp_param_lattices *src_plats,
2613 int src_idx, HOST_WIDE_INT offset_delta)
2615 bool pre_existing = dest_plats->aggs != NULL;
2616 struct ipcp_agg_lattice **dst_aglat;
2617 bool ret = false;
2619 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
2620 return true;
2621 if (src_plats->aggs_bottom)
2622 return set_agg_lats_contain_variable (dest_plats);
2623 if (src_plats->aggs_contain_variable)
2624 ret |= set_agg_lats_contain_variable (dest_plats);
2625 dst_aglat = &dest_plats->aggs;
2627 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2628 param_ipa_max_agg_items);
2629 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2630 src_aglat;
2631 src_aglat = src_aglat->next)
2633 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2635 if (new_offset < 0)
2636 continue;
2637 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
2638 &dst_aglat, pre_existing, &ret, max_agg_items))
2640 struct ipcp_agg_lattice *new_al = *dst_aglat;
2642 dst_aglat = &(*dst_aglat)->next;
2643 if (src_aglat->bottom)
2645 ret |= new_al->set_contains_variable ();
2646 continue;
2648 if (src_aglat->contains_variable)
2649 ret |= new_al->set_contains_variable ();
2650 for (ipcp_value<tree> *val = src_aglat->values;
2651 val;
2652 val = val->next)
2653 ret |= new_al->add_value (val->value, cs, val, src_idx,
2654 src_aglat->offset);
2656 else if (dest_plats->aggs_bottom)
2657 return true;
2659 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
2660 return ret;
2663 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2664 pass-through JFUNC and if so, whether it has conform and conforms to the
2665 rules about propagating values passed by reference. */
2667 static bool
2668 agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
2669 struct ipa_jump_func *jfunc)
2671 return src_plats->aggs
2672 && (!src_plats->aggs_by_ref
2673 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2676 /* Propagate values through ITEM, jump function for a part of an aggregate,
2677 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2678 associated with the jump function. Return true if AGLAT changed in any
2679 way. */
2681 static bool
2682 propagate_aggregate_lattice (struct cgraph_edge *cs,
2683 struct ipa_agg_jf_item *item,
2684 struct ipcp_agg_lattice *aglat)
2686 class ipa_node_params *caller_info;
2687 class ipcp_param_lattices *src_plats;
2688 struct ipcp_lattice<tree> *src_lat;
2689 HOST_WIDE_INT src_offset;
2690 int src_idx;
2691 tree load_type;
2692 bool ret;
2694 if (item->jftype == IPA_JF_CONST)
2696 tree value = item->value.constant;
2698 gcc_checking_assert (is_gimple_ip_invariant (value));
2699 return aglat->add_value (value, cs, NULL, 0);
2702 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2703 || item->jftype == IPA_JF_LOAD_AGG);
2705 caller_info = IPA_NODE_REF (cs->caller);
2706 src_idx = item->value.pass_through.formal_id;
2707 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2709 if (item->jftype == IPA_JF_PASS_THROUGH)
2711 load_type = NULL_TREE;
2712 src_lat = &src_plats->itself;
2713 src_offset = -1;
2715 else
2717 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
2718 struct ipcp_agg_lattice *src_aglat;
2720 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
2721 if (src_aglat->offset >= load_offset)
2722 break;
2724 load_type = item->value.load_agg.type;
2725 if (!src_aglat
2726 || src_aglat->offset > load_offset
2727 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
2728 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
2729 return aglat->set_contains_variable ();
2731 src_lat = src_aglat;
2732 src_offset = load_offset;
2735 if (src_lat->bottom
2736 || (!ipcp_versionable_function_p (cs->caller)
2737 && !src_lat->is_single_const ()))
2738 return aglat->set_contains_variable ();
2740 ret = propagate_vals_across_arith_jfunc (cs,
2741 item->value.pass_through.operation,
2742 load_type,
2743 item->value.pass_through.operand,
2744 src_lat, aglat,
2745 src_offset,
2746 src_idx,
2747 item->type);
2749 if (src_lat->contains_variable)
2750 ret |= aglat->set_contains_variable ();
2752 return ret;
2755 /* Propagate scalar values across jump function JFUNC that is associated with
2756 edge CS and put the values into DEST_LAT. */
2758 static bool
2759 propagate_aggs_across_jump_function (struct cgraph_edge *cs,
2760 struct ipa_jump_func *jfunc,
2761 class ipcp_param_lattices *dest_plats)
2763 bool ret = false;
2765 if (dest_plats->aggs_bottom)
2766 return false;
2768 if (jfunc->type == IPA_JF_PASS_THROUGH
2769 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2771 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2772 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2773 class ipcp_param_lattices *src_plats;
2775 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2776 if (agg_pass_through_permissible_p (src_plats, jfunc))
2778 /* Currently we do not produce clobber aggregate jump
2779 functions, replace with merging when we do. */
2780 gcc_assert (!jfunc->agg.items);
2781 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
2782 src_idx, 0);
2783 return ret;
2786 else if (jfunc->type == IPA_JF_ANCESTOR
2787 && ipa_get_jf_ancestor_agg_preserved (jfunc))
2789 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2790 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2791 class ipcp_param_lattices *src_plats;
2793 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2794 if (src_plats->aggs && src_plats->aggs_by_ref)
2796 /* Currently we do not produce clobber aggregate jump
2797 functions, replace with merging when we do. */
2798 gcc_assert (!jfunc->agg.items);
2799 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
2800 ipa_get_jf_ancestor_offset (jfunc));
2802 else if (!src_plats->aggs_by_ref)
2803 ret |= set_agg_lats_to_bottom (dest_plats);
2804 else
2805 ret |= set_agg_lats_contain_variable (dest_plats);
2806 return ret;
2809 if (jfunc->agg.items)
2811 bool pre_existing = dest_plats->aggs != NULL;
2812 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
2813 struct ipa_agg_jf_item *item;
2814 int i;
2816 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
2817 return true;
2819 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2820 param_ipa_max_agg_items);
2821 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2823 HOST_WIDE_INT val_size;
2825 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
2826 continue;
2827 val_size = tree_to_shwi (TYPE_SIZE (item->type));
2829 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
2830 &aglat, pre_existing, &ret, max_agg_items))
2832 ret |= propagate_aggregate_lattice (cs, item, *aglat);
2833 aglat = &(*aglat)->next;
2835 else if (dest_plats->aggs_bottom)
2836 return true;
2839 ret |= set_chain_of_aglats_contains_variable (*aglat);
2841 else
2842 ret |= set_agg_lats_contain_variable (dest_plats);
2844 return ret;
2847 /* Return true if on the way cfrom CS->caller to the final (non-alias and
2848 non-thunk) destination, the call passes through a thunk. */
2850 static bool
2851 call_passes_through_thunk (cgraph_edge *cs)
2853 cgraph_node *alias_or_thunk = cs->callee;
2854 while (alias_or_thunk->alias)
2855 alias_or_thunk = alias_or_thunk->get_alias_target ();
2856 return alias_or_thunk->thunk;
2859 /* Propagate constants from the caller to the callee of CS. INFO describes the
2860 caller. */
2862 static bool
2863 propagate_constants_across_call (struct cgraph_edge *cs)
2865 class ipa_node_params *callee_info;
2866 enum availability availability;
2867 cgraph_node *callee;
2868 class ipa_edge_args *args;
2869 bool ret = false;
2870 int i, args_count, parms_count;
2872 callee = cs->callee->function_symbol (&availability);
2873 if (!callee->definition)
2874 return false;
2875 gcc_checking_assert (callee->has_gimple_body_p ());
2876 callee_info = IPA_NODE_REF (callee);
2877 if (!callee_info)
2878 return false;
2880 args = IPA_EDGE_REF (cs);
2881 parms_count = ipa_get_param_count (callee_info);
2882 if (parms_count == 0)
2883 return false;
2884 if (!args
2885 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
2886 || !opt_for_fn (cs->caller->decl, optimize))
2888 for (i = 0; i < parms_count; i++)
2889 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2890 i));
2891 return ret;
2893 args_count = ipa_get_cs_argument_count (args);
2895 /* If this call goes through a thunk we must not propagate to the first (0th)
2896 parameter. However, we might need to uncover a thunk from below a series
2897 of aliases first. */
2898 if (call_passes_through_thunk (cs))
2900 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2901 0));
2902 i = 1;
2904 else
2905 i = 0;
2907 for (; (i < args_count) && (i < parms_count); i++)
2909 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
2910 class ipcp_param_lattices *dest_plats;
2911 tree param_type = ipa_get_type (callee_info, i);
2913 dest_plats = ipa_get_parm_lattices (callee_info, i);
2914 if (availability == AVAIL_INTERPOSABLE)
2915 ret |= set_all_contains_variable (dest_plats);
2916 else
2918 ret |= propagate_scalar_across_jump_function (cs, jump_func,
2919 &dest_plats->itself,
2920 param_type);
2921 ret |= propagate_context_across_jump_function (cs, jump_func, i,
2922 &dest_plats->ctxlat);
2924 |= propagate_bits_across_jump_function (cs, i, jump_func,
2925 &dest_plats->bits_lattice);
2926 ret |= propagate_aggs_across_jump_function (cs, jump_func,
2927 dest_plats);
2928 if (opt_for_fn (callee->decl, flag_ipa_vrp))
2929 ret |= propagate_vr_across_jump_function (cs, jump_func,
2930 dest_plats, param_type);
2931 else
2932 ret |= dest_plats->m_value_range.set_to_bottom ();
2935 for (; i < parms_count; i++)
2936 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
2938 return ret;
2941 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
2942 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2943 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
2945 static tree
2946 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
2947 vec<tree> known_csts,
2948 vec<ipa_polymorphic_call_context> known_contexts,
2949 vec<ipa_agg_value_set> known_aggs,
2950 struct ipa_agg_replacement_value *agg_reps,
2951 bool *speculative)
2953 int param_index = ie->indirect_info->param_index;
2954 HOST_WIDE_INT anc_offset;
2955 tree t = NULL;
2956 tree target = NULL;
2958 *speculative = false;
2960 if (param_index == -1)
2961 return NULL_TREE;
2963 if (!ie->indirect_info->polymorphic)
2965 tree t = NULL;
2967 if (ie->indirect_info->agg_contents)
2969 t = NULL;
2970 if (agg_reps && ie->indirect_info->guaranteed_unmodified)
2972 while (agg_reps)
2974 if (agg_reps->index == param_index
2975 && agg_reps->offset == ie->indirect_info->offset
2976 && agg_reps->by_ref == ie->indirect_info->by_ref)
2978 t = agg_reps->value;
2979 break;
2981 agg_reps = agg_reps->next;
2984 if (!t)
2986 struct ipa_agg_value_set *agg;
2987 if (known_aggs.length () > (unsigned int) param_index)
2988 agg = &known_aggs[param_index];
2989 else
2990 agg = NULL;
2991 bool from_global_constant;
2992 t = ipa_find_agg_cst_for_param (agg,
2993 (unsigned) param_index
2994 < known_csts.length ()
2995 ? known_csts[param_index]
2996 : NULL,
2997 ie->indirect_info->offset,
2998 ie->indirect_info->by_ref,
2999 &from_global_constant);
3000 if (t
3001 && !from_global_constant
3002 && !ie->indirect_info->guaranteed_unmodified)
3003 t = NULL_TREE;
3006 else if ((unsigned) param_index < known_csts.length ())
3007 t = known_csts[param_index];
3009 if (t
3010 && TREE_CODE (t) == ADDR_EXPR
3011 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
3012 return TREE_OPERAND (t, 0);
3013 else
3014 return NULL_TREE;
3017 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3018 return NULL_TREE;
3020 gcc_assert (!ie->indirect_info->agg_contents);
3021 anc_offset = ie->indirect_info->offset;
3023 t = NULL;
3025 /* Try to work out value of virtual table pointer value in replacements. */
3026 if (!t && agg_reps && !ie->indirect_info->by_ref)
3028 while (agg_reps)
3030 if (agg_reps->index == param_index
3031 && agg_reps->offset == ie->indirect_info->offset
3032 && agg_reps->by_ref)
3034 t = agg_reps->value;
3035 break;
3037 agg_reps = agg_reps->next;
3041 /* Try to work out value of virtual table pointer value in known
3042 aggregate values. */
3043 if (!t && known_aggs.length () > (unsigned int) param_index
3044 && !ie->indirect_info->by_ref)
3046 struct ipa_agg_value_set *agg = &known_aggs[param_index];
3047 t = ipa_find_agg_cst_for_param (agg,
3048 (unsigned) param_index
3049 < known_csts.length ()
3050 ? known_csts[param_index] : NULL,
3051 ie->indirect_info->offset, true);
3054 /* If we found the virtual table pointer, lookup the target. */
3055 if (t)
3057 tree vtable;
3058 unsigned HOST_WIDE_INT offset;
3059 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
3061 bool can_refer;
3062 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3063 vtable, offset, &can_refer);
3064 if (can_refer)
3066 if (!target
3067 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
3068 || !possible_polymorphic_call_target_p
3069 (ie, cgraph_node::get (target)))
3071 /* Do not speculate builtin_unreachable, it is stupid! */
3072 if (ie->indirect_info->vptr_changed)
3073 return NULL;
3074 target = ipa_impossible_devirt_target (ie, target);
3076 *speculative = ie->indirect_info->vptr_changed;
3077 if (!*speculative)
3078 return target;
3083 /* Do we know the constant value of pointer? */
3084 if (!t && (unsigned) param_index < known_csts.length ())
3085 t = known_csts[param_index];
3087 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
3089 ipa_polymorphic_call_context context;
3090 if (known_contexts.length () > (unsigned int) param_index)
3092 context = known_contexts[param_index];
3093 context.offset_by (anc_offset);
3094 if (ie->indirect_info->vptr_changed)
3095 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3096 ie->indirect_info->otr_type);
3097 if (t)
3099 ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
3100 (t, ie->indirect_info->otr_type, anc_offset);
3101 if (!ctx2.useless_p ())
3102 context.combine_with (ctx2, ie->indirect_info->otr_type);
3105 else if (t)
3107 context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
3108 anc_offset);
3109 if (ie->indirect_info->vptr_changed)
3110 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3111 ie->indirect_info->otr_type);
3113 else
3114 return NULL_TREE;
3116 vec <cgraph_node *>targets;
3117 bool final;
3119 targets = possible_polymorphic_call_targets
3120 (ie->indirect_info->otr_type,
3121 ie->indirect_info->otr_token,
3122 context, &final);
3123 if (!final || targets.length () > 1)
3125 struct cgraph_node *node;
3126 if (*speculative)
3127 return target;
3128 if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3129 || ie->speculative || !ie->maybe_hot_p ())
3130 return NULL;
3131 node = try_speculative_devirtualization (ie->indirect_info->otr_type,
3132 ie->indirect_info->otr_token,
3133 context);
3134 if (node)
3136 *speculative = true;
3137 target = node->decl;
3139 else
3140 return NULL;
3142 else
3144 *speculative = false;
3145 if (targets.length () == 1)
3146 target = targets[0]->decl;
3147 else
3148 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3151 if (target && !possible_polymorphic_call_target_p (ie,
3152 cgraph_node::get (target)))
3154 if (*speculative)
3155 return NULL;
3156 target = ipa_impossible_devirt_target (ie, target);
3159 return target;
3162 /* If an indirect edge IE can be turned into a direct one based on data in
3163 AVALS, return the destination. Store into *SPECULATIVE a boolean determinig
3164 whether the discovered target is only speculative guess. */
3166 tree
3167 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
3168 ipa_call_arg_values *avals,
3169 bool *speculative)
3171 return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3172 avals->m_known_contexts,
3173 avals->m_known_aggs,
3174 NULL, speculative);
3177 /* The same functionality as above overloaded for ipa_auto_call_arg_values. */
3179 tree
3180 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
3181 ipa_auto_call_arg_values *avals,
3182 bool *speculative)
3184 return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3185 avals->m_known_contexts,
3186 avals->m_known_aggs,
3187 NULL, speculative);
3190 /* Calculate devirtualization time bonus for NODE, assuming we know information
3191 about arguments stored in AVALS. */
3193 static int
3194 devirtualization_time_bonus (struct cgraph_node *node,
3195 ipa_auto_call_arg_values *avals)
3197 struct cgraph_edge *ie;
3198 int res = 0;
3200 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
3202 struct cgraph_node *callee;
3203 class ipa_fn_summary *isummary;
3204 enum availability avail;
3205 tree target;
3206 bool speculative;
3208 target = ipa_get_indirect_edge_target (ie, avals, &speculative);
3209 if (!target)
3210 continue;
3212 /* Only bare minimum benefit for clearly un-inlineable targets. */
3213 res += 1;
3214 callee = cgraph_node::get (target);
3215 if (!callee || !callee->definition)
3216 continue;
3217 callee = callee->function_symbol (&avail);
3218 if (avail < AVAIL_AVAILABLE)
3219 continue;
3220 isummary = ipa_fn_summaries->get (callee);
3221 if (!isummary || !isummary->inlinable)
3222 continue;
3224 int size = ipa_size_summaries->get (callee)->size;
3225 /* FIXME: The values below need re-considering and perhaps also
3226 integrating into the cost metrics, at lest in some very basic way. */
3227 int max_inline_insns_auto
3228 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3229 if (size <= max_inline_insns_auto / 4)
3230 res += 31 / ((int)speculative + 1);
3231 else if (size <= max_inline_insns_auto / 2)
3232 res += 15 / ((int)speculative + 1);
3233 else if (size <= max_inline_insns_auto
3234 || DECL_DECLARED_INLINE_P (callee->decl))
3235 res += 7 / ((int)speculative + 1);
3238 return res;
3241 /* Return time bonus incurred because of hints stored in ESTIMATES. */
3243 static int
3244 hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates)
3246 int result = 0;
3247 ipa_hints hints = estimates.hints;
3248 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
3249 result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3251 sreal bonus_for_one = opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3253 if (hints & INLINE_HINT_loop_iterations)
3254 result += (estimates.loops_with_known_iterations * bonus_for_one).to_int ();
3256 if (hints & INLINE_HINT_loop_stride)
3257 result += (estimates.loops_with_known_strides * bonus_for_one).to_int ();
3259 return result;
3262 /* If there is a reason to penalize the function described by INFO in the
3263 cloning goodness evaluation, do so. */
3265 static inline sreal
3266 incorporate_penalties (cgraph_node *node, ipa_node_params *info,
3267 sreal evaluation)
3269 if (info->node_within_scc && !info->node_is_self_scc)
3270 evaluation = (evaluation
3271 * (100 - opt_for_fn (node->decl,
3272 param_ipa_cp_recursion_penalty))) / 100;
3274 if (info->node_calling_single_call)
3275 evaluation = (evaluation
3276 * (100 - opt_for_fn (node->decl,
3277 param_ipa_cp_single_call_penalty)))
3278 / 100;
3280 return evaluation;
3283 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3284 and SIZE_COST and with the sum of frequencies of incoming edges to the
3285 potential new clone in FREQUENCIES. */
3287 static bool
3288 good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit,
3289 sreal freq_sum, profile_count count_sum,
3290 int size_cost)
3292 if (time_benefit == 0
3293 || !opt_for_fn (node->decl, flag_ipa_cp_clone)
3294 || node->optimize_for_size_p ())
3295 return false;
3297 gcc_assert (size_cost > 0);
3299 class ipa_node_params *info = IPA_NODE_REF (node);
3300 int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
3301 if (max_count > profile_count::zero ())
3304 sreal factor = count_sum.probability_in (max_count).to_sreal ();
3305 sreal evaluation = (time_benefit * factor) / size_cost;
3306 evaluation = incorporate_penalties (node, info, evaluation);
3307 evaluation *= 1000;
3309 if (dump_file && (dump_flags & TDF_DETAILS))
3311 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3312 "size: %i, count_sum: ", time_benefit.to_double (),
3313 size_cost);
3314 count_sum.dump (dump_file);
3315 fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n",
3316 info->node_within_scc
3317 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3318 info->node_calling_single_call ? ", single_call" : "",
3319 evaluation.to_double (), eval_threshold);
3322 return evaluation.to_int () >= eval_threshold;
3324 else
3326 sreal evaluation = (time_benefit * freq_sum) / size_cost;
3327 evaluation = incorporate_penalties (node, info, evaluation);
3328 evaluation *= 1000;
3330 if (dump_file && (dump_flags & TDF_DETAILS))
3331 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3332 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
3333 "threshold: %i\n",
3334 time_benefit.to_double (), size_cost, freq_sum.to_double (),
3335 info->node_within_scc
3336 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3337 info->node_calling_single_call ? ", single_call" : "",
3338 evaluation.to_double (), eval_threshold);
3340 return evaluation.to_int () >= eval_threshold;
3344 /* Return all context independent values from aggregate lattices in PLATS in a
3345 vector. Return NULL if there are none. */
3347 static vec<ipa_agg_value>
3348 context_independent_aggregate_values (class ipcp_param_lattices *plats)
3350 vec<ipa_agg_value> res = vNULL;
3352 if (plats->aggs_bottom
3353 || plats->aggs_contain_variable
3354 || plats->aggs_count == 0)
3355 return vNULL;
3357 for (struct ipcp_agg_lattice *aglat = plats->aggs;
3358 aglat;
3359 aglat = aglat->next)
3360 if (aglat->is_single_const ())
3362 struct ipa_agg_value item;
3363 item.offset = aglat->offset;
3364 item.value = aglat->values->value;
3365 res.safe_push (item);
3367 return res;
3370 /* Grow vectors in AVALS and fill them with information about values of
3371 parameters that are known to be independent of the context. Only calculate
3372 m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If
3373 REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
3374 parameters will be stored in it.
3376 TODO: Also grow context independent value range vectors. */
3378 static bool
3379 gather_context_independent_values (class ipa_node_params *info,
3380 ipa_auto_call_arg_values *avals,
3381 bool calculate_aggs,
3382 int *removable_params_cost)
3384 int i, count = ipa_get_param_count (info);
3385 bool ret = false;
3387 avals->m_known_vals.safe_grow_cleared (count, true);
3388 avals->m_known_contexts.safe_grow_cleared (count, true);
3389 if (calculate_aggs)
3390 avals->m_known_aggs.safe_grow_cleared (count, true);
3392 if (removable_params_cost)
3393 *removable_params_cost = 0;
3395 for (i = 0; i < count; i++)
3397 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3398 ipcp_lattice<tree> *lat = &plats->itself;
3400 if (lat->is_single_const ())
3402 ipcp_value<tree> *val = lat->values;
3403 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3404 avals->m_known_vals[i] = val->value;
3405 if (removable_params_cost)
3406 *removable_params_cost
3407 += estimate_move_cost (TREE_TYPE (val->value), false);
3408 ret = true;
3410 else if (removable_params_cost
3411 && !ipa_is_param_used (info, i))
3412 *removable_params_cost
3413 += ipa_get_param_move_cost (info, i);
3415 if (!ipa_is_param_used (info, i))
3416 continue;
3418 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3419 /* Do not account known context as reason for cloning. We can see
3420 if it permits devirtualization. */
3421 if (ctxlat->is_single_const ())
3422 avals->m_known_contexts[i] = ctxlat->values->value;
3424 if (calculate_aggs)
3426 vec<ipa_agg_value> agg_items;
3427 struct ipa_agg_value_set *agg;
3429 agg_items = context_independent_aggregate_values (plats);
3430 agg = &avals->m_known_aggs[i];
3431 agg->items = agg_items;
3432 agg->by_ref = plats->aggs_by_ref;
3433 ret |= !agg_items.is_empty ();
3437 return ret;
3440 /* Perform time and size measurement of NODE with the context given in AVALS,
3441 calculate the benefit compared to the node without specialization and store
3442 it into VAL. Take into account REMOVABLE_PARAMS_COST of all
3443 context-independent or unused removable parameters and EST_MOVE_COST, the
3444 estimated movement of the considered parameter. */
3446 static void
3447 perform_estimation_of_a_value (cgraph_node *node,
3448 ipa_auto_call_arg_values *avals,
3449 int removable_params_cost, int est_move_cost,
3450 ipcp_value_base *val)
3452 sreal time_benefit;
3453 ipa_call_estimates estimates;
3455 estimate_ipcp_clone_size_and_time (node, avals, &estimates);
3457 /* Extern inline functions have no cloning local time benefits because they
3458 will be inlined anyway. The only reason to clone them is if it enables
3459 optimization in any of the functions they call. */
3460 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3461 time_benefit = 0;
3462 else
3463 time_benefit = (estimates.nonspecialized_time - estimates.time)
3464 + (devirtualization_time_bonus (node, avals)
3465 + hint_time_bonus (node, estimates)
3466 + removable_params_cost + est_move_cost);
3468 int size = estimates.size;
3469 gcc_checking_assert (size >=0);
3470 /* The inliner-heuristics based estimates may think that in certain
3471 contexts some functions do not have any size at all but we want
3472 all specializations to have at least a tiny cost, not least not to
3473 divide by zero. */
3474 if (size == 0)
3475 size = 1;
3477 val->local_time_benefit = time_benefit;
3478 val->local_size_cost = size;
3481 /* Get the overall limit oof growth based on parameters extracted from growth.
3482 it does not really make sense to mix functions with different overall growth
3483 limits but it is possible and if it happens, we do not want to select one
3484 limit at random. */
3486 static long
3487 get_max_overall_size (cgraph_node *node)
3489 long max_new_size = orig_overall_size;
3490 long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns);
3491 if (max_new_size < large_unit)
3492 max_new_size = large_unit;
3493 int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
3494 max_new_size += max_new_size * unit_growth / 100 + 1;
3495 return max_new_size;
3498 /* Iterate over known values of parameters of NODE and estimate the local
3499 effects in terms of time and size they have. */
3501 static void
3502 estimate_local_effects (struct cgraph_node *node)
3504 class ipa_node_params *info = IPA_NODE_REF (node);
3505 int i, count = ipa_get_param_count (info);
3506 bool always_const;
3507 int removable_params_cost;
3509 if (!count || !ipcp_versionable_function_p (node))
3510 return;
3512 if (dump_file && (dump_flags & TDF_DETAILS))
3513 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
3515 ipa_auto_call_arg_values avals;
3516 always_const = gather_context_independent_values (info, &avals, true,
3517 &removable_params_cost);
3518 int devirt_bonus = devirtualization_time_bonus (node, &avals);
3519 if (always_const || devirt_bonus
3520 || (removable_params_cost && node->can_change_signature))
3522 struct caller_statistics stats;
3523 ipa_call_estimates estimates;
3525 init_caller_stats (&stats);
3526 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3527 false);
3528 estimate_ipcp_clone_size_and_time (node, &avals, &estimates);
3529 sreal time = estimates.nonspecialized_time - estimates.time;
3530 time += devirt_bonus;
3531 time += hint_time_bonus (node, estimates);
3532 time += removable_params_cost;
3533 int size = estimates.size - stats.n_calls * removable_params_cost;
3535 if (dump_file)
3536 fprintf (dump_file, " - context independent values, size: %i, "
3537 "time_benefit: %f\n", size, (time).to_double ());
3539 if (size <= 0 || node->local)
3541 info->do_clone_for_all_contexts = true;
3543 if (dump_file)
3544 fprintf (dump_file, " Decided to specialize for all "
3545 "known contexts, code not going to grow.\n");
3547 else if (good_cloning_opportunity_p (node, time, stats.freq_sum,
3548 stats.count_sum, size))
3550 if (size + overall_size <= get_max_overall_size (node))
3552 info->do_clone_for_all_contexts = true;
3553 overall_size += size;
3555 if (dump_file)
3556 fprintf (dump_file, " Decided to specialize for all "
3557 "known contexts, growth (to %li) deemed "
3558 "beneficial.\n", overall_size);
3560 else if (dump_file && (dump_flags & TDF_DETAILS))
3561 fprintf (dump_file, " Not cloning for all contexts because "
3562 "maximum unit size would be reached with %li.\n",
3563 size + overall_size);
3565 else if (dump_file && (dump_flags & TDF_DETAILS))
3566 fprintf (dump_file, " Not cloning for all contexts because "
3567 "!good_cloning_opportunity_p.\n");
3571 for (i = 0; i < count; i++)
3573 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3574 ipcp_lattice<tree> *lat = &plats->itself;
3575 ipcp_value<tree> *val;
3577 if (lat->bottom
3578 || !lat->values
3579 || avals.m_known_vals[i])
3580 continue;
3582 for (val = lat->values; val; val = val->next)
3584 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3585 avals.m_known_vals[i] = val->value;
3587 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
3588 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3589 emc, val);
3591 if (dump_file && (dump_flags & TDF_DETAILS))
3593 fprintf (dump_file, " - estimates for value ");
3594 print_ipcp_constant_value (dump_file, val->value);
3595 fprintf (dump_file, " for ");
3596 ipa_dump_param (dump_file, info, i);
3597 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3598 val->local_time_benefit.to_double (),
3599 val->local_size_cost);
3602 avals.m_known_vals[i] = NULL_TREE;
3605 for (i = 0; i < count; i++)
3607 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3609 if (!plats->virt_call)
3610 continue;
3612 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3613 ipcp_value<ipa_polymorphic_call_context> *val;
3615 if (ctxlat->bottom
3616 || !ctxlat->values
3617 || !avals.m_known_contexts[i].useless_p ())
3618 continue;
3620 for (val = ctxlat->values; val; val = val->next)
3622 avals.m_known_contexts[i] = val->value;
3623 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3624 0, val);
3626 if (dump_file && (dump_flags & TDF_DETAILS))
3628 fprintf (dump_file, " - estimates for polymorphic context ");
3629 print_ipcp_constant_value (dump_file, val->value);
3630 fprintf (dump_file, " for ");
3631 ipa_dump_param (dump_file, info, i);
3632 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3633 val->local_time_benefit.to_double (),
3634 val->local_size_cost);
3637 avals.m_known_contexts[i] = ipa_polymorphic_call_context ();
3640 for (i = 0; i < count; i++)
3642 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3644 if (plats->aggs_bottom || !plats->aggs)
3645 continue;
3647 ipa_agg_value_set *agg = &avals.m_known_aggs[i];
3648 for (ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
3650 ipcp_value<tree> *val;
3651 if (aglat->bottom || !aglat->values
3652 /* If the following is true, the one value is in known_aggs. */
3653 || (!plats->aggs_contain_variable
3654 && aglat->is_single_const ()))
3655 continue;
3657 for (val = aglat->values; val; val = val->next)
3659 struct ipa_agg_value item;
3661 item.offset = aglat->offset;
3662 item.value = val->value;
3663 agg->items.safe_push (item);
3665 perform_estimation_of_a_value (node, &avals,
3666 removable_params_cost, 0, val);
3668 if (dump_file && (dump_flags & TDF_DETAILS))
3670 fprintf (dump_file, " - estimates for value ");
3671 print_ipcp_constant_value (dump_file, val->value);
3672 fprintf (dump_file, " for ");
3673 ipa_dump_param (dump_file, info, i);
3674 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3675 "]: time_benefit: %g, size: %i\n",
3676 plats->aggs_by_ref ? "ref " : "",
3677 aglat->offset,
3678 val->local_time_benefit.to_double (),
3679 val->local_size_cost);
3682 agg->items.pop ();
3689 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3690 topological sort of values. */
3692 template <typename valtype>
3693 void
3694 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
3696 ipcp_value_source<valtype> *src;
3698 if (cur_val->dfs)
3699 return;
3701 dfs_counter++;
3702 cur_val->dfs = dfs_counter;
3703 cur_val->low_link = dfs_counter;
3705 cur_val->topo_next = stack;
3706 stack = cur_val;
3707 cur_val->on_stack = true;
3709 for (src = cur_val->sources; src; src = src->next)
3710 if (src->val)
3712 if (src->val->dfs == 0)
3714 add_val (src->val);
3715 if (src->val->low_link < cur_val->low_link)
3716 cur_val->low_link = src->val->low_link;
3718 else if (src->val->on_stack
3719 && src->val->dfs < cur_val->low_link)
3720 cur_val->low_link = src->val->dfs;
3723 if (cur_val->dfs == cur_val->low_link)
3725 ipcp_value<valtype> *v, *scc_list = NULL;
3729 v = stack;
3730 stack = v->topo_next;
3731 v->on_stack = false;
3733 v->scc_next = scc_list;
3734 scc_list = v;
3736 while (v != cur_val);
3738 cur_val->topo_next = values_topo;
3739 values_topo = cur_val;
3743 /* Add all values in lattices associated with NODE to the topological sort if
3744 they are not there yet. */
3746 static void
3747 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
3749 class ipa_node_params *info = IPA_NODE_REF (node);
3750 int i, count = ipa_get_param_count (info);
3752 for (i = 0; i < count; i++)
3754 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3755 ipcp_lattice<tree> *lat = &plats->itself;
3756 struct ipcp_agg_lattice *aglat;
3758 if (!lat->bottom)
3760 ipcp_value<tree> *val;
3761 for (val = lat->values; val; val = val->next)
3762 topo->constants.add_val (val);
3765 if (!plats->aggs_bottom)
3766 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3767 if (!aglat->bottom)
3769 ipcp_value<tree> *val;
3770 for (val = aglat->values; val; val = val->next)
3771 topo->constants.add_val (val);
3774 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3775 if (!ctxlat->bottom)
3777 ipcp_value<ipa_polymorphic_call_context> *ctxval;
3778 for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
3779 topo->contexts.add_val (ctxval);
3784 /* One pass of constants propagation along the call graph edges, from callers
3785 to callees (requires topological ordering in TOPO), iterate over strongly
3786 connected components. */
3788 static void
3789 propagate_constants_topo (class ipa_topo_info *topo)
3791 int i;
3793 for (i = topo->nnodes - 1; i >= 0; i--)
3795 unsigned j;
3796 struct cgraph_node *v, *node = topo->order[i];
3797 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
3799 /* First, iteratively propagate within the strongly connected component
3800 until all lattices stabilize. */
3801 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3802 if (v->has_gimple_body_p ())
3804 if (opt_for_fn (v->decl, flag_ipa_cp)
3805 && opt_for_fn (v->decl, optimize))
3806 push_node_to_stack (topo, v);
3807 /* When V is not optimized, we can not push it to stack, but
3808 still we need to set all its callees lattices to bottom. */
3809 else
3811 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
3812 propagate_constants_across_call (cs);
3816 v = pop_node_from_stack (topo);
3817 while (v)
3819 struct cgraph_edge *cs;
3820 class ipa_node_params *info = NULL;
3821 bool self_scc = true;
3823 for (cs = v->callees; cs; cs = cs->next_callee)
3824 if (ipa_edge_within_scc (cs))
3826 cgraph_node *callee = cs->callee->function_symbol ();
3828 if (v != callee)
3829 self_scc = false;
3831 if (!info)
3833 info = IPA_NODE_REF (v);
3834 info->node_within_scc = true;
3837 if (propagate_constants_across_call (cs))
3838 push_node_to_stack (topo, callee);
3841 if (info)
3842 info->node_is_self_scc = self_scc;
3844 v = pop_node_from_stack (topo);
3847 /* Afterwards, propagate along edges leading out of the SCC, calculates
3848 the local effects of the discovered constants and all valid values to
3849 their topological sort. */
3850 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
3851 if (v->has_gimple_body_p ()
3852 && opt_for_fn (v->decl, flag_ipa_cp)
3853 && opt_for_fn (v->decl, optimize))
3855 struct cgraph_edge *cs;
3857 estimate_local_effects (v);
3858 add_all_node_vals_to_toposort (v, topo);
3859 for (cs = v->callees; cs; cs = cs->next_callee)
3860 if (!ipa_edge_within_scc (cs))
3861 propagate_constants_across_call (cs);
3863 cycle_nodes.release ();
3867 /* Propagate the estimated effects of individual values along the topological
3868 from the dependent values to those they depend on. */
3870 template <typename valtype>
3871 void
3872 value_topo_info<valtype>::propagate_effects ()
3874 ipcp_value<valtype> *base;
3875 hash_set<ipcp_value<valtype> *> processed_srcvals;
3877 for (base = values_topo; base; base = base->topo_next)
3879 ipcp_value_source<valtype> *src;
3880 ipcp_value<valtype> *val;
3881 sreal time = 0;
3882 HOST_WIDE_INT size = 0;
3884 for (val = base; val; val = val->scc_next)
3886 time = time + val->local_time_benefit + val->prop_time_benefit;
3887 size = size + val->local_size_cost + val->prop_size_cost;
3890 for (val = base; val; val = val->scc_next)
3892 processed_srcvals.empty ();
3893 for (src = val->sources; src; src = src->next)
3894 if (src->val
3895 && src->cs->maybe_hot_p ())
3897 if (!processed_srcvals.add (src->val))
3899 HOST_WIDE_INT prop_size = size + src->val->prop_size_cost;
3900 if (prop_size < INT_MAX)
3901 src->val->prop_size_cost = prop_size;
3902 else
3903 continue;
3905 src->val->prop_time_benefit
3906 += time * src->cs->sreal_frequency ();
3909 if (size < INT_MAX)
3911 val->prop_time_benefit = time;
3912 val->prop_size_cost = size;
3914 else
3916 val->prop_time_benefit = 0;
3917 val->prop_size_cost = 0;
3924 /* Propagate constants, polymorphic contexts and their effects from the
3925 summaries interprocedurally. */
3927 static void
3928 ipcp_propagate_stage (class ipa_topo_info *topo)
3930 struct cgraph_node *node;
3932 if (dump_file)
3933 fprintf (dump_file, "\n Propagating constants:\n\n");
3935 max_count = profile_count::uninitialized ();
3937 FOR_EACH_DEFINED_FUNCTION (node)
3939 if (node->has_gimple_body_p ()
3940 && opt_for_fn (node->decl, flag_ipa_cp)
3941 && opt_for_fn (node->decl, optimize))
3943 class ipa_node_params *info = IPA_NODE_REF (node);
3944 determine_versionability (node, info);
3946 unsigned nlattices = ipa_get_param_count (info);
3947 void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
3948 info->lattices = new (chunk) ipcp_param_lattices[nlattices];
3949 initialize_node_lattices (node);
3951 ipa_size_summary *s = ipa_size_summaries->get (node);
3952 if (node->definition && !node->alias && s != NULL)
3953 overall_size += s->self_size;
3954 max_count = max_count.max (node->count.ipa ());
3957 orig_overall_size = overall_size;
3959 if (dump_file)
3960 fprintf (dump_file, "\noverall_size: %li\n", overall_size);
3962 propagate_constants_topo (topo);
3963 if (flag_checking)
3964 ipcp_verify_propagated_values ();
3965 topo->constants.propagate_effects ();
3966 topo->contexts.propagate_effects ();
3968 if (dump_file)
3970 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
3971 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
3975 /* Discover newly direct outgoing edges from NODE which is a new clone with
3976 known KNOWN_CSTS and make them direct. */
3978 static void
3979 ipcp_discover_new_direct_edges (struct cgraph_node *node,
3980 vec<tree> known_csts,
3981 vec<ipa_polymorphic_call_context>
3982 known_contexts,
3983 struct ipa_agg_replacement_value *aggvals)
3985 struct cgraph_edge *ie, *next_ie;
3986 bool found = false;
3988 for (ie = node->indirect_calls; ie; ie = next_ie)
3990 tree target;
3991 bool speculative;
3993 next_ie = ie->next_callee;
3994 target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
3995 vNULL, aggvals, &speculative);
3996 if (target)
3998 bool agg_contents = ie->indirect_info->agg_contents;
3999 bool polymorphic = ie->indirect_info->polymorphic;
4000 int param_index = ie->indirect_info->param_index;
4001 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
4002 speculative);
4003 found = true;
4005 if (cs && !agg_contents && !polymorphic)
4007 class ipa_node_params *info = IPA_NODE_REF (node);
4008 int c = ipa_get_controlled_uses (info, param_index);
4009 if (c != IPA_UNDESCRIBED_USE)
4011 struct ipa_ref *to_del;
4013 c--;
4014 ipa_set_controlled_uses (info, param_index, c);
4015 if (dump_file && (dump_flags & TDF_DETAILS))
4016 fprintf (dump_file, " controlled uses count of param "
4017 "%i bumped down to %i\n", param_index, c);
4018 if (c == 0
4019 && (to_del = node->find_reference (cs->callee, NULL, 0)))
4021 if (dump_file && (dump_flags & TDF_DETAILS))
4022 fprintf (dump_file, " and even removing its "
4023 "cloning-created reference\n");
4024 to_del->remove_reference ();
4030 /* Turning calls to direct calls will improve overall summary. */
4031 if (found)
4032 ipa_update_overall_fn_summary (node);
4035 class edge_clone_summary;
4036 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
4038 /* Edge clone summary. */
4040 class edge_clone_summary
4042 public:
4043 /* Default constructor. */
4044 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
4046 /* Default destructor. */
4047 ~edge_clone_summary ()
4049 if (prev_clone)
4050 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
4051 if (next_clone)
4052 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
4055 cgraph_edge *prev_clone;
4056 cgraph_edge *next_clone;
4059 class edge_clone_summary_t:
4060 public call_summary <edge_clone_summary *>
4062 public:
4063 edge_clone_summary_t (symbol_table *symtab):
4064 call_summary <edge_clone_summary *> (symtab)
4066 m_initialize_when_cloning = true;
4069 virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4070 edge_clone_summary *src_data,
4071 edge_clone_summary *dst_data);
4074 /* Edge duplication hook. */
4076 void
4077 edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4078 edge_clone_summary *src_data,
4079 edge_clone_summary *dst_data)
4081 if (src_data->next_clone)
4082 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
4083 dst_data->prev_clone = src_edge;
4084 dst_data->next_clone = src_data->next_clone;
4085 src_data->next_clone = dst_edge;
4088 /* Return true is CS calls DEST or its clone for all contexts. When
4089 ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
4090 edges from/to an all-context clone. */
4092 static bool
4093 calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest,
4094 bool allow_recursion_to_clone)
4096 enum availability availability;
4097 cgraph_node *callee = cs->callee->function_symbol (&availability);
4099 if (availability <= AVAIL_INTERPOSABLE)
4100 return false;
4101 if (callee == dest)
4102 return true;
4103 if (!allow_recursion_to_clone && cs->caller == callee)
4104 return false;
4106 class ipa_node_params *info = IPA_NODE_REF (callee);
4107 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
4110 /* Return true if edge CS does bring about the value described by SRC to
4111 DEST_VAL of node DEST or its clone for all contexts. */
4113 static bool
4114 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
4115 cgraph_node *dest, ipcp_value<tree> *dest_val)
4117 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4119 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val)
4120 || caller_info->node_dead)
4121 return false;
4123 if (!src->val)
4124 return true;
4126 if (caller_info->ipcp_orig_node)
4128 tree t;
4129 if (src->offset == -1)
4130 t = caller_info->known_csts[src->index];
4131 else
4132 t = get_clone_agg_value (cs->caller, src->offset, src->index);
4133 return (t != NULL_TREE
4134 && values_equal_for_ipcp_p (src->val->value, t));
4136 else
4138 if (src->val == dest_val)
4139 return true;
4141 struct ipcp_agg_lattice *aglat;
4142 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4143 src->index);
4144 if (src->offset == -1)
4145 return (plats->itself.is_single_const ()
4146 && values_equal_for_ipcp_p (src->val->value,
4147 plats->itself.values->value));
4148 else
4150 if (plats->aggs_bottom || plats->aggs_contain_variable)
4151 return false;
4152 for (aglat = plats->aggs; aglat; aglat = aglat->next)
4153 if (aglat->offset == src->offset)
4154 return (aglat->is_single_const ()
4155 && values_equal_for_ipcp_p (src->val->value,
4156 aglat->values->value));
4158 return false;
4162 /* Return true if edge CS does bring about the value described by SRC to
4163 DST_VAL of node DEST or its clone for all contexts. */
4165 static bool
4166 cgraph_edge_brings_value_p (cgraph_edge *cs,
4167 ipcp_value_source<ipa_polymorphic_call_context> *src,
4168 cgraph_node *dest,
4169 ipcp_value<ipa_polymorphic_call_context> *)
4171 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
4173 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true)
4174 || caller_info->node_dead)
4175 return false;
4176 if (!src->val)
4177 return true;
4179 if (caller_info->ipcp_orig_node)
4180 return (caller_info->known_contexts.length () > (unsigned) src->index)
4181 && values_equal_for_ipcp_p (src->val->value,
4182 caller_info->known_contexts[src->index]);
4184 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4185 src->index);
4186 return plats->ctxlat.is_single_const ()
4187 && values_equal_for_ipcp_p (src->val->value,
4188 plats->ctxlat.values->value);
4191 /* Get the next clone in the linked list of clones of an edge. */
4193 static inline struct cgraph_edge *
4194 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
4196 edge_clone_summary *s = edge_clone_summaries->get (cs);
4197 return s != NULL ? s->next_clone : NULL;
4200 /* Given VAL that is intended for DEST, iterate over all its sources and if any
4201 of them is viable and hot, return true. In that case, for those that still
4202 hold, add their edge frequency and their number into *FREQUENCY and
4203 *CALLER_COUNT respectively. */
4205 template <typename valtype>
4206 static bool
4207 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
4208 sreal *freq_sum, profile_count *count_sum,
4209 int *caller_count)
4211 ipcp_value_source<valtype> *src;
4212 sreal freq = 0;
4213 int count = 0;
4214 profile_count cnt = profile_count::zero ();
4215 bool hot = false;
4216 bool non_self_recursive = false;
4218 for (src = val->sources; src; src = src->next)
4220 struct cgraph_edge *cs = src->cs;
4221 while (cs)
4223 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4225 count++;
4226 freq += cs->sreal_frequency ();
4227 if (cs->count.ipa ().initialized_p ())
4228 cnt += cs->count.ipa ();
4229 hot |= cs->maybe_hot_p ();
4230 if (cs->caller != dest)
4231 non_self_recursive = true;
4233 cs = get_next_cgraph_edge_clone (cs);
4237 /* If the only edges bringing a value are self-recursive ones, do not bother
4238 evaluating it. */
4239 if (!non_self_recursive)
4240 return false;
4242 *freq_sum = freq;
4243 *count_sum = cnt;
4244 *caller_count = count;
4246 if (!hot && IPA_NODE_REF (dest)->node_within_scc)
4248 struct cgraph_edge *cs;
4250 /* Cold non-SCC source edge could trigger hot recursive execution of
4251 function. Consider the case as hot and rely on following cost model
4252 computation to further select right one. */
4253 for (cs = dest->callers; cs; cs = cs->next_caller)
4254 if (cs->caller == dest && cs->maybe_hot_p ())
4255 return true;
4258 return hot;
4261 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4262 to let a non-self-recursive caller be the first element. Thus, we can
4263 simplify intersecting operations on values that arrive from all of these
4264 callers, especially when there exists self-recursive call. Return true if
4265 this kind of adjustment is possible. */
4267 static bool
4268 adjust_callers_for_value_intersection (vec<cgraph_edge *> callers,
4269 cgraph_node *node)
4271 for (unsigned i = 0; i < callers.length (); i++)
4273 cgraph_edge *cs = callers[i];
4275 if (cs->caller != node)
4277 if (i > 0)
4279 callers[i] = callers[0];
4280 callers[0] = cs;
4282 return true;
4285 return false;
4288 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
4289 is assumed their number is known and equal to CALLER_COUNT. */
4291 template <typename valtype>
4292 static vec<cgraph_edge *>
4293 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
4294 int caller_count)
4296 ipcp_value_source<valtype> *src;
4297 vec<cgraph_edge *> ret;
4299 ret.create (caller_count);
4300 for (src = val->sources; src; src = src->next)
4302 struct cgraph_edge *cs = src->cs;
4303 while (cs)
4305 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4306 ret.quick_push (cs);
4307 cs = get_next_cgraph_edge_clone (cs);
4311 if (caller_count > 1)
4312 adjust_callers_for_value_intersection (ret, dest);
4314 return ret;
4317 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4318 Return it or NULL if for some reason it cannot be created. */
4320 static struct ipa_replace_map *
4321 get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
4323 struct ipa_replace_map *replace_map;
4325 replace_map = ggc_alloc<ipa_replace_map> ();
4326 if (dump_file)
4328 fprintf (dump_file, " replacing ");
4329 ipa_dump_param (dump_file, info, parm_num);
4331 fprintf (dump_file, " with const ");
4332 print_generic_expr (dump_file, value);
4333 fprintf (dump_file, "\n");
4335 replace_map->parm_num = parm_num;
4336 replace_map->new_tree = value;
4337 return replace_map;
4340 /* Dump new profiling counts */
4342 static void
4343 dump_profile_updates (struct cgraph_node *orig_node,
4344 struct cgraph_node *new_node)
4346 struct cgraph_edge *cs;
4348 fprintf (dump_file, " setting count of the specialized node to ");
4349 new_node->count.dump (dump_file);
4350 fprintf (dump_file, "\n");
4351 for (cs = new_node->callees; cs; cs = cs->next_callee)
4353 fprintf (dump_file, " edge to %s has count ",
4354 cs->callee->dump_name ());
4355 cs->count.dump (dump_file);
4356 fprintf (dump_file, "\n");
4359 fprintf (dump_file, " setting count of the original node to ");
4360 orig_node->count.dump (dump_file);
4361 fprintf (dump_file, "\n");
4362 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4364 fprintf (dump_file, " edge to %s is left with ",
4365 cs->callee->dump_name ());
4366 cs->count.dump (dump_file);
4367 fprintf (dump_file, "\n");
4371 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4372 their profile information to reflect this. */
4374 static void
4375 update_profiling_info (struct cgraph_node *orig_node,
4376 struct cgraph_node *new_node)
4378 struct cgraph_edge *cs;
4379 struct caller_statistics stats;
4380 profile_count new_sum, orig_sum;
4381 profile_count remainder, orig_node_count = orig_node->count;
4382 profile_count orig_new_node_count = new_node->count;
4384 if (!(orig_node_count.ipa () > profile_count::zero ()))
4385 return;
4387 init_caller_stats (&stats);
4388 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4389 false);
4390 orig_sum = stats.count_sum;
4391 init_caller_stats (&stats);
4392 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4393 false);
4394 new_sum = stats.count_sum;
4396 if (orig_node_count < orig_sum + new_sum)
4398 if (dump_file)
4400 fprintf (dump_file, " Problem: node %s has too low count ",
4401 orig_node->dump_name ());
4402 orig_node_count.dump (dump_file);
4403 fprintf (dump_file, "while the sum of incoming count is ");
4404 (orig_sum + new_sum).dump (dump_file);
4405 fprintf (dump_file, "\n");
4408 orig_node_count = (orig_sum + new_sum).apply_scale (12, 10);
4409 if (dump_file)
4411 fprintf (dump_file, " proceeding by pretending it was ");
4412 orig_node_count.dump (dump_file);
4413 fprintf (dump_file, "\n");
4417 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
4418 - new_sum.ipa ());
4420 /* With partial train run we do not want to assume that original's
4421 count is zero whenever we redurect all executed edges to clone.
4422 Simply drop profile to local one in this case. */
4423 if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
4424 && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
4425 && flag_profile_partial_training)
4426 remainder = remainder.guessed_local ();
4428 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
4429 new_node->count = new_sum;
4430 orig_node->count = remainder;
4432 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
4433 for (cs = new_node->callees; cs; cs = cs->next_callee)
4434 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4435 for (cs = new_node->indirect_calls; cs; cs = cs->next_callee)
4436 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4438 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
4439 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4440 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4441 for (cs = orig_node->indirect_calls; cs; cs = cs->next_callee)
4442 cs->count = cs->count.apply_scale (remainder, orig_node_count);
4444 if (dump_file)
4445 dump_profile_updates (orig_node, new_node);
4448 /* Update the respective profile of specialized NEW_NODE and the original
4449 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4450 have been redirected to the specialized version. */
4452 static void
4453 update_specialized_profile (struct cgraph_node *new_node,
4454 struct cgraph_node *orig_node,
4455 profile_count redirected_sum)
4457 struct cgraph_edge *cs;
4458 profile_count new_node_count, orig_node_count = orig_node->count;
4460 if (dump_file)
4462 fprintf (dump_file, " the sum of counts of redirected edges is ");
4463 redirected_sum.dump (dump_file);
4464 fprintf (dump_file, "\n");
4466 if (!(orig_node_count > profile_count::zero ()))
4467 return;
4469 gcc_assert (orig_node_count >= redirected_sum);
4471 new_node_count = new_node->count;
4472 new_node->count += redirected_sum;
4473 orig_node->count -= redirected_sum;
4475 for (cs = new_node->callees; cs; cs = cs->next_callee)
4476 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
4478 for (cs = orig_node->callees; cs; cs = cs->next_callee)
4480 profile_count dec = cs->count.apply_scale (redirected_sum,
4481 orig_node_count);
4482 cs->count -= dec;
4485 if (dump_file)
4486 dump_profile_updates (orig_node, new_node);
4489 /* Return true if we would like to remove a parameter from NODE when cloning it
4490 with KNOWN_CSTS scalar constants. */
4492 static bool
4493 want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
4495 auto_vec<bool, 16> surviving;
4496 bool filled_vec = false;
4497 ipa_node_params *info = IPA_NODE_REF (node);
4498 int i, count = ipa_get_param_count (info);
4500 for (i = 0; i < count; i++)
4502 if (!known_csts[i] && ipa_is_param_used (info, i))
4503 continue;
4505 if (!filled_vec)
4507 clone_info *info = clone_info::get (node);
4508 if (!info || !info->param_adjustments)
4509 return true;
4510 info->param_adjustments->get_surviving_params (&surviving);
4511 filled_vec = true;
4513 if (surviving.length() < (unsigned) i && surviving[i])
4514 return true;
4516 return false;
4519 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4520 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4521 redirect all edges in CALLERS to it. */
4523 static struct cgraph_node *
4524 create_specialized_node (struct cgraph_node *node,
4525 vec<tree> known_csts,
4526 vec<ipa_polymorphic_call_context> known_contexts,
4527 struct ipa_agg_replacement_value *aggvals,
4528 vec<cgraph_edge *> callers)
4530 class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
4531 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
4532 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
4533 struct ipa_agg_replacement_value *av;
4534 struct cgraph_node *new_node;
4535 int i, count = ipa_get_param_count (info);
4536 clone_info *cinfo = clone_info::get (node);
4537 ipa_param_adjustments *old_adjustments = cinfo
4538 ? cinfo->param_adjustments : NULL;
4539 ipa_param_adjustments *new_adjustments;
4540 gcc_assert (!info->ipcp_orig_node);
4541 gcc_assert (node->can_change_signature
4542 || !old_adjustments);
4544 if (old_adjustments)
4546 /* At the moment all IPA optimizations should use the number of
4547 parameters of the prevailing decl as the m_always_copy_start.
4548 Handling any other value would complicate the code below, so for the
4549 time bing let's only assert it is so. */
4550 gcc_assert (old_adjustments->m_always_copy_start == count
4551 || old_adjustments->m_always_copy_start < 0);
4552 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
4553 for (i = 0; i < old_adj_count; i++)
4555 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
4556 if (!node->can_change_signature
4557 || old_adj->op != IPA_PARAM_OP_COPY
4558 || (!known_csts[old_adj->base_index]
4559 && ipa_is_param_used (info, old_adj->base_index)))
4561 ipa_adjusted_param new_adj = *old_adj;
4563 new_adj.prev_clone_adjustment = true;
4564 new_adj.prev_clone_index = i;
4565 vec_safe_push (new_params, new_adj);
4568 bool skip_return = old_adjustments->m_skip_return;
4569 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4570 ipa_param_adjustments (new_params, count,
4571 skip_return));
4573 else if (node->can_change_signature
4574 && want_remove_some_param_p (node, known_csts))
4576 ipa_adjusted_param adj;
4577 memset (&adj, 0, sizeof (adj));
4578 adj.op = IPA_PARAM_OP_COPY;
4579 for (i = 0; i < count; i++)
4580 if (!known_csts[i] && ipa_is_param_used (info, i))
4582 adj.base_index = i;
4583 adj.prev_clone_index = i;
4584 vec_safe_push (new_params, adj);
4586 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4587 ipa_param_adjustments (new_params, count, false));
4589 else
4590 new_adjustments = NULL;
4592 replace_trees = cinfo ? vec_safe_copy (cinfo->tree_map) : NULL;
4593 for (i = 0; i < count; i++)
4595 tree t = known_csts[i];
4596 if (t)
4598 struct ipa_replace_map *replace_map;
4600 gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
4601 replace_map = get_replacement_map (info, t, i);
4602 if (replace_map)
4603 vec_safe_push (replace_trees, replace_map);
4606 auto_vec<cgraph_edge *, 2> self_recursive_calls;
4607 for (i = callers.length () - 1; i >= 0; i--)
4609 cgraph_edge *cs = callers[i];
4610 if (cs->caller == node)
4612 self_recursive_calls.safe_push (cs);
4613 callers.unordered_remove (i);
4617 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
4618 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4619 node->decl)));
4620 new_node = node->create_virtual_clone (callers, replace_trees,
4621 new_adjustments, "constprop",
4622 suffix_counter);
4623 suffix_counter++;
4625 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
4626 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
4628 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
4629 /* Cloned edges can disappear during cloning as speculation can be
4630 resolved, check that we have one and that it comes from the last
4631 cloning. */
4632 if (cs && cs->caller == new_node)
4633 cs->redirect_callee_duplicating_thunks (new_node);
4634 /* Any future code that would make more than one clone of an outgoing
4635 edge would confuse this mechanism, so let's check that does not
4636 happen. */
4637 gcc_checking_assert (!cs
4638 || !get_next_cgraph_edge_clone (cs)
4639 || get_next_cgraph_edge_clone (cs)->caller != new_node);
4641 if (have_self_recursive_calls)
4642 new_node->expand_all_artificial_thunks ();
4644 ipa_set_node_agg_value_chain (new_node, aggvals);
4645 for (av = aggvals; av; av = av->next)
4646 new_node->maybe_create_reference (av->value, NULL);
4648 if (dump_file && (dump_flags & TDF_DETAILS))
4650 fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ());
4651 if (known_contexts.exists ())
4653 for (i = 0; i < count; i++)
4654 if (!known_contexts[i].useless_p ())
4656 fprintf (dump_file, " known ctx %i is ", i);
4657 known_contexts[i].dump (dump_file);
4660 if (aggvals)
4661 ipa_dump_agg_replacement_values (dump_file, aggvals);
4663 ipa_check_create_node_params ();
4664 update_profiling_info (node, new_node);
4665 new_info = IPA_NODE_REF (new_node);
4666 new_info->ipcp_orig_node = node;
4667 new_node->ipcp_clone = true;
4668 new_info->known_csts = known_csts;
4669 new_info->known_contexts = known_contexts;
4671 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
4673 callers.release ();
4674 return new_node;
4677 /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
4678 pass-through function to itself when the cgraph_node involved is not an
4679 IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
4680 no-operation pass-through. */
4682 static bool
4683 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
4684 bool simple = true)
4686 enum availability availability;
4687 if (cs->caller == cs->callee->function_symbol (&availability)
4688 && availability > AVAIL_INTERPOSABLE
4689 && jfunc->type == IPA_JF_PASS_THROUGH
4690 && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4691 && ipa_get_jf_pass_through_formal_id (jfunc) == i
4692 && IPA_NODE_REF (cs->caller)
4693 && !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
4694 return true;
4695 return false;
4698 /* Return true if JFUNC, which describes a part of an aggregate represented or
4699 pointed to by the i-th parameter of call CS, is a pass-through function to
4700 itself when the cgraph_node involved is not an IPA-CP clone.. When
4701 SIMPLE is true, further check if JFUNC is a simple no-operation
4702 pass-through. */
4704 static bool
4705 self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
4706 int i, bool simple = true)
4708 enum availability availability;
4709 if (cs->caller == cs->callee->function_symbol (&availability)
4710 && availability > AVAIL_INTERPOSABLE
4711 && jfunc->jftype == IPA_JF_LOAD_AGG
4712 && jfunc->offset == jfunc->value.load_agg.offset
4713 && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
4714 && jfunc->value.pass_through.formal_id == i
4715 && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)
4716 && IPA_NODE_REF (cs->caller)
4717 && !IPA_NODE_REF (cs->caller)->ipcp_orig_node)
4718 return true;
4719 return false;
4722 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
4723 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
4725 static void
4726 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
4727 vec<tree> known_csts,
4728 vec<cgraph_edge *> callers)
4730 class ipa_node_params *info = IPA_NODE_REF (node);
4731 int i, count = ipa_get_param_count (info);
4733 for (i = 0; i < count; i++)
4735 struct cgraph_edge *cs;
4736 tree newval = NULL_TREE;
4737 int j;
4738 bool first = true;
4739 tree type = ipa_get_type (info, i);
4741 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
4742 continue;
4744 FOR_EACH_VEC_ELT (callers, j, cs)
4746 struct ipa_jump_func *jump_func;
4747 tree t;
4749 if (!IPA_EDGE_REF (cs)
4750 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
4751 || (i == 0
4752 && call_passes_through_thunk (cs)))
4754 newval = NULL_TREE;
4755 break;
4757 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
4759 /* Besides simple pass-through jump function, arithmetic jump
4760 function could also introduce argument-direct-pass-through for
4761 self-feeding recursive call. For example,
4763 fn (int i)
4765 fn (i & 1);
4768 Given that i is 0, recursive propagation via (i & 1) also gets
4769 0. */
4770 if (self_recursive_pass_through_p (cs, jump_func, i, false))
4772 gcc_assert (newval);
4773 t = ipa_get_jf_arith_result (
4774 ipa_get_jf_pass_through_operation (jump_func),
4775 newval,
4776 ipa_get_jf_pass_through_operand (jump_func),
4777 type);
4779 else
4780 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func,
4781 type);
4782 if (!t
4783 || (newval
4784 && !values_equal_for_ipcp_p (t, newval))
4785 || (!first && !newval))
4787 newval = NULL_TREE;
4788 break;
4790 else
4791 newval = t;
4792 first = false;
4795 if (newval)
4797 if (dump_file && (dump_flags & TDF_DETAILS))
4799 fprintf (dump_file, " adding an extra known scalar value ");
4800 print_ipcp_constant_value (dump_file, newval);
4801 fprintf (dump_file, " for ");
4802 ipa_dump_param (dump_file, info, i);
4803 fprintf (dump_file, "\n");
4806 known_csts[i] = newval;
4811 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4812 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4813 CALLERS. */
4815 static void
4816 find_more_contexts_for_caller_subset (cgraph_node *node,
4817 vec<ipa_polymorphic_call_context>
4818 *known_contexts,
4819 vec<cgraph_edge *> callers)
4821 ipa_node_params *info = IPA_NODE_REF (node);
4822 int i, count = ipa_get_param_count (info);
4824 for (i = 0; i < count; i++)
4826 cgraph_edge *cs;
4828 if (ipa_get_poly_ctx_lat (info, i)->bottom
4829 || (known_contexts->exists ()
4830 && !(*known_contexts)[i].useless_p ()))
4831 continue;
4833 ipa_polymorphic_call_context newval;
4834 bool first = true;
4835 int j;
4837 FOR_EACH_VEC_ELT (callers, j, cs)
4839 if (!IPA_EDGE_REF (cs)
4840 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
4841 return;
4842 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
4844 ipa_polymorphic_call_context ctx;
4845 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
4846 jfunc);
4847 if (first)
4849 newval = ctx;
4850 first = false;
4852 else
4853 newval.meet_with (ctx);
4854 if (newval.useless_p ())
4855 break;
4858 if (!newval.useless_p ())
4860 if (dump_file && (dump_flags & TDF_DETAILS))
4862 fprintf (dump_file, " adding an extra known polymorphic "
4863 "context ");
4864 print_ipcp_constant_value (dump_file, newval);
4865 fprintf (dump_file, " for ");
4866 ipa_dump_param (dump_file, info, i);
4867 fprintf (dump_file, "\n");
4870 if (!known_contexts->exists ())
4871 known_contexts->safe_grow_cleared (ipa_get_param_count (info),
4872 true);
4873 (*known_contexts)[i] = newval;
4879 /* Go through PLATS and create a vector of values consisting of values and
4880 offsets (minus OFFSET) of lattices that contain only a single value. */
4882 static vec<ipa_agg_value>
4883 copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
4885 vec<ipa_agg_value> res = vNULL;
4887 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4888 return vNULL;
4890 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
4891 if (aglat->is_single_const ())
4893 struct ipa_agg_value ti;
4894 ti.offset = aglat->offset - offset;
4895 ti.value = aglat->values->value;
4896 res.safe_push (ti);
4898 return res;
4901 /* Intersect all values in INTER with single value lattices in PLATS (while
4902 subtracting OFFSET). */
4904 static void
4905 intersect_with_plats (class ipcp_param_lattices *plats,
4906 vec<ipa_agg_value> *inter,
4907 HOST_WIDE_INT offset)
4909 struct ipcp_agg_lattice *aglat;
4910 struct ipa_agg_value *item;
4911 int k;
4913 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4915 inter->release ();
4916 return;
4919 aglat = plats->aggs;
4920 FOR_EACH_VEC_ELT (*inter, k, item)
4922 bool found = false;
4923 if (!item->value)
4924 continue;
4925 while (aglat)
4927 if (aglat->offset - offset > item->offset)
4928 break;
4929 if (aglat->offset - offset == item->offset)
4931 if (aglat->is_single_const ())
4933 tree value = aglat->values->value;
4935 if (values_equal_for_ipcp_p (item->value, value))
4936 found = true;
4938 break;
4940 aglat = aglat->next;
4942 if (!found)
4943 item->value = NULL_TREE;
4947 /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
4948 vector result while subtracting OFFSET from the individual value offsets. */
4950 static vec<ipa_agg_value>
4951 agg_replacements_to_vector (struct cgraph_node *node, int index,
4952 HOST_WIDE_INT offset)
4954 struct ipa_agg_replacement_value *av;
4955 vec<ipa_agg_value> res = vNULL;
4957 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
4958 if (av->index == index
4959 && (av->offset - offset) >= 0)
4961 struct ipa_agg_value item;
4962 gcc_checking_assert (av->value);
4963 item.offset = av->offset - offset;
4964 item.value = av->value;
4965 res.safe_push (item);
4968 return res;
4971 /* Intersect all values in INTER with those that we have already scheduled to
4972 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4973 (while subtracting OFFSET). */
4975 static void
4976 intersect_with_agg_replacements (struct cgraph_node *node, int index,
4977 vec<ipa_agg_value> *inter,
4978 HOST_WIDE_INT offset)
4980 struct ipa_agg_replacement_value *srcvals;
4981 struct ipa_agg_value *item;
4982 int i;
4984 srcvals = ipa_get_agg_replacements_for_node (node);
4985 if (!srcvals)
4987 inter->release ();
4988 return;
4991 FOR_EACH_VEC_ELT (*inter, i, item)
4993 struct ipa_agg_replacement_value *av;
4994 bool found = false;
4995 if (!item->value)
4996 continue;
4997 for (av = srcvals; av; av = av->next)
4999 gcc_checking_assert (av->value);
5000 if (av->index == index
5001 && av->offset - offset == item->offset)
5003 if (values_equal_for_ipcp_p (item->value, av->value))
5004 found = true;
5005 break;
5008 if (!found)
5009 item->value = NULL_TREE;
5013 /* Intersect values in INTER with aggregate values that come along edge CS to
5014 parameter number INDEX and return it. If INTER does not actually exist yet,
5015 copy all incoming values to it. If we determine we ended up with no values
5016 whatsoever, return a released vector. */
5018 static vec<ipa_agg_value>
5019 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
5020 vec<ipa_agg_value> inter)
5022 struct ipa_jump_func *jfunc;
5023 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
5024 if (jfunc->type == IPA_JF_PASS_THROUGH
5025 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
5027 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5028 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
5030 if (caller_info->ipcp_orig_node)
5032 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
5033 class ipcp_param_lattices *orig_plats;
5034 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
5035 src_idx);
5036 if (agg_pass_through_permissible_p (orig_plats, jfunc))
5038 if (!inter.exists ())
5039 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
5040 else
5041 intersect_with_agg_replacements (cs->caller, src_idx,
5042 &inter, 0);
5043 return inter;
5046 else
5048 class ipcp_param_lattices *src_plats;
5049 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
5050 if (agg_pass_through_permissible_p (src_plats, jfunc))
5052 /* Currently we do not produce clobber aggregate jump
5053 functions, adjust when we do. */
5054 gcc_checking_assert (!jfunc->agg.items);
5055 if (!inter.exists ())
5056 inter = copy_plats_to_inter (src_plats, 0);
5057 else
5058 intersect_with_plats (src_plats, &inter, 0);
5059 return inter;
5063 else if (jfunc->type == IPA_JF_ANCESTOR
5064 && ipa_get_jf_ancestor_agg_preserved (jfunc))
5066 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5067 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
5068 class ipcp_param_lattices *src_plats;
5069 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
5071 if (caller_info->ipcp_orig_node)
5073 if (!inter.exists ())
5074 inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
5075 else
5076 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
5077 delta);
5079 else
5081 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
5082 /* Currently we do not produce clobber aggregate jump
5083 functions, adjust when we do. */
5084 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
5085 if (!inter.exists ())
5086 inter = copy_plats_to_inter (src_plats, delta);
5087 else
5088 intersect_with_plats (src_plats, &inter, delta);
5090 return inter;
5093 if (jfunc->agg.items)
5095 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5096 struct ipa_agg_value *item;
5097 int k;
5099 if (!inter.exists ())
5100 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
5102 struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
5103 tree value = ipa_agg_value_from_node (caller_info, cs->caller,
5104 agg_item);
5105 if (value)
5107 struct ipa_agg_value agg_value;
5109 agg_value.value = value;
5110 agg_value.offset = agg_item->offset;
5111 inter.safe_push (agg_value);
5114 else
5115 FOR_EACH_VEC_ELT (inter, k, item)
5117 int l = 0;
5118 bool found = false;
5120 if (!item->value)
5121 continue;
5123 while ((unsigned) l < jfunc->agg.items->length ())
5125 struct ipa_agg_jf_item *ti;
5126 ti = &(*jfunc->agg.items)[l];
5127 if (ti->offset > item->offset)
5128 break;
5129 if (ti->offset == item->offset)
5131 tree value;
5133 /* Besides simple pass-through aggregate jump function,
5134 arithmetic aggregate jump function could also bring
5135 same aggregate value as parameter passed-in for
5136 self-feeding recursive call. For example,
5138 fn (int *i)
5140 int j = *i & 1;
5141 fn (&j);
5144 Given that *i is 0, recursive propagation via (*i & 1)
5145 also gets 0. */
5146 if (self_recursive_agg_pass_through_p (cs, ti, index,
5147 false))
5148 value = ipa_get_jf_arith_result (
5149 ti->value.pass_through.operation,
5150 item->value,
5151 ti->value.pass_through.operand,
5152 ti->type);
5153 else
5154 value = ipa_agg_value_from_node (caller_info,
5155 cs->caller, ti);
5157 if (value && values_equal_for_ipcp_p (item->value, value))
5158 found = true;
5159 break;
5161 l++;
5163 if (!found)
5164 item->value = NULL;
5167 else
5169 inter.release ();
5170 return vNULL;
5172 return inter;
5175 /* Look at edges in CALLERS and collect all known aggregate values that arrive
5176 from all of them. */
5178 static struct ipa_agg_replacement_value *
5179 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
5180 vec<cgraph_edge *> callers)
5182 class ipa_node_params *dest_info = IPA_NODE_REF (node);
5183 struct ipa_agg_replacement_value *res;
5184 struct ipa_agg_replacement_value **tail = &res;
5185 struct cgraph_edge *cs;
5186 int i, j, count = ipa_get_param_count (dest_info);
5188 FOR_EACH_VEC_ELT (callers, j, cs)
5190 if (!IPA_EDGE_REF (cs))
5192 count = 0;
5193 break;
5195 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5196 if (c < count)
5197 count = c;
5200 for (i = 0; i < count; i++)
5202 struct cgraph_edge *cs;
5203 vec<ipa_agg_value> inter = vNULL;
5204 struct ipa_agg_value *item;
5205 class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
5206 int j;
5208 /* Among other things, the following check should deal with all by_ref
5209 mismatches. */
5210 if (plats->aggs_bottom)
5211 continue;
5213 FOR_EACH_VEC_ELT (callers, j, cs)
5215 struct ipa_jump_func *jfunc
5216 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
5217 if (self_recursive_pass_through_p (cs, jfunc, i)
5218 && (!plats->aggs_by_ref
5219 || ipa_get_jf_pass_through_agg_preserved (jfunc)))
5220 continue;
5221 inter = intersect_aggregates_with_edge (cs, i, inter);
5223 if (!inter.exists ())
5224 goto next_param;
5227 FOR_EACH_VEC_ELT (inter, j, item)
5229 struct ipa_agg_replacement_value *v;
5231 if (!item->value)
5232 continue;
5234 v = ggc_alloc<ipa_agg_replacement_value> ();
5235 v->index = i;
5236 v->offset = item->offset;
5237 v->value = item->value;
5238 v->by_ref = plats->aggs_by_ref;
5239 *tail = v;
5240 tail = &v->next;
5243 next_param:
5244 if (inter.exists ())
5245 inter.release ();
5247 *tail = NULL;
5248 return res;
5251 /* Determine whether CS also brings all scalar values that the NODE is
5252 specialized for. */
5254 static bool
5255 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
5256 struct cgraph_node *node)
5258 class ipa_node_params *dest_info = IPA_NODE_REF (node);
5259 int count = ipa_get_param_count (dest_info);
5260 class ipa_node_params *caller_info;
5261 class ipa_edge_args *args;
5262 int i;
5264 caller_info = IPA_NODE_REF (cs->caller);
5265 args = IPA_EDGE_REF (cs);
5266 for (i = 0; i < count; i++)
5268 struct ipa_jump_func *jump_func;
5269 tree val, t;
5271 val = dest_info->known_csts[i];
5272 if (!val)
5273 continue;
5275 if (i >= ipa_get_cs_argument_count (args))
5276 return false;
5277 jump_func = ipa_get_ith_jump_func (args, i);
5278 t = ipa_value_from_jfunc (caller_info, jump_func,
5279 ipa_get_type (dest_info, i));
5280 if (!t || !values_equal_for_ipcp_p (val, t))
5281 return false;
5283 return true;
5286 /* Determine whether CS also brings all aggregate values that NODE is
5287 specialized for. */
5288 static bool
5289 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
5290 struct cgraph_node *node)
5292 class ipa_node_params *orig_node_info;
5293 struct ipa_agg_replacement_value *aggval;
5294 int i, ec, count;
5296 aggval = ipa_get_agg_replacements_for_node (node);
5297 if (!aggval)
5298 return true;
5300 count = ipa_get_param_count (IPA_NODE_REF (node));
5301 ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5302 if (ec < count)
5303 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5304 if (aggval->index >= ec)
5305 return false;
5307 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
5309 for (i = 0; i < count; i++)
5311 class ipcp_param_lattices *plats;
5312 bool interesting = false;
5313 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5314 if (aggval->index == i)
5316 interesting = true;
5317 break;
5319 if (!interesting)
5320 continue;
5322 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
5323 if (plats->aggs_bottom)
5324 return false;
5326 vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL);
5327 if (!values.exists ())
5328 return false;
5330 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5331 if (aggval->index == i)
5333 struct ipa_agg_value *item;
5334 int j;
5335 bool found = false;
5336 FOR_EACH_VEC_ELT (values, j, item)
5337 if (item->value
5338 && item->offset == av->offset
5339 && values_equal_for_ipcp_p (item->value, av->value))
5341 found = true;
5342 break;
5344 if (!found)
5346 values.release ();
5347 return false;
5350 values.release ();
5352 return true;
5355 /* Given an original NODE and a VAL for which we have already created a
5356 specialized clone, look whether there are incoming edges that still lead
5357 into the old node but now also bring the requested value and also conform to
5358 all other criteria such that they can be redirected the special node.
5359 This function can therefore redirect the final edge in a SCC. */
5361 template <typename valtype>
5362 static void
5363 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
5365 ipcp_value_source<valtype> *src;
5366 profile_count redirected_sum = profile_count::zero ();
5368 for (src = val->sources; src; src = src->next)
5370 struct cgraph_edge *cs = src->cs;
5371 while (cs)
5373 if (cgraph_edge_brings_value_p (cs, src, node, val)
5374 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
5375 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
5377 if (dump_file)
5378 fprintf (dump_file, " - adding an extra caller %s of %s\n",
5379 cs->caller->dump_name (),
5380 val->spec_node->dump_name ());
5382 cs->redirect_callee_duplicating_thunks (val->spec_node);
5383 val->spec_node->expand_all_artificial_thunks ();
5384 if (cs->count.ipa ().initialized_p ())
5385 redirected_sum = redirected_sum + cs->count.ipa ();
5387 cs = get_next_cgraph_edge_clone (cs);
5391 if (redirected_sum.nonzero_p ())
5392 update_specialized_profile (val->spec_node, node, redirected_sum);
5395 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5397 static bool
5398 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
5400 ipa_polymorphic_call_context *ctx;
5401 int i;
5403 FOR_EACH_VEC_ELT (known_contexts, i, ctx)
5404 if (!ctx->useless_p ())
5405 return true;
5406 return false;
5409 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5411 static vec<ipa_polymorphic_call_context>
5412 copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
5414 if (known_contexts_useful_p (known_contexts))
5415 return known_contexts.copy ();
5416 else
5417 return vNULL;
5420 /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
5421 according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its
5422 copy too. */
5424 static void
5425 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
5426 vec<tree> *known_csts,
5427 vec<ipa_polymorphic_call_context> *known_contexts,
5428 ipcp_value<tree> *val, int index)
5430 *known_csts = avals->m_known_vals.copy ();
5431 *known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
5432 (*known_csts)[index] = val->value;
5435 /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy
5436 contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
5437 INDEX. */
5439 static void
5440 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
5441 vec<tree> *known_csts,
5442 vec<ipa_polymorphic_call_context> *known_contexts,
5443 ipcp_value<ipa_polymorphic_call_context> *val,
5444 int index)
5446 *known_csts = avals->m_known_vals.copy ();
5447 *known_contexts = avals->m_known_contexts.copy ();
5448 (*known_contexts)[index] = val->value;
5451 /* Return true if OFFSET indicates this was not an aggregate value or there is
5452 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5453 AGGVALS list. */
5455 DEBUG_FUNCTION bool
5456 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
5457 int index, HOST_WIDE_INT offset, tree value)
5459 if (offset == -1)
5460 return true;
5462 while (aggvals)
5464 if (aggvals->index == index
5465 && aggvals->offset == offset
5466 && values_equal_for_ipcp_p (aggvals->value, value))
5467 return true;
5468 aggvals = aggvals->next;
5470 return false;
5473 /* Return true if offset is minus one because source of a polymorphic context
5474 cannot be an aggregate value. */
5476 DEBUG_FUNCTION bool
5477 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
5478 int , HOST_WIDE_INT offset,
5479 ipa_polymorphic_call_context)
5481 return offset == -1;
5484 /* Decide whether to create a special version of NODE for value VAL of
5485 parameter at the given INDEX. If OFFSET is -1, the value is for the
5486 parameter itself, otherwise it is stored at the given OFFSET of the
5487 parameter. AVALS describes the other already known values. */
5489 template <typename valtype>
5490 static bool
5491 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
5492 ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals)
5494 struct ipa_agg_replacement_value *aggvals;
5495 int caller_count;
5496 sreal freq_sum;
5497 profile_count count_sum;
5498 vec<cgraph_edge *> callers;
5500 if (val->spec_node)
5502 perhaps_add_new_callers (node, val);
5503 return false;
5505 else if (val->local_size_cost + overall_size > get_max_overall_size (node))
5507 if (dump_file && (dump_flags & TDF_DETAILS))
5508 fprintf (dump_file, " Ignoring candidate value because "
5509 "maximum unit size would be reached with %li.\n",
5510 val->local_size_cost + overall_size);
5511 return false;
5513 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
5514 &caller_count))
5515 return false;
5517 if (!dbg_cnt (ipa_cp_values))
5518 return false;
5520 if (dump_file && (dump_flags & TDF_DETAILS))
5522 fprintf (dump_file, " - considering value ");
5523 print_ipcp_constant_value (dump_file, val->value);
5524 fprintf (dump_file, " for ");
5525 ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
5526 if (offset != -1)
5527 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
5528 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
5531 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
5532 freq_sum, count_sum,
5533 val->local_size_cost)
5534 && !good_cloning_opportunity_p (node, val->prop_time_benefit,
5535 freq_sum, count_sum, val->prop_size_cost))
5536 return false;
5538 if (dump_file)
5539 fprintf (dump_file, " Creating a specialized node of %s.\n",
5540 node->dump_name ());
5542 vec<tree> known_csts;
5543 vec<ipa_polymorphic_call_context> known_contexts;
5545 callers = gather_edges_for_value (val, node, caller_count);
5546 if (offset == -1)
5547 copy_known_vectors_add_val (avals, &known_csts, &known_contexts, val, index);
5548 else
5550 known_csts = avals->m_known_vals.copy ();
5551 known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
5553 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5554 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5555 aggvals = find_aggregate_values_for_callers_subset (node, callers);
5556 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
5557 offset, val->value));
5558 val->spec_node = create_specialized_node (node, known_csts, known_contexts,
5559 aggvals, callers);
5560 overall_size += val->local_size_cost;
5561 if (dump_file && (dump_flags & TDF_DETAILS))
5562 fprintf (dump_file, " overall size reached %li\n",
5563 overall_size);
5565 /* TODO: If for some lattice there is only one other known value
5566 left, make a special node for it too. */
5568 return true;
5571 /* Decide whether and what specialized clones of NODE should be created. */
5573 static bool
5574 decide_whether_version_node (struct cgraph_node *node)
5576 class ipa_node_params *info = IPA_NODE_REF (node);
5577 int i, count = ipa_get_param_count (info);
5578 bool ret = false;
5580 if (count == 0)
5581 return false;
5583 if (dump_file && (dump_flags & TDF_DETAILS))
5584 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
5585 node->dump_name ());
5587 ipa_auto_call_arg_values avals;
5588 gather_context_independent_values (info, &avals, false, NULL);
5590 for (i = 0; i < count;i++)
5592 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5593 ipcp_lattice<tree> *lat = &plats->itself;
5594 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
5596 if (!lat->bottom
5597 && !avals.m_known_vals[i])
5599 ipcp_value<tree> *val;
5600 for (val = lat->values; val; val = val->next)
5601 ret |= decide_about_value (node, i, -1, val, &avals);
5604 if (!plats->aggs_bottom)
5606 struct ipcp_agg_lattice *aglat;
5607 ipcp_value<tree> *val;
5608 for (aglat = plats->aggs; aglat; aglat = aglat->next)
5609 if (!aglat->bottom && aglat->values
5610 /* If the following is false, the one value has been considered
5611 for cloning for all contexts. */
5612 && (plats->aggs_contain_variable
5613 || !aglat->is_single_const ()))
5614 for (val = aglat->values; val; val = val->next)
5615 ret |= decide_about_value (node, i, aglat->offset, val, &avals);
5618 if (!ctxlat->bottom
5619 && avals.m_known_contexts[i].useless_p ())
5621 ipcp_value<ipa_polymorphic_call_context> *val;
5622 for (val = ctxlat->values; val; val = val->next)
5623 ret |= decide_about_value (node, i, -1, val, &avals);
5626 info = IPA_NODE_REF (node);
5629 if (info->do_clone_for_all_contexts)
5631 if (!dbg_cnt (ipa_cp_values))
5633 info->do_clone_for_all_contexts = false;
5634 return ret;
5637 struct cgraph_node *clone;
5638 vec<cgraph_edge *> callers = node->collect_callers ();
5640 for (int i = callers.length () - 1; i >= 0; i--)
5642 cgraph_edge *cs = callers[i];
5643 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5645 if (caller_info && caller_info->node_dead)
5646 callers.unordered_remove (i);
5649 if (!adjust_callers_for_value_intersection (callers, node))
5651 /* If node is not called by anyone, or all its caller edges are
5652 self-recursive, the node is not really in use, no need to do
5653 cloning. */
5654 callers.release ();
5655 info->do_clone_for_all_contexts = false;
5656 return ret;
5659 if (dump_file)
5660 fprintf (dump_file, " - Creating a specialized node of %s "
5661 "for all known contexts.\n", node->dump_name ());
5663 vec<tree> known_csts = avals.m_known_vals.copy ();
5664 vec<ipa_polymorphic_call_context> known_contexts
5665 = copy_useful_known_contexts (avals.m_known_contexts);
5666 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5667 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5668 ipa_agg_replacement_value *aggvals
5669 = find_aggregate_values_for_callers_subset (node, callers);
5671 if (!known_contexts_useful_p (known_contexts))
5673 known_contexts.release ();
5674 known_contexts = vNULL;
5676 clone = create_specialized_node (node, known_csts, known_contexts,
5677 aggvals, callers);
5678 info = IPA_NODE_REF (node);
5679 info->do_clone_for_all_contexts = false;
5680 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
5681 ret = true;
5684 return ret;
5687 /* Transitively mark all callees of NODE within the same SCC as not dead. */
5689 static void
5690 spread_undeadness (struct cgraph_node *node)
5692 struct cgraph_edge *cs;
5694 for (cs = node->callees; cs; cs = cs->next_callee)
5695 if (ipa_edge_within_scc (cs))
5697 struct cgraph_node *callee;
5698 class ipa_node_params *info;
5700 callee = cs->callee->function_symbol (NULL);
5701 info = IPA_NODE_REF (callee);
5703 if (info && info->node_dead)
5705 info->node_dead = 0;
5706 spread_undeadness (callee);
5711 /* Return true if NODE has a caller from outside of its SCC that is not
5712 dead. Worker callback for cgraph_for_node_and_aliases. */
5714 static bool
5715 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
5716 void *data ATTRIBUTE_UNUSED)
5718 struct cgraph_edge *cs;
5720 for (cs = node->callers; cs; cs = cs->next_caller)
5721 if (cs->caller->thunk
5722 && cs->caller->call_for_symbol_thunks_and_aliases
5723 (has_undead_caller_from_outside_scc_p, NULL, true))
5724 return true;
5725 else if (!ipa_edge_within_scc (cs)
5726 && (!IPA_NODE_REF (cs->caller) /* Unoptimized caller. */
5727 || !IPA_NODE_REF (cs->caller)->node_dead))
5728 return true;
5729 return false;
5733 /* Identify nodes within the same SCC as NODE which are no longer needed
5734 because of new clones and will be removed as unreachable. */
5736 static void
5737 identify_dead_nodes (struct cgraph_node *node)
5739 struct cgraph_node *v;
5740 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5741 if (v->local
5742 && IPA_NODE_REF (v)
5743 && !v->call_for_symbol_thunks_and_aliases
5744 (has_undead_caller_from_outside_scc_p, NULL, true))
5745 IPA_NODE_REF (v)->node_dead = 1;
5747 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5748 if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
5749 spread_undeadness (v);
5751 if (dump_file && (dump_flags & TDF_DETAILS))
5753 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5754 if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
5755 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
5759 /* The decision stage. Iterate over the topological order of call graph nodes
5760 TOPO and make specialized clones if deemed beneficial. */
5762 static void
5763 ipcp_decision_stage (class ipa_topo_info *topo)
5765 int i;
5767 if (dump_file)
5768 fprintf (dump_file, "\nIPA decision stage:\n\n");
5770 for (i = topo->nnodes - 1; i >= 0; i--)
5772 struct cgraph_node *node = topo->order[i];
5773 bool change = false, iterate = true;
5775 while (iterate)
5777 struct cgraph_node *v;
5778 iterate = false;
5779 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
5780 if (v->has_gimple_body_p ()
5781 && ipcp_versionable_function_p (v))
5782 iterate |= decide_whether_version_node (v);
5784 change |= iterate;
5786 if (change)
5787 identify_dead_nodes (node);
5791 /* Look up all the bits information that we have discovered and copy it over
5792 to the transformation summary. */
5794 static void
5795 ipcp_store_bits_results (void)
5797 cgraph_node *node;
5799 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5801 ipa_node_params *info = IPA_NODE_REF (node);
5802 bool dumped_sth = false;
5803 bool found_useful_result = false;
5805 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
5807 if (dump_file)
5808 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
5809 "; -fipa-bit-cp: disabled.\n",
5810 node->dump_name ());
5811 continue;
5814 if (info->ipcp_orig_node)
5815 info = IPA_NODE_REF (info->ipcp_orig_node);
5816 if (!info->lattices)
5817 /* Newly expanded artificial thunks do not have lattices. */
5818 continue;
5820 unsigned count = ipa_get_param_count (info);
5821 for (unsigned i = 0; i < count; i++)
5823 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5824 if (plats->bits_lattice.constant_p ())
5826 found_useful_result = true;
5827 break;
5831 if (!found_useful_result)
5832 continue;
5834 ipcp_transformation_initialize ();
5835 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5836 vec_safe_reserve_exact (ts->bits, count);
5838 for (unsigned i = 0; i < count; i++)
5840 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5841 ipa_bits *jfbits;
5843 if (plats->bits_lattice.constant_p ())
5845 jfbits
5846 = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
5847 plats->bits_lattice.get_mask ());
5848 if (!dbg_cnt (ipa_cp_bits))
5849 jfbits = NULL;
5851 else
5852 jfbits = NULL;
5854 ts->bits->quick_push (jfbits);
5855 if (!dump_file || !jfbits)
5856 continue;
5857 if (!dumped_sth)
5859 fprintf (dump_file, "Propagated bits info for function %s:\n",
5860 node->dump_name ());
5861 dumped_sth = true;
5863 fprintf (dump_file, " param %i: value = ", i);
5864 print_hex (jfbits->value, dump_file);
5865 fprintf (dump_file, ", mask = ");
5866 print_hex (jfbits->mask, dump_file);
5867 fprintf (dump_file, "\n");
5872 /* Look up all VR information that we have discovered and copy it over
5873 to the transformation summary. */
5875 static void
5876 ipcp_store_vr_results (void)
5878 cgraph_node *node;
5880 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5882 ipa_node_params *info = IPA_NODE_REF (node);
5883 bool found_useful_result = false;
5885 if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
5887 if (dump_file)
5888 fprintf (dump_file, "Not considering %s for VR discovery "
5889 "and propagate; -fipa-ipa-vrp: disabled.\n",
5890 node->dump_name ());
5891 continue;
5894 if (info->ipcp_orig_node)
5895 info = IPA_NODE_REF (info->ipcp_orig_node);
5896 if (!info->lattices)
5897 /* Newly expanded artificial thunks do not have lattices. */
5898 continue;
5900 unsigned count = ipa_get_param_count (info);
5901 for (unsigned i = 0; i < count; i++)
5903 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5904 if (!plats->m_value_range.bottom_p ()
5905 && !plats->m_value_range.top_p ())
5907 found_useful_result = true;
5908 break;
5911 if (!found_useful_result)
5912 continue;
5914 ipcp_transformation_initialize ();
5915 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
5916 vec_safe_reserve_exact (ts->m_vr, count);
5918 for (unsigned i = 0; i < count; i++)
5920 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5921 ipa_vr vr;
5923 if (!plats->m_value_range.bottom_p ()
5924 && !plats->m_value_range.top_p ()
5925 && dbg_cnt (ipa_cp_vr))
5927 vr.known = true;
5928 vr.type = plats->m_value_range.m_vr.kind ();
5929 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
5930 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
5932 else
5934 vr.known = false;
5935 vr.type = VR_VARYING;
5936 vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
5938 ts->m_vr->quick_push (vr);
5943 /* The IPCP driver. */
5945 static unsigned int
5946 ipcp_driver (void)
5948 class ipa_topo_info topo;
5950 if (edge_clone_summaries == NULL)
5951 edge_clone_summaries = new edge_clone_summary_t (symtab);
5953 ipa_check_create_node_params ();
5954 ipa_check_create_edge_args ();
5955 clone_num_suffixes = new hash_map<const char *, unsigned>;
5957 if (dump_file)
5959 fprintf (dump_file, "\nIPA structures before propagation:\n");
5960 if (dump_flags & TDF_DETAILS)
5961 ipa_print_all_params (dump_file);
5962 ipa_print_all_jump_functions (dump_file);
5965 /* Topological sort. */
5966 build_toporder_info (&topo);
5967 /* Do the interprocedural propagation. */
5968 ipcp_propagate_stage (&topo);
5969 /* Decide what constant propagation and cloning should be performed. */
5970 ipcp_decision_stage (&topo);
5971 /* Store results of bits propagation. */
5972 ipcp_store_bits_results ();
5973 /* Store results of value range propagation. */
5974 ipcp_store_vr_results ();
5976 /* Free all IPCP structures. */
5977 delete clone_num_suffixes;
5978 free_toporder_info (&topo);
5979 delete edge_clone_summaries;
5980 edge_clone_summaries = NULL;
5981 ipa_free_all_structures_after_ipa_cp ();
5982 if (dump_file)
5983 fprintf (dump_file, "\nIPA constant propagation end\n");
5984 return 0;
5987 /* Initialization and computation of IPCP data structures. This is the initial
5988 intraprocedural analysis of functions, which gathers information to be
5989 propagated later on. */
5991 static void
5992 ipcp_generate_summary (void)
5994 struct cgraph_node *node;
5996 if (dump_file)
5997 fprintf (dump_file, "\nIPA constant propagation start:\n");
5998 ipa_register_cgraph_hooks ();
6000 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
6001 ipa_analyze_node (node);
6004 namespace {
6006 const pass_data pass_data_ipa_cp =
6008 IPA_PASS, /* type */
6009 "cp", /* name */
6010 OPTGROUP_NONE, /* optinfo_flags */
6011 TV_IPA_CONSTANT_PROP, /* tv_id */
6012 0, /* properties_required */
6013 0, /* properties_provided */
6014 0, /* properties_destroyed */
6015 0, /* todo_flags_start */
6016 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
6019 class pass_ipa_cp : public ipa_opt_pass_d
6021 public:
6022 pass_ipa_cp (gcc::context *ctxt)
6023 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
6024 ipcp_generate_summary, /* generate_summary */
6025 NULL, /* write_summary */
6026 NULL, /* read_summary */
6027 ipcp_write_transformation_summaries, /*
6028 write_optimization_summary */
6029 ipcp_read_transformation_summaries, /*
6030 read_optimization_summary */
6031 NULL, /* stmt_fixup */
6032 0, /* function_transform_todo_flags_start */
6033 ipcp_transform_function, /* function_transform */
6034 NULL) /* variable_transform */
6037 /* opt_pass methods: */
6038 virtual bool gate (function *)
6040 /* FIXME: We should remove the optimize check after we ensure we never run
6041 IPA passes when not optimizing. */
6042 return (flag_ipa_cp && optimize) || in_lto_p;
6045 virtual unsigned int execute (function *) { return ipcp_driver (); }
6047 }; // class pass_ipa_cp
6049 } // anon namespace
6051 ipa_opt_pass_d *
6052 make_pass_ipa_cp (gcc::context *ctxt)
6054 return new pass_ipa_cp (ctxt);
6057 /* Reset all state within ipa-cp.c so that we can rerun the compiler
6058 within the same process. For use by toplev::finalize. */
6060 void
6061 ipa_cp_c_finalize (void)
6063 max_count = profile_count::uninitialized ();
6064 overall_size = 0;
6065 orig_overall_size = 0;
6066 ipcp_free_transformation_sum ();