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