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