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