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