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