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