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