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