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