]> git.ipfire.org Git - people/ms/gcc.git/blob - gcc/ipa-cp.cc
c++: namespace-scoped friend in local class [PR69410]
[people/ms/gcc.git] / gcc / ipa-cp.cc
1 /* Interprocedural constant propagation
2 Copyright (C) 2005-2023 Free Software Foundation, Inc.
3
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
5 <mjambor@suse.cz>
6
7 This file is part of GCC.
8
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.
13
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.
18
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/>. */
22
23 /* Interprocedural constant propagation (IPA-CP).
24
25 The goal of this transformation is to
26
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
30
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.
35
36 The algorithm also propagates types and attempts to perform type based
37 devirtualization. Types are propagated much like constants.
38
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.
47
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.
52
53
54 First stage - intraprocedural analysis
55 =======================================
56
57 This phase computes jump_function and modification flags.
58
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:
62
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.
67
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.
70
71 ipcp_generate_summary() is the main function of the first stage.
72
73 Second stage - interprocedural analysis
74 ========================================
75
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.
79
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.
86
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.
92
93 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
94 third stage.
95
96 Third phase - materialization of clones, call statement updates.
97 ============================================
98
99 This stage is currently performed by call graph code (mainly in cgraphunit.cc
100 and tree-inline.cc) according to instructions inserted to the call graph by
101 the second stage. */
102
103 #define INCLUDE_ALGORITHM
104 #include "config.h"
105 #include "system.h"
106 #include "coretypes.h"
107 #include "backend.h"
108 #include "tree.h"
109 #include "gimple-expr.h"
110 #include "gimple.h"
111 #include "predict.h"
112 #include "alloc-pool.h"
113 #include "tree-pass.h"
114 #include "cgraph.h"
115 #include "diagnostic.h"
116 #include "fold-const.h"
117 #include "gimple-iterator.h"
118 #include "gimple-fold.h"
119 #include "symbol-summary.h"
120 #include "tree-vrp.h"
121 #include "ipa-prop.h"
122 #include "tree-pretty-print.h"
123 #include "tree-inline.h"
124 #include "ipa-fnsummary.h"
125 #include "ipa-utils.h"
126 #include "tree-ssa-ccp.h"
127 #include "stringpool.h"
128 #include "attribs.h"
129 #include "dbgcnt.h"
130 #include "symtab-clones.h"
131
132 template <typename valtype> class ipcp_value;
133
134 /* Describes a particular source for an IPA-CP value. */
135
136 template <typename valtype>
137 struct ipcp_value_source
138 {
139 public:
140 /* Aggregate offset of the source, negative if the source is scalar value of
141 the argument itself. */
142 HOST_WIDE_INT offset;
143 /* The incoming edge that brought the value. */
144 cgraph_edge *cs;
145 /* If the jump function that resulted into his value was a pass-through or an
146 ancestor, this is the ipcp_value of the caller from which the described
147 value has been derived. Otherwise it is NULL. */
148 ipcp_value<valtype> *val;
149 /* Next pointer in a linked list of sources of a value. */
150 ipcp_value_source *next;
151 /* If the jump function that resulted into his value was a pass-through or an
152 ancestor, this is the index of the parameter of the caller the jump
153 function references. */
154 int index;
155 };
156
157 /* Common ancestor for all ipcp_value instantiations. */
158
159 class ipcp_value_base
160 {
161 public:
162 /* Time benefit and that specializing the function for this value would bring
163 about in this function alone. */
164 sreal local_time_benefit;
165 /* Time benefit that specializing the function for this value can bring about
166 in it's callees. */
167 sreal prop_time_benefit;
168 /* Size cost that specializing the function for this value would bring about
169 in this function alone. */
170 int local_size_cost;
171 /* Size cost that specializing the function for this value can bring about in
172 it's callees. */
173 int prop_size_cost;
174
175 ipcp_value_base ()
176 : local_time_benefit (0), prop_time_benefit (0),
177 local_size_cost (0), prop_size_cost (0) {}
178 };
179
180 /* Describes one particular value stored in struct ipcp_lattice. */
181
182 template <typename valtype>
183 class ipcp_value : public ipcp_value_base
184 {
185 public:
186 /* The actual value for the given parameter. */
187 valtype value;
188 /* The list of sources from which this value originates. */
189 ipcp_value_source <valtype> *sources = nullptr;
190 /* Next pointers in a linked list of all values in a lattice. */
191 ipcp_value *next = nullptr;
192 /* Next pointers in a linked list of values in a strongly connected component
193 of values. */
194 ipcp_value *scc_next = nullptr;
195 /* Next pointers in a linked list of SCCs of values sorted topologically
196 according their sources. */
197 ipcp_value *topo_next = nullptr;
198 /* A specialized node created for this value, NULL if none has been (so far)
199 created. */
200 cgraph_node *spec_node = nullptr;
201 /* Depth first search number and low link for topological sorting of
202 values. */
203 int dfs = 0;
204 int low_link = 0;
205 /* SCC number to identify values which recursively feed into each other.
206 Values in the same SCC have the same SCC number. */
207 int scc_no = 0;
208 /* Non zero if the value is generated from another value in the same lattice
209 for a self-recursive call, the actual number is how many times the
210 operation has been performed. In the unlikely event of the value being
211 present in two chains fo self-recursive value generation chains, it is the
212 maximum. */
213 unsigned self_recursion_generated_level = 0;
214 /* True if this value is currently on the topo-sort stack. */
215 bool on_stack = false;
216
217 void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
218 HOST_WIDE_INT offset);
219
220 /* Return true if both THIS value and O feed into each other. */
221
222 bool same_scc (const ipcp_value<valtype> *o)
223 {
224 return o->scc_no == scc_no;
225 }
226
227 /* Return true, if a this value has been generated for a self-recursive call as
228 a result of an arithmetic pass-through jump-function acting on a value in
229 the same lattice function. */
230
231 bool self_recursion_generated_p ()
232 {
233 return self_recursion_generated_level > 0;
234 }
235 };
236
237 /* Lattice describing potential values of a formal parameter of a function, or
238 a part of an aggregate. TOP is represented by a lattice with zero values
239 and with contains_variable and bottom flags cleared. BOTTOM is represented
240 by a lattice with the bottom flag set. In that case, values and
241 contains_variable flag should be disregarded. */
242
243 template <typename valtype>
244 struct ipcp_lattice
245 {
246 public:
247 /* The list of known values and types in this lattice. Note that values are
248 not deallocated if a lattice is set to bottom because there may be value
249 sources referencing them. */
250 ipcp_value<valtype> *values;
251 /* Number of known values and types in this lattice. */
252 int values_count;
253 /* The lattice contains a variable component (in addition to values). */
254 bool contains_variable;
255 /* The value of the lattice is bottom (i.e. variable and unusable for any
256 propagation). */
257 bool bottom;
258
259 inline bool is_single_const ();
260 inline bool set_to_bottom ();
261 inline bool set_contains_variable ();
262 bool add_value (valtype newval, cgraph_edge *cs,
263 ipcp_value<valtype> *src_val = NULL,
264 int src_idx = 0, HOST_WIDE_INT offset = -1,
265 ipcp_value<valtype> **val_p = NULL,
266 unsigned same_lat_gen_level = 0);
267 void print (FILE * f, bool dump_sources, bool dump_benefits);
268 };
269
270 /* Lattice of tree values with an offset to describe a part of an
271 aggregate. */
272
273 struct ipcp_agg_lattice : public ipcp_lattice<tree>
274 {
275 public:
276 /* Offset that is being described by this lattice. */
277 HOST_WIDE_INT offset;
278 /* Size so that we don't have to re-compute it every time we traverse the
279 list. Must correspond to TYPE_SIZE of all lat values. */
280 HOST_WIDE_INT size;
281 /* Next element of the linked list. */
282 struct ipcp_agg_lattice *next;
283 };
284
285 /* Lattice of known bits, only capable of holding one value.
286 Bitwise constant propagation propagates which bits of a
287 value are constant.
288 For eg:
289 int f(int x)
290 {
291 return some_op (x);
292 }
293
294 int f1(int y)
295 {
296 if (cond)
297 return f (y & 0xff);
298 else
299 return f (y & 0xf);
300 }
301
302 In the above case, the param 'x' will always have all
303 the bits (except the bits in lsb) set to 0.
304 Hence the mask of 'x' would be 0xff. The mask
305 reflects that the bits in lsb are unknown.
306 The actual propagated value is given by m_value & ~m_mask. */
307
308 class ipcp_bits_lattice
309 {
310 public:
311 bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
312 bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
313 bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
314 bool set_to_bottom ();
315 bool set_to_constant (widest_int, widest_int);
316 bool known_nonzero_p () const;
317
318 widest_int get_value () const { return m_value; }
319 widest_int get_mask () const { return m_mask; }
320
321 bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
322 enum tree_code, tree, bool);
323
324 bool meet_with (widest_int, widest_int, unsigned);
325
326 void print (FILE *);
327
328 private:
329 enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
330
331 /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
332 If a bit in mask is set to 0, then the corresponding bit in
333 value is known to be constant. */
334 widest_int m_value, m_mask;
335
336 bool meet_with_1 (widest_int, widest_int, unsigned, bool);
337 void get_value_and_mask (tree, widest_int *, widest_int *);
338 };
339
340 /* Lattice of value ranges. */
341
342 class ipcp_vr_lattice
343 {
344 public:
345 value_range m_vr;
346
347 inline bool bottom_p () const;
348 inline bool top_p () const;
349 inline bool set_to_bottom ();
350 bool meet_with (const value_range *p_vr);
351 bool meet_with (const ipcp_vr_lattice &other);
352 void init () { gcc_assert (m_vr.undefined_p ()); }
353 void print (FILE * f);
354
355 private:
356 bool meet_with_1 (const value_range *other_vr);
357 };
358
359 /* Structure containing lattices for a parameter itself and for pieces of
360 aggregates that are passed in the parameter or by a reference in a parameter
361 plus some other useful flags. */
362
363 class ipcp_param_lattices
364 {
365 public:
366 /* Lattice describing the value of the parameter itself. */
367 ipcp_lattice<tree> itself;
368 /* Lattice describing the polymorphic contexts of a parameter. */
369 ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
370 /* Lattices describing aggregate parts. */
371 ipcp_agg_lattice *aggs;
372 /* Lattice describing known bits. */
373 ipcp_bits_lattice bits_lattice;
374 /* Lattice describing value range. */
375 ipcp_vr_lattice m_value_range;
376 /* Number of aggregate lattices */
377 int aggs_count;
378 /* True if aggregate data were passed by reference (as opposed to by
379 value). */
380 bool aggs_by_ref;
381 /* All aggregate lattices contain a variable component (in addition to
382 values). */
383 bool aggs_contain_variable;
384 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
385 for any propagation). */
386 bool aggs_bottom;
387
388 /* There is a virtual call based on this parameter. */
389 bool virt_call;
390 };
391
392 /* Allocation pools for values and their sources in ipa-cp. */
393
394 object_allocator<ipcp_value<tree> > ipcp_cst_values_pool
395 ("IPA-CP constant values");
396
397 object_allocator<ipcp_value<ipa_polymorphic_call_context> >
398 ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
399
400 object_allocator<ipcp_value_source<tree> > ipcp_sources_pool
401 ("IPA-CP value sources");
402
403 object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
404 ("IPA_CP aggregate lattices");
405
406 /* Base count to use in heuristics when using profile feedback. */
407
408 static profile_count base_count;
409
410 /* Original overall size of the program. */
411
412 static long overall_size, orig_overall_size;
413
414 /* Node name to unique clone suffix number map. */
415 static hash_map<const char *, unsigned> *clone_num_suffixes;
416
417 /* Return the param lattices structure corresponding to the Ith formal
418 parameter of the function described by INFO. */
419 static inline class ipcp_param_lattices *
420 ipa_get_parm_lattices (class ipa_node_params *info, int i)
421 {
422 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
423 gcc_checking_assert (!info->ipcp_orig_node);
424 gcc_checking_assert (info->lattices);
425 return &(info->lattices[i]);
426 }
427
428 /* Return the lattice corresponding to the scalar value of the Ith formal
429 parameter of the function described by INFO. */
430 static inline ipcp_lattice<tree> *
431 ipa_get_scalar_lat (class ipa_node_params *info, int i)
432 {
433 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
434 return &plats->itself;
435 }
436
437 /* Return the lattice corresponding to the scalar value of the Ith formal
438 parameter of the function described by INFO. */
439 static inline ipcp_lattice<ipa_polymorphic_call_context> *
440 ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
441 {
442 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
443 return &plats->ctxlat;
444 }
445
446 /* Return whether LAT is a lattice with a single constant and without an
447 undefined value. */
448
449 template <typename valtype>
450 inline bool
451 ipcp_lattice<valtype>::is_single_const ()
452 {
453 if (bottom || contains_variable || values_count != 1)
454 return false;
455 else
456 return true;
457 }
458
459 /* Return true iff X and Y should be considered equal values by IPA-CP. */
460
461 static bool
462 values_equal_for_ipcp_p (tree x, tree y)
463 {
464 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
465
466 if (x == y)
467 return true;
468
469 if (TREE_CODE (x) == ADDR_EXPR
470 && TREE_CODE (y) == ADDR_EXPR
471 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
472 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
473 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
474 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
475 else
476 return operand_equal_p (x, y, 0);
477 }
478
479 /* Print V which is extracted from a value in a lattice to F. */
480
481 static void
482 print_ipcp_constant_value (FILE * f, tree v)
483 {
484 if (TREE_CODE (v) == ADDR_EXPR
485 && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
486 {
487 fprintf (f, "& ");
488 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)));
489 }
490 else
491 print_generic_expr (f, v);
492 }
493
494 /* Print V which is extracted from a value in a lattice to F. */
495
496 static void
497 print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
498 {
499 v.dump(f, false);
500 }
501
502 /* Print a lattice LAT to F. */
503
504 template <typename valtype>
505 void
506 ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
507 {
508 ipcp_value<valtype> *val;
509 bool prev = false;
510
511 if (bottom)
512 {
513 fprintf (f, "BOTTOM\n");
514 return;
515 }
516
517 if (!values_count && !contains_variable)
518 {
519 fprintf (f, "TOP\n");
520 return;
521 }
522
523 if (contains_variable)
524 {
525 fprintf (f, "VARIABLE");
526 prev = true;
527 if (dump_benefits)
528 fprintf (f, "\n");
529 }
530
531 for (val = values; val; val = val->next)
532 {
533 if (dump_benefits && prev)
534 fprintf (f, " ");
535 else if (!dump_benefits && prev)
536 fprintf (f, ", ");
537 else
538 prev = true;
539
540 print_ipcp_constant_value (f, val->value);
541
542 if (dump_sources)
543 {
544 ipcp_value_source<valtype> *s;
545
546 if (val->self_recursion_generated_p ())
547 fprintf (f, " [self_gen(%i), from:",
548 val->self_recursion_generated_level);
549 else
550 fprintf (f, " [scc: %i, from:", val->scc_no);
551 for (s = val->sources; s; s = s->next)
552 fprintf (f, " %i(%f)", s->cs->caller->order,
553 s->cs->sreal_frequency ().to_double ());
554 fprintf (f, "]");
555 }
556
557 if (dump_benefits)
558 fprintf (f, " [loc_time: %g, loc_size: %i, "
559 "prop_time: %g, prop_size: %i]\n",
560 val->local_time_benefit.to_double (), val->local_size_cost,
561 val->prop_time_benefit.to_double (), val->prop_size_cost);
562 }
563 if (!dump_benefits)
564 fprintf (f, "\n");
565 }
566
567 void
568 ipcp_bits_lattice::print (FILE *f)
569 {
570 if (top_p ())
571 fprintf (f, " Bits unknown (TOP)\n");
572 else if (bottom_p ())
573 fprintf (f, " Bits unusable (BOTTOM)\n");
574 else
575 {
576 fprintf (f, " Bits: value = "); print_hex (get_value (), f);
577 fprintf (f, ", mask = "); print_hex (get_mask (), f);
578 fprintf (f, "\n");
579 }
580 }
581
582 /* Print value range lattice to F. */
583
584 void
585 ipcp_vr_lattice::print (FILE * f)
586 {
587 dump_value_range (f, &m_vr);
588 }
589
590 /* Print all ipcp_lattices of all functions to F. */
591
592 static void
593 print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
594 {
595 struct cgraph_node *node;
596 int i, count;
597
598 fprintf (f, "\nLattices:\n");
599 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
600 {
601 class ipa_node_params *info;
602
603 info = ipa_node_params_sum->get (node);
604 /* Skip unoptimized functions and constprop clones since we don't make
605 lattices for them. */
606 if (!info || info->ipcp_orig_node)
607 continue;
608 fprintf (f, " Node: %s:\n", node->dump_name ());
609 count = ipa_get_param_count (info);
610 for (i = 0; i < count; i++)
611 {
612 struct ipcp_agg_lattice *aglat;
613 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
614 fprintf (f, " param [%d]: ", i);
615 plats->itself.print (f, dump_sources, dump_benefits);
616 fprintf (f, " ctxs: ");
617 plats->ctxlat.print (f, dump_sources, dump_benefits);
618 plats->bits_lattice.print (f);
619 fprintf (f, " ");
620 plats->m_value_range.print (f);
621 fprintf (f, "\n");
622 if (plats->virt_call)
623 fprintf (f, " virt_call flag set\n");
624
625 if (plats->aggs_bottom)
626 {
627 fprintf (f, " AGGS BOTTOM\n");
628 continue;
629 }
630 if (plats->aggs_contain_variable)
631 fprintf (f, " AGGS VARIABLE\n");
632 for (aglat = plats->aggs; aglat; aglat = aglat->next)
633 {
634 fprintf (f, " %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
635 plats->aggs_by_ref ? "ref " : "", aglat->offset);
636 aglat->print (f, dump_sources, dump_benefits);
637 }
638 }
639 }
640 }
641
642 /* Determine whether it is at all technically possible to create clones of NODE
643 and store this information in the ipa_node_params structure associated
644 with NODE. */
645
646 static void
647 determine_versionability (struct cgraph_node *node,
648 class ipa_node_params *info)
649 {
650 const char *reason = NULL;
651
652 /* There are a number of generic reasons functions cannot be versioned. We
653 also cannot remove parameters if there are type attributes such as fnspec
654 present. */
655 if (node->alias || node->thunk)
656 reason = "alias or thunk";
657 else if (!node->versionable)
658 reason = "not a tree_versionable_function";
659 else if (node->get_availability () <= AVAIL_INTERPOSABLE)
660 reason = "insufficient body availability";
661 else if (!opt_for_fn (node->decl, optimize)
662 || !opt_for_fn (node->decl, flag_ipa_cp))
663 reason = "non-optimized function";
664 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
665 {
666 /* Ideally we should clone the SIMD clones themselves and create
667 vector copies of them, so IPA-cp and SIMD clones can happily
668 coexist, but that may not be worth the effort. */
669 reason = "function has SIMD clones";
670 }
671 else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)))
672 {
673 /* Ideally we should clone the target clones themselves and create
674 copies of them, so IPA-cp and target clones can happily
675 coexist, but that may not be worth the effort. */
676 reason = "function target_clones attribute";
677 }
678 /* Don't clone decls local to a comdat group; it breaks and for C++
679 decloned constructors, inlining is always better anyway. */
680 else if (node->comdat_local_p ())
681 reason = "comdat-local function";
682 else if (node->calls_comdat_local)
683 {
684 /* TODO: call is versionable if we make sure that all
685 callers are inside of a comdat group. */
686 reason = "calls comdat-local function";
687 }
688
689 /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
690 work only when inlined. Cloning them may still lead to better code
691 because ipa-cp will not give up on cloning further. If the function is
692 external this however leads to wrong code because we may end up producing
693 offline copy of the function. */
694 if (DECL_EXTERNAL (node->decl))
695 for (cgraph_edge *edge = node->callees; !reason && edge;
696 edge = edge->next_callee)
697 if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
698 {
699 if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
700 reason = "external function which calls va_arg_pack";
701 if (DECL_FUNCTION_CODE (edge->callee->decl)
702 == BUILT_IN_VA_ARG_PACK_LEN)
703 reason = "external function which calls va_arg_pack_len";
704 }
705
706 if (reason && dump_file && !node->alias && !node->thunk)
707 fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
708 node->dump_name (), reason);
709
710 info->versionable = (reason == NULL);
711 }
712
713 /* Return true if it is at all technically possible to create clones of a
714 NODE. */
715
716 static bool
717 ipcp_versionable_function_p (struct cgraph_node *node)
718 {
719 ipa_node_params *info = ipa_node_params_sum->get (node);
720 return info && info->versionable;
721 }
722
723 /* Structure holding accumulated information about callers of a node. */
724
725 struct caller_statistics
726 {
727 /* If requested (see below), self-recursive call counts are summed into this
728 field. */
729 profile_count rec_count_sum;
730 /* The sum of all ipa counts of all the other (non-recursive) calls. */
731 profile_count count_sum;
732 /* Sum of all frequencies for all calls. */
733 sreal freq_sum;
734 /* Number of calls and hot calls respectively. */
735 int n_calls, n_hot_calls;
736 /* If itself is set up, also count the number of non-self-recursive
737 calls. */
738 int n_nonrec_calls;
739 /* If non-NULL, this is the node itself and calls from it should have their
740 counts included in rec_count_sum and not count_sum. */
741 cgraph_node *itself;
742 };
743
744 /* Initialize fields of STAT to zeroes and optionally set it up so that edges
745 from IGNORED_CALLER are not counted. */
746
747 static inline void
748 init_caller_stats (caller_statistics *stats, cgraph_node *itself = NULL)
749 {
750 stats->rec_count_sum = profile_count::zero ();
751 stats->count_sum = profile_count::zero ();
752 stats->n_calls = 0;
753 stats->n_hot_calls = 0;
754 stats->n_nonrec_calls = 0;
755 stats->freq_sum = 0;
756 stats->itself = itself;
757 }
758
759 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
760 non-thunk incoming edges to NODE. */
761
762 static bool
763 gather_caller_stats (struct cgraph_node *node, void *data)
764 {
765 struct caller_statistics *stats = (struct caller_statistics *) data;
766 struct cgraph_edge *cs;
767
768 for (cs = node->callers; cs; cs = cs->next_caller)
769 if (!cs->caller->thunk)
770 {
771 ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
772 if (info && info->node_dead)
773 continue;
774
775 if (cs->count.ipa ().initialized_p ())
776 {
777 if (stats->itself && stats->itself == cs->caller)
778 stats->rec_count_sum += cs->count.ipa ();
779 else
780 stats->count_sum += cs->count.ipa ();
781 }
782 stats->freq_sum += cs->sreal_frequency ();
783 stats->n_calls++;
784 if (stats->itself && stats->itself != cs->caller)
785 stats->n_nonrec_calls++;
786
787 if (cs->maybe_hot_p ())
788 stats->n_hot_calls ++;
789 }
790 return false;
791
792 }
793
794 /* Return true if this NODE is viable candidate for cloning. */
795
796 static bool
797 ipcp_cloning_candidate_p (struct cgraph_node *node)
798 {
799 struct caller_statistics stats;
800
801 gcc_checking_assert (node->has_gimple_body_p ());
802
803 if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
804 {
805 if (dump_file)
806 fprintf (dump_file, "Not considering %s for cloning; "
807 "-fipa-cp-clone disabled.\n",
808 node->dump_name ());
809 return false;
810 }
811
812 if (node->optimize_for_size_p ())
813 {
814 if (dump_file)
815 fprintf (dump_file, "Not considering %s for cloning; "
816 "optimizing it for size.\n",
817 node->dump_name ());
818 return false;
819 }
820
821 init_caller_stats (&stats);
822 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
823
824 if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
825 {
826 if (dump_file)
827 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
828 node->dump_name ());
829 return true;
830 }
831
832 /* When profile is available and function is hot, propagate into it even if
833 calls seems cold; constant propagation can improve function's speed
834 significantly. */
835 if (stats.count_sum > profile_count::zero ()
836 && node->count.ipa ().initialized_p ())
837 {
838 if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
839 {
840 if (dump_file)
841 fprintf (dump_file, "Considering %s for cloning; "
842 "usually called directly.\n",
843 node->dump_name ());
844 return true;
845 }
846 }
847 if (!stats.n_hot_calls)
848 {
849 if (dump_file)
850 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
851 node->dump_name ());
852 return false;
853 }
854 if (dump_file)
855 fprintf (dump_file, "Considering %s for cloning.\n",
856 node->dump_name ());
857 return true;
858 }
859
860 template <typename valtype>
861 class value_topo_info
862 {
863 public:
864 /* Head of the linked list of topologically sorted values. */
865 ipcp_value<valtype> *values_topo;
866 /* Stack for creating SCCs, represented by a linked list too. */
867 ipcp_value<valtype> *stack;
868 /* Counter driving the algorithm in add_val_to_toposort. */
869 int dfs_counter;
870
871 value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
872 {}
873 void add_val (ipcp_value<valtype> *cur_val);
874 void propagate_effects ();
875 };
876
877 /* Arrays representing a topological ordering of call graph nodes and a stack
878 of nodes used during constant propagation and also data required to perform
879 topological sort of values and propagation of benefits in the determined
880 order. */
881
882 class ipa_topo_info
883 {
884 public:
885 /* Array with obtained topological order of cgraph nodes. */
886 struct cgraph_node **order;
887 /* Stack of cgraph nodes used during propagation within SCC until all values
888 in the SCC stabilize. */
889 struct cgraph_node **stack;
890 int nnodes, stack_top;
891
892 value_topo_info<tree> constants;
893 value_topo_info<ipa_polymorphic_call_context> contexts;
894
895 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
896 constants ()
897 {}
898 };
899
900 /* Skip edges from and to nodes without ipa_cp enabled.
901 Ignore not available symbols. */
902
903 static bool
904 ignore_edge_p (cgraph_edge *e)
905 {
906 enum availability avail;
907 cgraph_node *ultimate_target
908 = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
909
910 return (avail <= AVAIL_INTERPOSABLE
911 || !opt_for_fn (ultimate_target->decl, optimize)
912 || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
913 }
914
915 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
916
917 static void
918 build_toporder_info (class ipa_topo_info *topo)
919 {
920 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
921 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
922
923 gcc_checking_assert (topo->stack_top == 0);
924 topo->nnodes = ipa_reduced_postorder (topo->order, true,
925 ignore_edge_p);
926 }
927
928 /* Free information about strongly connected components and the arrays in
929 TOPO. */
930
931 static void
932 free_toporder_info (class ipa_topo_info *topo)
933 {
934 ipa_free_postorder_info ();
935 free (topo->order);
936 free (topo->stack);
937 }
938
939 /* Add NODE to the stack in TOPO, unless it is already there. */
940
941 static inline void
942 push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
943 {
944 ipa_node_params *info = ipa_node_params_sum->get (node);
945 if (info->node_enqueued)
946 return;
947 info->node_enqueued = 1;
948 topo->stack[topo->stack_top++] = node;
949 }
950
951 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
952 is empty. */
953
954 static struct cgraph_node *
955 pop_node_from_stack (class ipa_topo_info *topo)
956 {
957 if (topo->stack_top)
958 {
959 struct cgraph_node *node;
960 topo->stack_top--;
961 node = topo->stack[topo->stack_top];
962 ipa_node_params_sum->get (node)->node_enqueued = 0;
963 return node;
964 }
965 else
966 return NULL;
967 }
968
969 /* Set lattice LAT to bottom and return true if it previously was not set as
970 such. */
971
972 template <typename valtype>
973 inline bool
974 ipcp_lattice<valtype>::set_to_bottom ()
975 {
976 bool ret = !bottom;
977 bottom = true;
978 return ret;
979 }
980
981 /* Mark lattice as containing an unknown value and return true if it previously
982 was not marked as such. */
983
984 template <typename valtype>
985 inline bool
986 ipcp_lattice<valtype>::set_contains_variable ()
987 {
988 bool ret = !contains_variable;
989 contains_variable = true;
990 return ret;
991 }
992
993 /* Set all aggregate lattices in PLATS to bottom and return true if they were
994 not previously set as such. */
995
996 static inline bool
997 set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
998 {
999 bool ret = !plats->aggs_bottom;
1000 plats->aggs_bottom = true;
1001 return ret;
1002 }
1003
1004 /* Mark all aggregate lattices in PLATS as containing an unknown value and
1005 return true if they were not previously marked as such. */
1006
1007 static inline bool
1008 set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
1009 {
1010 bool ret = !plats->aggs_contain_variable;
1011 plats->aggs_contain_variable = true;
1012 return ret;
1013 }
1014
1015 bool
1016 ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
1017 {
1018 return meet_with_1 (&other.m_vr);
1019 }
1020
1021 /* Meet the current value of the lattice with value range described by VR
1022 lattice. */
1023
1024 bool
1025 ipcp_vr_lattice::meet_with (const value_range *p_vr)
1026 {
1027 return meet_with_1 (p_vr);
1028 }
1029
1030 /* Meet the current value of the lattice with value range described by
1031 OTHER_VR lattice. Return TRUE if anything changed. */
1032
1033 bool
1034 ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
1035 {
1036 if (bottom_p ())
1037 return false;
1038
1039 if (other_vr->varying_p ())
1040 return set_to_bottom ();
1041
1042 value_range save (m_vr);
1043 m_vr.union_ (*other_vr);
1044 return m_vr != save;
1045 }
1046
1047 /* Return true if value range information in the lattice is yet unknown. */
1048
1049 bool
1050 ipcp_vr_lattice::top_p () const
1051 {
1052 return m_vr.undefined_p ();
1053 }
1054
1055 /* Return true if value range information in the lattice is known to be
1056 unusable. */
1057
1058 bool
1059 ipcp_vr_lattice::bottom_p () const
1060 {
1061 return m_vr.varying_p ();
1062 }
1063
1064 /* Set value range information in the lattice to bottom. Return true if it
1065 previously was in a different state. */
1066
1067 bool
1068 ipcp_vr_lattice::set_to_bottom ()
1069 {
1070 if (m_vr.varying_p ())
1071 return false;
1072 /* ?? We create all sorts of VARYING ranges for floats, structures,
1073 and other types which we cannot handle as ranges. We should
1074 probably avoid handling them throughout the pass, but it's easier
1075 to create a sensible VARYING here and let the lattice
1076 propagate. */
1077 m_vr.set_varying (integer_type_node);
1078 return true;
1079 }
1080
1081 /* Set lattice value to bottom, if it already isn't the case. */
1082
1083 bool
1084 ipcp_bits_lattice::set_to_bottom ()
1085 {
1086 if (bottom_p ())
1087 return false;
1088 m_lattice_val = IPA_BITS_VARYING;
1089 m_value = 0;
1090 m_mask = -1;
1091 return true;
1092 }
1093
1094 /* Set to constant if it isn't already. Only meant to be called
1095 when switching state from TOP. */
1096
1097 bool
1098 ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask)
1099 {
1100 gcc_assert (top_p ());
1101 m_lattice_val = IPA_BITS_CONSTANT;
1102 m_value = wi::bit_and (wi::bit_not (mask), value);
1103 m_mask = mask;
1104 return true;
1105 }
1106
1107 /* Return true if any of the known bits are non-zero. */
1108
1109 bool
1110 ipcp_bits_lattice::known_nonzero_p () const
1111 {
1112 if (!constant_p ())
1113 return false;
1114 return wi::ne_p (wi::bit_and (wi::bit_not (m_mask), m_value), 0);
1115 }
1116
1117 /* Convert operand to value, mask form. */
1118
1119 void
1120 ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_int *maskp)
1121 {
1122 wide_int get_nonzero_bits (const_tree);
1123
1124 if (TREE_CODE (operand) == INTEGER_CST)
1125 {
1126 *valuep = wi::to_widest (operand);
1127 *maskp = 0;
1128 }
1129 else
1130 {
1131 *valuep = 0;
1132 *maskp = -1;
1133 }
1134 }
1135
1136 /* Meet operation, similar to ccp_lattice_meet, we xor values
1137 if this->value, value have different values at same bit positions, we want
1138 to drop that bit to varying. Return true if mask is changed.
1139 This function assumes that the lattice value is in CONSTANT state. If
1140 DROP_ALL_ONES, mask out any known bits with value one afterwards. */
1141
1142 bool
1143 ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask,
1144 unsigned precision, bool drop_all_ones)
1145 {
1146 gcc_assert (constant_p ());
1147
1148 widest_int old_mask = m_mask;
1149 m_mask = (m_mask | mask) | (m_value ^ value);
1150 if (drop_all_ones)
1151 m_mask |= m_value;
1152 m_value &= ~m_mask;
1153
1154 if (wi::sext (m_mask, precision) == -1)
1155 return set_to_bottom ();
1156
1157 return m_mask != old_mask;
1158 }
1159
1160 /* Meet the bits lattice with operand
1161 described by <value, mask, sgn, precision. */
1162
1163 bool
1164 ipcp_bits_lattice::meet_with (widest_int value, widest_int mask,
1165 unsigned precision)
1166 {
1167 if (bottom_p ())
1168 return false;
1169
1170 if (top_p ())
1171 {
1172 if (wi::sext (mask, precision) == -1)
1173 return set_to_bottom ();
1174 return set_to_constant (value, mask);
1175 }
1176
1177 return meet_with_1 (value, mask, precision, false);
1178 }
1179
1180 /* Meet bits lattice with the result of bit_value_binop (other, operand)
1181 if code is binary operation or bit_value_unop (other) if code is unary op.
1182 In the case when code is nop_expr, no adjustment is required. If
1183 DROP_ALL_ONES, mask out any known bits with value one afterwards. */
1184
1185 bool
1186 ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
1187 signop sgn, enum tree_code code, tree operand,
1188 bool drop_all_ones)
1189 {
1190 if (other.bottom_p ())
1191 return set_to_bottom ();
1192
1193 if (bottom_p () || other.top_p ())
1194 return false;
1195
1196 widest_int adjusted_value, adjusted_mask;
1197
1198 if (TREE_CODE_CLASS (code) == tcc_binary)
1199 {
1200 tree type = TREE_TYPE (operand);
1201 widest_int o_value, o_mask;
1202 get_value_and_mask (operand, &o_value, &o_mask);
1203
1204 bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask,
1205 sgn, precision, other.get_value (), other.get_mask (),
1206 TYPE_SIGN (type), TYPE_PRECISION (type), o_value, o_mask);
1207
1208 if (wi::sext (adjusted_mask, precision) == -1)
1209 return set_to_bottom ();
1210 }
1211
1212 else if (TREE_CODE_CLASS (code) == tcc_unary)
1213 {
1214 bit_value_unop (code, sgn, precision, &adjusted_value,
1215 &adjusted_mask, sgn, precision, other.get_value (),
1216 other.get_mask ());
1217
1218 if (wi::sext (adjusted_mask, precision) == -1)
1219 return set_to_bottom ();
1220 }
1221
1222 else
1223 return set_to_bottom ();
1224
1225 if (top_p ())
1226 {
1227 if (drop_all_ones)
1228 {
1229 adjusted_mask |= adjusted_value;
1230 adjusted_value &= ~adjusted_mask;
1231 }
1232 if (wi::sext (adjusted_mask, precision) == -1)
1233 return set_to_bottom ();
1234 return set_to_constant (adjusted_value, adjusted_mask);
1235 }
1236 else
1237 return meet_with_1 (adjusted_value, adjusted_mask, precision,
1238 drop_all_ones);
1239 }
1240
1241 /* Dump the contents of the list to FILE. */
1242
1243 void
1244 ipa_argagg_value_list::dump (FILE *f)
1245 {
1246 bool comma = false;
1247 for (const ipa_argagg_value &av : m_elts)
1248 {
1249 fprintf (f, "%s %i[%u]=", comma ? "," : "",
1250 av.index, av.unit_offset);
1251 print_generic_expr (f, av.value);
1252 if (av.by_ref)
1253 fprintf (f, "(by_ref)");
1254 comma = true;
1255 }
1256 fprintf (f, "\n");
1257 }
1258
1259 /* Dump the contents of the list to stderr. */
1260
1261 void
1262 ipa_argagg_value_list::debug ()
1263 {
1264 dump (stderr);
1265 }
1266
1267 /* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
1268 NULL if there is no such constant. */
1269
1270 const ipa_argagg_value *
1271 ipa_argagg_value_list::get_elt (int index, unsigned unit_offset) const
1272 {
1273 ipa_argagg_value key;
1274 key.index = index;
1275 key.unit_offset = unit_offset;
1276 const ipa_argagg_value *res
1277 = std::lower_bound (m_elts.begin (), m_elts.end (), key,
1278 [] (const ipa_argagg_value &elt,
1279 const ipa_argagg_value &val)
1280 {
1281 if (elt.index < val.index)
1282 return true;
1283 if (elt.index > val.index)
1284 return false;
1285 if (elt.unit_offset < val.unit_offset)
1286 return true;
1287 return false;
1288 });
1289
1290 if (res == m_elts.end ()
1291 || res->index != index
1292 || res->unit_offset != unit_offset)
1293 res = nullptr;
1294
1295 /* TODO: perhaps remove the check (that the underlying array is indeed
1296 sorted) if it turns out it can be too slow? */
1297 if (!flag_checking)
1298 return res;
1299
1300 const ipa_argagg_value *slow_res = NULL;
1301 int prev_index = -1;
1302 unsigned prev_unit_offset = 0;
1303 for (const ipa_argagg_value &av : m_elts)
1304 {
1305 gcc_assert (prev_index < 0
1306 || prev_index < av.index
1307 || prev_unit_offset < av.unit_offset);
1308 prev_index = av.index;
1309 prev_unit_offset = av.unit_offset;
1310 if (av.index == index
1311 && av.unit_offset == unit_offset)
1312 slow_res = &av;
1313 }
1314 gcc_assert (res == slow_res);
1315
1316 return res;
1317 }
1318
1319 /* Return the first item describing a constant stored for parameter with INDEX,
1320 regardless of offset or reference, or NULL if there is no such constant. */
1321
1322 const ipa_argagg_value *
1323 ipa_argagg_value_list::get_elt_for_index (int index) const
1324 {
1325 const ipa_argagg_value *res
1326 = std::lower_bound (m_elts.begin (), m_elts.end (), index,
1327 [] (const ipa_argagg_value &elt, unsigned idx)
1328 {
1329 return elt.index < idx;
1330 });
1331 if (res == m_elts.end ()
1332 || res->index != index)
1333 res = nullptr;
1334 return res;
1335 }
1336
1337 /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, not
1338 performing any check of whether value is passed by reference, or NULL_TREE
1339 if there is no such constant. */
1340
1341 tree
1342 ipa_argagg_value_list::get_value (int index, unsigned unit_offset) const
1343 {
1344 const ipa_argagg_value *av = get_elt (index, unit_offset);
1345 return av ? av->value : NULL_TREE;
1346 }
1347
1348 /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is
1349 passed by reference or not according to BY_REF, or NULL_TREE if there is
1350 no such constant. */
1351
1352 tree
1353 ipa_argagg_value_list::get_value (int index, unsigned unit_offset,
1354 bool by_ref) const
1355 {
1356 const ipa_argagg_value *av = get_elt (index, unit_offset);
1357 if (av && av->by_ref == by_ref)
1358 return av->value;
1359 return NULL_TREE;
1360 }
1361
1362 /* Return true if all elements present in OTHER are also present in this
1363 list. */
1364
1365 bool
1366 ipa_argagg_value_list::superset_of_p (const ipa_argagg_value_list &other) const
1367 {
1368 unsigned j = 0;
1369 for (unsigned i = 0; i < other.m_elts.size (); i++)
1370 {
1371 unsigned other_index = other.m_elts[i].index;
1372 unsigned other_offset = other.m_elts[i].unit_offset;
1373
1374 while (j < m_elts.size ()
1375 && (m_elts[j].index < other_index
1376 || (m_elts[j].index == other_index
1377 && m_elts[j].unit_offset < other_offset)))
1378 j++;
1379
1380 if (j >= m_elts.size ()
1381 || m_elts[j].index != other_index
1382 || m_elts[j].unit_offset != other_offset
1383 || m_elts[j].by_ref != other.m_elts[i].by_ref
1384 || !m_elts[j].value
1385 || !values_equal_for_ipcp_p (m_elts[j].value, other.m_elts[i].value))
1386 return false;
1387 }
1388 return true;
1389 }
1390
1391 /* Push all items in this list that describe parameter SRC_INDEX into RES as
1392 ones describing DST_INDEX while subtracting UNIT_DELTA from their unit
1393 offsets but skip those which would end up with a negative offset. */
1394
1395 void
1396 ipa_argagg_value_list::push_adjusted_values (unsigned src_index,
1397 unsigned dest_index,
1398 unsigned unit_delta,
1399 vec<ipa_argagg_value> *res) const
1400 {
1401 const ipa_argagg_value *av = get_elt_for_index (src_index);
1402 if (!av)
1403 return;
1404 unsigned prev_unit_offset = 0;
1405 bool first = true;
1406 for (; av < m_elts.end (); ++av)
1407 {
1408 if (av->index > src_index)
1409 return;
1410 if (av->index == src_index
1411 && (av->unit_offset >= unit_delta)
1412 && av->value)
1413 {
1414 ipa_argagg_value new_av;
1415 gcc_checking_assert (av->value);
1416 new_av.value = av->value;
1417 new_av.unit_offset = av->unit_offset - unit_delta;
1418 new_av.index = dest_index;
1419 new_av.by_ref = av->by_ref;
1420
1421 /* Quick check that the offsets we push are indeed increasing. */
1422 gcc_assert (first
1423 || new_av.unit_offset > prev_unit_offset);
1424 prev_unit_offset = new_av.unit_offset;
1425 first = false;
1426
1427 res->safe_push (new_av);
1428 }
1429 }
1430 }
1431
1432 /* Push to RES information about single lattices describing aggregate values in
1433 PLATS as those describing parameter DEST_INDEX and the original offset minus
1434 UNIT_DELTA. Return true if any item has been pushed to RES. */
1435
1436 static bool
1437 push_agg_values_from_plats (ipcp_param_lattices *plats, int dest_index,
1438 unsigned unit_delta,
1439 vec<ipa_argagg_value> *res)
1440 {
1441 if (plats->aggs_contain_variable)
1442 return false;
1443
1444 bool pushed_sth = false;
1445 bool first = true;
1446 unsigned prev_unit_offset = 0;
1447 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
1448 if (aglat->is_single_const ()
1449 && (aglat->offset / BITS_PER_UNIT - unit_delta) >= 0)
1450 {
1451 ipa_argagg_value iav;
1452 iav.value = aglat->values->value;
1453 iav.unit_offset = aglat->offset / BITS_PER_UNIT - unit_delta;
1454 iav.index = dest_index;
1455 iav.by_ref = plats->aggs_by_ref;
1456
1457 gcc_assert (first
1458 || iav.unit_offset > prev_unit_offset);
1459 prev_unit_offset = iav.unit_offset;
1460 first = false;
1461
1462 pushed_sth = true;
1463 res->safe_push (iav);
1464 }
1465 return pushed_sth;
1466 }
1467
1468 /* Turn all values in LIST that are not present in OTHER into NULL_TREEs.
1469 Return the number of remaining valid entries. */
1470
1471 static unsigned
1472 intersect_argaggs_with (vec<ipa_argagg_value> &elts,
1473 const vec<ipa_argagg_value> &other)
1474 {
1475 unsigned valid_entries = 0;
1476 unsigned j = 0;
1477 for (unsigned i = 0; i < elts.length (); i++)
1478 {
1479 if (!elts[i].value)
1480 continue;
1481
1482 unsigned this_index = elts[i].index;
1483 unsigned this_offset = elts[i].unit_offset;
1484
1485 while (j < other.length ()
1486 && (other[j].index < this_index
1487 || (other[j].index == this_index
1488 && other[j].unit_offset < this_offset)))
1489 j++;
1490
1491 if (j >= other.length ())
1492 {
1493 elts[i].value = NULL_TREE;
1494 continue;
1495 }
1496
1497 if (other[j].index == this_index
1498 && other[j].unit_offset == this_offset
1499 && other[j].by_ref == elts[i].by_ref
1500 && other[j].value
1501 && values_equal_for_ipcp_p (other[j].value, elts[i].value))
1502 valid_entries++;
1503 else
1504 elts[i].value = NULL_TREE;
1505 }
1506 return valid_entries;
1507 }
1508
1509 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
1510 return true is any of them has not been marked as such so far. */
1511
1512 static inline bool
1513 set_all_contains_variable (class ipcp_param_lattices *plats)
1514 {
1515 bool ret;
1516 ret = plats->itself.set_contains_variable ();
1517 ret |= plats->ctxlat.set_contains_variable ();
1518 ret |= set_agg_lats_contain_variable (plats);
1519 ret |= plats->bits_lattice.set_to_bottom ();
1520 ret |= plats->m_value_range.set_to_bottom ();
1521 return ret;
1522 }
1523
1524 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
1525 points to by the number of callers to NODE. */
1526
1527 static bool
1528 count_callers (cgraph_node *node, void *data)
1529 {
1530 int *caller_count = (int *) data;
1531
1532 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
1533 /* Local thunks can be handled transparently, but if the thunk cannot
1534 be optimized out, count it as a real use. */
1535 if (!cs->caller->thunk || !cs->caller->local)
1536 ++*caller_count;
1537 return false;
1538 }
1539
1540 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
1541 the one caller of some other node. Set the caller's corresponding flag. */
1542
1543 static bool
1544 set_single_call_flag (cgraph_node *node, void *)
1545 {
1546 cgraph_edge *cs = node->callers;
1547 /* Local thunks can be handled transparently, skip them. */
1548 while (cs && cs->caller->thunk && cs->caller->local)
1549 cs = cs->next_caller;
1550 if (cs)
1551 if (ipa_node_params* info = ipa_node_params_sum->get (cs->caller))
1552 {
1553 info->node_calling_single_call = true;
1554 return true;
1555 }
1556 return false;
1557 }
1558
1559 /* Initialize ipcp_lattices. */
1560
1561 static void
1562 initialize_node_lattices (struct cgraph_node *node)
1563 {
1564 ipa_node_params *info = ipa_node_params_sum->get (node);
1565 struct cgraph_edge *ie;
1566 bool disable = false, variable = false;
1567 int i;
1568
1569 gcc_checking_assert (node->has_gimple_body_p ());
1570
1571 if (!ipa_get_param_count (info))
1572 disable = true;
1573 else if (node->local)
1574 {
1575 int caller_count = 0;
1576 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
1577 true);
1578 gcc_checking_assert (caller_count > 0);
1579 if (caller_count == 1)
1580 node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
1581 NULL, true);
1582 }
1583 else
1584 {
1585 /* When cloning is allowed, we can assume that externally visible
1586 functions are not called. We will compensate this by cloning
1587 later. */
1588 if (ipcp_versionable_function_p (node)
1589 && ipcp_cloning_candidate_p (node))
1590 variable = true;
1591 else
1592 disable = true;
1593 }
1594
1595 if (dump_file && (dump_flags & TDF_DETAILS)
1596 && !node->alias && !node->thunk)
1597 {
1598 fprintf (dump_file, "Initializing lattices of %s\n",
1599 node->dump_name ());
1600 if (disable || variable)
1601 fprintf (dump_file, " Marking all lattices as %s\n",
1602 disable ? "BOTTOM" : "VARIABLE");
1603 }
1604
1605 auto_vec<bool, 16> surviving_params;
1606 bool pre_modified = false;
1607
1608 clone_info *cinfo = clone_info::get (node);
1609
1610 if (!disable && cinfo && cinfo->param_adjustments)
1611 {
1612 /* At the moment all IPA optimizations should use the number of
1613 parameters of the prevailing decl as the m_always_copy_start.
1614 Handling any other value would complicate the code below, so for the
1615 time bing let's only assert it is so. */
1616 gcc_assert ((cinfo->param_adjustments->m_always_copy_start
1617 == ipa_get_param_count (info))
1618 || cinfo->param_adjustments->m_always_copy_start < 0);
1619
1620 pre_modified = true;
1621 cinfo->param_adjustments->get_surviving_params (&surviving_params);
1622
1623 if (dump_file && (dump_flags & TDF_DETAILS)
1624 && !node->alias && !node->thunk)
1625 {
1626 bool first = true;
1627 for (int j = 0; j < ipa_get_param_count (info); j++)
1628 {
1629 if (j < (int) surviving_params.length ()
1630 && surviving_params[j])
1631 continue;
1632 if (first)
1633 {
1634 fprintf (dump_file,
1635 " The following parameters are dead on arrival:");
1636 first = false;
1637 }
1638 fprintf (dump_file, " %u", j);
1639 }
1640 if (!first)
1641 fprintf (dump_file, "\n");
1642 }
1643 }
1644
1645 for (i = 0; i < ipa_get_param_count (info); i++)
1646 {
1647 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
1648 if (disable
1649 || !ipa_get_type (info, i)
1650 || (pre_modified && (surviving_params.length () <= (unsigned) i
1651 || !surviving_params[i])))
1652 {
1653 plats->itself.set_to_bottom ();
1654 plats->ctxlat.set_to_bottom ();
1655 set_agg_lats_to_bottom (plats);
1656 plats->bits_lattice.set_to_bottom ();
1657 plats->m_value_range.m_vr = value_range ();
1658 plats->m_value_range.set_to_bottom ();
1659 }
1660 else
1661 {
1662 plats->m_value_range.init ();
1663 if (variable)
1664 set_all_contains_variable (plats);
1665 }
1666 }
1667
1668 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1669 if (ie->indirect_info->polymorphic
1670 && ie->indirect_info->param_index >= 0)
1671 {
1672 gcc_checking_assert (ie->indirect_info->param_index >= 0);
1673 ipa_get_parm_lattices (info,
1674 ie->indirect_info->param_index)->virt_call = 1;
1675 }
1676 }
1677
1678 /* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
1679 PARAM_TYPE. */
1680
1681 static bool
1682 ipacp_value_safe_for_type (tree param_type, tree value)
1683 {
1684 tree val_type = TREE_TYPE (value);
1685 if (param_type == val_type
1686 || useless_type_conversion_p (param_type, val_type)
1687 || fold_convertible_p (param_type, value))
1688 return true;
1689 else
1690 return false;
1691 }
1692
1693 /* Return the result of a (possibly arithmetic) operation on the constant
1694 value INPUT. OPERAND is 2nd operand for binary operation. RES_TYPE is
1695 the type of the parameter to which the result is passed. Return
1696 NULL_TREE if that cannot be determined or be considered an
1697 interprocedural invariant. */
1698
1699 static tree
1700 ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
1701 tree res_type)
1702 {
1703 tree res;
1704
1705 if (opcode == NOP_EXPR)
1706 return input;
1707 if (!is_gimple_ip_invariant (input))
1708 return NULL_TREE;
1709
1710 if (opcode == ASSERT_EXPR)
1711 {
1712 if (values_equal_for_ipcp_p (input, operand))
1713 return input;
1714 else
1715 return NULL_TREE;
1716 }
1717
1718 if (!res_type)
1719 {
1720 if (TREE_CODE_CLASS (opcode) == tcc_comparison)
1721 res_type = boolean_type_node;
1722 else if (expr_type_first_operand_type_p (opcode))
1723 res_type = TREE_TYPE (input);
1724 else
1725 return NULL_TREE;
1726 }
1727
1728 if (TREE_CODE_CLASS (opcode) == tcc_unary)
1729 res = fold_unary (opcode, res_type, input);
1730 else
1731 res = fold_binary (opcode, res_type, input, operand);
1732
1733 if (res && !is_gimple_ip_invariant (res))
1734 return NULL_TREE;
1735
1736 return res;
1737 }
1738
1739 /* Return the result of a (possibly arithmetic) pass through jump function
1740 JFUNC on the constant value INPUT. RES_TYPE is the type of the parameter
1741 to which the result is passed. Return NULL_TREE if that cannot be
1742 determined or be considered an interprocedural invariant. */
1743
1744 static tree
1745 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
1746 tree res_type)
1747 {
1748 return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
1749 input,
1750 ipa_get_jf_pass_through_operand (jfunc),
1751 res_type);
1752 }
1753
1754 /* Return the result of an ancestor jump function JFUNC on the constant value
1755 INPUT. Return NULL_TREE if that cannot be determined. */
1756
1757 static tree
1758 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
1759 {
1760 gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
1761 if (TREE_CODE (input) == ADDR_EXPR)
1762 {
1763 gcc_checking_assert (is_gimple_ip_invariant_address (input));
1764 poly_int64 off = ipa_get_jf_ancestor_offset (jfunc);
1765 if (known_eq (off, 0))
1766 return input;
1767 poly_int64 byte_offset = exact_div (off, BITS_PER_UNIT);
1768 return build1 (ADDR_EXPR, TREE_TYPE (input),
1769 fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (input)), input,
1770 build_int_cst (ptr_type_node, byte_offset)));
1771 }
1772 else if (ipa_get_jf_ancestor_keep_null (jfunc)
1773 && zerop (input))
1774 return input;
1775 else
1776 return NULL_TREE;
1777 }
1778
1779 /* Determine whether JFUNC evaluates to a single known constant value and if
1780 so, return it. Otherwise return NULL. INFO describes the caller node or
1781 the one it is inlined to, so that pass-through jump functions can be
1782 evaluated. PARM_TYPE is the type of the parameter to which the result is
1783 passed. */
1784
1785 tree
1786 ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
1787 tree parm_type)
1788 {
1789 if (jfunc->type == IPA_JF_CONST)
1790 return ipa_get_jf_constant (jfunc);
1791 else if (jfunc->type == IPA_JF_PASS_THROUGH
1792 || jfunc->type == IPA_JF_ANCESTOR)
1793 {
1794 tree input;
1795 int idx;
1796
1797 if (jfunc->type == IPA_JF_PASS_THROUGH)
1798 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1799 else
1800 idx = ipa_get_jf_ancestor_formal_id (jfunc);
1801
1802 if (info->ipcp_orig_node)
1803 input = info->known_csts[idx];
1804 else
1805 {
1806 ipcp_lattice<tree> *lat;
1807
1808 if (!info->lattices
1809 || idx >= ipa_get_param_count (info))
1810 return NULL_TREE;
1811 lat = ipa_get_scalar_lat (info, idx);
1812 if (!lat->is_single_const ())
1813 return NULL_TREE;
1814 input = lat->values->value;
1815 }
1816
1817 if (!input)
1818 return NULL_TREE;
1819
1820 if (jfunc->type == IPA_JF_PASS_THROUGH)
1821 return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
1822 else
1823 return ipa_get_jf_ancestor_result (jfunc, input);
1824 }
1825 else
1826 return NULL_TREE;
1827 }
1828
1829 /* Determine whether JFUNC evaluates to single known polymorphic context, given
1830 that INFO describes the caller node or the one it is inlined to, CS is the
1831 call graph edge corresponding to JFUNC and CSIDX index of the described
1832 parameter. */
1833
1834 ipa_polymorphic_call_context
1835 ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
1836 ipa_jump_func *jfunc)
1837 {
1838 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
1839 ipa_polymorphic_call_context ctx;
1840 ipa_polymorphic_call_context *edge_ctx
1841 = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
1842
1843 if (edge_ctx && !edge_ctx->useless_p ())
1844 ctx = *edge_ctx;
1845
1846 if (jfunc->type == IPA_JF_PASS_THROUGH
1847 || jfunc->type == IPA_JF_ANCESTOR)
1848 {
1849 ipa_polymorphic_call_context srcctx;
1850 int srcidx;
1851 bool type_preserved = true;
1852 if (jfunc->type == IPA_JF_PASS_THROUGH)
1853 {
1854 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1855 return ctx;
1856 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1857 srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
1858 }
1859 else
1860 {
1861 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1862 srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
1863 }
1864 if (info->ipcp_orig_node)
1865 {
1866 if (info->known_contexts.exists ())
1867 srcctx = info->known_contexts[srcidx];
1868 }
1869 else
1870 {
1871 if (!info->lattices
1872 || srcidx >= ipa_get_param_count (info))
1873 return ctx;
1874 ipcp_lattice<ipa_polymorphic_call_context> *lat;
1875 lat = ipa_get_poly_ctx_lat (info, srcidx);
1876 if (!lat->is_single_const ())
1877 return ctx;
1878 srcctx = lat->values->value;
1879 }
1880 if (srcctx.useless_p ())
1881 return ctx;
1882 if (jfunc->type == IPA_JF_ANCESTOR)
1883 srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1884 if (!type_preserved)
1885 srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1886 srcctx.combine_with (ctx);
1887 return srcctx;
1888 }
1889
1890 return ctx;
1891 }
1892
1893 /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
1894 DST_TYPE on value range in SRC_VR and store it to DST_VR. Return true if
1895 the result is a range or an anti-range. */
1896
1897 static bool
1898 ipa_vr_operation_and_type_effects (value_range *dst_vr,
1899 value_range *src_vr,
1900 enum tree_code operation,
1901 tree dst_type, tree src_type)
1902 {
1903 range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
1904 if (dst_vr->varying_p () || dst_vr->undefined_p ())
1905 return false;
1906 return true;
1907 }
1908
1909 /* Determine value_range of JFUNC given that INFO describes the caller node or
1910 the one it is inlined to, CS is the call graph edge corresponding to JFUNC
1911 and PARM_TYPE of the parameter. */
1912
1913 value_range
1914 ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
1915 ipa_jump_func *jfunc, tree parm_type)
1916 {
1917 value_range vr;
1918 if (jfunc->m_vr)
1919 ipa_vr_operation_and_type_effects (&vr,
1920 jfunc->m_vr,
1921 NOP_EXPR, parm_type,
1922 jfunc->m_vr->type ());
1923 if (vr.singleton_p ())
1924 return vr;
1925 if (jfunc->type == IPA_JF_PASS_THROUGH)
1926 {
1927 int idx;
1928 ipcp_transformation *sum
1929 = ipcp_get_transformation_summary (cs->caller->inlined_to
1930 ? cs->caller->inlined_to
1931 : cs->caller);
1932 if (!sum || !sum->m_vr)
1933 return vr;
1934
1935 idx = ipa_get_jf_pass_through_formal_id (jfunc);
1936
1937 if (!(*sum->m_vr)[idx].known)
1938 return vr;
1939 tree vr_type = ipa_get_type (info, idx);
1940 value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
1941 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
1942 (*sum->m_vr)[idx].type);
1943
1944 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
1945
1946 if (TREE_CODE_CLASS (operation) == tcc_unary)
1947 {
1948 value_range res;
1949
1950 if (ipa_vr_operation_and_type_effects (&res,
1951 &srcvr,
1952 operation, parm_type,
1953 vr_type))
1954 vr.intersect (res);
1955 }
1956 else
1957 {
1958 value_range op_res, res;
1959 tree op = ipa_get_jf_pass_through_operand (jfunc);
1960 value_range op_vr (op, op);
1961
1962 range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
1963 if (ipa_vr_operation_and_type_effects (&res,
1964 &op_res,
1965 NOP_EXPR, parm_type,
1966 vr_type))
1967 vr.intersect (res);
1968 }
1969 }
1970 return vr;
1971 }
1972
1973 /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
1974 single known constant value and if so, return it. Otherwise return NULL.
1975 NODE and INFO describes the caller node or the one it is inlined to, and
1976 its related info. */
1977
1978 tree
1979 ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
1980 const ipa_agg_jf_item *item)
1981 {
1982 tree value = NULL_TREE;
1983 int src_idx;
1984
1985 if (item->offset < 0
1986 || item->jftype == IPA_JF_UNKNOWN
1987 || item->offset >= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT)
1988 return NULL_TREE;
1989
1990 if (item->jftype == IPA_JF_CONST)
1991 return item->value.constant;
1992
1993 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
1994 || item->jftype == IPA_JF_LOAD_AGG);
1995
1996 src_idx = item->value.pass_through.formal_id;
1997
1998 if (info->ipcp_orig_node)
1999 {
2000 if (item->jftype == IPA_JF_PASS_THROUGH)
2001 value = info->known_csts[src_idx];
2002 else if (ipcp_transformation *ts = ipcp_get_transformation_summary (node))
2003 {
2004 ipa_argagg_value_list avl (ts);
2005 value = avl.get_value (src_idx,
2006 item->value.load_agg.offset / BITS_PER_UNIT,
2007 item->value.load_agg.by_ref);
2008 }
2009 }
2010 else if (info->lattices)
2011 {
2012 class ipcp_param_lattices *src_plats
2013 = ipa_get_parm_lattices (info, src_idx);
2014
2015 if (item->jftype == IPA_JF_PASS_THROUGH)
2016 {
2017 struct ipcp_lattice<tree> *lat = &src_plats->itself;
2018
2019 if (!lat->is_single_const ())
2020 return NULL_TREE;
2021
2022 value = lat->values->value;
2023 }
2024 else if (src_plats->aggs
2025 && !src_plats->aggs_bottom
2026 && !src_plats->aggs_contain_variable
2027 && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
2028 {
2029 struct ipcp_agg_lattice *aglat;
2030
2031 for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
2032 {
2033 if (aglat->offset > item->value.load_agg.offset)
2034 break;
2035
2036 if (aglat->offset == item->value.load_agg.offset)
2037 {
2038 if (aglat->is_single_const ())
2039 value = aglat->values->value;
2040 break;
2041 }
2042 }
2043 }
2044 }
2045
2046 if (!value)
2047 return NULL_TREE;
2048
2049 if (item->jftype == IPA_JF_LOAD_AGG)
2050 {
2051 tree load_type = item->value.load_agg.type;
2052 tree value_type = TREE_TYPE (value);
2053
2054 /* Ensure value type is compatible with load type. */
2055 if (!useless_type_conversion_p (load_type, value_type))
2056 return NULL_TREE;
2057 }
2058
2059 return ipa_get_jf_arith_result (item->value.pass_through.operation,
2060 value,
2061 item->value.pass_through.operand,
2062 item->type);
2063 }
2064
2065 /* Process all items in AGG_JFUNC relative to caller (or the node the original
2066 caller is inlined to) NODE which described by INFO and push the results to
2067 RES as describing values passed in parameter DST_INDEX. */
2068
2069 void
2070 ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node,
2071 ipa_agg_jump_function *agg_jfunc,
2072 unsigned dst_index,
2073 vec<ipa_argagg_value> *res)
2074 {
2075 unsigned prev_unit_offset = 0;
2076 bool first = true;
2077
2078 for (const ipa_agg_jf_item &item : agg_jfunc->items)
2079 {
2080 tree value = ipa_agg_value_from_jfunc (info, node, &item);
2081 if (!value)
2082 continue;
2083
2084 ipa_argagg_value iav;
2085 iav.value = value;
2086 iav.unit_offset = item.offset / BITS_PER_UNIT;
2087 iav.index = dst_index;
2088 iav.by_ref = agg_jfunc->by_ref;
2089
2090 gcc_assert (first
2091 || iav.unit_offset > prev_unit_offset);
2092 prev_unit_offset = iav.unit_offset;
2093 first = false;
2094
2095 res->safe_push (iav);
2096 }
2097 }
2098
2099 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
2100 bottom, not containing a variable component and without any known value at
2101 the same time. */
2102
2103 DEBUG_FUNCTION void
2104 ipcp_verify_propagated_values (void)
2105 {
2106 struct cgraph_node *node;
2107
2108 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
2109 {
2110 ipa_node_params *info = ipa_node_params_sum->get (node);
2111 if (!opt_for_fn (node->decl, flag_ipa_cp)
2112 || !opt_for_fn (node->decl, optimize))
2113 continue;
2114 int i, count = ipa_get_param_count (info);
2115
2116 for (i = 0; i < count; i++)
2117 {
2118 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
2119
2120 if (!lat->bottom
2121 && !lat->contains_variable
2122 && lat->values_count == 0)
2123 {
2124 if (dump_file)
2125 {
2126 symtab->dump (dump_file);
2127 fprintf (dump_file, "\nIPA lattices after constant "
2128 "propagation, before gcc_unreachable:\n");
2129 print_all_lattices (dump_file, true, false);
2130 }
2131
2132 gcc_unreachable ();
2133 }
2134 }
2135 }
2136 }
2137
2138 /* Return true iff X and Y should be considered equal contexts by IPA-CP. */
2139
2140 static bool
2141 values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
2142 ipa_polymorphic_call_context y)
2143 {
2144 return x.equal_to (y);
2145 }
2146
2147
2148 /* Add a new value source to the value represented by THIS, marking that a
2149 value comes from edge CS and (if the underlying jump function is a
2150 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
2151 parameter described by SRC_INDEX. OFFSET is negative if the source was the
2152 scalar value of the parameter itself or the offset within an aggregate. */
2153
2154 template <typename valtype>
2155 void
2156 ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
2157 int src_idx, HOST_WIDE_INT offset)
2158 {
2159 ipcp_value_source<valtype> *src;
2160
2161 src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
2162 src->offset = offset;
2163 src->cs = cs;
2164 src->val = src_val;
2165 src->index = src_idx;
2166
2167 src->next = sources;
2168 sources = src;
2169 }
2170
2171 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
2172 SOURCE and clear all other fields. */
2173
2174 static ipcp_value<tree> *
2175 allocate_and_init_ipcp_value (tree cst, unsigned same_lat_gen_level)
2176 {
2177 ipcp_value<tree> *val;
2178
2179 val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>();
2180 val->value = cst;
2181 val->self_recursion_generated_level = same_lat_gen_level;
2182 return val;
2183 }
2184
2185 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
2186 value to SOURCE and clear all other fields. */
2187
2188 static ipcp_value<ipa_polymorphic_call_context> *
2189 allocate_and_init_ipcp_value (ipa_polymorphic_call_context ctx,
2190 unsigned same_lat_gen_level)
2191 {
2192 ipcp_value<ipa_polymorphic_call_context> *val;
2193
2194 val = new (ipcp_poly_ctx_values_pool.allocate ())
2195 ipcp_value<ipa_polymorphic_call_context>();
2196 val->value = ctx;
2197 val->self_recursion_generated_level = same_lat_gen_level;
2198 return val;
2199 }
2200
2201 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
2202 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
2203 meaning. OFFSET -1 means the source is scalar and not a part of an
2204 aggregate. If non-NULL, VAL_P records address of existing or newly added
2205 ipcp_value.
2206
2207 If the value is generated for a self-recursive call as a result of an
2208 arithmetic pass-through jump-function acting on a value in the same lattice,
2209 SAME_LAT_GEN_LEVEL must be the length of such chain, otherwise it must be
2210 zero. If it is non-zero, PARAM_IPA_CP_VALUE_LIST_SIZE limit is ignored. */
2211
2212 template <typename valtype>
2213 bool
2214 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
2215 ipcp_value<valtype> *src_val,
2216 int src_idx, HOST_WIDE_INT offset,
2217 ipcp_value<valtype> **val_p,
2218 unsigned same_lat_gen_level)
2219 {
2220 ipcp_value<valtype> *val, *last_val = NULL;
2221
2222 if (val_p)
2223 *val_p = NULL;
2224
2225 if (bottom)
2226 return false;
2227
2228 for (val = values; val; last_val = val, val = val->next)
2229 if (values_equal_for_ipcp_p (val->value, newval))
2230 {
2231 if (val_p)
2232 *val_p = val;
2233
2234 if (val->self_recursion_generated_level < same_lat_gen_level)
2235 val->self_recursion_generated_level = same_lat_gen_level;
2236
2237 if (ipa_edge_within_scc (cs))
2238 {
2239 ipcp_value_source<valtype> *s;
2240 for (s = val->sources; s; s = s->next)
2241 if (s->cs == cs && s->val == src_val)
2242 break;
2243 if (s)
2244 return false;
2245 }
2246
2247 val->add_source (cs, src_val, src_idx, offset);
2248 return false;
2249 }
2250
2251 if (!same_lat_gen_level && values_count == opt_for_fn (cs->caller->decl,
2252 param_ipa_cp_value_list_size))
2253 {
2254 /* We can only free sources, not the values themselves, because sources
2255 of other values in this SCC might point to them. */
2256 for (val = values; val; val = val->next)
2257 {
2258 while (val->sources)
2259 {
2260 ipcp_value_source<valtype> *src = val->sources;
2261 val->sources = src->next;
2262 ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
2263 }
2264 }
2265 values = NULL;
2266 return set_to_bottom ();
2267 }
2268
2269 values_count++;
2270 val = allocate_and_init_ipcp_value (newval, same_lat_gen_level);
2271 val->add_source (cs, src_val, src_idx, offset);
2272 val->next = NULL;
2273
2274 /* Add the new value to end of value list, which can reduce iterations
2275 of propagation stage for recursive function. */
2276 if (last_val)
2277 last_val->next = val;
2278 else
2279 values = val;
2280
2281 if (val_p)
2282 *val_p = val;
2283
2284 return true;
2285 }
2286
2287 /* A helper function that returns result of operation specified by OPCODE on
2288 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
2289 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
2290 acting as its second operand. If non-NULL, RES_TYPE is expected type of
2291 the result. */
2292
2293 static tree
2294 get_val_across_arith_op (enum tree_code opcode,
2295 tree opnd1_type,
2296 tree opnd2,
2297 ipcp_value<tree> *src_val,
2298 tree res_type)
2299 {
2300 tree opnd1 = src_val->value;
2301
2302 /* Skip source values that is incompatible with specified type. */
2303 if (opnd1_type
2304 && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
2305 return NULL_TREE;
2306
2307 return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
2308 }
2309
2310 /* Propagate values through an arithmetic transformation described by a jump
2311 function associated with edge CS, taking values from SRC_LAT and putting
2312 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
2313 OPND2 is a constant value if transformation is a binary operation.
2314 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
2315 a part of the aggregate. SRC_IDX is the index of the source parameter.
2316 RES_TYPE is the value type of result being propagated into. Return true if
2317 DEST_LAT changed. */
2318
2319 static bool
2320 propagate_vals_across_arith_jfunc (cgraph_edge *cs,
2321 enum tree_code opcode,
2322 tree opnd1_type,
2323 tree opnd2,
2324 ipcp_lattice<tree> *src_lat,
2325 ipcp_lattice<tree> *dest_lat,
2326 HOST_WIDE_INT src_offset,
2327 int src_idx,
2328 tree res_type)
2329 {
2330 ipcp_value<tree> *src_val;
2331 bool ret = false;
2332
2333 /* Due to circular dependencies, propagating within an SCC through arithmetic
2334 transformation would create infinite number of values. But for
2335 self-feeding recursive function, we could allow propagation in a limited
2336 count, and this can enable a simple kind of recursive function versioning.
2337 For other scenario, we would just make lattices bottom. */
2338 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
2339 {
2340 int i;
2341
2342 int max_recursive_depth = opt_for_fn(cs->caller->decl,
2343 param_ipa_cp_max_recursive_depth);
2344 if (src_lat != dest_lat || max_recursive_depth < 1)
2345 return dest_lat->set_contains_variable ();
2346
2347 /* No benefit if recursive execution is in low probability. */
2348 if (cs->sreal_frequency () * 100
2349 <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
2350 param_ipa_cp_min_recursive_probability))
2351 return dest_lat->set_contains_variable ();
2352
2353 auto_vec<ipcp_value<tree> *, 8> val_seeds;
2354
2355 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2356 {
2357 /* Now we do not use self-recursively generated value as propagation
2358 source, this is absolutely conservative, but could avoid explosion
2359 of lattice's value space, especially when one recursive function
2360 calls another recursive. */
2361 if (src_val->self_recursion_generated_p ())
2362 {
2363 ipcp_value_source<tree> *s;
2364
2365 /* If the lattice has already been propagated for the call site,
2366 no need to do that again. */
2367 for (s = src_val->sources; s; s = s->next)
2368 if (s->cs == cs)
2369 return dest_lat->set_contains_variable ();
2370 }
2371 else
2372 val_seeds.safe_push (src_val);
2373 }
2374
2375 gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
2376
2377 /* Recursively generate lattice values with a limited count. */
2378 FOR_EACH_VEC_ELT (val_seeds, i, src_val)
2379 {
2380 for (int j = 1; j < max_recursive_depth; j++)
2381 {
2382 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2383 src_val, res_type);
2384 if (!cstval
2385 || !ipacp_value_safe_for_type (res_type, cstval))
2386 break;
2387
2388 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2389 src_offset, &src_val, j);
2390 gcc_checking_assert (src_val);
2391 }
2392 }
2393 ret |= dest_lat->set_contains_variable ();
2394 }
2395 else
2396 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2397 {
2398 /* Now we do not use self-recursively generated value as propagation
2399 source, otherwise it is easy to make value space of normal lattice
2400 overflow. */
2401 if (src_val->self_recursion_generated_p ())
2402 {
2403 ret |= dest_lat->set_contains_variable ();
2404 continue;
2405 }
2406
2407 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2408 src_val, res_type);
2409 if (cstval
2410 && ipacp_value_safe_for_type (res_type, cstval))
2411 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2412 src_offset);
2413 else
2414 ret |= dest_lat->set_contains_variable ();
2415 }
2416
2417 return ret;
2418 }
2419
2420 /* Propagate values through a pass-through jump function JFUNC associated with
2421 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2422 is the index of the source parameter. PARM_TYPE is the type of the
2423 parameter to which the result is passed. */
2424
2425 static bool
2426 propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
2427 ipcp_lattice<tree> *src_lat,
2428 ipcp_lattice<tree> *dest_lat, int src_idx,
2429 tree parm_type)
2430 {
2431 return propagate_vals_across_arith_jfunc (cs,
2432 ipa_get_jf_pass_through_operation (jfunc),
2433 NULL_TREE,
2434 ipa_get_jf_pass_through_operand (jfunc),
2435 src_lat, dest_lat, -1, src_idx, parm_type);
2436 }
2437
2438 /* Propagate values through an ancestor jump function JFUNC associated with
2439 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2440 is the index of the source parameter. */
2441
2442 static bool
2443 propagate_vals_across_ancestor (struct cgraph_edge *cs,
2444 struct ipa_jump_func *jfunc,
2445 ipcp_lattice<tree> *src_lat,
2446 ipcp_lattice<tree> *dest_lat, int src_idx,
2447 tree param_type)
2448 {
2449 ipcp_value<tree> *src_val;
2450 bool ret = false;
2451
2452 if (ipa_edge_within_scc (cs))
2453 return dest_lat->set_contains_variable ();
2454
2455 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2456 {
2457 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
2458
2459 if (t && ipacp_value_safe_for_type (param_type, t))
2460 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
2461 else
2462 ret |= dest_lat->set_contains_variable ();
2463 }
2464
2465 return ret;
2466 }
2467
2468 /* Propagate scalar values across jump function JFUNC that is associated with
2469 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2470 parameter to which the result is passed. */
2471
2472 static bool
2473 propagate_scalar_across_jump_function (struct cgraph_edge *cs,
2474 struct ipa_jump_func *jfunc,
2475 ipcp_lattice<tree> *dest_lat,
2476 tree param_type)
2477 {
2478 if (dest_lat->bottom)
2479 return false;
2480
2481 if (jfunc->type == IPA_JF_CONST)
2482 {
2483 tree val = ipa_get_jf_constant (jfunc);
2484 if (ipacp_value_safe_for_type (param_type, val))
2485 return dest_lat->add_value (val, cs, NULL, 0);
2486 else
2487 return dest_lat->set_contains_variable ();
2488 }
2489 else if (jfunc->type == IPA_JF_PASS_THROUGH
2490 || jfunc->type == IPA_JF_ANCESTOR)
2491 {
2492 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
2493 ipcp_lattice<tree> *src_lat;
2494 int src_idx;
2495 bool ret;
2496
2497 if (jfunc->type == IPA_JF_PASS_THROUGH)
2498 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2499 else
2500 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2501
2502 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
2503 if (src_lat->bottom)
2504 return dest_lat->set_contains_variable ();
2505
2506 /* If we would need to clone the caller and cannot, do not propagate. */
2507 if (!ipcp_versionable_function_p (cs->caller)
2508 && (src_lat->contains_variable
2509 || (src_lat->values_count > 1)))
2510 return dest_lat->set_contains_variable ();
2511
2512 if (jfunc->type == IPA_JF_PASS_THROUGH)
2513 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
2514 dest_lat, src_idx,
2515 param_type);
2516 else
2517 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
2518 src_idx, param_type);
2519
2520 if (src_lat->contains_variable)
2521 ret |= dest_lat->set_contains_variable ();
2522
2523 return ret;
2524 }
2525
2526 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2527 use it for indirect inlining), we should propagate them too. */
2528 return dest_lat->set_contains_variable ();
2529 }
2530
2531 /* Propagate scalar values across jump function JFUNC that is associated with
2532 edge CS and describes argument IDX and put the values into DEST_LAT. */
2533
2534 static bool
2535 propagate_context_across_jump_function (cgraph_edge *cs,
2536 ipa_jump_func *jfunc, int idx,
2537 ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
2538 {
2539 if (dest_lat->bottom)
2540 return false;
2541 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
2542 bool ret = false;
2543 bool added_sth = false;
2544 bool type_preserved = true;
2545
2546 ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
2547 = ipa_get_ith_polymorhic_call_context (args, idx);
2548
2549 if (edge_ctx_ptr)
2550 edge_ctx = *edge_ctx_ptr;
2551
2552 if (jfunc->type == IPA_JF_PASS_THROUGH
2553 || jfunc->type == IPA_JF_ANCESTOR)
2554 {
2555 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
2556 int src_idx;
2557 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
2558
2559 /* TODO: Once we figure out how to propagate speculations, it will
2560 probably be a good idea to switch to speculation if type_preserved is
2561 not set instead of punting. */
2562 if (jfunc->type == IPA_JF_PASS_THROUGH)
2563 {
2564 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
2565 goto prop_fail;
2566 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
2567 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2568 }
2569 else
2570 {
2571 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
2572 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2573 }
2574
2575 src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
2576 /* If we would need to clone the caller and cannot, do not propagate. */
2577 if (!ipcp_versionable_function_p (cs->caller)
2578 && (src_lat->contains_variable
2579 || (src_lat->values_count > 1)))
2580 goto prop_fail;
2581
2582 ipcp_value<ipa_polymorphic_call_context> *src_val;
2583 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2584 {
2585 ipa_polymorphic_call_context cur = src_val->value;
2586
2587 if (!type_preserved)
2588 cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
2589 if (jfunc->type == IPA_JF_ANCESTOR)
2590 cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
2591 /* TODO: In cases we know how the context is going to be used,
2592 we can improve the result by passing proper OTR_TYPE. */
2593 cur.combine_with (edge_ctx);
2594 if (!cur.useless_p ())
2595 {
2596 if (src_lat->contains_variable
2597 && !edge_ctx.equal_to (cur))
2598 ret |= dest_lat->set_contains_variable ();
2599 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
2600 added_sth = true;
2601 }
2602 }
2603 }
2604
2605 prop_fail:
2606 if (!added_sth)
2607 {
2608 if (!edge_ctx.useless_p ())
2609 ret |= dest_lat->add_value (edge_ctx, cs);
2610 else
2611 ret |= dest_lat->set_contains_variable ();
2612 }
2613
2614 return ret;
2615 }
2616
2617 /* Propagate bits across jfunc that is associated with
2618 edge cs and update dest_lattice accordingly. */
2619
2620 bool
2621 propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
2622 ipa_jump_func *jfunc,
2623 ipcp_bits_lattice *dest_lattice)
2624 {
2625 if (dest_lattice->bottom_p ())
2626 return false;
2627
2628 enum availability availability;
2629 cgraph_node *callee = cs->callee->function_symbol (&availability);
2630 ipa_node_params *callee_info = ipa_node_params_sum->get (callee);
2631 tree parm_type = ipa_get_type (callee_info, idx);
2632
2633 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2634 transform for these cases. Similarly, we can have bad type mismatches
2635 with LTO, avoid doing anything with those too. */
2636 if (!parm_type
2637 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
2638 {
2639 if (dump_file && (dump_flags & TDF_DETAILS))
2640 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
2641 "param %i of %s is NULL or unsuitable for bits propagation\n",
2642 idx, cs->callee->dump_name ());
2643
2644 return dest_lattice->set_to_bottom ();
2645 }
2646
2647 unsigned precision = TYPE_PRECISION (parm_type);
2648 signop sgn = TYPE_SIGN (parm_type);
2649
2650 if (jfunc->type == IPA_JF_PASS_THROUGH
2651 || jfunc->type == IPA_JF_ANCESTOR)
2652 {
2653 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
2654 tree operand = NULL_TREE;
2655 enum tree_code code;
2656 unsigned src_idx;
2657 bool keep_null = false;
2658
2659 if (jfunc->type == IPA_JF_PASS_THROUGH)
2660 {
2661 code = ipa_get_jf_pass_through_operation (jfunc);
2662 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2663 if (code != NOP_EXPR)
2664 operand = ipa_get_jf_pass_through_operand (jfunc);
2665 }
2666 else
2667 {
2668 code = POINTER_PLUS_EXPR;
2669 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2670 unsigned HOST_WIDE_INT offset
2671 = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
2672 keep_null = (ipa_get_jf_ancestor_keep_null (jfunc) || !offset);
2673 operand = build_int_cstu (size_type_node, offset);
2674 }
2675
2676 class ipcp_param_lattices *src_lats
2677 = ipa_get_parm_lattices (caller_info, src_idx);
2678
2679 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2680 for eg consider:
2681 int f(int x)
2682 {
2683 g (x & 0xff);
2684 }
2685 Assume lattice for x is bottom, however we can still propagate
2686 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2687 and we store it in jump function during analysis stage. */
2688
2689 if (!src_lats->bits_lattice.bottom_p ())
2690 {
2691 bool drop_all_ones
2692 = keep_null && !src_lats->bits_lattice.known_nonzero_p ();
2693
2694 return dest_lattice->meet_with (src_lats->bits_lattice, precision,
2695 sgn, code, operand, drop_all_ones);
2696 }
2697 }
2698
2699 if (jfunc->bits)
2700 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2701 precision);
2702 else
2703 return dest_lattice->set_to_bottom ();
2704 }
2705
2706 /* Propagate value range across jump function JFUNC that is associated with
2707 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2708 accordingly. */
2709
2710 static bool
2711 propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
2712 class ipcp_param_lattices *dest_plats,
2713 tree param_type)
2714 {
2715 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
2716
2717 if (dest_lat->bottom_p ())
2718 return false;
2719
2720 if (!param_type
2721 || (!INTEGRAL_TYPE_P (param_type)
2722 && !POINTER_TYPE_P (param_type)))
2723 return dest_lat->set_to_bottom ();
2724
2725 if (jfunc->type == IPA_JF_PASS_THROUGH)
2726 {
2727 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
2728 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
2729 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2730 class ipcp_param_lattices *src_lats
2731 = ipa_get_parm_lattices (caller_info, src_idx);
2732 tree operand_type = ipa_get_type (caller_info, src_idx);
2733
2734 if (src_lats->m_value_range.bottom_p ())
2735 return dest_lat->set_to_bottom ();
2736
2737 value_range vr;
2738 if (TREE_CODE_CLASS (operation) == tcc_unary)
2739 ipa_vr_operation_and_type_effects (&vr,
2740 &src_lats->m_value_range.m_vr,
2741 operation, param_type,
2742 operand_type);
2743 /* A crude way to prevent unbounded number of value range updates
2744 in SCC components. We should allow limited number of updates within
2745 SCC, too. */
2746 else if (!ipa_edge_within_scc (cs))
2747 {
2748 tree op = ipa_get_jf_pass_through_operand (jfunc);
2749 value_range op_vr (op, op);
2750 value_range op_res,res;
2751
2752 range_fold_binary_expr (&op_res, operation, operand_type,
2753 &src_lats->m_value_range.m_vr, &op_vr);
2754 ipa_vr_operation_and_type_effects (&vr,
2755 &op_res,
2756 NOP_EXPR, param_type,
2757 operand_type);
2758 }
2759 if (!vr.undefined_p () && !vr.varying_p ())
2760 {
2761 if (jfunc->m_vr)
2762 {
2763 value_range jvr;
2764 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2765 NOP_EXPR,
2766 param_type,
2767 jfunc->m_vr->type ()))
2768 vr.intersect (jvr);
2769 }
2770 return dest_lat->meet_with (&vr);
2771 }
2772 }
2773 else if (jfunc->type == IPA_JF_CONST)
2774 {
2775 tree val = ipa_get_jf_constant (jfunc);
2776 if (TREE_CODE (val) == INTEGER_CST)
2777 {
2778 val = fold_convert (param_type, val);
2779 if (TREE_OVERFLOW_P (val))
2780 val = drop_tree_overflow (val);
2781
2782 value_range tmpvr (val, val);
2783 return dest_lat->meet_with (&tmpvr);
2784 }
2785 }
2786
2787 value_range vr;
2788 if (jfunc->m_vr
2789 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
2790 param_type,
2791 jfunc->m_vr->type ()))
2792 return dest_lat->meet_with (&vr);
2793 else
2794 return dest_lat->set_to_bottom ();
2795 }
2796
2797 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2798 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2799 other cases, return false). If there are no aggregate items, set
2800 aggs_by_ref to NEW_AGGS_BY_REF. */
2801
2802 static bool
2803 set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
2804 bool new_aggs_by_ref)
2805 {
2806 if (dest_plats->aggs)
2807 {
2808 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
2809 {
2810 set_agg_lats_to_bottom (dest_plats);
2811 return true;
2812 }
2813 }
2814 else
2815 dest_plats->aggs_by_ref = new_aggs_by_ref;
2816 return false;
2817 }
2818
2819 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2820 already existing lattice for the given OFFSET and SIZE, marking all skipped
2821 lattices as containing variable and checking for overlaps. If there is no
2822 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2823 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2824 unless there are too many already. If there are two many, return false. If
2825 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2826 skipped lattices were newly marked as containing variable, set *CHANGE to
2827 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2828
2829 static bool
2830 merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
2831 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
2832 struct ipcp_agg_lattice ***aglat,
2833 bool pre_existing, bool *change, int max_agg_items)
2834 {
2835 gcc_checking_assert (offset >= 0);
2836
2837 while (**aglat && (**aglat)->offset < offset)
2838 {
2839 if ((**aglat)->offset + (**aglat)->size > offset)
2840 {
2841 set_agg_lats_to_bottom (dest_plats);
2842 return false;
2843 }
2844 *change |= (**aglat)->set_contains_variable ();
2845 *aglat = &(**aglat)->next;
2846 }
2847
2848 if (**aglat && (**aglat)->offset == offset)
2849 {
2850 if ((**aglat)->size != val_size)
2851 {
2852 set_agg_lats_to_bottom (dest_plats);
2853 return false;
2854 }
2855 gcc_assert (!(**aglat)->next
2856 || (**aglat)->next->offset >= offset + val_size);
2857 return true;
2858 }
2859 else
2860 {
2861 struct ipcp_agg_lattice *new_al;
2862
2863 if (**aglat && (**aglat)->offset < offset + val_size)
2864 {
2865 set_agg_lats_to_bottom (dest_plats);
2866 return false;
2867 }
2868 if (dest_plats->aggs_count == max_agg_items)
2869 return false;
2870 dest_plats->aggs_count++;
2871 new_al = ipcp_agg_lattice_pool.allocate ();
2872 memset (new_al, 0, sizeof (*new_al));
2873
2874 new_al->offset = offset;
2875 new_al->size = val_size;
2876 new_al->contains_variable = pre_existing;
2877
2878 new_al->next = **aglat;
2879 **aglat = new_al;
2880 return true;
2881 }
2882 }
2883
2884 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2885 containing an unknown value. */
2886
2887 static bool
2888 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
2889 {
2890 bool ret = false;
2891 while (aglat)
2892 {
2893 ret |= aglat->set_contains_variable ();
2894 aglat = aglat->next;
2895 }
2896 return ret;
2897 }
2898
2899 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2900 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2901 parameter used for lattice value sources. Return true if DEST_PLATS changed
2902 in any way. */
2903
2904 static bool
2905 merge_aggregate_lattices (struct cgraph_edge *cs,
2906 class ipcp_param_lattices *dest_plats,
2907 class ipcp_param_lattices *src_plats,
2908 int src_idx, HOST_WIDE_INT offset_delta)
2909 {
2910 bool pre_existing = dest_plats->aggs != NULL;
2911 struct ipcp_agg_lattice **dst_aglat;
2912 bool ret = false;
2913
2914 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
2915 return true;
2916 if (src_plats->aggs_bottom)
2917 return set_agg_lats_contain_variable (dest_plats);
2918 if (src_plats->aggs_contain_variable)
2919 ret |= set_agg_lats_contain_variable (dest_plats);
2920 dst_aglat = &dest_plats->aggs;
2921
2922 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2923 param_ipa_max_agg_items);
2924 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2925 src_aglat;
2926 src_aglat = src_aglat->next)
2927 {
2928 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2929
2930 if (new_offset < 0)
2931 continue;
2932 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
2933 &dst_aglat, pre_existing, &ret, max_agg_items))
2934 {
2935 struct ipcp_agg_lattice *new_al = *dst_aglat;
2936
2937 dst_aglat = &(*dst_aglat)->next;
2938 if (src_aglat->bottom)
2939 {
2940 ret |= new_al->set_contains_variable ();
2941 continue;
2942 }
2943 if (src_aglat->contains_variable)
2944 ret |= new_al->set_contains_variable ();
2945 for (ipcp_value<tree> *val = src_aglat->values;
2946 val;
2947 val = val->next)
2948 ret |= new_al->add_value (val->value, cs, val, src_idx,
2949 src_aglat->offset);
2950 }
2951 else if (dest_plats->aggs_bottom)
2952 return true;
2953 }
2954 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
2955 return ret;
2956 }
2957
2958 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
2959 pass-through JFUNC and if so, whether it has conform and conforms to the
2960 rules about propagating values passed by reference. */
2961
2962 static bool
2963 agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
2964 struct ipa_jump_func *jfunc)
2965 {
2966 return src_plats->aggs
2967 && (!src_plats->aggs_by_ref
2968 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2969 }
2970
2971 /* Propagate values through ITEM, jump function for a part of an aggregate,
2972 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2973 associated with the jump function. Return true if AGLAT changed in any
2974 way. */
2975
2976 static bool
2977 propagate_aggregate_lattice (struct cgraph_edge *cs,
2978 struct ipa_agg_jf_item *item,
2979 struct ipcp_agg_lattice *aglat)
2980 {
2981 class ipa_node_params *caller_info;
2982 class ipcp_param_lattices *src_plats;
2983 struct ipcp_lattice<tree> *src_lat;
2984 HOST_WIDE_INT src_offset;
2985 int src_idx;
2986 tree load_type;
2987 bool ret;
2988
2989 if (item->jftype == IPA_JF_CONST)
2990 {
2991 tree value = item->value.constant;
2992
2993 gcc_checking_assert (is_gimple_ip_invariant (value));
2994 return aglat->add_value (value, cs, NULL, 0);
2995 }
2996
2997 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2998 || item->jftype == IPA_JF_LOAD_AGG);
2999
3000 caller_info = ipa_node_params_sum->get (cs->caller);
3001 src_idx = item->value.pass_through.formal_id;
3002 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3003
3004 if (item->jftype == IPA_JF_PASS_THROUGH)
3005 {
3006 load_type = NULL_TREE;
3007 src_lat = &src_plats->itself;
3008 src_offset = -1;
3009 }
3010 else
3011 {
3012 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
3013 struct ipcp_agg_lattice *src_aglat;
3014
3015 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
3016 if (src_aglat->offset >= load_offset)
3017 break;
3018
3019 load_type = item->value.load_agg.type;
3020 if (!src_aglat
3021 || src_aglat->offset > load_offset
3022 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
3023 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
3024 return aglat->set_contains_variable ();
3025
3026 src_lat = src_aglat;
3027 src_offset = load_offset;
3028 }
3029
3030 if (src_lat->bottom
3031 || (!ipcp_versionable_function_p (cs->caller)
3032 && !src_lat->is_single_const ()))
3033 return aglat->set_contains_variable ();
3034
3035 ret = propagate_vals_across_arith_jfunc (cs,
3036 item->value.pass_through.operation,
3037 load_type,
3038 item->value.pass_through.operand,
3039 src_lat, aglat,
3040 src_offset,
3041 src_idx,
3042 item->type);
3043
3044 if (src_lat->contains_variable)
3045 ret |= aglat->set_contains_variable ();
3046
3047 return ret;
3048 }
3049
3050 /* Propagate scalar values across jump function JFUNC that is associated with
3051 edge CS and put the values into DEST_LAT. */
3052
3053 static bool
3054 propagate_aggs_across_jump_function (struct cgraph_edge *cs,
3055 struct ipa_jump_func *jfunc,
3056 class ipcp_param_lattices *dest_plats)
3057 {
3058 bool ret = false;
3059
3060 if (dest_plats->aggs_bottom)
3061 return false;
3062
3063 if (jfunc->type == IPA_JF_PASS_THROUGH
3064 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3065 {
3066 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
3067 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
3068 class ipcp_param_lattices *src_plats;
3069
3070 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3071 if (agg_pass_through_permissible_p (src_plats, jfunc))
3072 {
3073 /* Currently we do not produce clobber aggregate jump
3074 functions, replace with merging when we do. */
3075 gcc_assert (!jfunc->agg.items);
3076 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
3077 src_idx, 0);
3078 return ret;
3079 }
3080 }
3081 else if (jfunc->type == IPA_JF_ANCESTOR
3082 && ipa_get_jf_ancestor_agg_preserved (jfunc))
3083 {
3084 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
3085 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
3086 class ipcp_param_lattices *src_plats;
3087
3088 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3089 if (src_plats->aggs && src_plats->aggs_by_ref)
3090 {
3091 /* Currently we do not produce clobber aggregate jump
3092 functions, replace with merging when we do. */
3093 gcc_assert (!jfunc->agg.items);
3094 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
3095 ipa_get_jf_ancestor_offset (jfunc));
3096 }
3097 else if (!src_plats->aggs_by_ref)
3098 ret |= set_agg_lats_to_bottom (dest_plats);
3099 else
3100 ret |= set_agg_lats_contain_variable (dest_plats);
3101 return ret;
3102 }
3103
3104 if (jfunc->agg.items)
3105 {
3106 bool pre_existing = dest_plats->aggs != NULL;
3107 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
3108 struct ipa_agg_jf_item *item;
3109 int i;
3110
3111 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
3112 return true;
3113
3114 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
3115 param_ipa_max_agg_items);
3116 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
3117 {
3118 HOST_WIDE_INT val_size;
3119
3120 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
3121 continue;
3122 val_size = tree_to_shwi (TYPE_SIZE (item->type));
3123
3124 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
3125 &aglat, pre_existing, &ret, max_agg_items))
3126 {
3127 ret |= propagate_aggregate_lattice (cs, item, *aglat);
3128 aglat = &(*aglat)->next;
3129 }
3130 else if (dest_plats->aggs_bottom)
3131 return true;
3132 }
3133
3134 ret |= set_chain_of_aglats_contains_variable (*aglat);
3135 }
3136 else
3137 ret |= set_agg_lats_contain_variable (dest_plats);
3138
3139 return ret;
3140 }
3141
3142 /* Return true if on the way cfrom CS->caller to the final (non-alias and
3143 non-thunk) destination, the call passes through a thunk. */
3144
3145 static bool
3146 call_passes_through_thunk (cgraph_edge *cs)
3147 {
3148 cgraph_node *alias_or_thunk = cs->callee;
3149 while (alias_or_thunk->alias)
3150 alias_or_thunk = alias_or_thunk->get_alias_target ();
3151 return alias_or_thunk->thunk;
3152 }
3153
3154 /* Propagate constants from the caller to the callee of CS. INFO describes the
3155 caller. */
3156
3157 static bool
3158 propagate_constants_across_call (struct cgraph_edge *cs)
3159 {
3160 class ipa_node_params *callee_info;
3161 enum availability availability;
3162 cgraph_node *callee;
3163 class ipa_edge_args *args;
3164 bool ret = false;
3165 int i, args_count, parms_count;
3166
3167 callee = cs->callee->function_symbol (&availability);
3168 if (!callee->definition)
3169 return false;
3170 gcc_checking_assert (callee->has_gimple_body_p ());
3171 callee_info = ipa_node_params_sum->get (callee);
3172 if (!callee_info)
3173 return false;
3174
3175 args = ipa_edge_args_sum->get (cs);
3176 parms_count = ipa_get_param_count (callee_info);
3177 if (parms_count == 0)
3178 return false;
3179 if (!args
3180 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
3181 || !opt_for_fn (cs->caller->decl, optimize))
3182 {
3183 for (i = 0; i < parms_count; i++)
3184 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
3185 i));
3186 return ret;
3187 }
3188 args_count = ipa_get_cs_argument_count (args);
3189
3190 /* If this call goes through a thunk we must not propagate to the first (0th)
3191 parameter. However, we might need to uncover a thunk from below a series
3192 of aliases first. */
3193 if (call_passes_through_thunk (cs))
3194 {
3195 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
3196 0));
3197 i = 1;
3198 }
3199 else
3200 i = 0;
3201
3202 for (; (i < args_count) && (i < parms_count); i++)
3203 {
3204 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
3205 class ipcp_param_lattices *dest_plats;
3206 tree param_type = ipa_get_type (callee_info, i);
3207
3208 dest_plats = ipa_get_parm_lattices (callee_info, i);
3209 if (availability == AVAIL_INTERPOSABLE)
3210 ret |= set_all_contains_variable (dest_plats);
3211 else
3212 {
3213 ret |= propagate_scalar_across_jump_function (cs, jump_func,
3214 &dest_plats->itself,
3215 param_type);
3216 ret |= propagate_context_across_jump_function (cs, jump_func, i,
3217 &dest_plats->ctxlat);
3218 ret
3219 |= propagate_bits_across_jump_function (cs, i, jump_func,
3220 &dest_plats->bits_lattice);
3221 ret |= propagate_aggs_across_jump_function (cs, jump_func,
3222 dest_plats);
3223 if (opt_for_fn (callee->decl, flag_ipa_vrp))
3224 ret |= propagate_vr_across_jump_function (cs, jump_func,
3225 dest_plats, param_type);
3226 else
3227 ret |= dest_plats->m_value_range.set_to_bottom ();
3228 }
3229 }
3230 for (; i < parms_count; i++)
3231 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
3232
3233 return ret;
3234 }
3235
3236 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
3237 KNOWN_CONTEXTS, and known aggregates either in AVS or KNOWN_AGGS return
3238 the destination. The latter three can be NULL. If AGG_REPS is not NULL,
3239 KNOWN_AGGS is ignored. */
3240
3241 static tree
3242 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
3243 const vec<tree> &known_csts,
3244 const vec<ipa_polymorphic_call_context> &known_contexts,
3245 const ipa_argagg_value_list &avs,
3246 bool *speculative)
3247 {
3248 int param_index = ie->indirect_info->param_index;
3249 HOST_WIDE_INT anc_offset;
3250 tree t = NULL;
3251 tree target = NULL;
3252
3253 *speculative = false;
3254
3255 if (param_index == -1)
3256 return NULL_TREE;
3257
3258 if (!ie->indirect_info->polymorphic)
3259 {
3260 tree t = NULL;
3261
3262 if (ie->indirect_info->agg_contents)
3263 {
3264 t = NULL;
3265 if ((unsigned) param_index < known_csts.length ()
3266 && known_csts[param_index])
3267 t = ipa_find_agg_cst_from_init (known_csts[param_index],
3268 ie->indirect_info->offset,
3269 ie->indirect_info->by_ref);
3270
3271 if (!t && ie->indirect_info->guaranteed_unmodified)
3272 t = avs.get_value (param_index,
3273 ie->indirect_info->offset / BITS_PER_UNIT,
3274 ie->indirect_info->by_ref);
3275 }
3276 else if ((unsigned) param_index < known_csts.length ())
3277 t = known_csts[param_index];
3278
3279 if (t
3280 && TREE_CODE (t) == ADDR_EXPR
3281 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
3282 return TREE_OPERAND (t, 0);
3283 else
3284 return NULL_TREE;
3285 }
3286
3287 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
3288 return NULL_TREE;
3289
3290 gcc_assert (!ie->indirect_info->agg_contents);
3291 gcc_assert (!ie->indirect_info->by_ref);
3292 anc_offset = ie->indirect_info->offset;
3293
3294 t = NULL;
3295
3296 if ((unsigned) param_index < known_csts.length ()
3297 && known_csts[param_index])
3298 t = ipa_find_agg_cst_from_init (known_csts[param_index],
3299 ie->indirect_info->offset, true);
3300
3301 /* Try to work out value of virtual table pointer value in replacements. */
3302 /* or known aggregate values. */
3303 if (!t)
3304 t = avs.get_value (param_index,
3305 ie->indirect_info->offset / BITS_PER_UNIT,
3306 true);
3307
3308 /* If we found the virtual table pointer, lookup the target. */
3309 if (t)
3310 {
3311 tree vtable;
3312 unsigned HOST_WIDE_INT offset;
3313 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
3314 {
3315 bool can_refer;
3316 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
3317 vtable, offset, &can_refer);
3318 if (can_refer)
3319 {
3320 if (!target
3321 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
3322 || !possible_polymorphic_call_target_p
3323 (ie, cgraph_node::get (target)))
3324 {
3325 /* Do not speculate builtin_unreachable, it is stupid! */
3326 if (ie->indirect_info->vptr_changed)
3327 return NULL;
3328 target = ipa_impossible_devirt_target (ie, target);
3329 }
3330 *speculative = ie->indirect_info->vptr_changed;
3331 if (!*speculative)
3332 return target;
3333 }
3334 }
3335 }
3336
3337 /* Do we know the constant value of pointer? */
3338 if (!t && (unsigned) param_index < known_csts.length ())
3339 t = known_csts[param_index];
3340
3341 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
3342
3343 ipa_polymorphic_call_context context;
3344 if (known_contexts.length () > (unsigned int) param_index)
3345 {
3346 context = known_contexts[param_index];
3347 context.offset_by (anc_offset);
3348 if (ie->indirect_info->vptr_changed)
3349 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3350 ie->indirect_info->otr_type);
3351 if (t)
3352 {
3353 ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
3354 (t, ie->indirect_info->otr_type, anc_offset);
3355 if (!ctx2.useless_p ())
3356 context.combine_with (ctx2, ie->indirect_info->otr_type);
3357 }
3358 }
3359 else if (t)
3360 {
3361 context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
3362 anc_offset);
3363 if (ie->indirect_info->vptr_changed)
3364 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3365 ie->indirect_info->otr_type);
3366 }
3367 else
3368 return NULL_TREE;
3369
3370 vec <cgraph_node *>targets;
3371 bool final;
3372
3373 targets = possible_polymorphic_call_targets
3374 (ie->indirect_info->otr_type,
3375 ie->indirect_info->otr_token,
3376 context, &final);
3377 if (!final || targets.length () > 1)
3378 {
3379 struct cgraph_node *node;
3380 if (*speculative)
3381 return target;
3382 if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3383 || ie->speculative || !ie->maybe_hot_p ())
3384 return NULL;
3385 node = try_speculative_devirtualization (ie->indirect_info->otr_type,
3386 ie->indirect_info->otr_token,
3387 context);
3388 if (node)
3389 {
3390 *speculative = true;
3391 target = node->decl;
3392 }
3393 else
3394 return NULL;
3395 }
3396 else
3397 {
3398 *speculative = false;
3399 if (targets.length () == 1)
3400 target = targets[0]->decl;
3401 else
3402 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3403 }
3404
3405 if (target && !possible_polymorphic_call_target_p (ie,
3406 cgraph_node::get (target)))
3407 {
3408 if (*speculative)
3409 return NULL;
3410 target = ipa_impossible_devirt_target (ie, target);
3411 }
3412
3413 return target;
3414 }
3415
3416 /* If an indirect edge IE can be turned into a direct one based on data in
3417 AVALS, return the destination. Store into *SPECULATIVE a boolean determinig
3418 whether the discovered target is only speculative guess. */
3419
3420 tree
3421 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
3422 ipa_call_arg_values *avals,
3423 bool *speculative)
3424 {
3425 ipa_argagg_value_list avl (avals);
3426 return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3427 avals->m_known_contexts,
3428 avl, speculative);
3429 }
3430
3431 /* Calculate devirtualization time bonus for NODE, assuming we know information
3432 about arguments stored in AVALS. */
3433
3434 static int
3435 devirtualization_time_bonus (struct cgraph_node *node,
3436 ipa_auto_call_arg_values *avals)
3437 {
3438 struct cgraph_edge *ie;
3439 int res = 0;
3440
3441 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
3442 {
3443 struct cgraph_node *callee;
3444 class ipa_fn_summary *isummary;
3445 enum availability avail;
3446 tree target;
3447 bool speculative;
3448
3449 ipa_argagg_value_list avl (avals);
3450 target = ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
3451 avals->m_known_contexts,
3452 avl, &speculative);
3453 if (!target)
3454 continue;
3455
3456 /* Only bare minimum benefit for clearly un-inlineable targets. */
3457 res += 1;
3458 callee = cgraph_node::get (target);
3459 if (!callee || !callee->definition)
3460 continue;
3461 callee = callee->function_symbol (&avail);
3462 if (avail < AVAIL_AVAILABLE)
3463 continue;
3464 isummary = ipa_fn_summaries->get (callee);
3465 if (!isummary || !isummary->inlinable)
3466 continue;
3467
3468 int size = ipa_size_summaries->get (callee)->size;
3469 /* FIXME: The values below need re-considering and perhaps also
3470 integrating into the cost metrics, at lest in some very basic way. */
3471 int max_inline_insns_auto
3472 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3473 if (size <= max_inline_insns_auto / 4)
3474 res += 31 / ((int)speculative + 1);
3475 else if (size <= max_inline_insns_auto / 2)
3476 res += 15 / ((int)speculative + 1);
3477 else if (size <= max_inline_insns_auto
3478 || DECL_DECLARED_INLINE_P (callee->decl))
3479 res += 7 / ((int)speculative + 1);
3480 }
3481
3482 return res;
3483 }
3484
3485 /* Return time bonus incurred because of hints stored in ESTIMATES. */
3486
3487 static int
3488 hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates)
3489 {
3490 int result = 0;
3491 ipa_hints hints = estimates.hints;
3492 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
3493 result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3494
3495 sreal bonus_for_one = opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
3496
3497 if (hints & INLINE_HINT_loop_iterations)
3498 result += (estimates.loops_with_known_iterations * bonus_for_one).to_int ();
3499
3500 if (hints & INLINE_HINT_loop_stride)
3501 result += (estimates.loops_with_known_strides * bonus_for_one).to_int ();
3502
3503 return result;
3504 }
3505
3506 /* If there is a reason to penalize the function described by INFO in the
3507 cloning goodness evaluation, do so. */
3508
3509 static inline sreal
3510 incorporate_penalties (cgraph_node *node, ipa_node_params *info,
3511 sreal evaluation)
3512 {
3513 if (info->node_within_scc && !info->node_is_self_scc)
3514 evaluation = (evaluation
3515 * (100 - opt_for_fn (node->decl,
3516 param_ipa_cp_recursion_penalty))) / 100;
3517
3518 if (info->node_calling_single_call)
3519 evaluation = (evaluation
3520 * (100 - opt_for_fn (node->decl,
3521 param_ipa_cp_single_call_penalty)))
3522 / 100;
3523
3524 return evaluation;
3525 }
3526
3527 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3528 and SIZE_COST and with the sum of frequencies of incoming edges to the
3529 potential new clone in FREQUENCIES. */
3530
3531 static bool
3532 good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit,
3533 sreal freq_sum, profile_count count_sum,
3534 int size_cost)
3535 {
3536 if (time_benefit == 0
3537 || !opt_for_fn (node->decl, flag_ipa_cp_clone)
3538 || node->optimize_for_size_p ())
3539 return false;
3540
3541 gcc_assert (size_cost > 0);
3542
3543 ipa_node_params *info = ipa_node_params_sum->get (node);
3544 int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
3545 if (count_sum.nonzero_p ())
3546 {
3547 gcc_assert (base_count.nonzero_p ());
3548 sreal factor = count_sum.probability_in (base_count).to_sreal ();
3549 sreal evaluation = (time_benefit * factor) / size_cost;
3550 evaluation = incorporate_penalties (node, info, evaluation);
3551 evaluation *= 1000;
3552
3553 if (dump_file && (dump_flags & TDF_DETAILS))
3554 {
3555 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3556 "size: %i, count_sum: ", time_benefit.to_double (),
3557 size_cost);
3558 count_sum.dump (dump_file);
3559 fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n",
3560 info->node_within_scc
3561 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3562 info->node_calling_single_call ? ", single_call" : "",
3563 evaluation.to_double (), eval_threshold);
3564 }
3565
3566 return evaluation.to_int () >= eval_threshold;
3567 }
3568 else
3569 {
3570 sreal evaluation = (time_benefit * freq_sum) / size_cost;
3571 evaluation = incorporate_penalties (node, info, evaluation);
3572 evaluation *= 1000;
3573
3574 if (dump_file && (dump_flags & TDF_DETAILS))
3575 fprintf (dump_file, " good_cloning_opportunity_p (time: %g, "
3576 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
3577 "threshold: %i\n",
3578 time_benefit.to_double (), size_cost, freq_sum.to_double (),
3579 info->node_within_scc
3580 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
3581 info->node_calling_single_call ? ", single_call" : "",
3582 evaluation.to_double (), eval_threshold);
3583
3584 return evaluation.to_int () >= eval_threshold;
3585 }
3586 }
3587
3588 /* Grow vectors in AVALS and fill them with information about values of
3589 parameters that are known to be independent of the context. Only calculate
3590 m_known_aggs if CALCULATE_AGGS is true. INFO describes the function. If
3591 REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
3592 parameters will be stored in it.
3593
3594 TODO: Also grow context independent value range vectors. */
3595
3596 static bool
3597 gather_context_independent_values (class ipa_node_params *info,
3598 ipa_auto_call_arg_values *avals,
3599 bool calculate_aggs,
3600 int *removable_params_cost)
3601 {
3602 int i, count = ipa_get_param_count (info);
3603 bool ret = false;
3604
3605 avals->m_known_vals.safe_grow_cleared (count, true);
3606 avals->m_known_contexts.safe_grow_cleared (count, true);
3607
3608 if (removable_params_cost)
3609 *removable_params_cost = 0;
3610
3611 for (i = 0; i < count; i++)
3612 {
3613 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3614 ipcp_lattice<tree> *lat = &plats->itself;
3615
3616 if (lat->is_single_const ())
3617 {
3618 ipcp_value<tree> *val = lat->values;
3619 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3620 avals->m_known_vals[i] = val->value;
3621 if (removable_params_cost)
3622 *removable_params_cost
3623 += estimate_move_cost (TREE_TYPE (val->value), false);
3624 ret = true;
3625 }
3626 else if (removable_params_cost
3627 && !ipa_is_param_used (info, i))
3628 *removable_params_cost
3629 += ipa_get_param_move_cost (info, i);
3630
3631 if (!ipa_is_param_used (info, i))
3632 continue;
3633
3634 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3635 /* Do not account known context as reason for cloning. We can see
3636 if it permits devirtualization. */
3637 if (ctxlat->is_single_const ())
3638 avals->m_known_contexts[i] = ctxlat->values->value;
3639
3640 if (calculate_aggs)
3641 ret |= push_agg_values_from_plats (plats, i, 0, &avals->m_known_aggs);
3642 }
3643
3644 return ret;
3645 }
3646
3647 /* Perform time and size measurement of NODE with the context given in AVALS,
3648 calculate the benefit compared to the node without specialization and store
3649 it into VAL. Take into account REMOVABLE_PARAMS_COST of all
3650 context-independent or unused removable parameters and EST_MOVE_COST, the
3651 estimated movement of the considered parameter. */
3652
3653 static void
3654 perform_estimation_of_a_value (cgraph_node *node,
3655 ipa_auto_call_arg_values *avals,
3656 int removable_params_cost, int est_move_cost,
3657 ipcp_value_base *val)
3658 {
3659 sreal time_benefit;
3660 ipa_call_estimates estimates;
3661
3662 estimate_ipcp_clone_size_and_time (node, avals, &estimates);
3663
3664 /* Extern inline functions have no cloning local time benefits because they
3665 will be inlined anyway. The only reason to clone them is if it enables
3666 optimization in any of the functions they call. */
3667 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3668 time_benefit = 0;
3669 else
3670 time_benefit = (estimates.nonspecialized_time - estimates.time)
3671 + (devirtualization_time_bonus (node, avals)
3672 + hint_time_bonus (node, estimates)
3673 + removable_params_cost + est_move_cost);
3674
3675 int size = estimates.size;
3676 gcc_checking_assert (size >=0);
3677 /* The inliner-heuristics based estimates may think that in certain
3678 contexts some functions do not have any size at all but we want
3679 all specializations to have at least a tiny cost, not least not to
3680 divide by zero. */
3681 if (size == 0)
3682 size = 1;
3683
3684 val->local_time_benefit = time_benefit;
3685 val->local_size_cost = size;
3686 }
3687
3688 /* Get the overall limit oof growth based on parameters extracted from growth.
3689 it does not really make sense to mix functions with different overall growth
3690 limits but it is possible and if it happens, we do not want to select one
3691 limit at random. */
3692
3693 static long
3694 get_max_overall_size (cgraph_node *node)
3695 {
3696 long max_new_size = orig_overall_size;
3697 long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns);
3698 if (max_new_size < large_unit)
3699 max_new_size = large_unit;
3700 int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
3701 max_new_size += max_new_size * unit_growth / 100 + 1;
3702 return max_new_size;
3703 }
3704
3705 /* Return true if NODE should be cloned just for a parameter removal, possibly
3706 dumping a reason if not. */
3707
3708 static bool
3709 clone_for_param_removal_p (cgraph_node *node)
3710 {
3711 if (!node->can_change_signature)
3712 {
3713 if (dump_file && (dump_flags & TDF_DETAILS))
3714 fprintf (dump_file, " Not considering cloning to remove parameters, "
3715 "function cannot change signature.\n");
3716 return false;
3717 }
3718 if (node->can_be_local_p ())
3719 {
3720 if (dump_file && (dump_flags & TDF_DETAILS))
3721 fprintf (dump_file, " Not considering cloning to remove parameters, "
3722 "IPA-SRA can do it potentially better.\n");
3723 return false;
3724 }
3725 return true;
3726 }
3727
3728 /* Iterate over known values of parameters of NODE and estimate the local
3729 effects in terms of time and size they have. */
3730
3731 static void
3732 estimate_local_effects (struct cgraph_node *node)
3733 {
3734 ipa_node_params *info = ipa_node_params_sum->get (node);
3735 int count = ipa_get_param_count (info);
3736 bool always_const;
3737 int removable_params_cost;
3738
3739 if (!count || !ipcp_versionable_function_p (node))
3740 return;
3741
3742 if (dump_file && (dump_flags & TDF_DETAILS))
3743 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
3744
3745 ipa_auto_call_arg_values avals;
3746 always_const = gather_context_independent_values (info, &avals, true,
3747 &removable_params_cost);
3748 int devirt_bonus = devirtualization_time_bonus (node, &avals);
3749 if (always_const || devirt_bonus
3750 || (removable_params_cost && clone_for_param_removal_p (node)))
3751 {
3752 struct caller_statistics stats;
3753 ipa_call_estimates estimates;
3754
3755 init_caller_stats (&stats);
3756 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3757 false);
3758 estimate_ipcp_clone_size_and_time (node, &avals, &estimates);
3759 sreal time = estimates.nonspecialized_time - estimates.time;
3760 time += devirt_bonus;
3761 time += hint_time_bonus (node, estimates);
3762 time += removable_params_cost;
3763 int size = estimates.size - stats.n_calls * removable_params_cost;
3764
3765 if (dump_file)
3766 fprintf (dump_file, " - context independent values, size: %i, "
3767 "time_benefit: %f\n", size, (time).to_double ());
3768
3769 if (size <= 0 || node->local)
3770 {
3771 info->do_clone_for_all_contexts = true;
3772
3773 if (dump_file)
3774 fprintf (dump_file, " Decided to specialize for all "
3775 "known contexts, code not going to grow.\n");
3776 }
3777 else if (good_cloning_opportunity_p (node, time, stats.freq_sum,
3778 stats.count_sum, size))
3779 {
3780 if (size + overall_size <= get_max_overall_size (node))
3781 {
3782 info->do_clone_for_all_contexts = true;
3783 overall_size += size;
3784
3785 if (dump_file)
3786 fprintf (dump_file, " Decided to specialize for all "
3787 "known contexts, growth (to %li) deemed "
3788 "beneficial.\n", overall_size);
3789 }
3790 else if (dump_file && (dump_flags & TDF_DETAILS))
3791 fprintf (dump_file, " Not cloning for all contexts because "
3792 "maximum unit size would be reached with %li.\n",
3793 size + overall_size);
3794 }
3795 else if (dump_file && (dump_flags & TDF_DETAILS))
3796 fprintf (dump_file, " Not cloning for all contexts because "
3797 "!good_cloning_opportunity_p.\n");
3798
3799 }
3800
3801 for (int i = 0; i < count; i++)
3802 {
3803 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3804 ipcp_lattice<tree> *lat = &plats->itself;
3805 ipcp_value<tree> *val;
3806
3807 if (lat->bottom
3808 || !lat->values
3809 || avals.m_known_vals[i])
3810 continue;
3811
3812 for (val = lat->values; val; val = val->next)
3813 {
3814 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3815 avals.m_known_vals[i] = val->value;
3816
3817 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
3818 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3819 emc, val);
3820
3821 if (dump_file && (dump_flags & TDF_DETAILS))
3822 {
3823 fprintf (dump_file, " - estimates for value ");
3824 print_ipcp_constant_value (dump_file, val->value);
3825 fprintf (dump_file, " for ");
3826 ipa_dump_param (dump_file, info, i);
3827 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3828 val->local_time_benefit.to_double (),
3829 val->local_size_cost);
3830 }
3831 }
3832 avals.m_known_vals[i] = NULL_TREE;
3833 }
3834
3835 for (int i = 0; i < count; i++)
3836 {
3837 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
3838
3839 if (!plats->virt_call)
3840 continue;
3841
3842 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3843 ipcp_value<ipa_polymorphic_call_context> *val;
3844
3845 if (ctxlat->bottom
3846 || !ctxlat->values
3847 || !avals.m_known_contexts[i].useless_p ())
3848 continue;
3849
3850 for (val = ctxlat->values; val; val = val->next)
3851 {
3852 avals.m_known_contexts[i] = val->value;
3853 perform_estimation_of_a_value (node, &avals, removable_params_cost,
3854 0, val);
3855
3856 if (dump_file && (dump_flags & TDF_DETAILS))
3857 {
3858 fprintf (dump_file, " - estimates for polymorphic context ");
3859 print_ipcp_constant_value (dump_file, val->value);
3860 fprintf (dump_file, " for ");
3861 ipa_dump_param (dump_file, info, i);
3862 fprintf (dump_file, ": time_benefit: %g, size: %i\n",
3863 val->local_time_benefit.to_double (),
3864 val->local_size_cost);
3865 }
3866 }
3867 avals.m_known_contexts[i] = ipa_polymorphic_call_context ();
3868 }
3869
3870 unsigned all_ctx_len = avals.m_known_aggs.length ();
3871 auto_vec<ipa_argagg_value, 32> all_ctx;
3872 all_ctx.reserve_exact (all_ctx_len);
3873 all_ctx.splice (avals.m_known_aggs);
3874 avals.m_known_aggs.safe_grow_cleared (all_ctx_len + 1);
3875
3876 unsigned j = 0;
3877 for (int index = 0; index < count; index++)
3878 {
3879 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, index);
3880
3881 if (plats->aggs_bottom || !plats->aggs)
3882 continue;
3883
3884 for (ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
3885 {
3886 ipcp_value<tree> *val;
3887 if (aglat->bottom || !aglat->values
3888 /* If the following is true, the one value is already part of all
3889 context estimations. */
3890 || (!plats->aggs_contain_variable
3891 && aglat->is_single_const ()))
3892 continue;
3893
3894 unsigned unit_offset = aglat->offset / BITS_PER_UNIT;
3895 while (j < all_ctx_len
3896 && (all_ctx[j].index < index
3897 || (all_ctx[j].index == index
3898 && all_ctx[j].unit_offset < unit_offset)))
3899 {
3900 avals.m_known_aggs[j] = all_ctx[j];
3901 j++;
3902 }
3903
3904 for (unsigned k = j; k < all_ctx_len; k++)
3905 avals.m_known_aggs[k+1] = all_ctx[k];
3906
3907 for (val = aglat->values; val; val = val->next)
3908 {
3909 avals.m_known_aggs[j].value = val->value;
3910 avals.m_known_aggs[j].unit_offset = unit_offset;
3911 avals.m_known_aggs[j].index = index;
3912 avals.m_known_aggs[j].by_ref = plats->aggs_by_ref;
3913
3914 perform_estimation_of_a_value (node, &avals,
3915 removable_params_cost, 0, val);
3916
3917 if (dump_file && (dump_flags & TDF_DETAILS))
3918 {
3919 fprintf (dump_file, " - estimates for value ");
3920 print_ipcp_constant_value (dump_file, val->value);
3921 fprintf (dump_file, " for ");
3922 ipa_dump_param (dump_file, info, index);
3923 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
3924 "]: time_benefit: %g, size: %i\n",
3925 plats->aggs_by_ref ? "ref " : "",
3926 aglat->offset,
3927 val->local_time_benefit.to_double (),
3928 val->local_size_cost);
3929 }
3930 }
3931 }
3932 }
3933 }
3934
3935
3936 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3937 topological sort of values. */
3938
3939 template <typename valtype>
3940 void
3941 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
3942 {
3943 ipcp_value_source<valtype> *src;
3944
3945 if (cur_val->dfs)
3946 return;
3947
3948 dfs_counter++;
3949 cur_val->dfs = dfs_counter;
3950 cur_val->low_link = dfs_counter;
3951
3952 cur_val->topo_next = stack;
3953 stack = cur_val;
3954 cur_val->on_stack = true;
3955
3956 for (src = cur_val->sources; src; src = src->next)
3957 if (src->val)
3958 {
3959 if (src->val->dfs == 0)
3960 {
3961 add_val (src->val);
3962 if (src->val->low_link < cur_val->low_link)
3963 cur_val->low_link = src->val->low_link;
3964 }
3965 else if (src->val->on_stack
3966 && src->val->dfs < cur_val->low_link)
3967 cur_val->low_link = src->val->dfs;
3968 }
3969
3970 if (cur_val->dfs == cur_val->low_link)
3971 {
3972 ipcp_value<valtype> *v, *scc_list = NULL;
3973
3974 do
3975 {
3976 v = stack;
3977 stack = v->topo_next;
3978 v->on_stack = false;
3979 v->scc_no = cur_val->dfs;
3980
3981 v->scc_next = scc_list;
3982 scc_list = v;
3983 }
3984 while (v != cur_val);
3985
3986 cur_val->topo_next = values_topo;
3987 values_topo = cur_val;
3988 }
3989 }
3990
3991 /* Add all values in lattices associated with NODE to the topological sort if
3992 they are not there yet. */
3993
3994 static void
3995 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
3996 {
3997 ipa_node_params *info = ipa_node_params_sum->get (node);
3998 int i, count = ipa_get_param_count (info);
3999
4000 for (i = 0; i < count; i++)
4001 {
4002 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4003 ipcp_lattice<tree> *lat = &plats->itself;
4004 struct ipcp_agg_lattice *aglat;
4005
4006 if (!lat->bottom)
4007 {
4008 ipcp_value<tree> *val;
4009 for (val = lat->values; val; val = val->next)
4010 topo->constants.add_val (val);
4011 }
4012
4013 if (!plats->aggs_bottom)
4014 for (aglat = plats->aggs; aglat; aglat = aglat->next)
4015 if (!aglat->bottom)
4016 {
4017 ipcp_value<tree> *val;
4018 for (val = aglat->values; val; val = val->next)
4019 topo->constants.add_val (val);
4020 }
4021
4022 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
4023 if (!ctxlat->bottom)
4024 {
4025 ipcp_value<ipa_polymorphic_call_context> *ctxval;
4026 for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
4027 topo->contexts.add_val (ctxval);
4028 }
4029 }
4030 }
4031
4032 /* One pass of constants propagation along the call graph edges, from callers
4033 to callees (requires topological ordering in TOPO), iterate over strongly
4034 connected components. */
4035
4036 static void
4037 propagate_constants_topo (class ipa_topo_info *topo)
4038 {
4039 int i;
4040
4041 for (i = topo->nnodes - 1; i >= 0; i--)
4042 {
4043 unsigned j;
4044 struct cgraph_node *v, *node = topo->order[i];
4045 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
4046
4047 /* First, iteratively propagate within the strongly connected component
4048 until all lattices stabilize. */
4049 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
4050 if (v->has_gimple_body_p ())
4051 {
4052 if (opt_for_fn (v->decl, flag_ipa_cp)
4053 && opt_for_fn (v->decl, optimize))
4054 push_node_to_stack (topo, v);
4055 /* When V is not optimized, we can not push it to stack, but
4056 still we need to set all its callees lattices to bottom. */
4057 else
4058 {
4059 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
4060 propagate_constants_across_call (cs);
4061 }
4062 }
4063
4064 v = pop_node_from_stack (topo);
4065 while (v)
4066 {
4067 struct cgraph_edge *cs;
4068 class ipa_node_params *info = NULL;
4069 bool self_scc = true;
4070
4071 for (cs = v->callees; cs; cs = cs->next_callee)
4072 if (ipa_edge_within_scc (cs))
4073 {
4074 cgraph_node *callee = cs->callee->function_symbol ();
4075
4076 if (v != callee)
4077 self_scc = false;
4078
4079 if (!info)
4080 {
4081 info = ipa_node_params_sum->get (v);
4082 info->node_within_scc = true;
4083 }
4084
4085 if (propagate_constants_across_call (cs))
4086 push_node_to_stack (topo, callee);
4087 }
4088
4089 if (info)
4090 info->node_is_self_scc = self_scc;
4091
4092 v = pop_node_from_stack (topo);
4093 }
4094
4095 /* Afterwards, propagate along edges leading out of the SCC, calculates
4096 the local effects of the discovered constants and all valid values to
4097 their topological sort. */
4098 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
4099 if (v->has_gimple_body_p ()
4100 && opt_for_fn (v->decl, flag_ipa_cp)
4101 && opt_for_fn (v->decl, optimize))
4102 {
4103 struct cgraph_edge *cs;
4104
4105 estimate_local_effects (v);
4106 add_all_node_vals_to_toposort (v, topo);
4107 for (cs = v->callees; cs; cs = cs->next_callee)
4108 if (!ipa_edge_within_scc (cs))
4109 propagate_constants_across_call (cs);
4110 }
4111 cycle_nodes.release ();
4112 }
4113 }
4114
4115 /* Propagate the estimated effects of individual values along the topological
4116 from the dependent values to those they depend on. */
4117
4118 template <typename valtype>
4119 void
4120 value_topo_info<valtype>::propagate_effects ()
4121 {
4122 ipcp_value<valtype> *base;
4123 hash_set<ipcp_value<valtype> *> processed_srcvals;
4124
4125 for (base = values_topo; base; base = base->topo_next)
4126 {
4127 ipcp_value_source<valtype> *src;
4128 ipcp_value<valtype> *val;
4129 sreal time = 0;
4130 HOST_WIDE_INT size = 0;
4131
4132 for (val = base; val; val = val->scc_next)
4133 {
4134 time = time + val->local_time_benefit + val->prop_time_benefit;
4135 size = size + val->local_size_cost + val->prop_size_cost;
4136 }
4137
4138 for (val = base; val; val = val->scc_next)
4139 {
4140 processed_srcvals.empty ();
4141 for (src = val->sources; src; src = src->next)
4142 if (src->val
4143 && src->cs->maybe_hot_p ())
4144 {
4145 if (!processed_srcvals.add (src->val))
4146 {
4147 HOST_WIDE_INT prop_size = size + src->val->prop_size_cost;
4148 if (prop_size < INT_MAX)
4149 src->val->prop_size_cost = prop_size;
4150 else
4151 continue;
4152 }
4153
4154 int special_factor = 1;
4155 if (val->same_scc (src->val))
4156 special_factor
4157 = opt_for_fn(src->cs->caller->decl,
4158 param_ipa_cp_recursive_freq_factor);
4159 else if (val->self_recursion_generated_p ()
4160 && (src->cs->callee->function_symbol ()
4161 == src->cs->caller))
4162 {
4163 int max_recur_gen_depth
4164 = opt_for_fn(src->cs->caller->decl,
4165 param_ipa_cp_max_recursive_depth);
4166 special_factor = max_recur_gen_depth
4167 - val->self_recursion_generated_level + 1;
4168 }
4169
4170 src->val->prop_time_benefit
4171 += time * special_factor * src->cs->sreal_frequency ();
4172 }
4173
4174 if (size < INT_MAX)
4175 {
4176 val->prop_time_benefit = time;
4177 val->prop_size_cost = size;
4178 }
4179 else
4180 {
4181 val->prop_time_benefit = 0;
4182 val->prop_size_cost = 0;
4183 }
4184 }
4185 }
4186 }
4187
4188 /* Callback for qsort to sort counts of all edges. */
4189
4190 static int
4191 compare_edge_profile_counts (const void *a, const void *b)
4192 {
4193 const profile_count *cnt1 = (const profile_count *) a;
4194 const profile_count *cnt2 = (const profile_count *) b;
4195
4196 if (*cnt1 < *cnt2)
4197 return 1;
4198 if (*cnt1 > *cnt2)
4199 return -1;
4200 return 0;
4201 }
4202
4203
4204 /* Propagate constants, polymorphic contexts and their effects from the
4205 summaries interprocedurally. */
4206
4207 static void
4208 ipcp_propagate_stage (class ipa_topo_info *topo)
4209 {
4210 struct cgraph_node *node;
4211
4212 if (dump_file)
4213 fprintf (dump_file, "\n Propagating constants:\n\n");
4214
4215 base_count = profile_count::uninitialized ();
4216
4217 bool compute_count_base = false;
4218 unsigned base_count_pos_percent = 0;
4219 FOR_EACH_DEFINED_FUNCTION (node)
4220 {
4221 if (node->has_gimple_body_p ()
4222 && opt_for_fn (node->decl, flag_ipa_cp)
4223 && opt_for_fn (node->decl, optimize))
4224 {
4225 ipa_node_params *info = ipa_node_params_sum->get (node);
4226 determine_versionability (node, info);
4227
4228 unsigned nlattices = ipa_get_param_count (info);
4229 void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
4230 info->lattices = new (chunk) ipcp_param_lattices[nlattices];
4231 initialize_node_lattices (node);
4232 }
4233 ipa_size_summary *s = ipa_size_summaries->get (node);
4234 if (node->definition && !node->alias && s != NULL)
4235 overall_size += s->self_size;
4236 if (node->count.ipa ().initialized_p ())
4237 {
4238 compute_count_base = true;
4239 unsigned pos_percent = opt_for_fn (node->decl,
4240 param_ipa_cp_profile_count_base);
4241 base_count_pos_percent = MAX (base_count_pos_percent, pos_percent);
4242 }
4243 }
4244
4245 if (compute_count_base)
4246 {
4247 auto_vec<profile_count> all_edge_counts;
4248 all_edge_counts.reserve_exact (symtab->edges_count);
4249 FOR_EACH_DEFINED_FUNCTION (node)
4250 for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
4251 {
4252 profile_count count = cs->count.ipa ();
4253 if (!count.nonzero_p ())
4254 continue;
4255
4256 enum availability avail;
4257 cgraph_node *tgt
4258 = cs->callee->function_or_virtual_thunk_symbol (&avail);
4259 ipa_node_params *info = ipa_node_params_sum->get (tgt);
4260 if (info && info->versionable)
4261 all_edge_counts.quick_push (count);
4262 }
4263
4264 if (!all_edge_counts.is_empty ())
4265 {
4266 gcc_assert (base_count_pos_percent <= 100);
4267 all_edge_counts.qsort (compare_edge_profile_counts);
4268
4269 unsigned base_count_pos
4270 = ((all_edge_counts.length () * (base_count_pos_percent)) / 100);
4271 base_count = all_edge_counts[base_count_pos];
4272
4273 if (dump_file)
4274 {
4275 fprintf (dump_file, "\nSelected base_count from %u edges at "
4276 "position %u, arriving at: ", all_edge_counts.length (),
4277 base_count_pos);
4278 base_count.dump (dump_file);
4279 fprintf (dump_file, "\n");
4280 }
4281 }
4282 else if (dump_file)
4283 fprintf (dump_file, "\nNo candidates with non-zero call count found, "
4284 "continuing as if without profile feedback.\n");
4285 }
4286
4287 orig_overall_size = overall_size;
4288
4289 if (dump_file)
4290 fprintf (dump_file, "\noverall_size: %li\n", overall_size);
4291
4292 propagate_constants_topo (topo);
4293 if (flag_checking)
4294 ipcp_verify_propagated_values ();
4295 topo->constants.propagate_effects ();
4296 topo->contexts.propagate_effects ();
4297
4298 if (dump_file)
4299 {
4300 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
4301 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
4302 }
4303 }
4304
4305 /* Discover newly direct outgoing edges from NODE which is a new clone with
4306 known KNOWN_CSTS and make them direct. */
4307
4308 static void
4309 ipcp_discover_new_direct_edges (struct cgraph_node *node,
4310 vec<tree> known_csts,
4311 vec<ipa_polymorphic_call_context>
4312 known_contexts,
4313 vec<ipa_argagg_value, va_gc> *aggvals)
4314 {
4315 struct cgraph_edge *ie, *next_ie;
4316 bool found = false;
4317
4318 for (ie = node->indirect_calls; ie; ie = next_ie)
4319 {
4320 tree target;
4321 bool speculative;
4322
4323 next_ie = ie->next_callee;
4324 ipa_argagg_value_list avs (aggvals);
4325 target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
4326 avs, &speculative);
4327 if (target)
4328 {
4329 bool agg_contents = ie->indirect_info->agg_contents;
4330 bool polymorphic = ie->indirect_info->polymorphic;
4331 int param_index = ie->indirect_info->param_index;
4332 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
4333 speculative);
4334 found = true;
4335
4336 if (cs && !agg_contents && !polymorphic)
4337 {
4338 ipa_node_params *info = ipa_node_params_sum->get (node);
4339 int c = ipa_get_controlled_uses (info, param_index);
4340 if (c != IPA_UNDESCRIBED_USE
4341 && !ipa_get_param_load_dereferenced (info, param_index))
4342 {
4343 struct ipa_ref *to_del;
4344
4345 c--;
4346 ipa_set_controlled_uses (info, param_index, c);
4347 if (dump_file && (dump_flags & TDF_DETAILS))
4348 fprintf (dump_file, " controlled uses count of param "
4349 "%i bumped down to %i\n", param_index, c);
4350 if (c == 0
4351 && (to_del = node->find_reference (cs->callee, NULL, 0)))
4352 {
4353 if (dump_file && (dump_flags & TDF_DETAILS))
4354 fprintf (dump_file, " and even removing its "
4355 "cloning-created reference\n");
4356 to_del->remove_reference ();
4357 }
4358 }
4359 }
4360 }
4361 }
4362 /* Turning calls to direct calls will improve overall summary. */
4363 if (found)
4364 ipa_update_overall_fn_summary (node);
4365 }
4366
4367 class edge_clone_summary;
4368 static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
4369
4370 /* Edge clone summary. */
4371
4372 class edge_clone_summary
4373 {
4374 public:
4375 /* Default constructor. */
4376 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
4377
4378 /* Default destructor. */
4379 ~edge_clone_summary ()
4380 {
4381 if (prev_clone)
4382 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
4383 if (next_clone)
4384 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
4385 }
4386
4387 cgraph_edge *prev_clone;
4388 cgraph_edge *next_clone;
4389 };
4390
4391 class edge_clone_summary_t:
4392 public call_summary <edge_clone_summary *>
4393 {
4394 public:
4395 edge_clone_summary_t (symbol_table *symtab):
4396 call_summary <edge_clone_summary *> (symtab)
4397 {
4398 m_initialize_when_cloning = true;
4399 }
4400
4401 void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4402 edge_clone_summary *src_data,
4403 edge_clone_summary *dst_data) final override;
4404 };
4405
4406 /* Edge duplication hook. */
4407
4408 void
4409 edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4410 edge_clone_summary *src_data,
4411 edge_clone_summary *dst_data)
4412 {
4413 if (src_data->next_clone)
4414 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
4415 dst_data->prev_clone = src_edge;
4416 dst_data->next_clone = src_data->next_clone;
4417 src_data->next_clone = dst_edge;
4418 }
4419
4420 /* Return true is CS calls DEST or its clone for all contexts. When
4421 ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
4422 edges from/to an all-context clone. */
4423
4424 static bool
4425 calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest,
4426 bool allow_recursion_to_clone)
4427 {
4428 enum availability availability;
4429 cgraph_node *callee = cs->callee->function_symbol (&availability);
4430
4431 if (availability <= AVAIL_INTERPOSABLE)
4432 return false;
4433 if (callee == dest)
4434 return true;
4435 if (!allow_recursion_to_clone && cs->caller == callee)
4436 return false;
4437
4438 ipa_node_params *info = ipa_node_params_sum->get (callee);
4439 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
4440 }
4441
4442 /* Return true if edge CS does bring about the value described by SRC to
4443 DEST_VAL of node DEST or its clone for all contexts. */
4444
4445 static bool
4446 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
4447 cgraph_node *dest, ipcp_value<tree> *dest_val)
4448 {
4449 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
4450
4451 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val)
4452 || caller_info->node_dead)
4453 return false;
4454
4455 if (!src->val)
4456 return true;
4457
4458 if (caller_info->ipcp_orig_node)
4459 {
4460 tree t = NULL_TREE;
4461 if (src->offset == -1)
4462 t = caller_info->known_csts[src->index];
4463 else if (ipcp_transformation *ts
4464 = ipcp_get_transformation_summary (cs->caller))
4465 {
4466 ipa_argagg_value_list avl (ts);
4467 t = avl.get_value (src->index, src->offset / BITS_PER_UNIT);
4468 }
4469 return (t != NULL_TREE
4470 && values_equal_for_ipcp_p (src->val->value, t));
4471 }
4472 else
4473 {
4474 if (src->val == dest_val)
4475 return true;
4476
4477 struct ipcp_agg_lattice *aglat;
4478 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4479 src->index);
4480 if (src->offset == -1)
4481 return (plats->itself.is_single_const ()
4482 && values_equal_for_ipcp_p (src->val->value,
4483 plats->itself.values->value));
4484 else
4485 {
4486 if (plats->aggs_bottom || plats->aggs_contain_variable)
4487 return false;
4488 for (aglat = plats->aggs; aglat; aglat = aglat->next)
4489 if (aglat->offset == src->offset)
4490 return (aglat->is_single_const ()
4491 && values_equal_for_ipcp_p (src->val->value,
4492 aglat->values->value));
4493 }
4494 return false;
4495 }
4496 }
4497
4498 /* Return true if edge CS does bring about the value described by SRC to
4499 DST_VAL of node DEST or its clone for all contexts. */
4500
4501 static bool
4502 cgraph_edge_brings_value_p (cgraph_edge *cs,
4503 ipcp_value_source<ipa_polymorphic_call_context> *src,
4504 cgraph_node *dest,
4505 ipcp_value<ipa_polymorphic_call_context> *)
4506 {
4507 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
4508
4509 if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true)
4510 || caller_info->node_dead)
4511 return false;
4512 if (!src->val)
4513 return true;
4514
4515 if (caller_info->ipcp_orig_node)
4516 return (caller_info->known_contexts.length () > (unsigned) src->index)
4517 && values_equal_for_ipcp_p (src->val->value,
4518 caller_info->known_contexts[src->index]);
4519
4520 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
4521 src->index);
4522 return plats->ctxlat.is_single_const ()
4523 && values_equal_for_ipcp_p (src->val->value,
4524 plats->ctxlat.values->value);
4525 }
4526
4527 /* Get the next clone in the linked list of clones of an edge. */
4528
4529 static inline struct cgraph_edge *
4530 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
4531 {
4532 edge_clone_summary *s = edge_clone_summaries->get (cs);
4533 return s != NULL ? s->next_clone : NULL;
4534 }
4535
4536 /* Given VAL that is intended for DEST, iterate over all its sources and if any
4537 of them is viable and hot, return true. In that case, for those that still
4538 hold, add their edge frequency and their number and cumulative profile
4539 counts of self-ecursive and other edges into *FREQUENCY, *CALLER_COUNT,
4540 REC_COUNT_SUM and NONREC_COUNT_SUM respectively. */
4541
4542 template <typename valtype>
4543 static bool
4544 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
4545 sreal *freq_sum, int *caller_count,
4546 profile_count *rec_count_sum,
4547 profile_count *nonrec_count_sum)
4548 {
4549 ipcp_value_source<valtype> *src;
4550 sreal freq = 0;
4551 int count = 0;
4552 profile_count rec_cnt = profile_count::zero ();
4553 profile_count nonrec_cnt = profile_count::zero ();
4554 bool hot = false;
4555 bool non_self_recursive = false;
4556
4557 for (src = val->sources; src; src = src->next)
4558 {
4559 struct cgraph_edge *cs = src->cs;
4560 while (cs)
4561 {
4562 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4563 {
4564 count++;
4565 freq += cs->sreal_frequency ();
4566 hot |= cs->maybe_hot_p ();
4567 if (cs->caller != dest)
4568 {
4569 non_self_recursive = true;
4570 if (cs->count.ipa ().initialized_p ())
4571 rec_cnt += cs->count.ipa ();
4572 }
4573 else if (cs->count.ipa ().initialized_p ())
4574 nonrec_cnt += cs->count.ipa ();
4575 }
4576 cs = get_next_cgraph_edge_clone (cs);
4577 }
4578 }
4579
4580 /* If the only edges bringing a value are self-recursive ones, do not bother
4581 evaluating it. */
4582 if (!non_self_recursive)
4583 return false;
4584
4585 *freq_sum = freq;
4586 *caller_count = count;
4587 *rec_count_sum = rec_cnt;
4588 *nonrec_count_sum = nonrec_cnt;
4589
4590 if (!hot && ipa_node_params_sum->get (dest)->node_within_scc)
4591 {
4592 struct cgraph_edge *cs;
4593
4594 /* Cold non-SCC source edge could trigger hot recursive execution of
4595 function. Consider the case as hot and rely on following cost model
4596 computation to further select right one. */
4597 for (cs = dest->callers; cs; cs = cs->next_caller)
4598 if (cs->caller == dest && cs->maybe_hot_p ())
4599 return true;
4600 }
4601
4602 return hot;
4603 }
4604
4605 /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4606 to let a non-self-recursive caller be the first element. Thus, we can
4607 simplify intersecting operations on values that arrive from all of these
4608 callers, especially when there exists self-recursive call. Return true if
4609 this kind of adjustment is possible. */
4610
4611 static bool
4612 adjust_callers_for_value_intersection (vec<cgraph_edge *> &callers,
4613 cgraph_node *node)
4614 {
4615 for (unsigned i = 0; i < callers.length (); i++)
4616 {
4617 cgraph_edge *cs = callers[i];
4618
4619 if (cs->caller != node)
4620 {
4621 if (i > 0)
4622 {
4623 callers[i] = callers[0];
4624 callers[0] = cs;
4625 }
4626 return true;
4627 }
4628 }
4629 return false;
4630 }
4631
4632 /* Return a vector of incoming edges that do bring value VAL to node DEST. It
4633 is assumed their number is known and equal to CALLER_COUNT. */
4634
4635 template <typename valtype>
4636 static vec<cgraph_edge *>
4637 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
4638 int caller_count)
4639 {
4640 ipcp_value_source<valtype> *src;
4641 vec<cgraph_edge *> ret;
4642
4643 ret.create (caller_count);
4644 for (src = val->sources; src; src = src->next)
4645 {
4646 struct cgraph_edge *cs = src->cs;
4647 while (cs)
4648 {
4649 if (cgraph_edge_brings_value_p (cs, src, dest, val))
4650 ret.quick_push (cs);
4651 cs = get_next_cgraph_edge_clone (cs);
4652 }
4653 }
4654
4655 if (caller_count > 1)
4656 adjust_callers_for_value_intersection (ret, dest);
4657
4658 return ret;
4659 }
4660
4661 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4662 Return it or NULL if for some reason it cannot be created. FORCE_LOAD_REF
4663 should be set to true when the reference created for the constant should be
4664 a load one and not an address one because the corresponding parameter p is
4665 only used as *p. */
4666
4667 static struct ipa_replace_map *
4668 get_replacement_map (class ipa_node_params *info, tree value, int parm_num,
4669 bool force_load_ref)
4670 {
4671 struct ipa_replace_map *replace_map;
4672
4673 replace_map = ggc_alloc<ipa_replace_map> ();
4674 if (dump_file)
4675 {
4676 fprintf (dump_file, " replacing ");
4677 ipa_dump_param (dump_file, info, parm_num);
4678
4679 fprintf (dump_file, " with const ");
4680 print_generic_expr (dump_file, value);
4681
4682 if (force_load_ref)
4683 fprintf (dump_file, " - forcing load reference\n");
4684 else
4685 fprintf (dump_file, "\n");
4686 }
4687 replace_map->parm_num = parm_num;
4688 replace_map->new_tree = value;
4689 replace_map->force_load_ref = force_load_ref;
4690 return replace_map;
4691 }
4692
4693 /* Dump new profiling counts of NODE. SPEC is true when NODE is a specialzied
4694 one, otherwise it will be referred to as the original node. */
4695
4696 static void
4697 dump_profile_updates (cgraph_node *node, bool spec)
4698 {
4699 if (spec)
4700 fprintf (dump_file, " setting count of the specialized node %s to ",
4701 node->dump_name ());
4702 else
4703 fprintf (dump_file, " setting count of the original node %s to ",
4704 node->dump_name ());
4705
4706 node->count.dump (dump_file);
4707 fprintf (dump_file, "\n");
4708 for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
4709 {
4710 fprintf (dump_file, " edge to %s has count ",
4711 cs->callee->dump_name ());
4712 cs->count.dump (dump_file);
4713 fprintf (dump_file, "\n");
4714 }
4715 }
4716
4717 /* With partial train run we do not want to assume that original's count is
4718 zero whenever we redurect all executed edges to clone. Simply drop profile
4719 to local one in this case. In eany case, return the new value. ORIG_NODE
4720 is the original node and its count has not been updaed yet. */
4721
4722 profile_count
4723 lenient_count_portion_handling (profile_count remainder, cgraph_node *orig_node)
4724 {
4725 if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
4726 && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
4727 && opt_for_fn (orig_node->decl, flag_profile_partial_training))
4728 remainder = remainder.guessed_local ();
4729
4730 return remainder;
4731 }
4732
4733 /* Structure to sum counts coming from nodes other than the original node and
4734 its clones. */
4735
4736 struct gather_other_count_struct
4737 {
4738 cgraph_node *orig;
4739 profile_count other_count;
4740 };
4741
4742 /* Worker callback of call_for_symbol_thunks_and_aliases summing the number of
4743 counts that come from non-self-recursive calls.. */
4744
4745 static bool
4746 gather_count_of_non_rec_edges (cgraph_node *node, void *data)
4747 {
4748 gather_other_count_struct *desc = (gather_other_count_struct *) data;
4749 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
4750 if (cs->caller != desc->orig && cs->caller->clone_of != desc->orig)
4751 desc->other_count += cs->count.ipa ();
4752 return false;
4753 }
4754
4755 /* Structure to help analyze if we need to boost counts of some clones of some
4756 non-recursive edges to match the new callee count. */
4757
4758 struct desc_incoming_count_struct
4759 {
4760 cgraph_node *orig;
4761 hash_set <cgraph_edge *> *processed_edges;
4762 profile_count count;
4763 unsigned unproc_orig_rec_edges;
4764 };
4765
4766 /* Go over edges calling NODE and its thunks and gather information about
4767 incoming counts so that we know if we need to make any adjustments. */
4768
4769 static void
4770 analyze_clone_icoming_counts (cgraph_node *node,
4771 desc_incoming_count_struct *desc)
4772 {
4773 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
4774 if (cs->caller->thunk)
4775 {
4776 analyze_clone_icoming_counts (cs->caller, desc);
4777 continue;
4778 }
4779 else
4780 {
4781 if (cs->count.initialized_p ())
4782 desc->count += cs->count.ipa ();
4783 if (!desc->processed_edges->contains (cs)
4784 && cs->caller->clone_of == desc->orig)
4785 desc->unproc_orig_rec_edges++;
4786 }
4787 }
4788
4789 /* If caller edge counts of a clone created for a self-recursive arithmetic
4790 jump function must be adjusted because it is coming from a the "seed" clone
4791 for the first value and so has been excessively scaled back as if it was not
4792 a recursive call, adjust it so that the incoming counts of NODE match its
4793 count. NODE is the node or its thunk. */
4794
4795 static void
4796 adjust_clone_incoming_counts (cgraph_node *node,
4797 desc_incoming_count_struct *desc)
4798 {
4799 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
4800 if (cs->caller->thunk)
4801 {
4802 adjust_clone_incoming_counts (cs->caller, desc);
4803 profile_count sum = profile_count::zero ();
4804 for (cgraph_edge *e = cs->caller->callers; e; e = e->next_caller)
4805 if (e->count.initialized_p ())
4806 sum += e->count.ipa ();
4807 cs->count = cs->count.combine_with_ipa_count (sum);
4808 }
4809 else if (!desc->processed_edges->contains (cs)
4810 && cs->caller->clone_of == desc->orig)
4811 {
4812 cs->count += desc->count;
4813 if (dump_file)
4814 {
4815 fprintf (dump_file, " Adjusted count of an incoming edge of "
4816 "a clone %s -> %s to ", cs->caller->dump_name (),
4817 cs->callee->dump_name ());
4818 cs->count.dump (dump_file);
4819 fprintf (dump_file, "\n");
4820 }
4821 }
4822 }
4823
4824 /* When ORIG_NODE has been cloned for values which have been generated fora
4825 self-recursive call as a result of an arithmetic pass-through
4826 jump-functions, adjust its count together with counts of all such clones in
4827 SELF_GEN_CLONES which also at this point contains ORIG_NODE itself.
4828
4829 The function sums the counts of the original node and all its clones that
4830 cannot be attributed to a specific clone because it comes from a
4831 non-recursive edge. This sum is then evenly divided between the clones and
4832 on top of that each one gets all the counts which can be attributed directly
4833 to it. */
4834
4835 static void
4836 update_counts_for_self_gen_clones (cgraph_node *orig_node,
4837 const vec<cgraph_node *> &self_gen_clones)
4838 {
4839 profile_count redist_sum = orig_node->count.ipa ();
4840 if (!(redist_sum > profile_count::zero ()))
4841 return;
4842
4843 if (dump_file)
4844 fprintf (dump_file, " Updating profile of self recursive clone "
4845 "series\n");
4846
4847 gather_other_count_struct gocs;
4848 gocs.orig = orig_node;
4849 gocs.other_count = profile_count::zero ();
4850
4851 auto_vec <profile_count, 8> other_edges_count;
4852 for (cgraph_node *n : self_gen_clones)
4853 {
4854 gocs.other_count = profile_count::zero ();
4855 n->call_for_symbol_thunks_and_aliases (gather_count_of_non_rec_edges,
4856 &gocs, false);
4857 other_edges_count.safe_push (gocs.other_count);
4858 redist_sum -= gocs.other_count;
4859 }
4860
4861 hash_set<cgraph_edge *> processed_edges;
4862 unsigned i = 0;
4863 for (cgraph_node *n : self_gen_clones)
4864 {
4865 profile_count orig_count = n->count;
4866 profile_count new_count
4867 = (redist_sum / self_gen_clones.length () + other_edges_count[i]);
4868 new_count = lenient_count_portion_handling (new_count, orig_node);
4869 n->count = new_count;
4870 profile_count::adjust_for_ipa_scaling (&new_count, &orig_count);
4871 for (cgraph_edge *cs = n->callees; cs; cs = cs->next_callee)
4872 {
4873 cs->count = cs->count.apply_scale (new_count, orig_count);
4874 processed_edges.add (cs);
4875 }
4876 for (cgraph_edge *cs = n->indirect_calls; cs; cs = cs->next_callee)
4877 cs->count = cs->count.apply_scale (new_count, orig_count);
4878
4879 i++;
4880 }
4881
4882 /* There are still going to be edges to ORIG_NODE that have one or more
4883 clones coming from another node clone in SELF_GEN_CLONES and which we
4884 scaled by the same amount, which means that the total incoming sum of
4885 counts to ORIG_NODE will be too high, scale such edges back. */
4886 for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee)
4887 {
4888 if (cs->callee->ultimate_alias_target () == orig_node)
4889 {
4890 unsigned den = 0;
4891 for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e))
4892 if (e->callee->ultimate_alias_target () == orig_node
4893 && processed_edges.contains (e))
4894 den++;
4895 if (den > 0)
4896 for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e))
4897 if (e->callee->ultimate_alias_target () == orig_node
4898 && processed_edges.contains (e))
4899 e->count /= den;
4900 }
4901 }
4902
4903 /* Edges from the seeds of the valus generated for arithmetic jump-functions
4904 along self-recursive edges are likely to have fairly low count and so
4905 edges from them to nodes in the self_gen_clones do not correspond to the
4906 artificially distributed count of the nodes, the total sum of incoming
4907 edges to some clones might be too low. Detect this situation and correct
4908 it. */
4909 for (cgraph_node *n : self_gen_clones)
4910 {
4911 if (!(n->count.ipa () > profile_count::zero ()))
4912 continue;
4913
4914 desc_incoming_count_struct desc;
4915 desc.orig = orig_node;
4916 desc.processed_edges = &processed_edges;
4917 desc.count = profile_count::zero ();
4918 desc.unproc_orig_rec_edges = 0;
4919 analyze_clone_icoming_counts (n, &desc);
4920
4921 if (n->count.differs_from_p (desc.count))
4922 {
4923 if (n->count > desc.count
4924 && desc.unproc_orig_rec_edges > 0)
4925 {
4926 desc.count = n->count - desc.count;
4927 desc.count = desc.count /= desc.unproc_orig_rec_edges;
4928 adjust_clone_incoming_counts (n, &desc);
4929 }
4930 else if (dump_file)
4931 fprintf (dump_file,
4932 " Unable to fix up incoming counts for %s.\n",
4933 n->dump_name ());
4934 }
4935 }
4936
4937 if (dump_file)
4938 for (cgraph_node *n : self_gen_clones)
4939 dump_profile_updates (n, n != orig_node);
4940 return;
4941 }
4942
4943 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4944 their profile information to reflect this. This function should not be used
4945 for clones generated for arithmetic pass-through jump functions on a
4946 self-recursive call graph edge, that situation is handled by
4947 update_counts_for_self_gen_clones. */
4948
4949 static void
4950 update_profiling_info (struct cgraph_node *orig_node,
4951 struct cgraph_node *new_node)
4952 {
4953 struct caller_statistics stats;
4954 profile_count new_sum;
4955 profile_count remainder, orig_node_count = orig_node->count.ipa ();
4956
4957 if (!(orig_node_count > profile_count::zero ()))
4958 return;
4959
4960 if (dump_file)
4961 {
4962 fprintf (dump_file, " Updating profile from original count: ");
4963 orig_node_count.dump (dump_file);
4964 fprintf (dump_file, "\n");
4965 }
4966
4967 init_caller_stats (&stats, new_node);
4968 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4969 false);
4970 new_sum = stats.count_sum;
4971
4972 bool orig_edges_processed = false;
4973 if (new_sum > orig_node_count)
4974 {
4975 /* TODO: Profile has alreay gone astray, keep what we have but lower it
4976 to global0 category. */
4977 remainder = orig_node->count.global0 ();
4978
4979 for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee)
4980 cs->count = cs->count.global0 ();
4981 for (cgraph_edge *cs = orig_node->indirect_calls;
4982 cs;
4983 cs = cs->next_callee)
4984 cs->count = cs->count.global0 ();
4985 orig_edges_processed = true;
4986 }
4987 else if (stats.rec_count_sum.nonzero_p ())
4988 {
4989 int new_nonrec_calls = stats.n_nonrec_calls;
4990 /* There are self-recursive edges which are likely to bring in the
4991 majority of calls but which we must divide in between the original and
4992 new node. */
4993 init_caller_stats (&stats, orig_node);
4994 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats,
4995 &stats, false);
4996 int orig_nonrec_calls = stats.n_nonrec_calls;
4997 profile_count orig_nonrec_call_count = stats.count_sum;
4998
4999 if (orig_node->local)
5000 {
5001 if (!orig_nonrec_call_count.nonzero_p ())
5002 {
5003 if (dump_file)
5004 fprintf (dump_file, " The original is local and the only "
5005 "incoming edges from non-dead callers with nonzero "
5006 "counts are self-recursive, assuming it is cold.\n");
5007 /* The NEW_NODE count and counts of all its outgoing edges
5008 are still unmodified copies of ORIG_NODE's. Just clear
5009 the latter and bail out. */
5010 profile_count zero;
5011 if (opt_for_fn (orig_node->decl, flag_profile_partial_training))
5012 zero = profile_count::zero ().guessed_local ();
5013 else
5014 zero = profile_count::adjusted_zero ();
5015 orig_node->count = zero;
5016 for (cgraph_edge *cs = orig_node->callees;
5017 cs;
5018 cs = cs->next_callee)
5019 cs->count = zero;
5020 for (cgraph_edge *cs = orig_node->indirect_calls;
5021 cs;
5022 cs = cs->next_callee)
5023 cs->count = zero;
5024 return;
5025 }
5026 }
5027 else
5028 {
5029 /* Let's behave as if there was another caller that accounts for all
5030 the calls that were either indirect or from other compilation
5031 units. */
5032 orig_nonrec_calls++;
5033 profile_count pretend_caller_count
5034 = (orig_node_count - new_sum - orig_nonrec_call_count
5035 - stats.rec_count_sum);
5036 orig_nonrec_call_count += pretend_caller_count;
5037 }
5038
5039 /* Divide all "unexplained" counts roughly proportionally to sums of
5040 counts of non-recursive calls.
5041
5042 We put rather arbitrary limits on how many counts we claim because the
5043 number of non-self-recursive incoming count is only a rough guideline
5044 and there are cases (such as mcf) where using it blindly just takes
5045 too many. And if lattices are considered in the opposite order we
5046 could also take too few. */
5047 profile_count unexp = orig_node_count - new_sum - orig_nonrec_call_count;
5048
5049 int limit_den = 2 * (orig_nonrec_calls + new_nonrec_calls);
5050 profile_count new_part
5051 = MAX(MIN (unexp.apply_scale (new_sum,
5052 new_sum + orig_nonrec_call_count),
5053 unexp.apply_scale (limit_den - 1, limit_den)),
5054 unexp.apply_scale (new_nonrec_calls, limit_den));
5055 if (dump_file)
5056 {
5057 fprintf (dump_file, " Claiming ");
5058 new_part.dump (dump_file);
5059 fprintf (dump_file, " of unexplained ");
5060 unexp.dump (dump_file);
5061 fprintf (dump_file, " counts because of self-recursive "
5062 "calls\n");
5063 }
5064 new_sum += new_part;
5065 remainder = lenient_count_portion_handling (orig_node_count - new_sum,
5066 orig_node);
5067 }
5068 else
5069 remainder = lenient_count_portion_handling (orig_node_count - new_sum,
5070 orig_node);
5071
5072 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
5073 new_node->count = new_sum;
5074 orig_node->count = remainder;
5075
5076 profile_count orig_new_node_count = orig_node_count;
5077 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
5078 for (cgraph_edge *cs = new_node->callees; cs; cs = cs->next_callee)
5079 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
5080 for (cgraph_edge *cs = new_node->indirect_calls; cs; cs = cs->next_callee)
5081 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
5082
5083 if (!orig_edges_processed)
5084 {
5085 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
5086 for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee)
5087 cs->count = cs->count.apply_scale (remainder, orig_node_count);
5088 for (cgraph_edge *cs = orig_node->indirect_calls;
5089 cs;
5090 cs = cs->next_callee)
5091 cs->count = cs->count.apply_scale (remainder, orig_node_count);
5092 }
5093
5094 if (dump_file)
5095 {
5096 dump_profile_updates (new_node, true);
5097 dump_profile_updates (orig_node, false);
5098 }
5099 }
5100
5101 /* Update the respective profile of specialized NEW_NODE and the original
5102 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
5103 have been redirected to the specialized version. */
5104
5105 static void
5106 update_specialized_profile (struct cgraph_node *new_node,
5107 struct cgraph_node *orig_node,
5108 profile_count redirected_sum)
5109 {
5110 struct cgraph_edge *cs;
5111 profile_count new_node_count, orig_node_count = orig_node->count.ipa ();
5112
5113 if (dump_file)
5114 {
5115 fprintf (dump_file, " the sum of counts of redirected edges is ");
5116 redirected_sum.dump (dump_file);
5117 fprintf (dump_file, "\n old ipa count of the original node is ");
5118 orig_node_count.dump (dump_file);
5119 fprintf (dump_file, "\n");
5120 }
5121 if (!(orig_node_count > profile_count::zero ()))
5122 return;
5123
5124 new_node_count = new_node->count;
5125 new_node->count += redirected_sum;
5126 orig_node->count
5127 = lenient_count_portion_handling (orig_node->count - redirected_sum,
5128 orig_node);
5129
5130 for (cs = new_node->callees; cs; cs = cs->next_callee)
5131 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
5132
5133 for (cs = orig_node->callees; cs; cs = cs->next_callee)
5134 {
5135 profile_count dec = cs->count.apply_scale (redirected_sum,
5136 orig_node_count);
5137 cs->count -= dec;
5138 }
5139
5140 if (dump_file)
5141 {
5142 dump_profile_updates (new_node, true);
5143 dump_profile_updates (orig_node, false);
5144 }
5145 }
5146
5147 static void adjust_references_in_caller (cgraph_edge *cs,
5148 symtab_node *symbol, int index);
5149
5150 /* Simple structure to pass a symbol and index (with same meaning as parameters
5151 of adjust_references_in_caller) through a void* parameter of a
5152 call_for_symbol_thunks_and_aliases callback. */
5153 struct symbol_and_index_together
5154 {
5155 symtab_node *symbol;
5156 int index;
5157 };
5158
5159 /* Worker callback of call_for_symbol_thunks_and_aliases to recursively call
5160 adjust_references_in_caller on edges up in the call-graph, if necessary. */
5161 static bool
5162 adjust_refs_in_act_callers (struct cgraph_node *node, void *data)
5163 {
5164 symbol_and_index_together *pack = (symbol_and_index_together *) data;
5165 for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
5166 if (!cs->caller->thunk)
5167 adjust_references_in_caller (cs, pack->symbol, pack->index);
5168 return false;
5169 }
5170
5171 /* At INDEX of a function being called by CS there is an ADDR_EXPR of a
5172 variable which is only dereferenced and which is represented by SYMBOL. See
5173 if we can remove ADDR reference in callers assosiated witht the call. */
5174
5175 static void
5176 adjust_references_in_caller (cgraph_edge *cs, symtab_node *symbol, int index)
5177 {
5178 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
5179 ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, index);
5180 if (jfunc->type == IPA_JF_CONST)
5181 {
5182 ipa_ref *to_del = cs->caller->find_reference (symbol, cs->call_stmt,
5183 cs->lto_stmt_uid);
5184 if (!to_del)
5185 return;
5186 to_del->remove_reference ();
5187 if (dump_file)
5188 fprintf (dump_file, " Removed a reference from %s to %s.\n",
5189 cs->caller->dump_name (), symbol->dump_name ());
5190 return;
5191 }
5192
5193 if (jfunc->type != IPA_JF_PASS_THROUGH
5194 || ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
5195 return;
5196
5197 int fidx = ipa_get_jf_pass_through_formal_id (jfunc);
5198 cgraph_node *caller = cs->caller;
5199 ipa_node_params *caller_info = ipa_node_params_sum->get (caller);
5200 /* TODO: This consistency check may be too big and not really
5201 that useful. Consider removing it. */
5202 tree cst;
5203 if (caller_info->ipcp_orig_node)
5204 cst = caller_info->known_csts[fidx];
5205 else
5206 {
5207 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (caller_info, fidx);
5208 gcc_assert (lat->is_single_const ());
5209 cst = lat->values->value;
5210 }
5211 gcc_assert (TREE_CODE (cst) == ADDR_EXPR
5212 && (symtab_node::get (get_base_address (TREE_OPERAND (cst, 0)))
5213 == symbol));
5214
5215 int cuses = ipa_get_controlled_uses (caller_info, fidx);
5216 if (cuses == IPA_UNDESCRIBED_USE)
5217 return;
5218 gcc_assert (cuses > 0);
5219 cuses--;
5220 ipa_set_controlled_uses (caller_info, fidx, cuses);
5221 if (cuses)
5222 return;
5223
5224 if (caller_info->ipcp_orig_node)
5225 {
5226 /* Cloning machinery has created a reference here, we need to either
5227 remove it or change it to a read one. */
5228 ipa_ref *to_del = caller->find_reference (symbol, NULL, 0);
5229 if (to_del && to_del->use == IPA_REF_ADDR)
5230 {
5231 to_del->remove_reference ();
5232 if (dump_file)
5233 fprintf (dump_file, " Removed a reference from %s to %s.\n",
5234 cs->caller->dump_name (), symbol->dump_name ());
5235 if (ipa_get_param_load_dereferenced (caller_info, fidx))
5236 {
5237 caller->create_reference (symbol, IPA_REF_LOAD, NULL);
5238 if (dump_file)
5239 fprintf (dump_file,
5240 " ...and replaced it with LOAD one.\n");
5241 }
5242 }
5243 }
5244
5245 symbol_and_index_together pack;
5246 pack.symbol = symbol;
5247 pack.index = fidx;
5248 if (caller->can_change_signature)
5249 caller->call_for_symbol_thunks_and_aliases (adjust_refs_in_act_callers,
5250 &pack, true);
5251 }
5252
5253
5254 /* Return true if we would like to remove a parameter from NODE when cloning it
5255 with KNOWN_CSTS scalar constants. */
5256
5257 static bool
5258 want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
5259 {
5260 auto_vec<bool, 16> surviving;
5261 bool filled_vec = false;
5262 ipa_node_params *info = ipa_node_params_sum->get (node);
5263 int i, count = ipa_get_param_count (info);
5264
5265 for (i = 0; i < count; i++)
5266 {
5267 if (!known_csts[i] && ipa_is_param_used (info, i))
5268 continue;
5269
5270 if (!filled_vec)
5271 {
5272 clone_info *info = clone_info::get (node);
5273 if (!info || !info->param_adjustments)
5274 return true;
5275 info->param_adjustments->get_surviving_params (&surviving);
5276 filled_vec = true;
5277 }
5278 if (surviving.length() < (unsigned) i && surviving[i])
5279 return true;
5280 }
5281 return false;
5282 }
5283
5284 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
5285 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
5286 redirect all edges in CALLERS to it. */
5287
5288 static struct cgraph_node *
5289 create_specialized_node (struct cgraph_node *node,
5290 vec<tree> known_csts,
5291 vec<ipa_polymorphic_call_context> known_contexts,
5292 vec<ipa_argagg_value, va_gc> *aggvals,
5293 vec<cgraph_edge *> &callers)
5294 {
5295 ipa_node_params *new_info, *info = ipa_node_params_sum->get (node);
5296 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
5297 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
5298 struct cgraph_node *new_node;
5299 int i, count = ipa_get_param_count (info);
5300 clone_info *cinfo = clone_info::get (node);
5301 ipa_param_adjustments *old_adjustments = cinfo
5302 ? cinfo->param_adjustments : NULL;
5303 ipa_param_adjustments *new_adjustments;
5304 gcc_assert (!info->ipcp_orig_node);
5305 gcc_assert (node->can_change_signature
5306 || !old_adjustments);
5307
5308 if (old_adjustments)
5309 {
5310 /* At the moment all IPA optimizations should use the number of
5311 parameters of the prevailing decl as the m_always_copy_start.
5312 Handling any other value would complicate the code below, so for the
5313 time bing let's only assert it is so. */
5314 gcc_assert (old_adjustments->m_always_copy_start == count
5315 || old_adjustments->m_always_copy_start < 0);
5316 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
5317 for (i = 0; i < old_adj_count; i++)
5318 {
5319 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
5320 if (!node->can_change_signature
5321 || old_adj->op != IPA_PARAM_OP_COPY
5322 || (!known_csts[old_adj->base_index]
5323 && ipa_is_param_used (info, old_adj->base_index)))
5324 {
5325 ipa_adjusted_param new_adj = *old_adj;
5326
5327 new_adj.prev_clone_adjustment = true;
5328 new_adj.prev_clone_index = i;
5329 vec_safe_push (new_params, new_adj);
5330 }
5331 }
5332 bool skip_return = old_adjustments->m_skip_return;
5333 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
5334 ipa_param_adjustments (new_params, count,
5335 skip_return));
5336 }
5337 else if (node->can_change_signature
5338 && want_remove_some_param_p (node, known_csts))
5339 {
5340 ipa_adjusted_param adj;
5341 memset (&adj, 0, sizeof (adj));
5342 adj.op = IPA_PARAM_OP_COPY;
5343 for (i = 0; i < count; i++)
5344 if (!known_csts[i] && ipa_is_param_used (info, i))
5345 {
5346 adj.base_index = i;
5347 adj.prev_clone_index = i;
5348 vec_safe_push (new_params, adj);
5349 }
5350 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
5351 ipa_param_adjustments (new_params, count, false));
5352 }
5353 else
5354 new_adjustments = NULL;
5355
5356 auto_vec<cgraph_edge *, 2> self_recursive_calls;
5357 for (i = callers.length () - 1; i >= 0; i--)
5358 {
5359 cgraph_edge *cs = callers[i];
5360 if (cs->caller == node)
5361 {
5362 self_recursive_calls.safe_push (cs);
5363 callers.unordered_remove (i);
5364 }
5365 }
5366 replace_trees = cinfo ? vec_safe_copy (cinfo->tree_map) : NULL;
5367 for (i = 0; i < count; i++)
5368 {
5369 tree t = known_csts[i];
5370 if (!t)
5371 continue;
5372
5373 gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
5374
5375 bool load_ref = false;
5376 symtab_node *ref_symbol;
5377 if (TREE_CODE (t) == ADDR_EXPR)
5378 {
5379 tree base = get_base_address (TREE_OPERAND (t, 0));
5380 if (TREE_CODE (base) == VAR_DECL
5381 && ipa_get_controlled_uses (info, i) == 0
5382 && ipa_get_param_load_dereferenced (info, i)
5383 && (ref_symbol = symtab_node::get (base)))
5384 {
5385 load_ref = true;
5386 if (node->can_change_signature)
5387 for (cgraph_edge *caller : callers)
5388 adjust_references_in_caller (caller, ref_symbol, i);
5389 }
5390 }
5391
5392 ipa_replace_map *replace_map = get_replacement_map (info, t, i, load_ref);
5393 if (replace_map)
5394 vec_safe_push (replace_trees, replace_map);
5395 }
5396
5397 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
5398 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
5399 node->decl)));
5400 new_node = node->create_virtual_clone (callers, replace_trees,
5401 new_adjustments, "constprop",
5402 suffix_counter);
5403 suffix_counter++;
5404
5405 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
5406 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
5407 {
5408 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
5409 /* Cloned edges can disappear during cloning as speculation can be
5410 resolved, check that we have one and that it comes from the last
5411 cloning. */
5412 if (cs && cs->caller == new_node)
5413 cs->redirect_callee_duplicating_thunks (new_node);
5414 /* Any future code that would make more than one clone of an outgoing
5415 edge would confuse this mechanism, so let's check that does not
5416 happen. */
5417 gcc_checking_assert (!cs
5418 || !get_next_cgraph_edge_clone (cs)
5419 || get_next_cgraph_edge_clone (cs)->caller != new_node);
5420 }
5421 if (have_self_recursive_calls)
5422 new_node->expand_all_artificial_thunks ();
5423
5424 ipa_set_node_agg_value_chain (new_node, aggvals);
5425 for (const ipa_argagg_value &av : aggvals)
5426 new_node->maybe_create_reference (av.value, NULL);
5427
5428 if (dump_file && (dump_flags & TDF_DETAILS))
5429 {
5430 fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ());
5431 if (known_contexts.exists ())
5432 {
5433 for (i = 0; i < count; i++)
5434 if (!known_contexts[i].useless_p ())
5435 {
5436 fprintf (dump_file, " known ctx %i is ", i);
5437 known_contexts[i].dump (dump_file);
5438 }
5439 }
5440 if (aggvals)
5441 {
5442 fprintf (dump_file, " Aggregate replacements:");
5443 ipa_argagg_value_list avs (aggvals);
5444 avs.dump (dump_file);
5445 }
5446 }
5447
5448 new_info = ipa_node_params_sum->get (new_node);
5449 new_info->ipcp_orig_node = node;
5450 new_node->ipcp_clone = true;
5451 new_info->known_csts = known_csts;
5452 new_info->known_contexts = known_contexts;
5453
5454 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts,
5455 aggvals);
5456
5457 return new_node;
5458 }
5459
5460 /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
5461 pass-through function to itself when the cgraph_node involved is not an
5462 IPA-CP clone. When SIMPLE is true, further check if JFUNC is a simple
5463 no-operation pass-through. */
5464
5465 static bool
5466 self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
5467 bool simple = true)
5468 {
5469 enum availability availability;
5470 if (cs->caller == cs->callee->function_symbol (&availability)
5471 && availability > AVAIL_INTERPOSABLE
5472 && jfunc->type == IPA_JF_PASS_THROUGH
5473 && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
5474 && ipa_get_jf_pass_through_formal_id (jfunc) == i
5475 && ipa_node_params_sum->get (cs->caller)
5476 && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node)
5477 return true;
5478 return false;
5479 }
5480
5481 /* Return true if JFUNC, which describes a part of an aggregate represented or
5482 pointed to by the i-th parameter of call CS, is a pass-through function to
5483 itself when the cgraph_node involved is not an IPA-CP clone.. When
5484 SIMPLE is true, further check if JFUNC is a simple no-operation
5485 pass-through. */
5486
5487 static bool
5488 self_recursive_agg_pass_through_p (const cgraph_edge *cs,
5489 const ipa_agg_jf_item *jfunc,
5490 int i, bool simple = true)
5491 {
5492 enum availability availability;
5493 if (cs->caller == cs->callee->function_symbol (&availability)
5494 && availability > AVAIL_INTERPOSABLE
5495 && jfunc->jftype == IPA_JF_LOAD_AGG
5496 && jfunc->offset == jfunc->value.load_agg.offset
5497 && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
5498 && jfunc->value.pass_through.formal_id == i
5499 && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)
5500 && ipa_node_params_sum->get (cs->caller)
5501 && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node)
5502 return true;
5503 return false;
5504 }
5505
5506 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
5507 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
5508
5509 static void
5510 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
5511 vec<tree> &known_csts,
5512 const vec<cgraph_edge *> &callers)
5513 {
5514 ipa_node_params *info = ipa_node_params_sum->get (node);
5515 int i, count = ipa_get_param_count (info);
5516
5517 for (i = 0; i < count; i++)
5518 {
5519 struct cgraph_edge *cs;
5520 tree newval = NULL_TREE;
5521 int j;
5522 bool first = true;
5523 tree type = ipa_get_type (info, i);
5524
5525 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
5526 continue;
5527
5528 FOR_EACH_VEC_ELT (callers, j, cs)
5529 {
5530 struct ipa_jump_func *jump_func;
5531 tree t;
5532
5533 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
5534 if (!args
5535 || i >= ipa_get_cs_argument_count (args)
5536 || (i == 0
5537 && call_passes_through_thunk (cs)))
5538 {
5539 newval = NULL_TREE;
5540 break;
5541 }
5542 jump_func = ipa_get_ith_jump_func (args, i);
5543
5544 /* Besides simple pass-through jump function, arithmetic jump
5545 function could also introduce argument-direct-pass-through for
5546 self-feeding recursive call. For example,
5547
5548 fn (int i)
5549 {
5550 fn (i & 1);
5551 }
5552
5553 Given that i is 0, recursive propagation via (i & 1) also gets
5554 0. */
5555 if (self_recursive_pass_through_p (cs, jump_func, i, false))
5556 {
5557 gcc_assert (newval);
5558 t = ipa_get_jf_arith_result (
5559 ipa_get_jf_pass_through_operation (jump_func),
5560 newval,
5561 ipa_get_jf_pass_through_operand (jump_func),
5562 type);
5563 }
5564 else
5565 t = ipa_value_from_jfunc (ipa_node_params_sum->get (cs->caller),
5566 jump_func, type);
5567 if (!t
5568 || (newval
5569 && !values_equal_for_ipcp_p (t, newval))
5570 || (!first && !newval))
5571 {
5572 newval = NULL_TREE;
5573 break;
5574 }
5575 else
5576 newval = t;
5577 first = false;
5578 }
5579
5580 if (newval)
5581 {
5582 if (dump_file && (dump_flags & TDF_DETAILS))
5583 {
5584 fprintf (dump_file, " adding an extra known scalar value ");
5585 print_ipcp_constant_value (dump_file, newval);
5586 fprintf (dump_file, " for ");
5587 ipa_dump_param (dump_file, info, i);
5588 fprintf (dump_file, "\n");
5589 }
5590
5591 known_csts[i] = newval;
5592 }
5593 }
5594 }
5595
5596 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
5597 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
5598 CALLERS. */
5599
5600 static void
5601 find_more_contexts_for_caller_subset (cgraph_node *node,
5602 vec<ipa_polymorphic_call_context>
5603 *known_contexts,
5604 const vec<cgraph_edge *> &callers)
5605 {
5606 ipa_node_params *info = ipa_node_params_sum->get (node);
5607 int i, count = ipa_get_param_count (info);
5608
5609 for (i = 0; i < count; i++)
5610 {
5611 cgraph_edge *cs;
5612
5613 if (ipa_get_poly_ctx_lat (info, i)->bottom
5614 || (known_contexts->exists ()
5615 && !(*known_contexts)[i].useless_p ()))
5616 continue;
5617
5618 ipa_polymorphic_call_context newval;
5619 bool first = true;
5620 int j;
5621
5622 FOR_EACH_VEC_ELT (callers, j, cs)
5623 {
5624 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
5625 if (!args
5626 || i >= ipa_get_cs_argument_count (args))
5627 return;
5628 ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
5629 ipa_polymorphic_call_context ctx;
5630 ctx = ipa_context_from_jfunc (ipa_node_params_sum->get (cs->caller),
5631 cs, i, jfunc);
5632 if (first)
5633 {
5634 newval = ctx;
5635 first = false;
5636 }
5637 else
5638 newval.meet_with (ctx);
5639 if (newval.useless_p ())
5640 break;
5641 }
5642
5643 if (!newval.useless_p ())
5644 {
5645 if (dump_file && (dump_flags & TDF_DETAILS))
5646 {
5647 fprintf (dump_file, " adding an extra known polymorphic "
5648 "context ");
5649 print_ipcp_constant_value (dump_file, newval);
5650 fprintf (dump_file, " for ");
5651 ipa_dump_param (dump_file, info, i);
5652 fprintf (dump_file, "\n");
5653 }
5654
5655 if (!known_contexts->exists ())
5656 known_contexts->safe_grow_cleared (ipa_get_param_count (info),
5657 true);
5658 (*known_contexts)[i] = newval;
5659 }
5660
5661 }
5662 }
5663
5664 /* Push all aggregate values coming along edge CS for parameter number INDEX to
5665 RES. If INTERIM is non-NULL, it contains the current interim state of
5666 collected aggregate values which can be used to compute values passed over
5667 self-recursive edges.
5668
5669 This basically one iteration of push_agg_values_from_edge over one
5670 parameter, which allows for simpler early returns. */
5671
5672 static void
5673 push_agg_values_for_index_from_edge (struct cgraph_edge *cs, int index,
5674 vec<ipa_argagg_value> *res,
5675 const ipa_argagg_value_list *interim)
5676 {
5677 bool agg_values_from_caller = false;
5678 bool agg_jf_preserved = false;
5679 unsigned unit_delta = UINT_MAX;
5680 int src_idx = -1;
5681 ipa_jump_func *jfunc = ipa_get_ith_jump_func (ipa_edge_args_sum->get (cs),
5682 index);
5683
5684 if (jfunc->type == IPA_JF_PASS_THROUGH
5685 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
5686 {
5687 agg_values_from_caller = true;
5688 agg_jf_preserved = ipa_get_jf_pass_through_agg_preserved (jfunc);
5689 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
5690 unit_delta = 0;
5691 }
5692 else if (jfunc->type == IPA_JF_ANCESTOR
5693 && ipa_get_jf_ancestor_agg_preserved (jfunc))
5694 {
5695 agg_values_from_caller = true;
5696 agg_jf_preserved = true;
5697 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
5698 unit_delta = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
5699 }
5700
5701 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
5702 if (agg_values_from_caller)
5703 {
5704 if (caller_info->ipcp_orig_node)
5705 {
5706 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
5707 ipcp_transformation *ts
5708 = ipcp_get_transformation_summary (cs->caller);
5709 ipa_node_params *orig_info = ipa_node_params_sum->get (orig_node);
5710 ipcp_param_lattices *orig_plats
5711 = ipa_get_parm_lattices (orig_info, src_idx);
5712 if (ts
5713 && orig_plats->aggs
5714 && (agg_jf_preserved || !orig_plats->aggs_by_ref))
5715 {
5716 ipa_argagg_value_list src (ts);
5717 src.push_adjusted_values (src_idx, index, unit_delta, res);
5718 return;
5719 }
5720 }
5721 else
5722 {
5723 ipcp_param_lattices *src_plats
5724 = ipa_get_parm_lattices (caller_info, src_idx);
5725 if (src_plats->aggs
5726 && !src_plats->aggs_bottom
5727 && (agg_jf_preserved || !src_plats->aggs_by_ref))
5728 {
5729 if (interim && self_recursive_pass_through_p (cs, jfunc, index))
5730 {
5731 interim->push_adjusted_values (src_idx, index, unit_delta,
5732 res);
5733 return;
5734 }
5735 if (!src_plats->aggs_contain_variable)
5736 {
5737 push_agg_values_from_plats (src_plats, index, unit_delta,
5738 res);
5739 return;
5740 }
5741 }
5742 }
5743 }
5744
5745 if (!jfunc->agg.items)
5746 return;
5747 bool first = true;
5748 unsigned prev_unit_offset = 0;
5749 for (const ipa_agg_jf_item &agg_jf : *jfunc->agg.items)
5750 {
5751 tree value, srcvalue;
5752 /* Besides simple pass-through aggregate jump function, arithmetic
5753 aggregate jump function could also bring same aggregate value as
5754 parameter passed-in for self-feeding recursive call. For example,
5755
5756 fn (int *i)
5757 {
5758 int j = *i & 1;
5759 fn (&j);
5760 }
5761
5762 Given that *i is 0, recursive propagation via (*i & 1) also gets 0. */
5763 if (interim
5764 && self_recursive_agg_pass_through_p (cs, &agg_jf, index, false)
5765 && (srcvalue = interim->get_value(index,
5766 agg_jf.offset / BITS_PER_UNIT)))
5767 value = ipa_get_jf_arith_result (agg_jf.value.pass_through.operation,
5768 srcvalue,
5769 agg_jf.value.pass_through.operand,
5770 agg_jf.type);
5771 else
5772 value = ipa_agg_value_from_jfunc (caller_info, cs->caller,
5773 &agg_jf);
5774 if (value)
5775 {
5776 struct ipa_argagg_value iav;
5777 iav.value = value;
5778 iav.unit_offset = agg_jf.offset / BITS_PER_UNIT;
5779 iav.index = index;
5780 iav.by_ref = jfunc->agg.by_ref;
5781
5782 gcc_assert (first
5783 || iav.unit_offset > prev_unit_offset);
5784 prev_unit_offset = iav.unit_offset;
5785 first = false;
5786
5787 res->safe_push (iav);
5788 }
5789 }
5790 return;
5791 }
5792
5793 /* Push all aggregate values coming along edge CS to RES. DEST_INFO is the
5794 description of ultimate callee of CS or the one it was cloned from (the
5795 summary where lattices are). If INTERIM is non-NULL, it contains the
5796 current interim state of collected aggregate values which can be used to
5797 compute values passed over self-recursive edges (if OPTIMIZE_SELF_RECURSION
5798 is true) and to skip values which clearly will not be part of intersection
5799 with INTERIM. */
5800
5801 static void
5802 push_agg_values_from_edge (struct cgraph_edge *cs,
5803 ipa_node_params *dest_info,
5804 vec<ipa_argagg_value> *res,
5805 const ipa_argagg_value_list *interim,
5806 bool optimize_self_recursion)
5807 {
5808 ipa_edge_args *args = ipa_edge_args_sum->get (cs);
5809 if (!args)
5810 return;
5811
5812 int count = MIN (ipa_get_param_count (dest_info),
5813 ipa_get_cs_argument_count (args));
5814
5815 unsigned interim_index = 0;
5816 for (int index = 0; index < count; index++)
5817 {
5818 if (interim)
5819 {
5820 while (interim_index < interim->m_elts.size ()
5821 && interim->m_elts[interim_index].value
5822 && interim->m_elts[interim_index].index < index)
5823 interim_index++;
5824 if (interim_index >= interim->m_elts.size ()
5825 || interim->m_elts[interim_index].index > index)
5826 continue;
5827 }
5828
5829 ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, index);
5830 if (!ipa_is_param_used (dest_info, index)
5831 || plats->aggs_bottom)
5832 continue;
5833 push_agg_values_for_index_from_edge (cs, index, res,
5834 optimize_self_recursion ? interim
5835 : NULL);
5836 }
5837 }
5838
5839
5840 /* Look at edges in CALLERS and collect all known aggregate values that arrive
5841 from all of them. Return nullptr if there are none. */
5842
5843 static struct vec<ipa_argagg_value, va_gc> *
5844 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
5845 const vec<cgraph_edge *> &callers)
5846 {
5847 ipa_node_params *dest_info = ipa_node_params_sum->get (node);
5848 if (dest_info->ipcp_orig_node)
5849 dest_info = ipa_node_params_sum->get (dest_info->ipcp_orig_node);
5850
5851 /* gather_edges_for_value puts a non-recursive call into the first element of
5852 callers if it can. */
5853 auto_vec<ipa_argagg_value, 32> interim;
5854 push_agg_values_from_edge (callers[0], dest_info, &interim, NULL, true);
5855
5856 unsigned valid_entries = interim.length ();
5857 if (!valid_entries)
5858 return nullptr;
5859
5860 unsigned caller_count = callers.length();
5861 for (unsigned i = 1; i < caller_count; i++)
5862 {
5863 auto_vec<ipa_argagg_value, 32> last;
5864 ipa_argagg_value_list avs (&interim);
5865 push_agg_values_from_edge (callers[i], dest_info, &last, &avs, true);
5866
5867 valid_entries = intersect_argaggs_with (interim, last);
5868 if (!valid_entries)
5869 return nullptr;
5870 }
5871
5872 vec<ipa_argagg_value, va_gc> *res = NULL;
5873 vec_safe_reserve_exact (res, valid_entries);
5874 for (const ipa_argagg_value &av : interim)
5875 if (av.value)
5876 res->quick_push(av);
5877 gcc_checking_assert (res->length () == valid_entries);
5878 return res;
5879 }
5880
5881 /* Determine whether CS also brings all scalar values that the NODE is
5882 specialized for. */
5883
5884 static bool
5885 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
5886 struct cgraph_node *node)
5887 {
5888 ipa_node_params *dest_info = ipa_node_params_sum->get (node);
5889 int count = ipa_get_param_count (dest_info);
5890 class ipa_node_params *caller_info;
5891 class ipa_edge_args *args;
5892 int i;
5893
5894 caller_info = ipa_node_params_sum->get (cs->caller);
5895 args = ipa_edge_args_sum->get (cs);
5896 for (i = 0; i < count; i++)
5897 {
5898 struct ipa_jump_func *jump_func;
5899 tree val, t;
5900
5901 val = dest_info->known_csts[i];
5902 if (!val)
5903 continue;
5904
5905 if (i >= ipa_get_cs_argument_count (args))
5906 return false;
5907 jump_func = ipa_get_ith_jump_func (args, i);
5908 t = ipa_value_from_jfunc (caller_info, jump_func,
5909 ipa_get_type (dest_info, i));
5910 if (!t || !values_equal_for_ipcp_p (val, t))
5911 return false;
5912 }
5913 return true;
5914 }
5915
5916 /* Determine whether CS also brings all aggregate values that NODE is
5917 specialized for. */
5918
5919 static bool
5920 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
5921 struct cgraph_node *node)
5922 {
5923 ipcp_transformation *ts = ipcp_get_transformation_summary (node);
5924 if (!ts || vec_safe_is_empty (ts->m_agg_values))
5925 return true;
5926
5927 const ipa_argagg_value_list existing (ts->m_agg_values);
5928 auto_vec<ipa_argagg_value, 32> edge_values;
5929 ipa_node_params *dest_info = ipa_node_params_sum->get (node);
5930 gcc_checking_assert (dest_info->ipcp_orig_node);
5931 dest_info = ipa_node_params_sum->get (dest_info->ipcp_orig_node);
5932 push_agg_values_from_edge (cs, dest_info, &edge_values, &existing, false);
5933 const ipa_argagg_value_list avl (&edge_values);
5934 return avl.superset_of_p (existing);
5935 }
5936
5937 /* Given an original NODE and a VAL for which we have already created a
5938 specialized clone, look whether there are incoming edges that still lead
5939 into the old node but now also bring the requested value and also conform to
5940 all other criteria such that they can be redirected the special node.
5941 This function can therefore redirect the final edge in a SCC. */
5942
5943 template <typename valtype>
5944 static void
5945 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
5946 {
5947 ipcp_value_source<valtype> *src;
5948 profile_count redirected_sum = profile_count::zero ();
5949
5950 for (src = val->sources; src; src = src->next)
5951 {
5952 struct cgraph_edge *cs = src->cs;
5953 while (cs)
5954 {
5955 if (cgraph_edge_brings_value_p (cs, src, node, val)
5956 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
5957 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
5958 {
5959 if (dump_file)
5960 fprintf (dump_file, " - adding an extra caller %s of %s\n",
5961 cs->caller->dump_name (),
5962 val->spec_node->dump_name ());
5963
5964 cs->redirect_callee_duplicating_thunks (val->spec_node);
5965 val->spec_node->expand_all_artificial_thunks ();
5966 if (cs->count.ipa ().initialized_p ())
5967 redirected_sum = redirected_sum + cs->count.ipa ();
5968 }
5969 cs = get_next_cgraph_edge_clone (cs);
5970 }
5971 }
5972
5973 if (redirected_sum.nonzero_p ())
5974 update_specialized_profile (val->spec_node, node, redirected_sum);
5975 }
5976
5977 /* Return true if KNOWN_CONTEXTS contain at least one useful context. */
5978
5979 static bool
5980 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
5981 {
5982 ipa_polymorphic_call_context *ctx;
5983 int i;
5984
5985 FOR_EACH_VEC_ELT (known_contexts, i, ctx)
5986 if (!ctx->useless_p ())
5987 return true;
5988 return false;
5989 }
5990
5991 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5992
5993 static vec<ipa_polymorphic_call_context>
5994 copy_useful_known_contexts (const vec<ipa_polymorphic_call_context> &known_contexts)
5995 {
5996 if (known_contexts_useful_p (known_contexts))
5997 return known_contexts.copy ();
5998 else
5999 return vNULL;
6000 }
6001
6002 /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
6003 according to VAL and INDEX. If non-empty, replace KNOWN_CONTEXTS with its
6004 copy too. */
6005
6006 static void
6007 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
6008 vec<tree> *known_csts,
6009 vec<ipa_polymorphic_call_context> *known_contexts,
6010 ipcp_value<tree> *val, int index)
6011 {
6012 *known_csts = avals->m_known_vals.copy ();
6013 *known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
6014 (*known_csts)[index] = val->value;
6015 }
6016
6017 /* Copy known scalar values from AVALS into KNOWN_CSTS. Similarly, copy
6018 contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
6019 INDEX. */
6020
6021 static void
6022 copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
6023 vec<tree> *known_csts,
6024 vec<ipa_polymorphic_call_context> *known_contexts,
6025 ipcp_value<ipa_polymorphic_call_context> *val,
6026 int index)
6027 {
6028 *known_csts = avals->m_known_vals.copy ();
6029 *known_contexts = avals->m_known_contexts.copy ();
6030 (*known_contexts)[index] = val->value;
6031 }
6032
6033 /* Return true if OFFSET indicates this was not an aggregate value or there is
6034 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
6035 AGGVALS list. */
6036
6037 DEBUG_FUNCTION bool
6038 ipcp_val_agg_replacement_ok_p (vec<ipa_argagg_value, va_gc> *aggvals,
6039 int index, HOST_WIDE_INT offset, tree value)
6040 {
6041 if (offset == -1)
6042 return true;
6043
6044 const ipa_argagg_value_list avl (aggvals);
6045 tree v = avl.get_value (index, offset / BITS_PER_UNIT);
6046 return v && values_equal_for_ipcp_p (v, value);
6047 }
6048
6049 /* Return true if offset is minus one because source of a polymorphic context
6050 cannot be an aggregate value. */
6051
6052 DEBUG_FUNCTION bool
6053 ipcp_val_agg_replacement_ok_p (vec<ipa_argagg_value, va_gc> *,
6054 int , HOST_WIDE_INT offset,
6055 ipa_polymorphic_call_context)
6056 {
6057 return offset == -1;
6058 }
6059
6060 /* Decide whether to create a special version of NODE for value VAL of
6061 parameter at the given INDEX. If OFFSET is -1, the value is for the
6062 parameter itself, otherwise it is stored at the given OFFSET of the
6063 parameter. AVALS describes the other already known values. SELF_GEN_CLONES
6064 is a vector which contains clones created for self-recursive calls with an
6065 arithmetic pass-through jump function. */
6066
6067 template <typename valtype>
6068 static bool
6069 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
6070 ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals,
6071 vec<cgraph_node *> *self_gen_clones)
6072 {
6073 int caller_count;
6074 sreal freq_sum;
6075 profile_count count_sum, rec_count_sum;
6076 vec<cgraph_edge *> callers;
6077
6078 if (val->spec_node)
6079 {
6080 perhaps_add_new_callers (node, val);
6081 return false;
6082 }
6083 else if (val->local_size_cost + overall_size > get_max_overall_size (node))
6084 {
6085 if (dump_file && (dump_flags & TDF_DETAILS))
6086 fprintf (dump_file, " Ignoring candidate value because "
6087 "maximum unit size would be reached with %li.\n",
6088 val->local_size_cost + overall_size);
6089 return false;
6090 }
6091 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &caller_count,
6092 &rec_count_sum, &count_sum))
6093 return false;
6094
6095 if (!dbg_cnt (ipa_cp_values))
6096 return false;
6097
6098 if (val->self_recursion_generated_p ())
6099 {
6100 /* The edge counts in this case might not have been adjusted yet.
6101 Nevertleless, even if they were it would be only a guesswork which we
6102 can do now. The recursive part of the counts can be derived from the
6103 count of the original node anyway. */
6104 if (node->count.ipa ().nonzero_p ())
6105 {
6106 unsigned dem = self_gen_clones->length () + 1;
6107 rec_count_sum = node->count.ipa () / dem;
6108 }
6109 else
6110 rec_count_sum = profile_count::zero ();
6111 }
6112
6113 /* get_info_about_necessary_edges only sums up ipa counts. */
6114 count_sum += rec_count_sum;
6115
6116 if (dump_file && (dump_flags & TDF_DETAILS))
6117 {
6118 fprintf (dump_file, " - considering value ");
6119 print_ipcp_constant_value (dump_file, val->value);
6120 fprintf (dump_file, " for ");
6121 ipa_dump_param (dump_file, ipa_node_params_sum->get (node), index);
6122 if (offset != -1)
6123 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
6124 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
6125 }
6126
6127 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
6128 freq_sum, count_sum,
6129 val->local_size_cost)
6130 && !good_cloning_opportunity_p (node, val->prop_time_benefit,
6131 freq_sum, count_sum, val->prop_size_cost))
6132 return false;
6133
6134 if (dump_file)
6135 fprintf (dump_file, " Creating a specialized node of %s.\n",
6136 node->dump_name ());
6137
6138 vec<tree> known_csts;
6139 vec<ipa_polymorphic_call_context> known_contexts;
6140
6141 callers = gather_edges_for_value (val, node, caller_count);
6142 if (offset == -1)
6143 copy_known_vectors_add_val (avals, &known_csts, &known_contexts, val, index);
6144 else
6145 {
6146 known_csts = avals->m_known_vals.copy ();
6147 known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
6148 }
6149 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
6150 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
6151 vec<ipa_argagg_value, va_gc> *aggvals
6152 = find_aggregate_values_for_callers_subset (node, callers);
6153 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
6154 offset, val->value));
6155 val->spec_node = create_specialized_node (node, known_csts, known_contexts,
6156 aggvals, callers);
6157
6158 if (val->self_recursion_generated_p ())
6159 self_gen_clones->safe_push (val->spec_node);
6160 else
6161 update_profiling_info (node, val->spec_node);
6162
6163 callers.release ();
6164 overall_size += val->local_size_cost;
6165 if (dump_file && (dump_flags & TDF_DETAILS))
6166 fprintf (dump_file, " overall size reached %li\n",
6167 overall_size);
6168
6169 /* TODO: If for some lattice there is only one other known value
6170 left, make a special node for it too. */
6171
6172 return true;
6173 }
6174
6175 /* Decide whether and what specialized clones of NODE should be created. */
6176
6177 static bool
6178 decide_whether_version_node (struct cgraph_node *node)
6179 {
6180 ipa_node_params *info = ipa_node_params_sum->get (node);
6181 int i, count = ipa_get_param_count (info);
6182 bool ret = false;
6183
6184 if (count == 0)
6185 return false;
6186
6187 if (dump_file && (dump_flags & TDF_DETAILS))
6188 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
6189 node->dump_name ());
6190
6191 auto_vec <cgraph_node *, 9> self_gen_clones;
6192 ipa_auto_call_arg_values avals;
6193 gather_context_independent_values (info, &avals, false, NULL);
6194
6195 for (i = 0; i < count;i++)
6196 {
6197 if (!ipa_is_param_used (info, i))
6198 continue;
6199
6200 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
6201 ipcp_lattice<tree> *lat = &plats->itself;
6202 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
6203
6204 if (!lat->bottom
6205 && !avals.m_known_vals[i])
6206 {
6207 ipcp_value<tree> *val;
6208 for (val = lat->values; val; val = val->next)
6209 {
6210 /* If some values generated for self-recursive calls with
6211 arithmetic jump functions fall outside of the known
6212 value_range for the parameter, we can skip them. VR interface
6213 supports this only for integers now. */
6214 if (TREE_CODE (val->value) == INTEGER_CST
6215 && !plats->m_value_range.bottom_p ()
6216 && !plats->m_value_range.m_vr.contains_p (val->value))
6217 {
6218 /* This can happen also if a constant present in the source
6219 code falls outside of the range of parameter's type, so we
6220 cannot assert. */
6221 if (dump_file && (dump_flags & TDF_DETAILS))
6222 {
6223 fprintf (dump_file, " - skipping%s value ",
6224 val->self_recursion_generated_p ()
6225 ? " self_recursion_generated" : "");
6226 print_ipcp_constant_value (dump_file, val->value);
6227 fprintf (dump_file, " because it is outside known "
6228 "value range.\n");
6229 }
6230 continue;
6231 }
6232 ret |= decide_about_value (node, i, -1, val, &avals,
6233 &self_gen_clones);
6234 }
6235 }
6236
6237 if (!plats->aggs_bottom)
6238 {
6239 struct ipcp_agg_lattice *aglat;
6240 ipcp_value<tree> *val;
6241 for (aglat = plats->aggs; aglat; aglat = aglat->next)
6242 if (!aglat->bottom && aglat->values
6243 /* If the following is false, the one value has been considered
6244 for cloning for all contexts. */
6245 && (plats->aggs_contain_variable
6246 || !aglat->is_single_const ()))
6247 for (val = aglat->values; val; val = val->next)
6248 ret |= decide_about_value (node, i, aglat->offset, val, &avals,
6249 &self_gen_clones);
6250 }
6251
6252 if (!ctxlat->bottom
6253 && avals.m_known_contexts[i].useless_p ())
6254 {
6255 ipcp_value<ipa_polymorphic_call_context> *val;
6256 for (val = ctxlat->values; val; val = val->next)
6257 ret |= decide_about_value (node, i, -1, val, &avals,
6258 &self_gen_clones);
6259 }
6260 }
6261
6262 if (!self_gen_clones.is_empty ())
6263 {
6264 self_gen_clones.safe_push (node);
6265 update_counts_for_self_gen_clones (node, self_gen_clones);
6266 }
6267
6268 if (info->do_clone_for_all_contexts)
6269 {
6270 if (!dbg_cnt (ipa_cp_values))
6271 {
6272 info->do_clone_for_all_contexts = false;
6273 return ret;
6274 }
6275
6276 struct cgraph_node *clone;
6277 auto_vec<cgraph_edge *> callers = node->collect_callers ();
6278
6279 for (int i = callers.length () - 1; i >= 0; i--)
6280 {
6281 cgraph_edge *cs = callers[i];
6282 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
6283
6284 if (caller_info && caller_info->node_dead)
6285 callers.unordered_remove (i);
6286 }
6287
6288 if (!adjust_callers_for_value_intersection (callers, node))
6289 {
6290 /* If node is not called by anyone, or all its caller edges are
6291 self-recursive, the node is not really in use, no need to do
6292 cloning. */
6293 info->do_clone_for_all_contexts = false;
6294 return ret;
6295 }
6296
6297 if (dump_file)
6298 fprintf (dump_file, " - Creating a specialized node of %s "
6299 "for all known contexts.\n", node->dump_name ());
6300
6301 vec<tree> known_csts = avals.m_known_vals.copy ();
6302 vec<ipa_polymorphic_call_context> known_contexts
6303 = copy_useful_known_contexts (avals.m_known_contexts);
6304 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
6305 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
6306 vec<ipa_argagg_value, va_gc> *aggvals
6307 = find_aggregate_values_for_callers_subset (node, callers);
6308
6309 if (!known_contexts_useful_p (known_contexts))
6310 {
6311 known_contexts.release ();
6312 known_contexts = vNULL;
6313 }
6314 clone = create_specialized_node (node, known_csts, known_contexts,
6315 aggvals, callers);
6316 info->do_clone_for_all_contexts = false;
6317 ipa_node_params_sum->get (clone)->is_all_contexts_clone = true;
6318 ret = true;
6319 }
6320
6321 return ret;
6322 }
6323
6324 /* Transitively mark all callees of NODE within the same SCC as not dead. */
6325
6326 static void
6327 spread_undeadness (struct cgraph_node *node)
6328 {
6329 struct cgraph_edge *cs;
6330
6331 for (cs = node->callees; cs; cs = cs->next_callee)
6332 if (ipa_edge_within_scc (cs))
6333 {
6334 struct cgraph_node *callee;
6335 class ipa_node_params *info;
6336
6337 callee = cs->callee->function_symbol (NULL);
6338 info = ipa_node_params_sum->get (callee);
6339
6340 if (info && info->node_dead)
6341 {
6342 info->node_dead = 0;
6343 spread_undeadness (callee);
6344 }
6345 }
6346 }
6347
6348 /* Return true if NODE has a caller from outside of its SCC that is not
6349 dead. Worker callback for cgraph_for_node_and_aliases. */
6350
6351 static bool
6352 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
6353 void *data ATTRIBUTE_UNUSED)
6354 {
6355 struct cgraph_edge *cs;
6356
6357 for (cs = node->callers; cs; cs = cs->next_caller)
6358 if (cs->caller->thunk
6359 && cs->caller->call_for_symbol_thunks_and_aliases
6360 (has_undead_caller_from_outside_scc_p, NULL, true))
6361 return true;
6362 else if (!ipa_edge_within_scc (cs))
6363 {
6364 ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
6365 if (!caller_info /* Unoptimized caller are like dead ones. */
6366 || !caller_info->node_dead)
6367 return true;
6368 }
6369 return false;
6370 }
6371
6372
6373 /* Identify nodes within the same SCC as NODE which are no longer needed
6374 because of new clones and will be removed as unreachable. */
6375
6376 static void
6377 identify_dead_nodes (struct cgraph_node *node)
6378 {
6379 struct cgraph_node *v;
6380 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
6381 if (v->local)
6382 {
6383 ipa_node_params *info = ipa_node_params_sum->get (v);
6384 if (info
6385 && !v->call_for_symbol_thunks_and_aliases
6386 (has_undead_caller_from_outside_scc_p, NULL, true))
6387 info->node_dead = 1;
6388 }
6389
6390 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
6391 {
6392 ipa_node_params *info = ipa_node_params_sum->get (v);
6393 if (info && !info->node_dead)
6394 spread_undeadness (v);
6395 }
6396
6397 if (dump_file && (dump_flags & TDF_DETAILS))
6398 {
6399 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
6400 if (ipa_node_params_sum->get (v)
6401 && ipa_node_params_sum->get (v)->node_dead)
6402 fprintf (dump_file, " Marking node as dead: %s.\n",
6403 v->dump_name ());
6404 }
6405 }
6406
6407 /* The decision stage. Iterate over the topological order of call graph nodes
6408 TOPO and make specialized clones if deemed beneficial. */
6409
6410 static void
6411 ipcp_decision_stage (class ipa_topo_info *topo)
6412 {
6413 int i;
6414
6415 if (dump_file)
6416 fprintf (dump_file, "\nIPA decision stage:\n\n");
6417
6418 for (i = topo->nnodes - 1; i >= 0; i--)
6419 {
6420 struct cgraph_node *node = topo->order[i];
6421 bool change = false, iterate = true;
6422
6423 while (iterate)
6424 {
6425 struct cgraph_node *v;
6426 iterate = false;
6427 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
6428 if (v->has_gimple_body_p ()
6429 && ipcp_versionable_function_p (v))
6430 iterate |= decide_whether_version_node (v);
6431
6432 change |= iterate;
6433 }
6434 if (change)
6435 identify_dead_nodes (node);
6436 }
6437 }
6438
6439 /* Look up all the bits information that we have discovered and copy it over
6440 to the transformation summary. */
6441
6442 static void
6443 ipcp_store_bits_results (void)
6444 {
6445 cgraph_node *node;
6446
6447 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
6448 {
6449 ipa_node_params *info = ipa_node_params_sum->get (node);
6450 bool dumped_sth = false;
6451 bool found_useful_result = false;
6452
6453 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
6454 {
6455 if (dump_file)
6456 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
6457 "; -fipa-bit-cp: disabled.\n",
6458 node->dump_name ());
6459 continue;
6460 }
6461
6462 if (info->ipcp_orig_node)
6463 info = ipa_node_params_sum->get (info->ipcp_orig_node);
6464 if (!info->lattices)
6465 /* Newly expanded artificial thunks do not have lattices. */
6466 continue;
6467
6468 unsigned count = ipa_get_param_count (info);
6469 for (unsigned i = 0; i < count; i++)
6470 {
6471 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
6472 if (plats->bits_lattice.constant_p ())
6473 {
6474 found_useful_result = true;
6475 break;
6476 }
6477 }
6478
6479 if (!found_useful_result)
6480 continue;
6481
6482 ipcp_transformation_initialize ();
6483 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
6484 vec_safe_reserve_exact (ts->bits, count);
6485
6486 for (unsigned i = 0; i < count; i++)
6487 {
6488 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
6489 ipa_bits *jfbits;
6490
6491 if (plats->bits_lattice.constant_p ())
6492 {
6493 jfbits
6494 = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
6495 plats->bits_lattice.get_mask ());
6496 if (!dbg_cnt (ipa_cp_bits))
6497 jfbits = NULL;
6498 }
6499 else
6500 jfbits = NULL;
6501
6502 ts->bits->quick_push (jfbits);
6503 if (!dump_file || !jfbits)
6504 continue;
6505 if (!dumped_sth)
6506 {
6507 fprintf (dump_file, "Propagated bits info for function %s:\n",
6508 node->dump_name ());
6509 dumped_sth = true;
6510 }
6511 fprintf (dump_file, " param %i: value = ", i);
6512 print_hex (jfbits->value, dump_file);
6513 fprintf (dump_file, ", mask = ");
6514 print_hex (jfbits->mask, dump_file);
6515 fprintf (dump_file, "\n");
6516 }
6517 }
6518 }
6519
6520 /* Look up all VR information that we have discovered and copy it over
6521 to the transformation summary. */
6522
6523 static void
6524 ipcp_store_vr_results (void)
6525 {
6526 cgraph_node *node;
6527
6528 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
6529 {
6530 ipa_node_params *info = ipa_node_params_sum->get (node);
6531 bool found_useful_result = false;
6532
6533 if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
6534 {
6535 if (dump_file)
6536 fprintf (dump_file, "Not considering %s for VR discovery "
6537 "and propagate; -fipa-ipa-vrp: disabled.\n",
6538 node->dump_name ());
6539 continue;
6540 }
6541
6542 if (info->ipcp_orig_node)
6543 info = ipa_node_params_sum->get (info->ipcp_orig_node);
6544 if (!info->lattices)
6545 /* Newly expanded artificial thunks do not have lattices. */
6546 continue;
6547
6548 unsigned count = ipa_get_param_count (info);
6549 for (unsigned i = 0; i < count; i++)
6550 {
6551 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
6552 if (!plats->m_value_range.bottom_p ()
6553 && !plats->m_value_range.top_p ())
6554 {
6555 found_useful_result = true;
6556 break;
6557 }
6558 }
6559 if (!found_useful_result)
6560 continue;
6561
6562 ipcp_transformation_initialize ();
6563 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
6564 vec_safe_reserve_exact (ts->m_vr, count);
6565
6566 for (unsigned i = 0; i < count; i++)
6567 {
6568 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
6569 ipa_vr vr;
6570
6571 if (!plats->m_value_range.bottom_p ()
6572 && !plats->m_value_range.top_p ()
6573 && dbg_cnt (ipa_cp_vr))
6574 {
6575 vr.known = true;
6576 vr.type = plats->m_value_range.m_vr.kind ();
6577 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
6578 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
6579 }
6580 else
6581 {
6582 vr.known = false;
6583 vr.type = VR_VARYING;
6584 vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
6585 }
6586 ts->m_vr->quick_push (vr);
6587 }
6588 }
6589 }
6590
6591 /* The IPCP driver. */
6592
6593 static unsigned int
6594 ipcp_driver (void)
6595 {
6596 class ipa_topo_info topo;
6597
6598 if (edge_clone_summaries == NULL)
6599 edge_clone_summaries = new edge_clone_summary_t (symtab);
6600
6601 ipa_check_create_node_params ();
6602 ipa_check_create_edge_args ();
6603 clone_num_suffixes = new hash_map<const char *, unsigned>;
6604
6605 if (dump_file)
6606 {
6607 fprintf (dump_file, "\nIPA structures before propagation:\n");
6608 if (dump_flags & TDF_DETAILS)
6609 ipa_print_all_params (dump_file);
6610 ipa_print_all_jump_functions (dump_file);
6611 }
6612
6613 /* Topological sort. */
6614 build_toporder_info (&topo);
6615 /* Do the interprocedural propagation. */
6616 ipcp_propagate_stage (&topo);
6617 /* Decide what constant propagation and cloning should be performed. */
6618 ipcp_decision_stage (&topo);
6619 /* Store results of bits propagation. */
6620 ipcp_store_bits_results ();
6621 /* Store results of value range propagation. */
6622 ipcp_store_vr_results ();
6623
6624 /* Free all IPCP structures. */
6625 delete clone_num_suffixes;
6626 free_toporder_info (&topo);
6627 delete edge_clone_summaries;
6628 edge_clone_summaries = NULL;
6629 ipa_free_all_structures_after_ipa_cp ();
6630 if (dump_file)
6631 fprintf (dump_file, "\nIPA constant propagation end\n");
6632 return 0;
6633 }
6634
6635 /* Initialization and computation of IPCP data structures. This is the initial
6636 intraprocedural analysis of functions, which gathers information to be
6637 propagated later on. */
6638
6639 static void
6640 ipcp_generate_summary (void)
6641 {
6642 struct cgraph_node *node;
6643
6644 if (dump_file)
6645 fprintf (dump_file, "\nIPA constant propagation start:\n");
6646 ipa_register_cgraph_hooks ();
6647
6648 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
6649 ipa_analyze_node (node);
6650 }
6651
6652 namespace {
6653
6654 const pass_data pass_data_ipa_cp =
6655 {
6656 IPA_PASS, /* type */
6657 "cp", /* name */
6658 OPTGROUP_NONE, /* optinfo_flags */
6659 TV_IPA_CONSTANT_PROP, /* tv_id */
6660 0, /* properties_required */
6661 0, /* properties_provided */
6662 0, /* properties_destroyed */
6663 0, /* todo_flags_start */
6664 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
6665 };
6666
6667 class pass_ipa_cp : public ipa_opt_pass_d
6668 {
6669 public:
6670 pass_ipa_cp (gcc::context *ctxt)
6671 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
6672 ipcp_generate_summary, /* generate_summary */
6673 NULL, /* write_summary */
6674 NULL, /* read_summary */
6675 ipcp_write_transformation_summaries, /*
6676 write_optimization_summary */
6677 ipcp_read_transformation_summaries, /*
6678 read_optimization_summary */
6679 NULL, /* stmt_fixup */
6680 0, /* function_transform_todo_flags_start */
6681 ipcp_transform_function, /* function_transform */
6682 NULL) /* variable_transform */
6683 {}
6684
6685 /* opt_pass methods: */
6686 bool gate (function *) final override
6687 {
6688 /* FIXME: We should remove the optimize check after we ensure we never run
6689 IPA passes when not optimizing. */
6690 return (flag_ipa_cp && optimize) || in_lto_p;
6691 }
6692
6693 unsigned int execute (function *) final override { return ipcp_driver (); }
6694
6695 }; // class pass_ipa_cp
6696
6697 } // anon namespace
6698
6699 ipa_opt_pass_d *
6700 make_pass_ipa_cp (gcc::context *ctxt)
6701 {
6702 return new pass_ipa_cp (ctxt);
6703 }
6704
6705 /* Reset all state within ipa-cp.cc so that we can rerun the compiler
6706 within the same process. For use by toplev::finalize. */
6707
6708 void
6709 ipa_cp_cc_finalize (void)
6710 {
6711 base_count = profile_count::uninitialized ();
6712 overall_size = 0;
6713 orig_overall_size = 0;
6714 ipcp_free_transformation_sum ();
6715 }