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