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