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