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