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