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