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