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