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