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