]> gcc.gnu.org Git - gcc.git/blame - gcc/ipa-cp.c
middle-end: Fix wrong code caused by disagreemed between FRE and access path oracle...
[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)
a0f6a8cb 1853 if (s->cs == cs && s->val == src_val)
310bc633
MJ
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
47772af1
FX
1900 self-feeding recursive function via some kind of pass-through jump
1901 function. */
9b14fc33
FX
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
47772af1 1912 if (!src->val || cs->caller != cs->callee->function_symbol ())
9b14fc33
FX
1913 return false;
1914
47772af1
FX
1915 if (src->val == val)
1916 continue;
1917
9b14fc33
FX
1918 if (!info)
1919 info = IPA_NODE_REF (cs->caller);
1920
1921 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info,
1922 src->index);
42d73fa9 1923 ipcp_lattice<tree> *src_lat;
9b14fc33
FX
1924 ipcp_value<tree> *src_val;
1925
42d73fa9
FX
1926 if (src->offset == -1)
1927 src_lat = &plats->itself;
1928 else
1929 {
1930 struct ipcp_agg_lattice *src_aglat;
1931
1932 for (src_aglat = plats->aggs; src_aglat; src_aglat = src_aglat->next)
1933 if (src_aglat->offset == src->offset)
1934 break;
1935
1936 if (!src_aglat)
1937 return false;
1938
1939 src_lat = src_aglat;
1940 }
1941
9b14fc33
FX
1942 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1943 if (src_val == val)
1944 break;
1945
1946 if (!src_val)
1947 return false;
1948 }
1949
310bc633
MJ
1950 return true;
1951}
fb3f88cc 1952
9b14fc33
FX
1953/* A helper function that returns result of operation specified by OPCODE on
1954 the value of SRC_VAL. If non-NULL, OPND1_TYPE is expected type for the
1955 value of SRC_VAL. If the operation is binary, OPND2 is a constant value
1956 acting as its second operand. If non-NULL, RES_TYPE is expected type of
1957 the result. */
1958
1959static tree
1960get_val_across_arith_op (enum tree_code opcode,
1961 tree opnd1_type,
1962 tree opnd2,
1963 ipcp_value<tree> *src_val,
1964 tree res_type)
1965{
1966 tree opnd1 = src_val->value;
1967
1968 /* Skip source values that is incompatible with specified type. */
1969 if (opnd1_type
1970 && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
1971 return NULL_TREE;
1972
1973 return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
1974}
1975
eb270950
FX
1976/* Propagate values through an arithmetic transformation described by a jump
1977 function associated with edge CS, taking values from SRC_LAT and putting
1978 them into DEST_LAT. OPND1_TYPE is expected type for the values in SRC_LAT.
1979 OPND2 is a constant value if transformation is a binary operation.
1980 SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
1981 a part of the aggregate. SRC_IDX is the index of the source parameter.
1982 RES_TYPE is the value type of result being propagated into. Return true if
1983 DEST_LAT changed. */
310bc633
MJ
1984
1985static bool
eb270950
FX
1986propagate_vals_across_arith_jfunc (cgraph_edge *cs,
1987 enum tree_code opcode,
1988 tree opnd1_type,
1989 tree opnd2,
1990 ipcp_lattice<tree> *src_lat,
1991 ipcp_lattice<tree> *dest_lat,
1992 HOST_WIDE_INT src_offset,
1993 int src_idx,
1994 tree res_type)
310bc633 1995{
c0cb5055 1996 ipcp_value<tree> *src_val;
310bc633
MJ
1997 bool ret = false;
1998
9b14fc33
FX
1999 /* Due to circular dependencies, propagating within an SCC through arithmetic
2000 transformation would create infinite number of values. But for
2001 self-feeding recursive function, we could allow propagation in a limited
2002 count, and this can enable a simple kind of recursive function versioning.
2003 For other scenario, we would just make lattices bottom. */
eb270950 2004 if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
9b14fc33
FX
2005 {
2006 int i;
2007
fdfd7f53
ML
2008 int max_recursive_depth = opt_for_fn(cs->caller->decl,
2009 param_ipa_cp_max_recursive_depth);
2010 if (src_lat != dest_lat || max_recursive_depth < 1)
9b14fc33
FX
2011 return dest_lat->set_contains_variable ();
2012
2013 /* No benefit if recursive execution is in low probability. */
2014 if (cs->sreal_frequency () * 100
fdfd7f53
ML
2015 <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
2016 param_ipa_cp_min_recursive_probability))
9b14fc33
FX
2017 return dest_lat->set_contains_variable ();
2018
2019 auto_vec<ipcp_value<tree> *, 8> val_seeds;
2020
2021 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2022 {
2023 /* Now we do not use self-recursively generated value as propagation
2024 source, this is absolutely conservative, but could avoid explosion
2025 of lattice's value space, especially when one recursive function
2026 calls another recursive. */
2027 if (self_recursively_generated_p (src_val))
2028 {
2029 ipcp_value_source<tree> *s;
2030
2031 /* If the lattice has already been propagated for the call site,
2032 no need to do that again. */
2033 for (s = src_val->sources; s; s = s->next)
2034 if (s->cs == cs)
2035 return dest_lat->set_contains_variable ();
2036 }
2037 else
2038 val_seeds.safe_push (src_val);
2039 }
2040
42d73fa9
FX
2041 gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
2042
9b14fc33
FX
2043 /* Recursively generate lattice values with a limited count. */
2044 FOR_EACH_VEC_ELT (val_seeds, i, src_val)
2045 {
fdfd7f53 2046 for (int j = 1; j < max_recursive_depth; j++)
9b14fc33
FX
2047 {
2048 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2049 src_val, res_type);
2050 if (!cstval)
2051 break;
2052
2053 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2054 src_offset, &src_val, true);
2055 gcc_checking_assert (src_val);
2056 }
2057 }
2058 ret |= dest_lat->set_contains_variable ();
2059 }
310bc633
MJ
2060 else
2061 for (src_val = src_lat->values; src_val; src_val = src_val->next)
0818c24c 2062 {
9b14fc33
FX
2063 /* Now we do not use self-recursively generated value as propagation
2064 source, otherwise it is easy to make value space of normal lattice
2065 overflow. */
2066 if (self_recursively_generated_p (src_val))
2067 {
2068 ret |= dest_lat->set_contains_variable ();
2069 continue;
2070 }
310bc633 2071
9b14fc33
FX
2072 tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
2073 src_val, res_type);
310bc633 2074 if (cstval)
eb270950
FX
2075 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
2076 src_offset);
310bc633 2077 else
c0cb5055 2078 ret |= dest_lat->set_contains_variable ();
0818c24c 2079 }
310bc633
MJ
2080
2081 return ret;
2082}
2083
eb270950
FX
2084/* Propagate values through a pass-through jump function JFUNC associated with
2085 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2086 is the index of the source parameter. PARM_TYPE is the type of the
2087 parameter to which the result is passed. */
2088
2089static bool
2090propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
2091 ipcp_lattice<tree> *src_lat,
2092 ipcp_lattice<tree> *dest_lat, int src_idx,
2093 tree parm_type)
2094{
2095 return propagate_vals_across_arith_jfunc (cs,
2096 ipa_get_jf_pass_through_operation (jfunc),
2097 NULL_TREE,
2098 ipa_get_jf_pass_through_operand (jfunc),
2099 src_lat, dest_lat, -1, src_idx, parm_type);
2100}
2101
310bc633
MJ
2102/* Propagate values through an ancestor jump function JFUNC associated with
2103 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
2104 is the index of the source parameter. */
2105
2106static bool
155c9907
JJ
2107propagate_vals_across_ancestor (struct cgraph_edge *cs,
2108 struct ipa_jump_func *jfunc,
2109 ipcp_lattice<tree> *src_lat,
2110 ipcp_lattice<tree> *dest_lat, int src_idx)
310bc633 2111{
c0cb5055 2112 ipcp_value<tree> *src_val;
310bc633
MJ
2113 bool ret = false;
2114
4cb13597 2115 if (ipa_edge_within_scc (cs))
c0cb5055 2116 return dest_lat->set_contains_variable ();
310bc633
MJ
2117
2118 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2119 {
7b872d9e 2120 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
310bc633
MJ
2121
2122 if (t)
c0cb5055 2123 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
310bc633 2124 else
c0cb5055 2125 ret |= dest_lat->set_contains_variable ();
310bc633
MJ
2126 }
2127
2128 return ret;
2129}
2130
2c9561b5 2131/* Propagate scalar values across jump function JFUNC that is associated with
e5cf5e11
PK
2132 edge CS and put the values into DEST_LAT. PARM_TYPE is the type of the
2133 parameter to which the result is passed. */
310bc633
MJ
2134
2135static bool
155c9907
JJ
2136propagate_scalar_across_jump_function (struct cgraph_edge *cs,
2137 struct ipa_jump_func *jfunc,
e5cf5e11
PK
2138 ipcp_lattice<tree> *dest_lat,
2139 tree param_type)
310bc633
MJ
2140{
2141 if (dest_lat->bottom)
2142 return false;
2143
44210a96 2144 if (jfunc->type == IPA_JF_CONST)
310bc633 2145 {
44210a96 2146 tree val = ipa_get_jf_constant (jfunc);
c0cb5055 2147 return dest_lat->add_value (val, cs, NULL, 0);
310bc633
MJ
2148 }
2149 else if (jfunc->type == IPA_JF_PASS_THROUGH
2150 || jfunc->type == IPA_JF_ANCESTOR)
2151 {
99b1c316 2152 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
c0cb5055 2153 ipcp_lattice<tree> *src_lat;
310bc633
MJ
2154 int src_idx;
2155 bool ret;
2156
2157 if (jfunc->type == IPA_JF_PASS_THROUGH)
7b872d9e 2158 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
310bc633 2159 else
7b872d9e 2160 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
310bc633 2161
2c9561b5 2162 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
310bc633 2163 if (src_lat->bottom)
c0cb5055 2164 return dest_lat->set_contains_variable ();
310bc633
MJ
2165
2166 /* If we would need to clone the caller and cannot, do not propagate. */
2167 if (!ipcp_versionable_function_p (cs->caller)
2168 && (src_lat->contains_variable
2169 || (src_lat->values_count > 1)))
c0cb5055 2170 return dest_lat->set_contains_variable ();
310bc633
MJ
2171
2172 if (jfunc->type == IPA_JF_PASS_THROUGH)
155c9907 2173 ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
e5cf5e11 2174 dest_lat, src_idx, param_type);
310bc633 2175 else
155c9907
JJ
2176 ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
2177 src_idx);
310bc633
MJ
2178
2179 if (src_lat->contains_variable)
c0cb5055 2180 ret |= dest_lat->set_contains_variable ();
310bc633
MJ
2181
2182 return ret;
2183 }
2184
2185 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
2186 use it for indirect inlining), we should propagate them too. */
c0cb5055 2187 return dest_lat->set_contains_variable ();
310bc633
MJ
2188}
2189
44210a96
MJ
2190/* Propagate scalar values across jump function JFUNC that is associated with
2191 edge CS and describes argument IDX and put the values into DEST_LAT. */
2192
2193static bool
155c9907 2194propagate_context_across_jump_function (cgraph_edge *cs,
44210a96
MJ
2195 ipa_jump_func *jfunc, int idx,
2196 ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
2197{
2198 ipa_edge_args *args = IPA_EDGE_REF (cs);
2199 if (dest_lat->bottom)
2200 return false;
2201 bool ret = false;
2202 bool added_sth = false;
df0d8136 2203 bool type_preserved = true;
44210a96
MJ
2204
2205 ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
2206 = ipa_get_ith_polymorhic_call_context (args, idx);
2207
2208 if (edge_ctx_ptr)
df0d8136 2209 edge_ctx = *edge_ctx_ptr;
44210a96
MJ
2210
2211 if (jfunc->type == IPA_JF_PASS_THROUGH
2212 || jfunc->type == IPA_JF_ANCESTOR)
2213 {
99b1c316 2214 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
44210a96
MJ
2215 int src_idx;
2216 ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
2217
2218 /* TODO: Once we figure out how to propagate speculations, it will
2219 probably be a good idea to switch to speculation if type_preserved is
2220 not set instead of punting. */
2221 if (jfunc->type == IPA_JF_PASS_THROUGH)
2222 {
df0d8136 2223 if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
44210a96 2224 goto prop_fail;
df0d8136 2225 type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
44210a96
MJ
2226 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2227 }
2228 else
2229 {
df0d8136 2230 type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
44210a96
MJ
2231 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2232 }
2233
2234 src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
2235 /* If we would need to clone the caller and cannot, do not propagate. */
2236 if (!ipcp_versionable_function_p (cs->caller)
2237 && (src_lat->contains_variable
2238 || (src_lat->values_count > 1)))
2239 goto prop_fail;
44210a96
MJ
2240
2241 ipcp_value<ipa_polymorphic_call_context> *src_val;
2242 for (src_val = src_lat->values; src_val; src_val = src_val->next)
2243 {
2244 ipa_polymorphic_call_context cur = src_val->value;
df0d8136
JH
2245
2246 if (!type_preserved)
2247 cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
44210a96
MJ
2248 if (jfunc->type == IPA_JF_ANCESTOR)
2249 cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
df0d8136
JH
2250 /* TODO: In cases we know how the context is going to be used,
2251 we can improve the result by passing proper OTR_TYPE. */
2252 cur.combine_with (edge_ctx);
44210a96
MJ
2253 if (!cur.useless_p ())
2254 {
df0d8136
JH
2255 if (src_lat->contains_variable
2256 && !edge_ctx.equal_to (cur))
2257 ret |= dest_lat->set_contains_variable ();
44210a96
MJ
2258 ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
2259 added_sth = true;
2260 }
2261 }
44210a96
MJ
2262 }
2263
2264 prop_fail:
2265 if (!added_sth)
2266 {
2267 if (!edge_ctx.useless_p ())
2268 ret |= dest_lat->add_value (edge_ctx, cs);
2269 else
2270 ret |= dest_lat->set_contains_variable ();
2271 }
2272
2273 return ret;
2274}
2275
209ca542
PK
2276/* Propagate bits across jfunc that is associated with
2277 edge cs and update dest_lattice accordingly. */
2278
2279bool
155c9907
JJ
2280propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
2281 ipa_jump_func *jfunc,
2282 ipcp_bits_lattice *dest_lattice)
209ca542
PK
2283{
2284 if (dest_lattice->bottom_p ())
2285 return false;
2286
2287 enum availability availability;
2288 cgraph_node *callee = cs->callee->function_symbol (&availability);
99b1c316 2289 class ipa_node_params *callee_info = IPA_NODE_REF (callee);
209ca542
PK
2290 tree parm_type = ipa_get_type (callee_info, idx);
2291
b93f25ad
ML
2292 /* For K&R C programs, ipa_get_type() could return NULL_TREE. Avoid the
2293 transform for these cases. Similarly, we can have bad type mismatches
2294 with LTO, avoid doing anything with those too. */
2295 if (!parm_type
2296 || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
209ca542
PK
2297 {
2298 if (dump_file && (dump_flags & TDF_DETAILS))
b93f25ad
ML
2299 fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
2300 "param %i of %s is NULL or unsuitable for bits propagation\n",
3629ff8a 2301 idx, cs->callee->dump_name ());
209ca542
PK
2302
2303 return dest_lattice->set_to_bottom ();
2304 }
2305
2306 unsigned precision = TYPE_PRECISION (parm_type);
2307 signop sgn = TYPE_SIGN (parm_type);
2308
67b97478
PK
2309 if (jfunc->type == IPA_JF_PASS_THROUGH
2310 || jfunc->type == IPA_JF_ANCESTOR)
209ca542 2311 {
99b1c316 2312 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
209ca542 2313 tree operand = NULL_TREE;
67b97478
PK
2314 enum tree_code code;
2315 unsigned src_idx;
209ca542 2316
67b97478
PK
2317 if (jfunc->type == IPA_JF_PASS_THROUGH)
2318 {
2319 code = ipa_get_jf_pass_through_operation (jfunc);
2320 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2321 if (code != NOP_EXPR)
2322 operand = ipa_get_jf_pass_through_operand (jfunc);
2323 }
2324 else
2325 {
155c9907 2326 code = POINTER_PLUS_EXPR;
67b97478
PK
2327 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
2328 unsigned HOST_WIDE_INT offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
2329 operand = build_int_cstu (size_type_node, offset);
2330 }
209ca542 2331
99b1c316 2332 class ipcp_param_lattices *src_lats
209ca542
PK
2333 = ipa_get_parm_lattices (caller_info, src_idx);
2334
2335 /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
2336 for eg consider:
2337 int f(int x)
2338 {
2339 g (x & 0xff);
2340 }
2341 Assume lattice for x is bottom, however we can still propagate
2342 result of x & 0xff == 0xff, which gets computed during ccp1 pass
2343 and we store it in jump function during analysis stage. */
2344
2345 if (src_lats->bits_lattice.bottom_p ()
86cd0334
MJ
2346 && jfunc->bits)
2347 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
209ca542
PK
2348 precision);
2349 else
2350 return dest_lattice->meet_with (src_lats->bits_lattice, precision, sgn,
2351 code, operand);
2352 }
2353
2354 else if (jfunc->type == IPA_JF_ANCESTOR)
2355 return dest_lattice->set_to_bottom ();
86cd0334
MJ
2356 else if (jfunc->bits)
2357 return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
2358 precision);
209ca542
PK
2359 else
2360 return dest_lattice->set_to_bottom ();
2361}
2362
8bc5448f 2363/* Propagate value range across jump function JFUNC that is associated with
5d5f1e95
KV
2364 edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
2365 accordingly. */
8bc5448f
KV
2366
2367static bool
155c9907 2368propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
99b1c316 2369 class ipcp_param_lattices *dest_plats,
155c9907 2370 tree param_type)
8bc5448f 2371{
8bc5448f
KV
2372 ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
2373
2374 if (dest_lat->bottom_p ())
2375 return false;
2376
5d5f1e95
KV
2377 if (!param_type
2378 || (!INTEGRAL_TYPE_P (param_type)
2379 && !POINTER_TYPE_P (param_type)))
2380 return dest_lat->set_to_bottom ();
2381
8bc5448f
KV
2382 if (jfunc->type == IPA_JF_PASS_THROUGH)
2383 {
a5e14a42 2384 enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
2b89b748
JH
2385 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2386 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
2387 class ipcp_param_lattices *src_lats
2388 = ipa_get_parm_lattices (caller_info, src_idx);
2389 tree operand_type = ipa_get_type (caller_info, src_idx);
8bc5448f 2390
2b89b748
JH
2391 if (src_lats->m_value_range.bottom_p ())
2392 return dest_lat->set_to_bottom ();
2393
2394 value_range vr;
a5e14a42 2395 if (TREE_CODE_CLASS (operation) == tcc_unary)
27f418b8
JJ
2396 ipa_vr_operation_and_type_effects (&vr,
2397 &src_lats->m_value_range.m_vr,
2398 operation, param_type,
2399 operand_type);
2b89b748
JH
2400 /* A crude way to prevent unbounded number of value range updates
2401 in SCC components. We should allow limited number of updates within
2402 SCC, too. */
2403 else if (!ipa_edge_within_scc (cs))
2404 {
2405 tree op = ipa_get_jf_pass_through_operand (jfunc);
2406 value_range op_vr (op, op);
2407 value_range op_res,res;
2408
2409 range_fold_binary_expr (&op_res, operation, operand_type,
2410 &src_lats->m_value_range.m_vr, &op_vr);
2411 ipa_vr_operation_and_type_effects (&vr,
2412 &op_res,
2413 NOP_EXPR, param_type,
2414 operand_type);
2415 }
2416 if (!vr.undefined_p () && !vr.varying_p ())
2417 {
2418 if (jfunc->m_vr)
2419 {
2420 value_range jvr;
2421 if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
2422 NOP_EXPR,
2423 param_type,
2424 jfunc->m_vr->type ()))
27f418b8 2425 vr.intersect (jvr);
2b89b748
JH
2426 }
2427 return dest_lat->meet_with (&vr);
a2b4c188 2428 }
8bc5448f
KV
2429 }
2430 else if (jfunc->type == IPA_JF_CONST)
2431 {
2432 tree val = ipa_get_jf_constant (jfunc);
2433 if (TREE_CODE (val) == INTEGER_CST)
2434 {
7d22d5a3 2435 val = fold_convert (param_type, val);
1e401340
KV
2436 if (TREE_OVERFLOW_P (val))
2437 val = drop_tree_overflow (val);
86cd0334 2438
5d462877 2439 value_range tmpvr (val, val);
86cd0334 2440 return dest_lat->meet_with (&tmpvr);
8bc5448f
KV
2441 }
2442 }
2443
028d81b1 2444 value_range vr;
86cd0334
MJ
2445 if (jfunc->m_vr
2446 && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
a5e14a42 2447 param_type,
54994253 2448 jfunc->m_vr->type ()))
a5e14a42 2449 return dest_lat->meet_with (&vr);
8bc5448f
KV
2450 else
2451 return dest_lat->set_to_bottom ();
2452}
2453
2c9561b5
MJ
2454/* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
2455 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
2456 other cases, return false). If there are no aggregate items, set
2457 aggs_by_ref to NEW_AGGS_BY_REF. */
2458
2459static bool
99b1c316 2460set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
2c9561b5
MJ
2461 bool new_aggs_by_ref)
2462{
2463 if (dest_plats->aggs)
2464 {
2465 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
2466 {
2467 set_agg_lats_to_bottom (dest_plats);
2468 return true;
2469 }
2470 }
2471 else
2472 dest_plats->aggs_by_ref = new_aggs_by_ref;
2473 return false;
2474}
2475
2476/* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
2477 already existing lattice for the given OFFSET and SIZE, marking all skipped
2478 lattices as containing variable and checking for overlaps. If there is no
2479 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
2480 it with offset, size and contains_variable to PRE_EXISTING, and return true,
2481 unless there are too many already. If there are two many, return false. If
2482 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
2483 skipped lattices were newly marked as containing variable, set *CHANGE to
de2e0835 2484 true. MAX_AGG_ITEMS is the maximum number of lattices. */
2c9561b5
MJ
2485
2486static bool
99b1c316 2487merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
2c9561b5
MJ
2488 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
2489 struct ipcp_agg_lattice ***aglat,
de2e0835 2490 bool pre_existing, bool *change, int max_agg_items)
2c9561b5
MJ
2491{
2492 gcc_checking_assert (offset >= 0);
2493
2494 while (**aglat && (**aglat)->offset < offset)
2495 {
2496 if ((**aglat)->offset + (**aglat)->size > offset)
2497 {
2498 set_agg_lats_to_bottom (dest_plats);
2499 return false;
2500 }
c0cb5055 2501 *change |= (**aglat)->set_contains_variable ();
2c9561b5
MJ
2502 *aglat = &(**aglat)->next;
2503 }
2504
2505 if (**aglat && (**aglat)->offset == offset)
2506 {
b66113e9 2507 if ((**aglat)->size != val_size)
2c9561b5
MJ
2508 {
2509 set_agg_lats_to_bottom (dest_plats);
2510 return false;
2511 }
b66113e9
MJ
2512 gcc_assert (!(**aglat)->next
2513 || (**aglat)->next->offset >= offset + val_size);
2c9561b5
MJ
2514 return true;
2515 }
2516 else
2517 {
2518 struct ipcp_agg_lattice *new_al;
2519
2520 if (**aglat && (**aglat)->offset < offset + val_size)
2521 {
2522 set_agg_lats_to_bottom (dest_plats);
2523 return false;
2524 }
de2e0835 2525 if (dest_plats->aggs_count == max_agg_items)
2c9561b5
MJ
2526 return false;
2527 dest_plats->aggs_count++;
2651e637 2528 new_al = ipcp_agg_lattice_pool.allocate ();
2c9561b5
MJ
2529 memset (new_al, 0, sizeof (*new_al));
2530
2531 new_al->offset = offset;
2532 new_al->size = val_size;
2533 new_al->contains_variable = pre_existing;
2534
2535 new_al->next = **aglat;
2536 **aglat = new_al;
2537 return true;
2538 }
2539}
2540
2541/* Set all AGLAT and all other aggregate lattices reachable by next pointers as
2542 containing an unknown value. */
2543
2544static bool
2545set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
2546{
2547 bool ret = false;
2548 while (aglat)
2549 {
c0cb5055 2550 ret |= aglat->set_contains_variable ();
2c9561b5
MJ
2551 aglat = aglat->next;
2552 }
2553 return ret;
2554}
2555
2556/* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
2557 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
2558 parameter used for lattice value sources. Return true if DEST_PLATS changed
2559 in any way. */
2560
2561static bool
2562merge_aggregate_lattices (struct cgraph_edge *cs,
99b1c316
MS
2563 class ipcp_param_lattices *dest_plats,
2564 class ipcp_param_lattices *src_plats,
2c9561b5
MJ
2565 int src_idx, HOST_WIDE_INT offset_delta)
2566{
2567 bool pre_existing = dest_plats->aggs != NULL;
2568 struct ipcp_agg_lattice **dst_aglat;
2569 bool ret = false;
2570
2571 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
2572 return true;
2573 if (src_plats->aggs_bottom)
2574 return set_agg_lats_contain_variable (dest_plats);
3e452a28
MJ
2575 if (src_plats->aggs_contain_variable)
2576 ret |= set_agg_lats_contain_variable (dest_plats);
2c9561b5
MJ
2577 dst_aglat = &dest_plats->aggs;
2578
de2e0835
MJ
2579 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2580 param_ipa_max_agg_items);
2c9561b5
MJ
2581 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
2582 src_aglat;
2583 src_aglat = src_aglat->next)
2584 {
2585 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
2586
2587 if (new_offset < 0)
2588 continue;
2589 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
de2e0835 2590 &dst_aglat, pre_existing, &ret, max_agg_items))
2c9561b5
MJ
2591 {
2592 struct ipcp_agg_lattice *new_al = *dst_aglat;
2593
2594 dst_aglat = &(*dst_aglat)->next;
2595 if (src_aglat->bottom)
2596 {
c0cb5055 2597 ret |= new_al->set_contains_variable ();
2c9561b5
MJ
2598 continue;
2599 }
2600 if (src_aglat->contains_variable)
c0cb5055
MJ
2601 ret |= new_al->set_contains_variable ();
2602 for (ipcp_value<tree> *val = src_aglat->values;
2c9561b5
MJ
2603 val;
2604 val = val->next)
c0cb5055
MJ
2605 ret |= new_al->add_value (val->value, cs, val, src_idx,
2606 src_aglat->offset);
2c9561b5
MJ
2607 }
2608 else if (dest_plats->aggs_bottom)
2609 return true;
2610 }
2611 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
2612 return ret;
2613}
2614
324e93f1
MJ
2615/* Determine whether there is anything to propagate FROM SRC_PLATS through a
2616 pass-through JFUNC and if so, whether it has conform and conforms to the
2617 rules about propagating values passed by reference. */
2618
2619static bool
99b1c316 2620agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
324e93f1
MJ
2621 struct ipa_jump_func *jfunc)
2622{
2623 return src_plats->aggs
2624 && (!src_plats->aggs_by_ref
2625 || ipa_get_jf_pass_through_agg_preserved (jfunc));
2626}
2627
eb270950
FX
2628/* Propagate values through ITEM, jump function for a part of an aggregate,
2629 into corresponding aggregate lattice AGLAT. CS is the call graph edge
2630 associated with the jump function. Return true if AGLAT changed in any
2631 way. */
2632
2633static bool
2634propagate_aggregate_lattice (struct cgraph_edge *cs,
2635 struct ipa_agg_jf_item *item,
2636 struct ipcp_agg_lattice *aglat)
2637{
2638 class ipa_node_params *caller_info;
2639 class ipcp_param_lattices *src_plats;
2640 struct ipcp_lattice<tree> *src_lat;
2641 HOST_WIDE_INT src_offset;
2642 int src_idx;
2643 tree load_type;
2644 bool ret;
2645
2646 if (item->jftype == IPA_JF_CONST)
2647 {
2648 tree value = item->value.constant;
2649
2650 gcc_checking_assert (is_gimple_ip_invariant (value));
2651 return aglat->add_value (value, cs, NULL, 0);
2652 }
2653
2654 gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
2655 || item->jftype == IPA_JF_LOAD_AGG);
2656
2657 caller_info = IPA_NODE_REF (cs->caller);
2658 src_idx = item->value.pass_through.formal_id;
2659 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2660
2661 if (item->jftype == IPA_JF_PASS_THROUGH)
2662 {
2663 load_type = NULL_TREE;
2664 src_lat = &src_plats->itself;
2665 src_offset = -1;
2666 }
2667 else
2668 {
2669 HOST_WIDE_INT load_offset = item->value.load_agg.offset;
2670 struct ipcp_agg_lattice *src_aglat;
2671
2672 for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
2673 if (src_aglat->offset >= load_offset)
2674 break;
2675
2676 load_type = item->value.load_agg.type;
2677 if (!src_aglat
2678 || src_aglat->offset > load_offset
2679 || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
2680 || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
2681 return aglat->set_contains_variable ();
2682
2683 src_lat = src_aglat;
2684 src_offset = load_offset;
2685 }
2686
2687 if (src_lat->bottom
2688 || (!ipcp_versionable_function_p (cs->caller)
2689 && !src_lat->is_single_const ()))
2690 return aglat->set_contains_variable ();
2691
2692 ret = propagate_vals_across_arith_jfunc (cs,
2693 item->value.pass_through.operation,
2694 load_type,
2695 item->value.pass_through.operand,
2696 src_lat, aglat,
2697 src_offset,
2698 src_idx,
2699 item->type);
2700
2701 if (src_lat->contains_variable)
2702 ret |= aglat->set_contains_variable ();
2703
2704 return ret;
2705}
2706
2c9561b5
MJ
2707/* Propagate scalar values across jump function JFUNC that is associated with
2708 edge CS and put the values into DEST_LAT. */
2709
2710static bool
155c9907
JJ
2711propagate_aggs_across_jump_function (struct cgraph_edge *cs,
2712 struct ipa_jump_func *jfunc,
99b1c316 2713 class ipcp_param_lattices *dest_plats)
2c9561b5
MJ
2714{
2715 bool ret = false;
2716
2717 if (dest_plats->aggs_bottom)
2718 return false;
2719
2720 if (jfunc->type == IPA_JF_PASS_THROUGH
2721 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
2722 {
99b1c316 2723 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2c9561b5 2724 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
99b1c316 2725 class ipcp_param_lattices *src_plats;
2c9561b5
MJ
2726
2727 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
324e93f1 2728 if (agg_pass_through_permissible_p (src_plats, jfunc))
2c9561b5
MJ
2729 {
2730 /* Currently we do not produce clobber aggregate jump
2731 functions, replace with merging when we do. */
2732 gcc_assert (!jfunc->agg.items);
2733 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
2734 src_idx, 0);
2735 }
2736 else
2737 ret |= set_agg_lats_contain_variable (dest_plats);
2738 }
2739 else if (jfunc->type == IPA_JF_ANCESTOR
2740 && ipa_get_jf_ancestor_agg_preserved (jfunc))
2741 {
99b1c316 2742 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2c9561b5 2743 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
99b1c316 2744 class ipcp_param_lattices *src_plats;
2c9561b5
MJ
2745
2746 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
2747 if (src_plats->aggs && src_plats->aggs_by_ref)
2748 {
2749 /* Currently we do not produce clobber aggregate jump
2750 functions, replace with merging when we do. */
2751 gcc_assert (!jfunc->agg.items);
2752 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
2753 ipa_get_jf_ancestor_offset (jfunc));
2754 }
2755 else if (!src_plats->aggs_by_ref)
2756 ret |= set_agg_lats_to_bottom (dest_plats);
2757 else
2758 ret |= set_agg_lats_contain_variable (dest_plats);
2759 }
2760 else if (jfunc->agg.items)
2761 {
2762 bool pre_existing = dest_plats->aggs != NULL;
2763 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
2764 struct ipa_agg_jf_item *item;
2765 int i;
2766
2767 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
2768 return true;
2769
de2e0835
MJ
2770 int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
2771 param_ipa_max_agg_items);
9771b263 2772 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2c9561b5
MJ
2773 {
2774 HOST_WIDE_INT val_size;
2775
eb270950 2776 if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
2c9561b5 2777 continue;
eb270950 2778 val_size = tree_to_shwi (TYPE_SIZE (item->type));
2c9561b5
MJ
2779
2780 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
de2e0835 2781 &aglat, pre_existing, &ret, max_agg_items))
2c9561b5 2782 {
eb270950 2783 ret |= propagate_aggregate_lattice (cs, item, *aglat);
2c9561b5
MJ
2784 aglat = &(*aglat)->next;
2785 }
2786 else if (dest_plats->aggs_bottom)
2787 return true;
2788 }
2789
2790 ret |= set_chain_of_aglats_contains_variable (*aglat);
2791 }
2792 else
2793 ret |= set_agg_lats_contain_variable (dest_plats);
2794
2795 return ret;
2796}
2797
173b7355
MJ
2798/* Return true if on the way cfrom CS->caller to the final (non-alias and
2799 non-thunk) destination, the call passes through a thunk. */
2800
2801static bool
2802call_passes_through_thunk_p (cgraph_edge *cs)
2803{
2804 cgraph_node *alias_or_thunk = cs->callee;
2805 while (alias_or_thunk->alias)
2806 alias_or_thunk = alias_or_thunk->get_alias_target ();
2807 return alias_or_thunk->thunk.thunk_p;
2808}
2809
310bc633
MJ
2810/* Propagate constants from the caller to the callee of CS. INFO describes the
2811 caller. */
2812
2813static bool
155c9907 2814propagate_constants_across_call (struct cgraph_edge *cs)
310bc633 2815{
99b1c316 2816 class ipa_node_params *callee_info;
310bc633 2817 enum availability availability;
173b7355 2818 cgraph_node *callee;
99b1c316 2819 class ipa_edge_args *args;
310bc633 2820 bool ret = false;
d7da5cc8 2821 int i, args_count, parms_count;
310bc633 2822
d52f5295 2823 callee = cs->callee->function_symbol (&availability);
67348ccc 2824 if (!callee->definition)
310bc633 2825 return false;
d52f5295 2826 gcc_checking_assert (callee->has_gimple_body_p ());
310bc633 2827 callee_info = IPA_NODE_REF (callee);
6cf67b62
JH
2828 if (!callee_info)
2829 return false;
310bc633
MJ
2830
2831 args = IPA_EDGE_REF (cs);
d7da5cc8 2832 parms_count = ipa_get_param_count (callee_info);
f3fec19f
MJ
2833 if (parms_count == 0)
2834 return false;
e72763e2
JH
2835 if (!args
2836 || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
2837 || !opt_for_fn (cs->caller->decl, optimize))
a33c028e
JH
2838 {
2839 for (i = 0; i < parms_count; i++)
2840 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2841 i));
2842 return ret;
2843 }
2844 args_count = ipa_get_cs_argument_count (args);
310bc633
MJ
2845
2846 /* If this call goes through a thunk we must not propagate to the first (0th)
2847 parameter. However, we might need to uncover a thunk from below a series
2848 of aliases first. */
173b7355 2849 if (call_passes_through_thunk_p (cs))
310bc633 2850 {
2c9561b5
MJ
2851 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
2852 0));
310bc633
MJ
2853 i = 1;
2854 }
2855 else
2856 i = 0;
2857
d7da5cc8 2858 for (; (i < args_count) && (i < parms_count); i++)
310bc633
MJ
2859 {
2860 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
99b1c316 2861 class ipcp_param_lattices *dest_plats;
a5e14a42 2862 tree param_type = ipa_get_type (callee_info, i);
310bc633 2863
2c9561b5 2864 dest_plats = ipa_get_parm_lattices (callee_info, i);
d52f5295 2865 if (availability == AVAIL_INTERPOSABLE)
2c9561b5 2866 ret |= set_all_contains_variable (dest_plats);
310bc633 2867 else
2c9561b5 2868 {
155c9907 2869 ret |= propagate_scalar_across_jump_function (cs, jump_func,
e5cf5e11
PK
2870 &dest_plats->itself,
2871 param_type);
155c9907
JJ
2872 ret |= propagate_context_across_jump_function (cs, jump_func, i,
2873 &dest_plats->ctxlat);
2874 ret
2875 |= propagate_bits_across_jump_function (cs, i, jump_func,
2876 &dest_plats->bits_lattice);
2877 ret |= propagate_aggs_across_jump_function (cs, jump_func,
2878 dest_plats);
8bc5448f 2879 if (opt_for_fn (callee->decl, flag_ipa_vrp))
155c9907
JJ
2880 ret |= propagate_vr_across_jump_function (cs, jump_func,
2881 dest_plats, param_type);
8bc5448f
KV
2882 else
2883 ret |= dest_plats->m_value_range.set_to_bottom ();
2c9561b5 2884 }
310bc633 2885 }
d7da5cc8 2886 for (; i < parms_count; i++)
2c9561b5 2887 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
d7da5cc8 2888
310bc633
MJ
2889 return ret;
2890}
2891
2892/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
3b97a5c7
MJ
2893 KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination. The latter
2894 three can be NULL. If AGG_REPS is not NULL, KNOWN_AGGS is ignored. */
310bc633 2895
162712de
MJ
2896static tree
2897ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
44210a96
MJ
2898 vec<tree> known_csts,
2899 vec<ipa_polymorphic_call_context> known_contexts,
eb270950 2900 vec<ipa_agg_value_set> known_aggs,
231b4916
JH
2901 struct ipa_agg_replacement_value *agg_reps,
2902 bool *speculative)
310bc633
MJ
2903{
2904 int param_index = ie->indirect_info->param_index;
44210a96 2905 HOST_WIDE_INT anc_offset;
b0d55476 2906 tree t = NULL;
85942f45 2907 tree target = NULL;
310bc633 2908
231b4916
JH
2909 *speculative = false;
2910
b0d55476 2911 if (param_index == -1)
310bc633
MJ
2912 return NULL_TREE;
2913
2914 if (!ie->indirect_info->polymorphic)
2915 {
b0d55476 2916 tree t = NULL;
8810cc52
MJ
2917
2918 if (ie->indirect_info->agg_contents)
2919 {
91bb9f80
MJ
2920 t = NULL;
2921 if (agg_reps && ie->indirect_info->guaranteed_unmodified)
162712de 2922 {
162712de
MJ
2923 while (agg_reps)
2924 {
2925 if (agg_reps->index == param_index
7b920a9a
MJ
2926 && agg_reps->offset == ie->indirect_info->offset
2927 && agg_reps->by_ref == ie->indirect_info->by_ref)
162712de
MJ
2928 {
2929 t = agg_reps->value;
2930 break;
2931 }
2932 agg_reps = agg_reps->next;
2933 }
2934 }
91bb9f80 2935 if (!t)
8810cc52 2936 {
eb270950 2937 struct ipa_agg_value_set *agg;
91bb9f80 2938 if (known_aggs.length () > (unsigned int) param_index)
eb270950 2939 agg = &known_aggs[param_index];
91bb9f80
MJ
2940 else
2941 agg = NULL;
2942 bool from_global_constant;
b0d55476
JH
2943 t = ipa_find_agg_cst_for_param (agg,
2944 (unsigned) param_index
2945 < known_csts.length ()
2946 ? known_csts[param_index]
2947 : NULL,
91bb9f80
MJ
2948 ie->indirect_info->offset,
2949 ie->indirect_info->by_ref,
2950 &from_global_constant);
44a71f36
MJ
2951 if (t
2952 && !from_global_constant
91bb9f80
MJ
2953 && !ie->indirect_info->guaranteed_unmodified)
2954 t = NULL_TREE;
8810cc52 2955 }
8810cc52 2956 }
b0d55476 2957 else if ((unsigned) param_index < known_csts.length ())
44210a96 2958 t = known_csts[param_index];
8810cc52 2959
155c9907
JJ
2960 if (t
2961 && TREE_CODE (t) == ADDR_EXPR
310bc633 2962 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
81fa35bd 2963 return TREE_OPERAND (t, 0);
310bc633
MJ
2964 else
2965 return NULL_TREE;
2966 }
2967
2bf86c84 2968 if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
85942f45
JH
2969 return NULL_TREE;
2970
8810cc52 2971 gcc_assert (!ie->indirect_info->agg_contents);
8b7773a4 2972 anc_offset = ie->indirect_info->offset;
310bc633 2973
85942f45
JH
2974 t = NULL;
2975
f25ae20e 2976 /* Try to work out value of virtual table pointer value in replacements. */
231b4916 2977 if (!t && agg_reps && !ie->indirect_info->by_ref)
85942f45
JH
2978 {
2979 while (agg_reps)
2980 {
2981 if (agg_reps->index == param_index
2982 && agg_reps->offset == ie->indirect_info->offset
2983 && agg_reps->by_ref)
2984 {
2985 t = agg_reps->value;
2986 break;
2987 }
2988 agg_reps = agg_reps->next;
2989 }
2990 }
2991
2992 /* Try to work out value of virtual table pointer value in known
2993 aggregate values. */
2994 if (!t && known_aggs.length () > (unsigned int) param_index
231b4916 2995 && !ie->indirect_info->by_ref)
85942f45 2996 {
eb270950 2997 struct ipa_agg_value_set *agg = &known_aggs[param_index];
b0d55476
JH
2998 t = ipa_find_agg_cst_for_param (agg,
2999 (unsigned) param_index
3000 < known_csts.length ()
3001 ? known_csts[param_index] : NULL,
155c9907 3002 ie->indirect_info->offset, true);
85942f45
JH
3003 }
3004
9de2f554 3005 /* If we found the virtual table pointer, lookup the target. */
85942f45 3006 if (t)
9de2f554
JH
3007 {
3008 tree vtable;
3009 unsigned HOST_WIDE_INT offset;
3010 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
3011 {
2994ab20 3012 bool can_refer;
9de2f554 3013 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2994ab20
JH
3014 vtable, offset, &can_refer);
3015 if (can_refer)
9de2f554 3016 {
2994ab20 3017 if (!target
cb1180d5 3018 || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
8472fa80 3019 || !possible_polymorphic_call_target_p
d52f5295 3020 (ie, cgraph_node::get (target)))
2994ab20
JH
3021 {
3022 /* Do not speculate builtin_unreachable, it is stupid! */
3023 if (ie->indirect_info->vptr_changed)
3024 return NULL;
3025 target = ipa_impossible_devirt_target (ie, target);
3026 }
155c9907 3027 *speculative = ie->indirect_info->vptr_changed;
231b4916 3028 if (!*speculative)
155c9907 3029 return target;
9de2f554 3030 }
9de2f554
JH
3031 }
3032 }
85942f45 3033
44210a96 3034 /* Do we know the constant value of pointer? */
b0d55476 3035 if (!t && (unsigned) param_index < known_csts.length ())
44210a96 3036 t = known_csts[param_index];
310bc633 3037
44210a96
MJ
3038 gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
3039
3040 ipa_polymorphic_call_context context;
3041 if (known_contexts.length () > (unsigned int) param_index)
310bc633 3042 {
44210a96 3043 context = known_contexts[param_index];
df0d8136
JH
3044 context.offset_by (anc_offset);
3045 if (ie->indirect_info->vptr_changed)
3046 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3047 ie->indirect_info->otr_type);
44210a96
MJ
3048 if (t)
3049 {
3050 ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
3051 (t, ie->indirect_info->otr_type, anc_offset);
3052 if (!ctx2.useless_p ())
3053 context.combine_with (ctx2, ie->indirect_info->otr_type);
3054 }
310bc633 3055 }
44210a96 3056 else if (t)
33c3b6be
JH
3057 {
3058 context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
3059 anc_offset);
3060 if (ie->indirect_info->vptr_changed)
3061 context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
3062 ie->indirect_info->otr_type);
3063 }
310bc633 3064 else
44210a96 3065 return NULL_TREE;
310bc633 3066
44210a96
MJ
3067 vec <cgraph_node *>targets;
3068 bool final;
3069
3070 targets = possible_polymorphic_call_targets
3071 (ie->indirect_info->otr_type,
3072 ie->indirect_info->otr_token,
3073 context, &final);
3074 if (!final || targets.length () > 1)
231b4916
JH
3075 {
3076 struct cgraph_node *node;
3077 if (*speculative)
3078 return target;
2bf86c84
JH
3079 if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
3080 || ie->speculative || !ie->maybe_hot_p ())
231b4916
JH
3081 return NULL;
3082 node = try_speculative_devirtualization (ie->indirect_info->otr_type,
3083 ie->indirect_info->otr_token,
3084 context);
3085 if (node)
3086 {
3087 *speculative = true;
3088 target = node->decl;
3089 }
3090 else
3091 return NULL;
3092 }
44210a96 3093 else
231b4916
JH
3094 {
3095 *speculative = false;
3096 if (targets.length () == 1)
3097 target = targets[0]->decl;
3098 else
3099 target = ipa_impossible_devirt_target (ie, NULL_TREE);
3100 }
b5165eb0
MJ
3101
3102 if (target && !possible_polymorphic_call_target_p (ie,
d52f5295 3103 cgraph_node::get (target)))
2994ab20
JH
3104 {
3105 if (*speculative)
3106 return NULL;
3107 target = ipa_impossible_devirt_target (ie, target);
3108 }
450ad0cd
JH
3109
3110 return target;
310bc633
MJ
3111}
3112
162712de 3113
44210a96
MJ
3114/* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
3115 KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
3116 return the destination. */
162712de
MJ
3117
3118tree
3119ipa_get_indirect_edge_target (struct cgraph_edge *ie,
44210a96
MJ
3120 vec<tree> known_csts,
3121 vec<ipa_polymorphic_call_context> known_contexts,
eb270950 3122 vec<ipa_agg_value_set> known_aggs,
231b4916 3123 bool *speculative)
162712de 3124{
44210a96 3125 return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
231b4916 3126 known_aggs, NULL, speculative);
162712de
MJ
3127}
3128
310bc633 3129/* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
44210a96 3130 and KNOWN_CONTEXTS. */
310bc633
MJ
3131
3132static int
3133devirtualization_time_bonus (struct cgraph_node *node,
9771b263 3134 vec<tree> known_csts,
44210a96 3135 vec<ipa_polymorphic_call_context> known_contexts,
eb270950 3136 vec<ipa_agg_value_set> known_aggs)
310bc633
MJ
3137{
3138 struct cgraph_edge *ie;
3139 int res = 0;
3140
3141 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
3142 {
3143 struct cgraph_node *callee;
99b1c316 3144 class ipa_fn_summary *isummary;
8ad274d2 3145 enum availability avail;
81fa35bd 3146 tree target;
231b4916 3147 bool speculative;
310bc633 3148
44210a96 3149 target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts,
231b4916 3150 known_aggs, &speculative);
310bc633
MJ
3151 if (!target)
3152 continue;
3153
3154 /* Only bare minimum benefit for clearly un-inlineable targets. */
3155 res += 1;
d52f5295 3156 callee = cgraph_node::get (target);
67348ccc 3157 if (!callee || !callee->definition)
310bc633 3158 continue;
d52f5295 3159 callee = callee->function_symbol (&avail);
8ad274d2
JH
3160 if (avail < AVAIL_AVAILABLE)
3161 continue;
56f62793 3162 isummary = ipa_fn_summaries->get (callee);
8472660b 3163 if (!isummary || !isummary->inlinable)
310bc633
MJ
3164 continue;
3165
f658ad30 3166 int size = ipa_size_summaries->get (callee)->size;
310bc633
MJ
3167 /* FIXME: The values below need re-considering and perhaps also
3168 integrating into the cost metrics, at lest in some very basic way. */
78a502ca
ML
3169 int max_inline_insns_auto
3170 = opt_for_fn (callee->decl, param_max_inline_insns_auto);
3171 if (size <= max_inline_insns_auto / 4)
231b4916 3172 res += 31 / ((int)speculative + 1);
78a502ca 3173 else if (size <= max_inline_insns_auto / 2)
231b4916 3174 res += 15 / ((int)speculative + 1);
78a502ca 3175 else if (size <= max_inline_insns_auto
67348ccc 3176 || DECL_DECLARED_INLINE_P (callee->decl))
231b4916 3177 res += 7 / ((int)speculative + 1);
310bc633
MJ
3178 }
3179
3180 return res;
3181}
3182
2c9561b5
MJ
3183/* Return time bonus incurred because of HINTS. */
3184
3185static int
fdfd7f53 3186hint_time_bonus (cgraph_node *node, ipa_hints hints)
2c9561b5 3187{
19321415 3188 int result = 0;
2c9561b5 3189 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
fdfd7f53 3190 result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
19321415 3191 return result;
2c9561b5
MJ
3192}
3193
af21714c
MJ
3194/* If there is a reason to penalize the function described by INFO in the
3195 cloning goodness evaluation, do so. */
3196
3197static inline int64_t
fdfd7f53
ML
3198incorporate_penalties (cgraph_node *node, ipa_node_params *info,
3199 int64_t evaluation)
af21714c 3200{
9b14fc33 3201 if (info->node_within_scc && !info->node_is_self_scc)
af21714c 3202 evaluation = (evaluation
fdfd7f53
ML
3203 * (100 - opt_for_fn (node->decl,
3204 param_ipa_cp_recursion_penalty))) / 100;
af21714c
MJ
3205
3206 if (info->node_calling_single_call)
3207 evaluation = (evaluation
fdfd7f53
ML
3208 * (100 - opt_for_fn (node->decl,
3209 param_ipa_cp_single_call_penalty)))
af21714c
MJ
3210 / 100;
3211
3212 return evaluation;
3213}
3214
310bc633
MJ
3215/* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
3216 and SIZE_COST and with the sum of frequencies of incoming edges to the
3217 potential new clone in FREQUENCIES. */
3218
3219static bool
3220good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
3995f3a2 3221 int freq_sum, profile_count count_sum, int size_cost)
310bc633
MJ
3222{
3223 if (time_benefit == 0
2bf86c84 3224 || !opt_for_fn (node->decl, flag_ipa_cp_clone)
5af56ae8 3225 || node->optimize_for_size_p ())
310bc633
MJ
3226 return false;
3227
df0227c4 3228 gcc_assert (size_cost > 0);
310bc633 3229
99b1c316 3230 class ipa_node_params *info = IPA_NODE_REF (node);
fdfd7f53 3231 int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
3995f3a2 3232 if (max_count > profile_count::zero ())
310bc633 3233 {
357067f2
JH
3234 int factor = RDIV (count_sum.probability_in
3235 (max_count).to_reg_br_prob_base ()
3995f3a2 3236 * 1000, REG_BR_PROB_BASE);
a9243bfc 3237 int64_t evaluation = (((int64_t) time_benefit * factor)
df0227c4 3238 / size_cost);
fdfd7f53 3239 evaluation = incorporate_penalties (node, info, evaluation);
310bc633
MJ
3240
3241 if (dump_file && (dump_flags & TDF_DETAILS))
3995f3a2
JH
3242 {
3243 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
3244 "size: %i, count_sum: ", time_benefit, size_cost);
3245 count_sum.dump (dump_file);
3246 fprintf (dump_file, "%s%s) -> evaluation: " "%" PRId64
df0227c4 3247 ", threshold: %i\n",
9b14fc33
FX
3248 info->node_within_scc
3249 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
af21714c 3250 info->node_calling_single_call ? ", single_call" : "",
fdfd7f53 3251 evaluation, eval_threshold);
3995f3a2 3252 }
310bc633 3253
fdfd7f53 3254 return evaluation >= eval_threshold;
310bc633
MJ
3255 }
3256 else
3257 {
a9243bfc 3258 int64_t evaluation = (((int64_t) time_benefit * freq_sum)
df0227c4 3259 / size_cost);
fdfd7f53 3260 evaluation = incorporate_penalties (node, info, evaluation);
310bc633
MJ
3261
3262 if (dump_file && (dump_flags & TDF_DETAILS))
3263 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
af21714c 3264 "size: %i, freq_sum: %i%s%s) -> evaluation: "
16998094 3265 "%" PRId64 ", threshold: %i\n",
af21714c 3266 time_benefit, size_cost, freq_sum,
9b14fc33
FX
3267 info->node_within_scc
3268 ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
af21714c 3269 info->node_calling_single_call ? ", single_call" : "",
fdfd7f53 3270 evaluation, eval_threshold);
310bc633 3271
fdfd7f53 3272 return evaluation >= eval_threshold;
310bc633
MJ
3273 }
3274}
3275
2c9561b5
MJ
3276/* Return all context independent values from aggregate lattices in PLATS in a
3277 vector. Return NULL if there are none. */
3278
eb270950 3279static vec<ipa_agg_value>
99b1c316 3280context_independent_aggregate_values (class ipcp_param_lattices *plats)
2c9561b5 3281{
eb270950 3282 vec<ipa_agg_value> res = vNULL;
2c9561b5
MJ
3283
3284 if (plats->aggs_bottom
3285 || plats->aggs_contain_variable
3286 || plats->aggs_count == 0)
eb270950 3287 return vNULL;
2c9561b5
MJ
3288
3289 for (struct ipcp_agg_lattice *aglat = plats->aggs;
3290 aglat;
3291 aglat = aglat->next)
c0cb5055 3292 if (aglat->is_single_const ())
2c9561b5 3293 {
eb270950 3294 struct ipa_agg_value item;
2c9561b5
MJ
3295 item.offset = aglat->offset;
3296 item.value = aglat->values->value;
eb270950 3297 res.safe_push (item);
2c9561b5
MJ
3298 }
3299 return res;
3300}
310bc633 3301
44210a96
MJ
3302/* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
3303 populate them with values of parameters that are known independent of the
3304 context. INFO describes the function. If REMOVABLE_PARAMS_COST is
3305 non-NULL, the movement cost of all removable parameters will be stored in
3306 it. */
310bc633
MJ
3307
3308static bool
99b1c316 3309gather_context_independent_values (class ipa_node_params *info,
44210a96
MJ
3310 vec<tree> *known_csts,
3311 vec<ipa_polymorphic_call_context>
3312 *known_contexts,
eb270950 3313 vec<ipa_agg_value_set> *known_aggs,
44210a96 3314 int *removable_params_cost)
310bc633
MJ
3315{
3316 int i, count = ipa_get_param_count (info);
3317 bool ret = false;
3318
9771b263 3319 known_csts->create (0);
44210a96 3320 known_contexts->create (0);
9771b263 3321 known_csts->safe_grow_cleared (count);
44210a96 3322 known_contexts->safe_grow_cleared (count);
2c9561b5
MJ
3323 if (known_aggs)
3324 {
9771b263
DN
3325 known_aggs->create (0);
3326 known_aggs->safe_grow_cleared (count);
2c9561b5 3327 }
310bc633
MJ
3328
3329 if (removable_params_cost)
3330 *removable_params_cost = 0;
3331
155c9907 3332 for (i = 0; i < count; i++)
310bc633 3333 {
99b1c316 3334 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055 3335 ipcp_lattice<tree> *lat = &plats->itself;
310bc633 3336
c0cb5055 3337 if (lat->is_single_const ())
310bc633 3338 {
c0cb5055 3339 ipcp_value<tree> *val = lat->values;
44210a96
MJ
3340 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3341 (*known_csts)[i] = val->value;
3342 if (removable_params_cost)
3343 *removable_params_cost
3344 += estimate_move_cost (TREE_TYPE (val->value), false);
3345 ret = true;
310bc633
MJ
3346 }
3347 else if (removable_params_cost
3348 && !ipa_is_param_used (info, i))
3349 *removable_params_cost
0e8853ee 3350 += ipa_get_param_move_cost (info, i);
2c9561b5 3351
5af56ae8
JH
3352 if (!ipa_is_param_used (info, i))
3353 continue;
3354
44210a96 3355 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
5af56ae8
JH
3356 /* Do not account known context as reason for cloning. We can see
3357 if it permits devirtualization. */
44210a96 3358 if (ctxlat->is_single_const ())
5af56ae8 3359 (*known_contexts)[i] = ctxlat->values->value;
44210a96 3360
2c9561b5
MJ
3361 if (known_aggs)
3362 {
eb270950
FX
3363 vec<ipa_agg_value> agg_items;
3364 struct ipa_agg_value_set *agg;
2c9561b5
MJ
3365
3366 agg_items = context_independent_aggregate_values (plats);
eb270950
FX
3367 agg = &(*known_aggs)[i];
3368 agg->items = agg_items;
3369 agg->by_ref = plats->aggs_by_ref;
3370 ret |= !agg_items.is_empty ();
2c9561b5 3371 }
310bc633
MJ
3372 }
3373
3374 return ret;
3375}
3376
c0cb5055 3377/* Perform time and size measurement of NODE with the context given in
44210a96 3378 KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
c0cb5055
MJ
3379 given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
3380 all context-independent removable parameters and EST_MOVE_COST of estimated
3381 movement of the considered parameter and store it into VAL. */
3382
3383static void
3384perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
44210a96 3385 vec<ipa_polymorphic_call_context> known_contexts,
eb270950 3386 vec<ipa_agg_value_set> known_aggs,
26f1a658 3387 int removable_params_cost,
c0cb5055
MJ
3388 int est_move_cost, ipcp_value_base *val)
3389{
ab38481c 3390 int size, time_benefit;
26f1a658 3391 sreal time, base_time;
0bceb671 3392 ipa_hints hints;
c0cb5055 3393
44210a96 3394 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
eb270950 3395 known_aggs, &size, &time,
26f1a658 3396 &base_time, &hints);
ab38481c
JH
3397 base_time -= time;
3398 if (base_time > 65535)
3399 base_time = 65535;
59d9a0aa
MJ
3400
3401 /* Extern inline functions have no cloning local time benefits because they
3402 will be inlined anyway. The only reason to clone them is if it enables
3403 optimization in any of the functions they call. */
3404 if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
3405 time_benefit = 0;
3406 else
3407 time_benefit = base_time.to_int ()
3408 + devirtualization_time_bonus (node, known_csts, known_contexts,
eb270950 3409 known_aggs)
fdfd7f53 3410 + hint_time_bonus (node, hints)
59d9a0aa 3411 + removable_params_cost + est_move_cost;
c0cb5055
MJ
3412
3413 gcc_checking_assert (size >=0);
3414 /* The inliner-heuristics based estimates may think that in certain
3415 contexts some functions do not have any size at all but we want
3416 all specializations to have at least a tiny cost, not least not to
3417 divide by zero. */
3418 if (size == 0)
3419 size = 1;
3420
3421 val->local_time_benefit = time_benefit;
3422 val->local_size_cost = size;
3423}
3424
f7725a48
MJ
3425/* Get the overall limit oof growth based on parameters extracted from growth.
3426 it does not really make sense to mix functions with different overall growth
3427 limits but it is possible and if it happens, we do not want to select one
3428 limit at random. */
3429
3430static long
3431get_max_overall_size (cgraph_node *node)
3432{
3433 long max_new_size = orig_overall_size;
3434 long large_unit = opt_for_fn (node->decl, param_large_unit_insns);
3435 if (max_new_size < large_unit)
3436 max_new_size = large_unit;
12122f94 3437 int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
f7725a48
MJ
3438 max_new_size += max_new_size * unit_growth / 100 + 1;
3439 return max_new_size;
3440}
3441
310bc633
MJ
3442/* Iterate over known values of parameters of NODE and estimate the local
3443 effects in terms of time and size they have. */
3444
3445static void
3446estimate_local_effects (struct cgraph_node *node)
3447{
99b1c316 3448 class ipa_node_params *info = IPA_NODE_REF (node);
310bc633 3449 int i, count = ipa_get_param_count (info);
44210a96
MJ
3450 vec<tree> known_csts;
3451 vec<ipa_polymorphic_call_context> known_contexts;
eb270950 3452 vec<ipa_agg_value_set> known_aggs;
310bc633 3453 bool always_const;
310bc633
MJ
3454 int removable_params_cost;
3455
3456 if (!count || !ipcp_versionable_function_p (node))
3457 return;
3458
ca30a539 3459 if (dump_file && (dump_flags & TDF_DETAILS))
464d0118 3460 fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
310bc633
MJ
3461
3462 always_const = gather_context_independent_values (info, &known_csts,
44210a96 3463 &known_contexts, &known_aggs,
310bc633 3464 &removable_params_cost);
5af56ae8 3465 int devirt_bonus = devirtualization_time_bonus (node, known_csts,
eb270950 3466 known_contexts, known_aggs);
dcf89d57 3467 if (always_const || devirt_bonus
87f94429 3468 || (removable_params_cost && node->can_change_signature))
ca30a539 3469 {
310bc633 3470 struct caller_statistics stats;
0bceb671 3471 ipa_hints hints;
26f1a658 3472 sreal time, base_time;
ab38481c 3473 int size;
310bc633
MJ
3474
3475 init_caller_stats (&stats);
d52f5295
ML
3476 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3477 false);
44210a96 3478 estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
eb270950 3479 known_aggs, &size, &time,
26f1a658 3480 &base_time, &hints);
5af56ae8 3481 time -= devirt_bonus;
fdfd7f53 3482 time -= hint_time_bonus (node, hints);
310bc633
MJ
3483 time -= removable_params_cost;
3484 size -= stats.n_calls * removable_params_cost;
3485
3486 if (dump_file)
3487 fprintf (dump_file, " - context independent values, size: %i, "
ab38481c 3488 "time_benefit: %f\n", size, (base_time - time).to_double ());
310bc633 3489
87f94429 3490 if (size <= 0 || node->local)
310bc633 3491 {
eb20b778 3492 info->do_clone_for_all_contexts = true;
310bc633
MJ
3493
3494 if (dump_file)
3495 fprintf (dump_file, " Decided to specialize for all "
3496 "known contexts, code not going to grow.\n");
3497 }
26f1a658 3498 else if (good_cloning_opportunity_p (node,
5036f628 3499 MIN ((base_time - time).to_int (),
26f1a658 3500 65536),
310bc633
MJ
3501 stats.freq_sum, stats.count_sum,
3502 size))
3503 {
f7725a48 3504 if (size + overall_size <= get_max_overall_size (node))
310bc633 3505 {
eb20b778 3506 info->do_clone_for_all_contexts = true;
310bc633
MJ
3507 overall_size += size;
3508
3509 if (dump_file)
3510 fprintf (dump_file, " Decided to specialize for all "
3511 "known contexts, growth deemed beneficial.\n");
3512 }
3513 else if (dump_file && (dump_flags & TDF_DETAILS))
f7725a48
MJ
3514 fprintf (dump_file, " Not cloning for all contexts because "
3515 "maximum unit size would be reached with %li.\n",
310bc633
MJ
3516 size + overall_size);
3517 }
5af56ae8
JH
3518 else if (dump_file && (dump_flags & TDF_DETAILS))
3519 fprintf (dump_file, " Not cloning for all contexts because "
3520 "!good_cloning_opportunity_p.\n");
155c9907 3521
ca30a539
JH
3522 }
3523
155c9907 3524 for (i = 0; i < count; i++)
ca30a539 3525 {
99b1c316 3526 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055
MJ
3527 ipcp_lattice<tree> *lat = &plats->itself;
3528 ipcp_value<tree> *val;
310bc633
MJ
3529
3530 if (lat->bottom
3531 || !lat->values
44210a96 3532 || known_csts[i])
310bc633
MJ
3533 continue;
3534
3535 for (val = lat->values; val; val = val->next)
3536 {
44210a96
MJ
3537 gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
3538 known_csts[i] = val->value;
310bc633 3539
44210a96
MJ
3540 int emc = estimate_move_cost (TREE_TYPE (val->value), true);
3541 perform_estimation_of_a_value (node, known_csts, known_contexts,
eb270950 3542 known_aggs,
c0cb5055 3543 removable_params_cost, emc, val);
0318fc77 3544
310bc633
MJ
3545 if (dump_file && (dump_flags & TDF_DETAILS))
3546 {
3547 fprintf (dump_file, " - estimates for value ");
3548 print_ipcp_constant_value (dump_file, val->value);
0e8853ee
JH
3549 fprintf (dump_file, " for ");
3550 ipa_dump_param (dump_file, info, i);
310bc633 3551 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
c0cb5055 3552 val->local_time_benefit, val->local_size_cost);
310bc633 3553 }
310bc633 3554 }
9771b263 3555 known_csts[i] = NULL_TREE;
2c9561b5
MJ
3556 }
3557
44210a96
MJ
3558 for (i = 0; i < count; i++)
3559 {
99b1c316 3560 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
44210a96
MJ
3561
3562 if (!plats->virt_call)
3563 continue;
3564
3565 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3566 ipcp_value<ipa_polymorphic_call_context> *val;
3567
3568 if (ctxlat->bottom
3569 || !ctxlat->values
3570 || !known_contexts[i].useless_p ())
3571 continue;
3572
3573 for (val = ctxlat->values; val; val = val->next)
3574 {
3575 known_contexts[i] = val->value;
3576 perform_estimation_of_a_value (node, known_csts, known_contexts,
eb270950 3577 known_aggs,
44210a96
MJ
3578 removable_params_cost, 0, val);
3579
3580 if (dump_file && (dump_flags & TDF_DETAILS))
3581 {
3582 fprintf (dump_file, " - estimates for polymorphic context ");
3583 print_ipcp_constant_value (dump_file, val->value);
3584 fprintf (dump_file, " for ");
3585 ipa_dump_param (dump_file, info, i);
3586 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
3587 val->local_time_benefit, val->local_size_cost);
3588 }
3589 }
3590 known_contexts[i] = ipa_polymorphic_call_context ();
3591 }
3592
155c9907 3593 for (i = 0; i < count; i++)
2c9561b5 3594 {
99b1c316 3595 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
eb270950 3596 struct ipa_agg_value_set *agg;
2c9561b5
MJ
3597 struct ipcp_agg_lattice *aglat;
3598
3599 if (plats->aggs_bottom || !plats->aggs)
3600 continue;
3601
eb270950 3602 agg = &known_aggs[i];
2c9561b5
MJ
3603 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3604 {
c0cb5055 3605 ipcp_value<tree> *val;
2c9561b5
MJ
3606 if (aglat->bottom || !aglat->values
3607 /* If the following is true, the one value is in known_aggs. */
3608 || (!plats->aggs_contain_variable
c0cb5055 3609 && aglat->is_single_const ()))
2c9561b5
MJ
3610 continue;
3611
3612 for (val = aglat->values; val; val = val->next)
3613 {
eb270950 3614 struct ipa_agg_value item;
2c9561b5
MJ
3615
3616 item.offset = aglat->offset;
3617 item.value = val->value;
eb270950 3618 agg->items.safe_push (item);
2c9561b5 3619
44210a96 3620 perform_estimation_of_a_value (node, known_csts, known_contexts,
eb270950 3621 known_aggs,
c0cb5055 3622 removable_params_cost, 0, val);
2c9561b5
MJ
3623
3624 if (dump_file && (dump_flags & TDF_DETAILS))
3625 {
3626 fprintf (dump_file, " - estimates for value ");
3627 print_ipcp_constant_value (dump_file, val->value);
0e8853ee 3628 fprintf (dump_file, " for ");
155c9907 3629 ipa_dump_param (dump_file, info, i);
2c9561b5 3630 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
c0cb5055
MJ
3631 "]: time_benefit: %i, size: %i\n",
3632 plats->aggs_by_ref ? "ref " : "",
3633 aglat->offset,
3634 val->local_time_benefit, val->local_size_cost);
2c9561b5
MJ
3635 }
3636
eb270950 3637 agg->items.pop ();
2c9561b5
MJ
3638 }
3639 }
3640 }
3641
9771b263 3642 known_csts.release ();
44210a96 3643 known_contexts.release ();
eb270950 3644 ipa_release_agg_values (known_aggs);
310bc633
MJ
3645}
3646
3647
3648/* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
3649 topological sort of values. */
3650
c0cb5055
MJ
3651template <typename valtype>
3652void
3653value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
310bc633 3654{
c0cb5055 3655 ipcp_value_source<valtype> *src;
310bc633
MJ
3656
3657 if (cur_val->dfs)
3658 return;
3659
3660 dfs_counter++;
3661 cur_val->dfs = dfs_counter;
3662 cur_val->low_link = dfs_counter;
3663
3664 cur_val->topo_next = stack;
3665 stack = cur_val;
3666 cur_val->on_stack = true;
3667
3668 for (src = cur_val->sources; src; src = src->next)
3669 if (src->val)
3670 {
3671 if (src->val->dfs == 0)
3672 {
c0cb5055 3673 add_val (src->val);
310bc633
MJ
3674 if (src->val->low_link < cur_val->low_link)
3675 cur_val->low_link = src->val->low_link;
3676 }
3677 else if (src->val->on_stack
3678 && src->val->dfs < cur_val->low_link)
3679 cur_val->low_link = src->val->dfs;
3680 }
3681
3682 if (cur_val->dfs == cur_val->low_link)
ca30a539 3683 {
c0cb5055 3684 ipcp_value<valtype> *v, *scc_list = NULL;
310bc633
MJ
3685
3686 do
3687 {
3688 v = stack;
3689 stack = v->topo_next;
3690 v->on_stack = false;
3691
3692 v->scc_next = scc_list;
3693 scc_list = v;
3694 }
3695 while (v != cur_val);
3696
3697 cur_val->topo_next = values_topo;
3698 values_topo = cur_val;
ca30a539 3699 }
518dc859
RL
3700}
3701
310bc633
MJ
3702/* Add all values in lattices associated with NODE to the topological sort if
3703 they are not there yet. */
3704
3705static void
c0cb5055 3706add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
518dc859 3707{
99b1c316 3708 class ipa_node_params *info = IPA_NODE_REF (node);
310bc633
MJ
3709 int i, count = ipa_get_param_count (info);
3710
155c9907 3711 for (i = 0; i < count; i++)
310bc633 3712 {
99b1c316 3713 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055 3714 ipcp_lattice<tree> *lat = &plats->itself;
2c9561b5 3715 struct ipcp_agg_lattice *aglat;
310bc633 3716
2c9561b5 3717 if (!lat->bottom)
44210a96
MJ
3718 {
3719 ipcp_value<tree> *val;
3720 for (val = lat->values; val; val = val->next)
3721 topo->constants.add_val (val);
3722 }
2c9561b5
MJ
3723
3724 if (!plats->aggs_bottom)
3725 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3726 if (!aglat->bottom)
44210a96
MJ
3727 {
3728 ipcp_value<tree> *val;
3729 for (val = aglat->values; val; val = val->next)
3730 topo->constants.add_val (val);
3731 }
3732
3733 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
3734 if (!ctxlat->bottom)
3735 {
3736 ipcp_value<ipa_polymorphic_call_context> *ctxval;
3737 for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
3738 topo->contexts.add_val (ctxval);
3739 }
310bc633 3740 }
518dc859
RL
3741}
3742
310bc633
MJ
3743/* One pass of constants propagation along the call graph edges, from callers
3744 to callees (requires topological ordering in TOPO), iterate over strongly
3745 connected components. */
3746
518dc859 3747static void
99b1c316 3748propagate_constants_topo (class ipa_topo_info *topo)
518dc859 3749{
310bc633 3750 int i;
518dc859 3751
310bc633 3752 for (i = topo->nnodes - 1; i >= 0; i--)
518dc859 3753 {
39e87baf 3754 unsigned j;
310bc633 3755 struct cgraph_node *v, *node = topo->order[i];
d52f5295 3756 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
310bc633 3757
310bc633
MJ
3758 /* First, iteratively propagate within the strongly connected component
3759 until all lattices stabilize. */
39e87baf 3760 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
d52f5295 3761 if (v->has_gimple_body_p ())
6cf67b62 3762 {
e72763e2
JH
3763 if (opt_for_fn (v->decl, flag_ipa_cp)
3764 && opt_for_fn (v->decl, optimize))
6cf67b62 3765 push_node_to_stack (topo, v);
223f4b10 3766 /* When V is not optimized, we can not push it to stack, but
6cf67b62
JH
3767 still we need to set all its callees lattices to bottom. */
3768 else
3769 {
3770 for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
3771 propagate_constants_across_call (cs);
3772 }
3773 }
310bc633 3774
39e87baf 3775 v = pop_node_from_stack (topo);
310bc633
MJ
3776 while (v)
3777 {
3778 struct cgraph_edge *cs;
9b14fc33
FX
3779 class ipa_node_params *info = NULL;
3780 bool self_scc = true;
310bc633
MJ
3781
3782 for (cs = v->callees; cs; cs = cs->next_callee)
af21714c
MJ
3783 if (ipa_edge_within_scc (cs))
3784 {
9b14fc33
FX
3785 cgraph_node *callee = cs->callee->function_symbol ();
3786
3787 if (v != callee)
3788 self_scc = false;
3789
3790 if (!info)
3791 {
3792 info = IPA_NODE_REF (v);
3793 info->node_within_scc = true;
3794 }
3795
155c9907 3796 if (propagate_constants_across_call (cs))
9b14fc33 3797 push_node_to_stack (topo, callee);
af21714c 3798 }
9b14fc33
FX
3799
3800 if (info)
3801 info->node_is_self_scc = self_scc;
3802
310bc633
MJ
3803 v = pop_node_from_stack (topo);
3804 }
3805
3806 /* Afterwards, propagate along edges leading out of the SCC, calculates
3807 the local effects of the discovered constants and all valid values to
3808 their topological sort. */
39e87baf 3809 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
6cf67b62 3810 if (v->has_gimple_body_p ()
e72763e2
JH
3811 && opt_for_fn (v->decl, flag_ipa_cp)
3812 && opt_for_fn (v->decl, optimize))
39e87baf
MJ
3813 {
3814 struct cgraph_edge *cs;
310bc633 3815
39e87baf 3816 estimate_local_effects (v);
c0cb5055 3817 add_all_node_vals_to_toposort (v, topo);
39e87baf 3818 for (cs = v->callees; cs; cs = cs->next_callee)
4cb13597 3819 if (!ipa_edge_within_scc (cs))
155c9907 3820 propagate_constants_across_call (cs);
39e87baf
MJ
3821 }
3822 cycle_nodes.release ();
518dc859
RL
3823 }
3824}
3825
df0227c4
MJ
3826
3827/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
3828 the bigger one if otherwise. */
3829
3830static int
3831safe_add (int a, int b)
3832{
3833 if (a > INT_MAX/2 || b > INT_MAX/2)
3834 return a > b ? a : b;
3835 else
3836 return a + b;
3837}
3838
3839
310bc633 3840/* Propagate the estimated effects of individual values along the topological
073a8998 3841 from the dependent values to those they depend on. */
310bc633 3842
c0cb5055
MJ
3843template <typename valtype>
3844void
3845value_topo_info<valtype>::propagate_effects ()
518dc859 3846{
c0cb5055 3847 ipcp_value<valtype> *base;
518dc859 3848
310bc633 3849 for (base = values_topo; base; base = base->topo_next)
518dc859 3850 {
c0cb5055
MJ
3851 ipcp_value_source<valtype> *src;
3852 ipcp_value<valtype> *val;
310bc633
MJ
3853 int time = 0, size = 0;
3854
3855 for (val = base; val; val = val->scc_next)
3856 {
df0227c4
MJ
3857 time = safe_add (time,
3858 val->local_time_benefit + val->prop_time_benefit);
3859 size = safe_add (size, val->local_size_cost + val->prop_size_cost);
310bc633
MJ
3860 }
3861
3862 for (val = base; val; val = val->scc_next)
3863 for (src = val->sources; src; src = src->next)
3864 if (src->val
3dafb85c 3865 && src->cs->maybe_hot_p ())
310bc633 3866 {
df0227c4
MJ
3867 src->val->prop_time_benefit = safe_add (time,
3868 src->val->prop_time_benefit);
3869 src->val->prop_size_cost = safe_add (size,
3870 src->val->prop_size_cost);
310bc633 3871 }
518dc859
RL
3872 }
3873}
3874
310bc633 3875
44210a96
MJ
3876/* Propagate constants, polymorphic contexts and their effects from the
3877 summaries interprocedurally. */
310bc633 3878
518dc859 3879static void
99b1c316 3880ipcp_propagate_stage (class ipa_topo_info *topo)
518dc859
RL
3881{
3882 struct cgraph_node *node;
518dc859 3883
310bc633
MJ
3884 if (dump_file)
3885 fprintf (dump_file, "\n Propagating constants:\n\n");
3886
e7a74006
JH
3887 max_count = profile_count::uninitialized ();
3888
310bc633
MJ
3889 FOR_EACH_DEFINED_FUNCTION (node)
3890 {
e72763e2
JH
3891 if (node->has_gimple_body_p ()
3892 && opt_for_fn (node->decl, flag_ipa_cp)
3893 && opt_for_fn (node->decl, optimize))
310bc633 3894 {
6cf67b62
JH
3895 class ipa_node_params *info = IPA_NODE_REF (node);
3896 determine_versionability (node, info);
99b1c316 3897 info->lattices = XCNEWVEC (class ipcp_param_lattices,
310bc633
MJ
3898 ipa_get_param_count (info));
3899 initialize_node_lattices (node);
3900 }
f658ad30 3901 ipa_size_summary *s = ipa_size_summaries->get (node);
56f62793
ML
3902 if (node->definition && !node->alias && s != NULL)
3903 overall_size += s->self_size;
1bad9c18 3904 max_count = max_count.max (node->count.ipa ());
310bc633
MJ
3905 }
3906
f7725a48 3907 orig_overall_size = overall_size;
310bc633
MJ
3908
3909 if (dump_file)
f7725a48 3910 fprintf (dump_file, "\noverall_size: %li\n", overall_size);
310bc633
MJ
3911
3912 propagate_constants_topo (topo);
b2b29377
MM
3913 if (flag_checking)
3914 ipcp_verify_propagated_values ();
c0cb5055 3915 topo->constants.propagate_effects ();
44210a96 3916 topo->contexts.propagate_effects ();
310bc633
MJ
3917
3918 if (dump_file)
3919 {
3920 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
3921 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
3922 }
3923}
3924
3925/* Discover newly direct outgoing edges from NODE which is a new clone with
44210a96 3926 known KNOWN_CSTS and make them direct. */
310bc633
MJ
3927
3928static void
3929ipcp_discover_new_direct_edges (struct cgraph_node *node,
44210a96
MJ
3930 vec<tree> known_csts,
3931 vec<ipa_polymorphic_call_context>
3932 known_contexts,
162712de 3933 struct ipa_agg_replacement_value *aggvals)
310bc633
MJ
3934{
3935 struct cgraph_edge *ie, *next_ie;
0f378cb5 3936 bool found = false;
310bc633
MJ
3937
3938 for (ie = node->indirect_calls; ie; ie = next_ie)
3939 {
81fa35bd 3940 tree target;
231b4916 3941 bool speculative;
310bc633
MJ
3942
3943 next_ie = ie->next_callee;
44210a96 3944 target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
231b4916 3945 vNULL, aggvals, &speculative);
310bc633 3946 if (target)
0f378cb5 3947 {
042ae7d2
JH
3948 bool agg_contents = ie->indirect_info->agg_contents;
3949 bool polymorphic = ie->indirect_info->polymorphic;
a4e33812 3950 int param_index = ie->indirect_info->param_index;
231b4916
JH
3951 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
3952 speculative);
0f378cb5 3953 found = true;
4502fe8d 3954
042ae7d2 3955 if (cs && !agg_contents && !polymorphic)
4502fe8d 3956 {
99b1c316 3957 class ipa_node_params *info = IPA_NODE_REF (node);
4502fe8d
MJ
3958 int c = ipa_get_controlled_uses (info, param_index);
3959 if (c != IPA_UNDESCRIBED_USE)
3960 {
3961 struct ipa_ref *to_del;
3962
3963 c--;
3964 ipa_set_controlled_uses (info, param_index, c);
3965 if (dump_file && (dump_flags & TDF_DETAILS))
3966 fprintf (dump_file, " controlled uses count of param "
3967 "%i bumped down to %i\n", param_index, c);
3968 if (c == 0
d122681a 3969 && (to_del = node->find_reference (cs->callee, NULL, 0)))
4502fe8d
MJ
3970 {
3971 if (dump_file && (dump_flags & TDF_DETAILS))
3972 fprintf (dump_file, " and even removing its "
3973 "cloning-created reference\n");
d122681a 3974 to_del->remove_reference ();
4502fe8d
MJ
3975 }
3976 }
3977 }
0f378cb5 3978 }
310bc633 3979 }
0f378cb5
JH
3980 /* Turning calls to direct calls will improve overall summary. */
3981 if (found)
0bceb671 3982 ipa_update_overall_fn_summary (node);
310bc633
MJ
3983}
3984
1ac2bdb4
ML
3985class edge_clone_summary;
3986static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
310bc633 3987
1ac2bdb4 3988/* Edge clone summary. */
310bc633 3989
6c1dae73 3990class edge_clone_summary
310bc633 3991{
6c1dae73 3992public:
1ac2bdb4
ML
3993 /* Default constructor. */
3994 edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
aef83682 3995
1ac2bdb4
ML
3996 /* Default destructor. */
3997 ~edge_clone_summary ()
3998 {
3999 if (prev_clone)
4000 edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
4001 if (next_clone)
4002 edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
4003 }
310bc633 4004
1ac2bdb4
ML
4005 cgraph_edge *prev_clone;
4006 cgraph_edge *next_clone;
4007};
aef83682 4008
1ac2bdb4
ML
4009class edge_clone_summary_t:
4010 public call_summary <edge_clone_summary *>
aef83682 4011{
1ac2bdb4
ML
4012public:
4013 edge_clone_summary_t (symbol_table *symtab):
4014 call_summary <edge_clone_summary *> (symtab)
4015 {
4016 m_initialize_when_cloning = true;
4017 }
aef83682 4018
1ac2bdb4
ML
4019 virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4020 edge_clone_summary *src_data,
4021 edge_clone_summary *dst_data);
4022};
4023
4024/* Edge duplication hook. */
4025
4026void
4027edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
4028 edge_clone_summary *src_data,
4029 edge_clone_summary *dst_data)
4030{
4031 if (src_data->next_clone)
4032 edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
4033 dst_data->prev_clone = src_edge;
4034 dst_data->next_clone = src_data->next_clone;
4035 src_data->next_clone = dst_edge;
aef83682
MJ
4036}
4037
47f4756e 4038/* Return true is NODE is DEST or its clone for all contexts. */
310bc633
MJ
4039
4040static bool
47f4756e
MJ
4041same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
4042{
4043 if (node == dest)
4044 return true;
4045
99b1c316 4046 class ipa_node_params *info = IPA_NODE_REF (node);
47f4756e
MJ
4047 return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
4048}
4049
7b668576
MJ
4050/* Return true if edge CS does bring about the value described by SRC to
4051 DEST_VAL of node DEST or its clone for all contexts. */
47f4756e
MJ
4052
4053static bool
4054cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
7b668576 4055 cgraph_node *dest, ipcp_value<tree> *dest_val)
310bc633 4056{
99b1c316 4057 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
47f4756e
MJ
4058 enum availability availability;
4059 cgraph_node *real_dest = cs->callee->function_symbol (&availability);
310bc633 4060
6cf67b62
JH
4061 if (availability <= AVAIL_INTERPOSABLE
4062 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
310bc633
MJ
4063 || caller_info->node_dead)
4064 return false;
2f1f3ac4
MJ
4065
4066 if (!src->val)
310bc633
MJ
4067 return true;
4068
4069 if (caller_info->ipcp_orig_node)
4070 {
2c9561b5
MJ
4071 tree t;
4072 if (src->offset == -1)
44210a96 4073 t = caller_info->known_csts[src->index];
2c9561b5
MJ
4074 else
4075 t = get_clone_agg_value (cs->caller, src->offset, src->index);
310bc633
MJ
4076 return (t != NULL_TREE
4077 && values_equal_for_ipcp_p (src->val->value, t));
4078 }
4079 else
518dc859 4080 {
2f1f3ac4
MJ
4081 /* At the moment we do not propagate over arithmetic jump functions in
4082 SCCs, so it is safe to detect self-feeding recursive calls in this
4083 way. */
4084 if (src->val == dest_val)
4085 return true;
4086
2c9561b5 4087 struct ipcp_agg_lattice *aglat;
99b1c316 4088 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
2c9561b5
MJ
4089 src->index);
4090 if (src->offset == -1)
c0cb5055 4091 return (plats->itself.is_single_const ()
2c9561b5
MJ
4092 && values_equal_for_ipcp_p (src->val->value,
4093 plats->itself.values->value));
310bc633 4094 else
2c9561b5
MJ
4095 {
4096 if (plats->aggs_bottom || plats->aggs_contain_variable)
4097 return false;
4098 for (aglat = plats->aggs; aglat; aglat = aglat->next)
4099 if (aglat->offset == src->offset)
c0cb5055 4100 return (aglat->is_single_const ()
2c9561b5
MJ
4101 && values_equal_for_ipcp_p (src->val->value,
4102 aglat->values->value));
4103 }
4104 return false;
310bc633
MJ
4105 }
4106}
4107
7b668576
MJ
4108/* Return true if edge CS does bring about the value described by SRC to
4109 DST_VAL of node DEST or its clone for all contexts. */
44210a96
MJ
4110
4111static bool
47f4756e
MJ
4112cgraph_edge_brings_value_p (cgraph_edge *cs,
4113 ipcp_value_source<ipa_polymorphic_call_context> *src,
7b668576
MJ
4114 cgraph_node *dest,
4115 ipcp_value<ipa_polymorphic_call_context> *)
44210a96 4116{
99b1c316 4117 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
6cf67b62
JH
4118 enum availability avail;
4119 cgraph_node *real_dest = cs->callee->function_symbol (&avail);
44210a96 4120
6cf67b62
JH
4121 if (avail <= AVAIL_INTERPOSABLE
4122 || !same_node_or_its_all_contexts_clone_p (real_dest, dest)
44210a96
MJ
4123 || caller_info->node_dead)
4124 return false;
4125 if (!src->val)
4126 return true;
4127
4128 if (caller_info->ipcp_orig_node)
4129 return (caller_info->known_contexts.length () > (unsigned) src->index)
4130 && values_equal_for_ipcp_p (src->val->value,
4131 caller_info->known_contexts[src->index]);
4132
99b1c316 4133 class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
44210a96
MJ
4134 src->index);
4135 return plats->ctxlat.is_single_const ()
4136 && values_equal_for_ipcp_p (src->val->value,
4137 plats->ctxlat.values->value);
4138}
4139
2c9561b5
MJ
4140/* Get the next clone in the linked list of clones of an edge. */
4141
4142static inline struct cgraph_edge *
4143get_next_cgraph_edge_clone (struct cgraph_edge *cs)
4144{
1ac2bdb4
ML
4145 edge_clone_summary *s = edge_clone_summaries->get (cs);
4146 return s != NULL ? s->next_clone : NULL;
2c9561b5
MJ
4147}
4148
7b668576
MJ
4149/* Given VAL that is intended for DEST, iterate over all its sources and if any
4150 of them is viable and hot, return true. In that case, for those that still
4151 hold, add their edge frequency and their number into *FREQUENCY and
4152 *CALLER_COUNT respectively. */
310bc633 4153
c0cb5055 4154template <typename valtype>
310bc633 4155static bool
47f4756e
MJ
4156get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
4157 int *freq_sum,
3995f3a2 4158 profile_count *count_sum, int *caller_count)
310bc633 4159{
c0cb5055 4160 ipcp_value_source<valtype> *src;
310bc633 4161 int freq = 0, count = 0;
3995f3a2 4162 profile_count cnt = profile_count::zero ();
310bc633 4163 bool hot = false;
7b668576 4164 bool non_self_recursive = false;
310bc633
MJ
4165
4166 for (src = val->sources; src; src = src->next)
4167 {
4168 struct cgraph_edge *cs = src->cs;
4169 while (cs)
518dc859 4170 {
7b668576 4171 if (cgraph_edge_brings_value_p (cs, src, dest, val))
310bc633
MJ
4172 {
4173 count++;
1bad9c18
JH
4174 freq += cs->frequency ();
4175 if (cs->count.ipa ().initialized_p ())
4176 cnt += cs->count.ipa ();
3dafb85c 4177 hot |= cs->maybe_hot_p ();
7b668576
MJ
4178 if (cs->caller != dest)
4179 non_self_recursive = true;
310bc633
MJ
4180 }
4181 cs = get_next_cgraph_edge_clone (cs);
518dc859
RL
4182 }
4183 }
310bc633 4184
7b668576
MJ
4185 /* If the only edges bringing a value are self-recursive ones, do not bother
4186 evaluating it. */
4187 if (!non_self_recursive)
4188 return false;
4189
310bc633
MJ
4190 *freq_sum = freq;
4191 *count_sum = cnt;
4192 *caller_count = count;
9b14fc33
FX
4193
4194 if (!hot && IPA_NODE_REF (dest)->node_within_scc)
4195 {
4196 struct cgraph_edge *cs;
4197
4198 /* Cold non-SCC source edge could trigger hot recursive execution of
4199 function. Consider the case as hot and rely on following cost model
4200 computation to further select right one. */
4201 for (cs = dest->callers; cs; cs = cs->next_caller)
4202 if (cs->caller == dest && cs->maybe_hot_p ())
4203 return true;
4204 }
4205
310bc633 4206 return hot;
518dc859
RL
4207}
4208
a0f6a8cb
FX
4209/* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
4210 to let a non-self-recursive caller be the first element. Thus, we can
4211 simplify intersecting operations on values that arrive from all of these
4212 callers, especially when there exists self-recursive call. Return true if
4213 this kind of adjustment is possible. */
4214
4215static bool
4216adjust_callers_for_value_intersection (vec<cgraph_edge *> callers,
4217 cgraph_node *node)
4218{
4219 for (unsigned i = 0; i < callers.length (); i++)
4220 {
4221 cgraph_edge *cs = callers[i];
4222
4223 if (cs->caller != node)
4224 {
4225 if (i > 0)
4226 {
4227 callers[i] = callers[0];
4228 callers[0] = cs;
4229 }
4230 return true;
4231 }
4232 }
4233 return false;
4234}
4235
47f4756e
MJ
4236/* Return a vector of incoming edges that do bring value VAL to node DEST. It
4237 is assumed their number is known and equal to CALLER_COUNT. */
310bc633 4238
c0cb5055 4239template <typename valtype>
d52f5295 4240static vec<cgraph_edge *>
47f4756e
MJ
4241gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
4242 int caller_count)
518dc859 4243{
c0cb5055 4244 ipcp_value_source<valtype> *src;
d52f5295 4245 vec<cgraph_edge *> ret;
310bc633 4246
9771b263 4247 ret.create (caller_count);
310bc633
MJ
4248 for (src = val->sources; src; src = src->next)
4249 {
4250 struct cgraph_edge *cs = src->cs;
4251 while (cs)
4252 {
7b668576 4253 if (cgraph_edge_brings_value_p (cs, src, dest, val))
9771b263 4254 ret.quick_push (cs);
310bc633
MJ
4255 cs = get_next_cgraph_edge_clone (cs);
4256 }
4257 }
4258
a0f6a8cb
FX
4259 if (caller_count > 1)
4260 adjust_callers_for_value_intersection (ret, dest);
4261
310bc633 4262 return ret;
518dc859
RL
4263}
4264
310bc633
MJ
4265/* Construct a replacement map for a know VALUE for a formal parameter PARAM.
4266 Return it or NULL if for some reason it cannot be created. */
4267
518dc859 4268static struct ipa_replace_map *
99b1c316 4269get_replacement_map (class ipa_node_params *info, tree value, int parm_num)
518dc859
RL
4270{
4271 struct ipa_replace_map *replace_map;
518dc859 4272
766090c2 4273 replace_map = ggc_alloc<ipa_replace_map> ();
c6f7cfc1
JH
4274 if (dump_file)
4275 {
0e8853ee
JH
4276 fprintf (dump_file, " replacing ");
4277 ipa_dump_param (dump_file, info, parm_num);
155c9907 4278
c6f7cfc1 4279 fprintf (dump_file, " with const ");
ef6cb4c7 4280 print_generic_expr (dump_file, value);
c6f7cfc1
JH
4281 fprintf (dump_file, "\n");
4282 }
49bde175 4283 replace_map->parm_num = parm_num;
310bc633 4284 replace_map->new_tree = value;
518dc859
RL
4285 return replace_map;
4286}
4287
310bc633 4288/* Dump new profiling counts */
518dc859 4289
518dc859 4290static void
310bc633
MJ
4291dump_profile_updates (struct cgraph_node *orig_node,
4292 struct cgraph_node *new_node)
518dc859 4293{
310bc633 4294 struct cgraph_edge *cs;
518dc859 4295
3995f3a2
JH
4296 fprintf (dump_file, " setting count of the specialized node to ");
4297 new_node->count.dump (dump_file);
4298 fprintf (dump_file, "\n");
155c9907 4299 for (cs = new_node->callees; cs; cs = cs->next_callee)
3995f3a2
JH
4300 {
4301 fprintf (dump_file, " edge to %s has count ",
3629ff8a 4302 cs->callee->dump_name ());
3995f3a2
JH
4303 cs->count.dump (dump_file);
4304 fprintf (dump_file, "\n");
4305 }
310bc633 4306
3995f3a2
JH
4307 fprintf (dump_file, " setting count of the original node to ");
4308 orig_node->count.dump (dump_file);
4309 fprintf (dump_file, "\n");
155c9907 4310 for (cs = orig_node->callees; cs; cs = cs->next_callee)
3995f3a2
JH
4311 {
4312 fprintf (dump_file, " edge to %s is left with ",
3629ff8a 4313 cs->callee->dump_name ());
3995f3a2
JH
4314 cs->count.dump (dump_file);
4315 fprintf (dump_file, "\n");
4316 }
310bc633 4317}
c6f7cfc1 4318
310bc633
MJ
4319/* After a specialized NEW_NODE version of ORIG_NODE has been created, update
4320 their profile information to reflect this. */
518dc859 4321
518dc859 4322static void
310bc633
MJ
4323update_profiling_info (struct cgraph_node *orig_node,
4324 struct cgraph_node *new_node)
518dc859 4325{
518dc859 4326 struct cgraph_edge *cs;
310bc633 4327 struct caller_statistics stats;
3995f3a2
JH
4328 profile_count new_sum, orig_sum;
4329 profile_count remainder, orig_node_count = orig_node->count;
2e7fd867 4330 profile_count orig_new_node_count = new_node->count;
310bc633 4331
1bad9c18 4332 if (!(orig_node_count.ipa () > profile_count::zero ()))
310bc633 4333 return;
518dc859 4334
310bc633 4335 init_caller_stats (&stats);
d52f5295
ML
4336 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4337 false);
310bc633
MJ
4338 orig_sum = stats.count_sum;
4339 init_caller_stats (&stats);
d52f5295
ML
4340 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
4341 false);
310bc633
MJ
4342 new_sum = stats.count_sum;
4343
4344 if (orig_node_count < orig_sum + new_sum)
518dc859 4345 {
310bc633 4346 if (dump_file)
3995f3a2
JH
4347 {
4348 fprintf (dump_file, " Problem: node %s has too low count ",
4349 orig_node->dump_name ());
4350 orig_node_count.dump (dump_file);
4351 fprintf (dump_file, "while the sum of incoming count is ");
4352 (orig_sum + new_sum).dump (dump_file);
4353 fprintf (dump_file, "\n");
4354 }
4355
4356 orig_node_count = (orig_sum + new_sum).apply_scale (12, 10);
310bc633 4357 if (dump_file)
3995f3a2
JH
4358 {
4359 fprintf (dump_file, " proceeding by pretending it was ");
4360 orig_node_count.dump (dump_file);
4361 fprintf (dump_file, "\n");
4362 }
518dc859 4363 }
310bc633 4364
517048ce
JH
4365 remainder = orig_node_count.combine_with_ipa_count (orig_node_count.ipa ()
4366 - new_sum.ipa ());
34fbe3f0
JH
4367
4368 /* With partial train run we do not want to assume that original's
4369 count is zero whenever we redurect all executed edges to clone.
4370 Simply drop profile to local one in this case. */
4371 if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
4372 && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
4373 && flag_profile_partial_training)
4374 remainder = remainder.guessed_local ();
4375
517048ce 4376 new_sum = orig_node_count.combine_with_ipa_count (new_sum);
2e7fd867 4377 new_node->count = new_sum;
310bc633
MJ
4378 orig_node->count = remainder;
4379
2e7fd867 4380 profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
155c9907 4381 for (cs = new_node->callees; cs; cs = cs->next_callee)
2e7fd867
JH
4382 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
4383 for (cs = new_node->indirect_calls; cs; cs = cs->next_callee)
4384 cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
310bc633 4385
5a686851 4386 profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
155c9907 4387 for (cs = orig_node->callees; cs; cs = cs->next_callee)
3995f3a2 4388 cs->count = cs->count.apply_scale (remainder, orig_node_count);
2e7fd867
JH
4389 for (cs = orig_node->indirect_calls; cs; cs = cs->next_callee)
4390 cs->count = cs->count.apply_scale (remainder, orig_node_count);
310bc633
MJ
4391
4392 if (dump_file)
4393 dump_profile_updates (orig_node, new_node);
518dc859
RL
4394}
4395
310bc633
MJ
4396/* Update the respective profile of specialized NEW_NODE and the original
4397 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
4398 have been redirected to the specialized version. */
4399
4400static void
4401update_specialized_profile (struct cgraph_node *new_node,
4402 struct cgraph_node *orig_node,
3995f3a2 4403 profile_count redirected_sum)
5e45130d 4404{
a065d52e 4405 struct cgraph_edge *cs;
3995f3a2 4406 profile_count new_node_count, orig_node_count = orig_node->count;
5e45130d 4407
310bc633 4408 if (dump_file)
3995f3a2
JH
4409 {
4410 fprintf (dump_file, " the sum of counts of redirected edges is ");
4411 redirected_sum.dump (dump_file);
4412 fprintf (dump_file, "\n");
4413 }
4414 if (!(orig_node_count > profile_count::zero ()))
310bc633 4415 return;
a065d52e 4416
310bc633 4417 gcc_assert (orig_node_count >= redirected_sum);
5e45130d 4418
310bc633
MJ
4419 new_node_count = new_node->count;
4420 new_node->count += redirected_sum;
4421 orig_node->count -= redirected_sum;
a065d52e 4422
155c9907 4423 for (cs = new_node->callees; cs; cs = cs->next_callee)
e3951b03 4424 cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
a065d52e 4425
155c9907 4426 for (cs = orig_node->callees; cs; cs = cs->next_callee)
310bc633 4427 {
3995f3a2
JH
4428 profile_count dec = cs->count.apply_scale (redirected_sum,
4429 orig_node_count);
4430 cs->count -= dec;
310bc633 4431 }
a065d52e 4432
310bc633
MJ
4433 if (dump_file)
4434 dump_profile_updates (orig_node, new_node);
5e45130d
JH
4435}
4436
ff6686d2
MJ
4437/* Return true if we would like to remove a parameter from NODE when cloning it
4438 with KNOWN_CSTS scalar constants. */
4439
4440static bool
4441want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
4442{
4443 auto_vec<bool, 16> surviving;
4444 bool filled_vec = false;
4445 ipa_node_params *info = IPA_NODE_REF (node);
4446 int i, count = ipa_get_param_count (info);
4447
4448 for (i = 0; i < count; i++)
4449 {
4450 if (!known_csts[i] && ipa_is_param_used (info, i))
4451 continue;
4452
4453 if (!filled_vec)
4454 {
4455 if (!node->clone.param_adjustments)
4456 return true;
4457 node->clone.param_adjustments->get_surviving_params (&surviving);
4458 filled_vec = true;
4459 }
4460 if (surviving.length() < (unsigned) i && surviving[i])
4461 return true;
4462 }
4463 return false;
4464}
4465
44210a96
MJ
4466/* Create a specialized version of NODE with known constants in KNOWN_CSTS,
4467 known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
4468 redirect all edges in CALLERS to it. */
a065d52e 4469
310bc633
MJ
4470static struct cgraph_node *
4471create_specialized_node (struct cgraph_node *node,
44210a96
MJ
4472 vec<tree> known_csts,
4473 vec<ipa_polymorphic_call_context> known_contexts,
2c9561b5 4474 struct ipa_agg_replacement_value *aggvals,
d52f5295 4475 vec<cgraph_edge *> callers)
5e45130d 4476{
99b1c316 4477 class ipa_node_params *new_info, *info = IPA_NODE_REF (node);
d52f5295 4478 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
ff6686d2 4479 vec<ipa_adjusted_param, va_gc> *new_params = NULL;
79ee9826 4480 struct ipa_agg_replacement_value *av;
310bc633
MJ
4481 struct cgraph_node *new_node;
4482 int i, count = ipa_get_param_count (info);
ff6686d2
MJ
4483 ipa_param_adjustments *old_adjustments = node->clone.param_adjustments;
4484 ipa_param_adjustments *new_adjustments;
310bc633 4485 gcc_assert (!info->ipcp_orig_node);
87f94429 4486 gcc_assert (node->can_change_signature
ff6686d2
MJ
4487 || !old_adjustments);
4488
4489 if (old_adjustments)
4490 {
4491 /* At the moment all IPA optimizations should use the number of
4492 parameters of the prevailing decl as the m_always_copy_start.
4493 Handling any other value would complicate the code below, so for the
4494 time bing let's only assert it is so. */
4495 gcc_assert (old_adjustments->m_always_copy_start == count
4496 || old_adjustments->m_always_copy_start < 0);
4497 int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
4498 for (i = 0; i < old_adj_count; i++)
310bc633 4499 {
ff6686d2 4500 ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
87f94429 4501 if (!node->can_change_signature
ff6686d2
MJ
4502 || old_adj->op != IPA_PARAM_OP_COPY
4503 || (!known_csts[old_adj->base_index]
4504 && ipa_is_param_used (info, old_adj->base_index)))
4505 {
4506 ipa_adjusted_param new_adj = *old_adj;
310bc633 4507
ff6686d2
MJ
4508 new_adj.prev_clone_adjustment = true;
4509 new_adj.prev_clone_index = i;
4510 vec_safe_push (new_params, new_adj);
4511 }
310bc633 4512 }
ff6686d2
MJ
4513 bool skip_return = old_adjustments->m_skip_return;
4514 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4515 ipa_param_adjustments (new_params, count,
4516 skip_return));
310bc633 4517 }
87f94429 4518 else if (node->can_change_signature
ff6686d2 4519 && want_remove_some_param_p (node, known_csts))
d7da5cc8 4520 {
ff6686d2
MJ
4521 ipa_adjusted_param adj;
4522 memset (&adj, 0, sizeof (adj));
4523 adj.op = IPA_PARAM_OP_COPY;
4524 for (i = 0; i < count; i++)
4525 if (!known_csts[i] && ipa_is_param_used (info, i))
4526 {
4527 adj.base_index = i;
4528 adj.prev_clone_index = i;
4529 vec_safe_push (new_params, adj);
4530 }
4531 new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
4532 ipa_param_adjustments (new_params, count, false));
d7da5cc8 4533 }
ff6686d2
MJ
4534 else
4535 new_adjustments = NULL;
310bc633 4536
ff6686d2 4537 replace_trees = vec_safe_copy (node->clone.tree_map);
155c9907 4538 for (i = 0; i < count; i++)
310bc633 4539 {
44210a96
MJ
4540 tree t = known_csts[i];
4541 if (t)
310bc633
MJ
4542 {
4543 struct ipa_replace_map *replace_map;
4544
44210a96 4545 gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
0e8853ee 4546 replace_map = get_replacement_map (info, t, i);
310bc633 4547 if (replace_map)
9771b263 4548 vec_safe_push (replace_trees, replace_map);
310bc633 4549 }
5e45130d 4550 }
7b668576
MJ
4551 auto_vec<cgraph_edge *, 2> self_recursive_calls;
4552 for (i = callers.length () - 1; i >= 0; i--)
4553 {
4554 cgraph_edge *cs = callers[i];
4555 if (cs->caller == node)
4556 {
4557 self_recursive_calls.safe_push (cs);
4558 callers.unordered_remove (i);
4559 }
4560 }
5e45130d 4561
9e0b0ec3
MP
4562 unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
4563 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
4564 node->decl)));
d52f5295 4565 new_node = node->create_virtual_clone (callers, replace_trees,
ff6686d2 4566 new_adjustments, "constprop",
53aedcce
MP
4567 suffix_counter);
4568 suffix_counter++;
7b668576 4569
5bf31c64 4570 bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
7b668576
MJ
4571 for (unsigned j = 0; j < self_recursive_calls.length (); j++)
4572 {
1ac2bdb4 4573 cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
5fc1b920
MJ
4574 /* Cloned edges can disappear during cloning as speculation can be
4575 resolved, check that we have one and that it comes from the last
4576 cloning. */
4577 if (cs && cs->caller == new_node)
4578 cs->redirect_callee_duplicating_thunks (new_node);
4579 /* Any future code that would make more than one clone of an outgoing
4580 edge would confuse this mechanism, so let's check that does not
4581 happen. */
4582 gcc_checking_assert (!cs
1ac2bdb4
ML
4583 || !get_next_cgraph_edge_clone (cs)
4584 || get_next_cgraph_edge_clone (cs)->caller != new_node);
7b668576 4585 }
5bf31c64
MJ
4586 if (have_self_recursive_calls)
4587 new_node->expand_all_artificial_thunks ();
7b668576 4588
2c9561b5 4589 ipa_set_node_agg_value_chain (new_node, aggvals);
79ee9826 4590 for (av = aggvals; av; av = av->next)
2d8d3ae2 4591 new_node->maybe_create_reference (av->value, NULL);
79ee9826 4592
310bc633 4593 if (dump_file && (dump_flags & TDF_DETAILS))
2c9561b5 4594 {
464d0118 4595 fprintf (dump_file, " the new node is %s.\n", new_node->dump_name ());
44210a96
MJ
4596 if (known_contexts.exists ())
4597 {
155c9907 4598 for (i = 0; i < count; i++)
44210a96
MJ
4599 if (!known_contexts[i].useless_p ())
4600 {
4601 fprintf (dump_file, " known ctx %i is ", i);
4602 known_contexts[i].dump (dump_file);
4603 }
4604 }
2c9561b5
MJ
4605 if (aggvals)
4606 ipa_dump_agg_replacement_values (dump_file, aggvals);
4607 }
9de6f6c3 4608 ipa_check_create_node_params ();
310bc633
MJ
4609 update_profiling_info (node, new_node);
4610 new_info = IPA_NODE_REF (new_node);
4611 new_info->ipcp_orig_node = node;
6cf67b62 4612 new_node->ipcp_clone = true;
44210a96
MJ
4613 new_info->known_csts = known_csts;
4614 new_info->known_contexts = known_contexts;
5e45130d 4615
44210a96 4616 ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
310bc633 4617
9771b263 4618 callers.release ();
310bc633 4619 return new_node;
5e45130d
JH
4620}
4621
7b668576 4622/* Return true, if JFUNC, which describes a i-th parameter of call CS, is a
a0f6a8cb
FX
4623 pass-through function to itself. When SIMPLE is true, further check if
4624 JFUNC is a simple no-operation pass-through. */
7b668576
MJ
4625
4626static bool
a0f6a8cb
FX
4627self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
4628 bool simple = true)
7b668576
MJ
4629{
4630 enum availability availability;
4631 if (cs->caller == cs->callee->function_symbol (&availability)
4632 && availability > AVAIL_INTERPOSABLE
4633 && jfunc->type == IPA_JF_PASS_THROUGH
a0f6a8cb 4634 && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
7b668576
MJ
4635 && ipa_get_jf_pass_through_formal_id (jfunc) == i)
4636 return true;
4637 return false;
4638}
4639
951e27f5 4640/* Return true, if JFUNC, which describes a part of an aggregate represented
a0f6a8cb
FX
4641 or pointed to by the i-th parameter of call CS, is a pass-through function
4642 to itself. When SIMPLE is true, further check if JFUNC is a simple
4643 no-operation pass-through. */
951e27f5
FX
4644
4645static bool
4646self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
a0f6a8cb 4647 int i, bool simple = true)
951e27f5
FX
4648{
4649 enum availability availability;
4650 if (cs->caller == cs->callee->function_symbol (&availability)
4651 && availability > AVAIL_INTERPOSABLE
4652 && jfunc->jftype == IPA_JF_LOAD_AGG
4653 && jfunc->offset == jfunc->value.load_agg.offset
a0f6a8cb
FX
4654 && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
4655 && jfunc->value.pass_through.formal_id == i
4656 && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type))
951e27f5
FX
4657 return true;
4658 return false;
4659}
4660
310bc633 4661/* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
44210a96 4662 KNOWN_CSTS with constants that are also known for all of the CALLERS. */
3949c4a7
MJ
4663
4664static void
2c9561b5 4665find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
44210a96 4666 vec<tree> known_csts,
d52f5295 4667 vec<cgraph_edge *> callers)
3949c4a7 4668{
99b1c316 4669 class ipa_node_params *info = IPA_NODE_REF (node);
310bc633 4670 int i, count = ipa_get_param_count (info);
3949c4a7 4671
155c9907 4672 for (i = 0; i < count; i++)
3949c4a7 4673 {
310bc633
MJ
4674 struct cgraph_edge *cs;
4675 tree newval = NULL_TREE;
4676 int j;
df0d8136 4677 bool first = true;
e5cf5e11 4678 tree type = ipa_get_type (info, i);
3949c4a7 4679
44210a96 4680 if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
3949c4a7
MJ
4681 continue;
4682
9771b263 4683 FOR_EACH_VEC_ELT (callers, j, cs)
49c471e3 4684 {
310bc633
MJ
4685 struct ipa_jump_func *jump_func;
4686 tree t;
40591473 4687
a33c028e
JH
4688 if (!IPA_EDGE_REF (cs)
4689 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
173b7355 4690 || (i == 0
31db0fe0 4691 && call_passes_through_thunk_p (cs)))
155c9907
JJ
4692 {
4693 newval = NULL_TREE;
4694 break;
4695 }
310bc633 4696 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
7b668576 4697
a0f6a8cb
FX
4698 /* Besides simple pass-through jump function, arithmetic jump
4699 function could also introduce argument-direct-pass-through for
4700 self-feeding recursive call. For example,
4701
4702 fn (int i)
4703 {
4704 fn (i & 1);
4705 }
4706
4707 Given that i is 0, recursive propagation via (i & 1) also gets
4708 0. */
4709 if (self_recursive_pass_through_p (cs, jump_func, i, false))
4710 {
4711 gcc_assert (newval);
4712 t = ipa_get_jf_arith_result (
4713 ipa_get_jf_pass_through_operation (jump_func),
4714 newval,
4715 ipa_get_jf_pass_through_operand (jump_func),
4716 type);
4717 }
4718 else
4719 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func,
4720 type);
310bc633
MJ
4721 if (!t
4722 || (newval
df0d8136
JH
4723 && !values_equal_for_ipcp_p (t, newval))
4724 || (!first && !newval))
3949c4a7 4725 {
310bc633
MJ
4726 newval = NULL_TREE;
4727 break;
3949c4a7 4728 }
310bc633
MJ
4729 else
4730 newval = t;
df0d8136 4731 first = false;
3949c4a7
MJ
4732 }
4733
310bc633
MJ
4734 if (newval)
4735 {
4736 if (dump_file && (dump_flags & TDF_DETAILS))
4737 {
2c9561b5 4738 fprintf (dump_file, " adding an extra known scalar value ");
310bc633 4739 print_ipcp_constant_value (dump_file, newval);
0e8853ee
JH
4740 fprintf (dump_file, " for ");
4741 ipa_dump_param (dump_file, info, i);
310bc633
MJ
4742 fprintf (dump_file, "\n");
4743 }
5e45130d 4744
44210a96 4745 known_csts[i] = newval;
310bc633 4746 }
5e45130d 4747 }
5e45130d
JH
4748}
4749
44210a96
MJ
4750/* Given a NODE and a subset of its CALLERS, try to populate plank slots in
4751 KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
4752 CALLERS. */
4753
4754static void
4755find_more_contexts_for_caller_subset (cgraph_node *node,
4756 vec<ipa_polymorphic_call_context>
4757 *known_contexts,
4758 vec<cgraph_edge *> callers)
4759{
4760 ipa_node_params *info = IPA_NODE_REF (node);
4761 int i, count = ipa_get_param_count (info);
4762
155c9907 4763 for (i = 0; i < count; i++)
44210a96
MJ
4764 {
4765 cgraph_edge *cs;
4766
4767 if (ipa_get_poly_ctx_lat (info, i)->bottom
4768 || (known_contexts->exists ()
4769 && !(*known_contexts)[i].useless_p ()))
4770 continue;
4771
4772 ipa_polymorphic_call_context newval;
df0d8136 4773 bool first = true;
44210a96
MJ
4774 int j;
4775
4776 FOR_EACH_VEC_ELT (callers, j, cs)
4777 {
a33c028e
JH
4778 if (!IPA_EDGE_REF (cs)
4779 || i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
44210a96
MJ
4780 return;
4781 ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
4782 i);
4783 ipa_polymorphic_call_context ctx;
4784 ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
4785 jfunc);
df0d8136 4786 if (first)
44210a96 4787 {
44210a96 4788 newval = ctx;
df0d8136 4789 first = false;
44210a96 4790 }
df0d8136
JH
4791 else
4792 newval.meet_with (ctx);
4793 if (newval.useless_p ())
4794 break;
44210a96
MJ
4795 }
4796
df0d8136 4797 if (!newval.useless_p ())
44210a96
MJ
4798 {
4799 if (dump_file && (dump_flags & TDF_DETAILS))
4800 {
4801 fprintf (dump_file, " adding an extra known polymorphic "
4802 "context ");
4803 print_ipcp_constant_value (dump_file, newval);
4804 fprintf (dump_file, " for ");
4805 ipa_dump_param (dump_file, info, i);
4806 fprintf (dump_file, "\n");
4807 }
4808
4809 if (!known_contexts->exists ())
4810 known_contexts->safe_grow_cleared (ipa_get_param_count (info));
4811 (*known_contexts)[i] = newval;
4812 }
4813
4814 }
4815}
4816
2c9561b5
MJ
4817/* Go through PLATS and create a vector of values consisting of values and
4818 offsets (minus OFFSET) of lattices that contain only a single value. */
4819
eb270950 4820static vec<ipa_agg_value>
99b1c316 4821copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
2c9561b5 4822{
eb270950 4823 vec<ipa_agg_value> res = vNULL;
2c9561b5
MJ
4824
4825 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
6e1aa848 4826 return vNULL;
2c9561b5
MJ
4827
4828 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
c0cb5055 4829 if (aglat->is_single_const ())
2c9561b5 4830 {
eb270950 4831 struct ipa_agg_value ti;
2c9561b5
MJ
4832 ti.offset = aglat->offset - offset;
4833 ti.value = aglat->values->value;
9771b263 4834 res.safe_push (ti);
2c9561b5
MJ
4835 }
4836 return res;
4837}
4838
4839/* Intersect all values in INTER with single value lattices in PLATS (while
4840 subtracting OFFSET). */
4841
4842static void
99b1c316 4843intersect_with_plats (class ipcp_param_lattices *plats,
eb270950 4844 vec<ipa_agg_value> *inter,
2c9561b5
MJ
4845 HOST_WIDE_INT offset)
4846{
4847 struct ipcp_agg_lattice *aglat;
eb270950 4848 struct ipa_agg_value *item;
2c9561b5
MJ
4849 int k;
4850
4851 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
4852 {
9771b263 4853 inter->release ();
2c9561b5
MJ
4854 return;
4855 }
4856
4857 aglat = plats->aggs;
9771b263 4858 FOR_EACH_VEC_ELT (*inter, k, item)
2c9561b5
MJ
4859 {
4860 bool found = false;
4861 if (!item->value)
4862 continue;
4863 while (aglat)
4864 {
4865 if (aglat->offset - offset > item->offset)
4866 break;
4867 if (aglat->offset - offset == item->offset)
4868 {
951e27f5
FX
4869 if (aglat->is_single_const ())
4870 {
4871 tree value = aglat->values->value;
4872
4873 if (values_equal_for_ipcp_p (item->value, value))
4874 found = true;
951e27f5 4875 }
2c9561b5
MJ
4876 break;
4877 }
4878 aglat = aglat->next;
4879 }
4880 if (!found)
4881 item->value = NULL_TREE;
4882 }
4883}
4884
5764ee3c 4885/* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
2c9561b5
MJ
4886 vector result while subtracting OFFSET from the individual value offsets. */
4887
eb270950 4888static vec<ipa_agg_value>
0fd44da3
MJ
4889agg_replacements_to_vector (struct cgraph_node *node, int index,
4890 HOST_WIDE_INT offset)
2c9561b5
MJ
4891{
4892 struct ipa_agg_replacement_value *av;
eb270950 4893 vec<ipa_agg_value> res = vNULL;
2c9561b5
MJ
4894
4895 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
0fd44da3
MJ
4896 if (av->index == index
4897 && (av->offset - offset) >= 0)
2c9561b5 4898 {
eb270950 4899 struct ipa_agg_value item;
2c9561b5
MJ
4900 gcc_checking_assert (av->value);
4901 item.offset = av->offset - offset;
4902 item.value = av->value;
9771b263 4903 res.safe_push (item);
2c9561b5
MJ
4904 }
4905
4906 return res;
4907}
4908
4909/* Intersect all values in INTER with those that we have already scheduled to
4910 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
4911 (while subtracting OFFSET). */
4912
4913static void
4914intersect_with_agg_replacements (struct cgraph_node *node, int index,
eb270950 4915 vec<ipa_agg_value> *inter,
2c9561b5
MJ
4916 HOST_WIDE_INT offset)
4917{
4918 struct ipa_agg_replacement_value *srcvals;
eb270950 4919 struct ipa_agg_value *item;
2c9561b5
MJ
4920 int i;
4921
4922 srcvals = ipa_get_agg_replacements_for_node (node);
4923 if (!srcvals)
4924 {
9771b263 4925 inter->release ();
2c9561b5
MJ
4926 return;
4927 }
4928
9771b263 4929 FOR_EACH_VEC_ELT (*inter, i, item)
2c9561b5
MJ
4930 {
4931 struct ipa_agg_replacement_value *av;
4932 bool found = false;
4933 if (!item->value)
4934 continue;
4935 for (av = srcvals; av; av = av->next)
4936 {
4937 gcc_checking_assert (av->value);
4938 if (av->index == index
4939 && av->offset - offset == item->offset)
4940 {
4941 if (values_equal_for_ipcp_p (item->value, av->value))
4942 found = true;
4943 break;
4944 }
4945 }
4946 if (!found)
4947 item->value = NULL_TREE;
4948 }
4949}
4950
7e9f2b6e
MJ
4951/* Intersect values in INTER with aggregate values that come along edge CS to
4952 parameter number INDEX and return it. If INTER does not actually exist yet,
4953 copy all incoming values to it. If we determine we ended up with no values
4954 whatsoever, return a released vector. */
4955
eb270950 4956static vec<ipa_agg_value>
7e9f2b6e 4957intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
eb270950 4958 vec<ipa_agg_value> inter)
7e9f2b6e
MJ
4959{
4960 struct ipa_jump_func *jfunc;
4961 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
4962 if (jfunc->type == IPA_JF_PASS_THROUGH
4963 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
4964 {
99b1c316 4965 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
7e9f2b6e
MJ
4966 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
4967
4968 if (caller_info->ipcp_orig_node)
4969 {
4970 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
99b1c316 4971 class ipcp_param_lattices *orig_plats;
7e9f2b6e
MJ
4972 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
4973 src_idx);
4974 if (agg_pass_through_permissible_p (orig_plats, jfunc))
4975 {
4976 if (!inter.exists ())
0fd44da3 4977 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
7e9f2b6e
MJ
4978 else
4979 intersect_with_agg_replacements (cs->caller, src_idx,
4980 &inter, 0);
4981 }
c8f40352
MJ
4982 else
4983 {
4984 inter.release ();
4985 return vNULL;
4986 }
7e9f2b6e
MJ
4987 }
4988 else
4989 {
99b1c316 4990 class ipcp_param_lattices *src_plats;
7e9f2b6e
MJ
4991 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
4992 if (agg_pass_through_permissible_p (src_plats, jfunc))
4993 {
4994 /* Currently we do not produce clobber aggregate jump
4995 functions, adjust when we do. */
4996 gcc_checking_assert (!jfunc->agg.items);
4997 if (!inter.exists ())
4998 inter = copy_plats_to_inter (src_plats, 0);
4999 else
5000 intersect_with_plats (src_plats, &inter, 0);
5001 }
c8f40352
MJ
5002 else
5003 {
5004 inter.release ();
5005 return vNULL;
5006 }
7e9f2b6e
MJ
5007 }
5008 }
5009 else if (jfunc->type == IPA_JF_ANCESTOR
5010 && ipa_get_jf_ancestor_agg_preserved (jfunc))
5011 {
99b1c316 5012 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
7e9f2b6e 5013 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
99b1c316 5014 class ipcp_param_lattices *src_plats;
7e9f2b6e
MJ
5015 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
5016
5017 if (caller_info->ipcp_orig_node)
5018 {
5019 if (!inter.exists ())
0fd44da3 5020 inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
7e9f2b6e 5021 else
0fd44da3 5022 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
7e9f2b6e
MJ
5023 delta);
5024 }
5025 else
5026 {
5de73c05 5027 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
7e9f2b6e
MJ
5028 /* Currently we do not produce clobber aggregate jump
5029 functions, adjust when we do. */
5030 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
5031 if (!inter.exists ())
5032 inter = copy_plats_to_inter (src_plats, delta);
5033 else
5034 intersect_with_plats (src_plats, &inter, delta);
5035 }
5036 }
5037 else if (jfunc->agg.items)
5038 {
eb270950
FX
5039 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5040 struct ipa_agg_value *item;
7e9f2b6e
MJ
5041 int k;
5042
5043 if (!inter.exists ())
5044 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
eb270950
FX
5045 {
5046 struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
a0f6a8cb
FX
5047 tree value = ipa_agg_value_from_node (caller_info, cs->caller,
5048 agg_item);
5049 if (value)
951e27f5 5050 {
a0f6a8cb 5051 struct ipa_agg_value agg_value;
eb270950 5052
eb270950 5053 agg_value.value = value;
a0f6a8cb
FX
5054 agg_value.offset = agg_item->offset;
5055 inter.safe_push (agg_value);
eb270950
FX
5056 }
5057 }
7e9f2b6e
MJ
5058 else
5059 FOR_EACH_VEC_ELT (inter, k, item)
5060 {
5061 int l = 0;
5de73c05 5062 bool found = false;
7e9f2b6e
MJ
5063
5064 if (!item->value)
5065 continue;
5066
5067 while ((unsigned) l < jfunc->agg.items->length ())
5068 {
5069 struct ipa_agg_jf_item *ti;
5070 ti = &(*jfunc->agg.items)[l];
5071 if (ti->offset > item->offset)
5072 break;
5073 if (ti->offset == item->offset)
5074 {
951e27f5
FX
5075 tree value;
5076
a0f6a8cb
FX
5077 /* Besides simple pass-through aggregate jump function,
5078 arithmetic aggregate jump function could also bring
5079 same aggregate value as parameter passed-in for
5080 self-feeding recursive call. For example,
5081
5082 fn (int *i)
5083 {
5084 int j = *i & 1;
5085 fn (&j);
5086 }
5087
5088 Given that *i is 0, recursive propagation via (*i & 1)
5089 also gets 0. */
5090 if (self_recursive_agg_pass_through_p (cs, ti, index,
5091 false))
5092 value = ipa_get_jf_arith_result (
5093 ti->value.pass_through.operation,
5094 item->value,
5095 ti->value.pass_through.operand,
5096 ti->type);
5097 else
5098 value = ipa_agg_value_from_node (caller_info,
5099 cs->caller, ti);
5100
5101 if (value && values_equal_for_ipcp_p (item->value, value))
5102 found = true;
7e9f2b6e
MJ
5103 break;
5104 }
5105 l++;
5106 }
5107 if (!found)
5108 item->value = NULL;
5109 }
5110 }
5111 else
5112 {
c3284718 5113 inter.release ();
eb270950 5114 return vNULL;
7e9f2b6e
MJ
5115 }
5116 return inter;
5117}
5118
2c9561b5
MJ
5119/* Look at edges in CALLERS and collect all known aggregate values that arrive
5120 from all of them. */
5121
5122static struct ipa_agg_replacement_value *
5123find_aggregate_values_for_callers_subset (struct cgraph_node *node,
d52f5295 5124 vec<cgraph_edge *> callers)
2c9561b5 5125{
99b1c316 5126 class ipa_node_params *dest_info = IPA_NODE_REF (node);
6f9549ee
MJ
5127 struct ipa_agg_replacement_value *res;
5128 struct ipa_agg_replacement_value **tail = &res;
2c9561b5 5129 struct cgraph_edge *cs;
dffdd6e5 5130 int i, j, count = ipa_get_param_count (dest_info);
2c9561b5 5131
9771b263 5132 FOR_EACH_VEC_ELT (callers, j, cs)
2c9561b5 5133 {
a33c028e
JH
5134 if (!IPA_EDGE_REF (cs))
5135 {
5136 count = 0;
5137 break;
5138 }
2c9561b5
MJ
5139 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5140 if (c < count)
5141 count = c;
5142 }
5143
155c9907 5144 for (i = 0; i < count; i++)
2c9561b5
MJ
5145 {
5146 struct cgraph_edge *cs;
eb270950
FX
5147 vec<ipa_agg_value> inter = vNULL;
5148 struct ipa_agg_value *item;
99b1c316 5149 class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
2c9561b5
MJ
5150 int j;
5151
5152 /* Among other things, the following check should deal with all by_ref
5153 mismatches. */
7b920a9a 5154 if (plats->aggs_bottom)
2c9561b5
MJ
5155 continue;
5156
9771b263 5157 FOR_EACH_VEC_ELT (callers, j, cs)
2c9561b5 5158 {
7b668576
MJ
5159 struct ipa_jump_func *jfunc
5160 = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
cf254442
MJ
5161 if (self_recursive_pass_through_p (cs, jfunc, i)
5162 && (!plats->aggs_by_ref
5163 || ipa_get_jf_pass_through_agg_preserved (jfunc)))
7b668576 5164 continue;
7e9f2b6e 5165 inter = intersect_aggregates_with_edge (cs, i, inter);
2c9561b5 5166
9771b263 5167 if (!inter.exists ())
2c9561b5
MJ
5168 goto next_param;
5169 }
5170
9771b263 5171 FOR_EACH_VEC_ELT (inter, j, item)
2c9561b5
MJ
5172 {
5173 struct ipa_agg_replacement_value *v;
5174
5175 if (!item->value)
5176 continue;
5177
766090c2 5178 v = ggc_alloc<ipa_agg_replacement_value> ();
2c9561b5
MJ
5179 v->index = i;
5180 v->offset = item->offset;
5181 v->value = item->value;
7b920a9a 5182 v->by_ref = plats->aggs_by_ref;
6f9549ee
MJ
5183 *tail = v;
5184 tail = &v->next;
2c9561b5
MJ
5185 }
5186
5187 next_param:
9771b263
DN
5188 if (inter.exists ())
5189 inter.release ();
2c9561b5 5190 }
6f9549ee 5191 *tail = NULL;
2c9561b5
MJ
5192 return res;
5193}
5194
2c9561b5
MJ
5195/* Determine whether CS also brings all scalar values that the NODE is
5196 specialized for. */
5197
5198static bool
5199cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
5200 struct cgraph_node *node)
5201{
99b1c316 5202 class ipa_node_params *dest_info = IPA_NODE_REF (node);
2c9561b5 5203 int count = ipa_get_param_count (dest_info);
99b1c316
MS
5204 class ipa_node_params *caller_info;
5205 class ipa_edge_args *args;
2c9561b5
MJ
5206 int i;
5207
5208 caller_info = IPA_NODE_REF (cs->caller);
5209 args = IPA_EDGE_REF (cs);
5210 for (i = 0; i < count; i++)
5211 {
5212 struct ipa_jump_func *jump_func;
5213 tree val, t;
5214
44210a96 5215 val = dest_info->known_csts[i];
2c9561b5
MJ
5216 if (!val)
5217 continue;
5218
5219 if (i >= ipa_get_cs_argument_count (args))
5220 return false;
5221 jump_func = ipa_get_ith_jump_func (args, i);
e5cf5e11
PK
5222 t = ipa_value_from_jfunc (caller_info, jump_func,
5223 ipa_get_type (dest_info, i));
2c9561b5
MJ
5224 if (!t || !values_equal_for_ipcp_p (val, t))
5225 return false;
5226 }
5227 return true;
5228}
5229
5230/* Determine whether CS also brings all aggregate values that NODE is
5231 specialized for. */
5232static bool
5233cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
5234 struct cgraph_node *node)
5235{
99b1c316 5236 class ipa_node_params *orig_node_info;
2c9561b5 5237 struct ipa_agg_replacement_value *aggval;
7e9f2b6e 5238 int i, ec, count;
2c9561b5
MJ
5239
5240 aggval = ipa_get_agg_replacements_for_node (node);
7e9f2b6e
MJ
5241 if (!aggval)
5242 return true;
5243
5244 count = ipa_get_param_count (IPA_NODE_REF (node));
5245 ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
5246 if (ec < count)
5247 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5248 if (aggval->index >= ec)
5249 return false;
5250
9576e7b1 5251 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
7e9f2b6e
MJ
5252
5253 for (i = 0; i < count; i++)
2c9561b5 5254 {
99b1c316 5255 class ipcp_param_lattices *plats;
7e9f2b6e
MJ
5256 bool interesting = false;
5257 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5258 if (aggval->index == i)
5259 {
5260 interesting = true;
5261 break;
5262 }
5263 if (!interesting)
5264 continue;
5265
9576e7b1 5266 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
7e9f2b6e 5267 if (plats->aggs_bottom)
2c9561b5 5268 return false;
2c9561b5 5269
8bda7ce8 5270 vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL);
c3284718 5271 if (!values.exists ())
2c9561b5
MJ
5272 return false;
5273
7e9f2b6e
MJ
5274 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
5275 if (aggval->index == i)
5276 {
eb270950 5277 struct ipa_agg_value *item;
7e9f2b6e
MJ
5278 int j;
5279 bool found = false;
5280 FOR_EACH_VEC_ELT (values, j, item)
5281 if (item->value
5282 && item->offset == av->offset
5283 && values_equal_for_ipcp_p (item->value, av->value))
c3272a92
PCC
5284 {
5285 found = true;
5286 break;
5287 }
7e9f2b6e
MJ
5288 if (!found)
5289 {
c3284718 5290 values.release ();
7e9f2b6e
MJ
5291 return false;
5292 }
5293 }
8bda7ce8 5294 values.release ();
2c9561b5
MJ
5295 }
5296 return true;
5297}
5298
310bc633
MJ
5299/* Given an original NODE and a VAL for which we have already created a
5300 specialized clone, look whether there are incoming edges that still lead
5301 into the old node but now also bring the requested value and also conform to
026c3cfd 5302 all other criteria such that they can be redirected the special node.
310bc633 5303 This function can therefore redirect the final edge in a SCC. */
3e66255c 5304
c0cb5055 5305template <typename valtype>
3e66255c 5306static void
c0cb5055 5307perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
3e66255c 5308{
c0cb5055 5309 ipcp_value_source<valtype> *src;
3995f3a2 5310 profile_count redirected_sum = profile_count::zero ();
3e66255c 5311
310bc633 5312 for (src = val->sources; src; src = src->next)
3e66255c 5313 {
310bc633
MJ
5314 struct cgraph_edge *cs = src->cs;
5315 while (cs)
5316 {
7b668576 5317 if (cgraph_edge_brings_value_p (cs, src, node, val)
47f4756e
MJ
5318 && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
5319 && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
310bc633 5320 {
47f4756e 5321 if (dump_file)
464d0118
ML
5322 fprintf (dump_file, " - adding an extra caller %s of %s\n",
5323 cs->caller->dump_name (),
5324 val->spec_node->dump_name ());
47f4756e 5325
6a4bad95
MJ
5326 cs->redirect_callee_duplicating_thunks (val->spec_node);
5327 val->spec_node->expand_all_artificial_thunks ();
1bad9c18
JH
5328 if (cs->count.ipa ().initialized_p ())
5329 redirected_sum = redirected_sum + cs->count.ipa ();
310bc633
MJ
5330 }
5331 cs = get_next_cgraph_edge_clone (cs);
5332 }
3e66255c 5333 }
310bc633 5334
e3951b03 5335 if (redirected_sum.nonzero_p ())
310bc633 5336 update_specialized_profile (val->spec_node, node, redirected_sum);
3e66255c
MJ
5337}
5338
44210a96 5339/* Return true if KNOWN_CONTEXTS contain at least one useful context. */
3e66255c 5340
44210a96
MJ
5341static bool
5342known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
5343{
5344 ipa_polymorphic_call_context *ctx;
5345 int i;
5346
5347 FOR_EACH_VEC_ELT (known_contexts, i, ctx)
5348 if (!ctx->useless_p ())
5349 return true;
5350 return false;
5351}
5352
5353/* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL. */
5354
5355static vec<ipa_polymorphic_call_context>
5356copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
5357{
5358 if (known_contexts_useful_p (known_contexts))
5359 return known_contexts.copy ();
5360 else
5361 return vNULL;
5362}
5363
5364/* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX. If
5365 non-empty, replace KNOWN_CONTEXTS with its copy too. */
310bc633 5366
518dc859 5367static void
44210a96
MJ
5368modify_known_vectors_with_val (vec<tree> *known_csts,
5369 vec<ipa_polymorphic_call_context> *known_contexts,
5370 ipcp_value<tree> *val,
5371 int index)
518dc859 5372{
44210a96
MJ
5373 *known_csts = known_csts->copy ();
5374 *known_contexts = copy_useful_known_contexts (*known_contexts);
5375 (*known_csts)[index] = val->value;
5376}
518dc859 5377
44210a96
MJ
5378/* Replace KNOWN_CSTS with its copy. Also copy KNOWN_CONTEXTS and modify the
5379 copy according to VAL and INDEX. */
5380
5381static void
5382modify_known_vectors_with_val (vec<tree> *known_csts,
5383 vec<ipa_polymorphic_call_context> *known_contexts,
5384 ipcp_value<ipa_polymorphic_call_context> *val,
5385 int index)
5386{
5387 *known_csts = known_csts->copy ();
5388 *known_contexts = known_contexts->copy ();
5389 (*known_contexts)[index] = val->value;
310bc633 5390}
5e45130d 5391
44210a96
MJ
5392/* Return true if OFFSET indicates this was not an aggregate value or there is
5393 a replacement equivalent to VALUE, INDEX and OFFSET among those in the
5394 AGGVALS list. */
2c9561b5
MJ
5395
5396DEBUG_FUNCTION bool
44210a96
MJ
5397ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
5398 int index, HOST_WIDE_INT offset, tree value)
2c9561b5 5399{
44210a96
MJ
5400 if (offset == -1)
5401 return true;
5402
2c9561b5
MJ
5403 while (aggvals)
5404 {
5405 if (aggvals->index == index
5406 && aggvals->offset == offset
5407 && values_equal_for_ipcp_p (aggvals->value, value))
5408 return true;
5409 aggvals = aggvals->next;
5410 }
5411 return false;
5412}
5413
f25ae20e 5414/* Return true if offset is minus one because source of a polymorphic context
44210a96
MJ
5415 cannot be an aggregate value. */
5416
5417DEBUG_FUNCTION bool
5418ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
5419 int , HOST_WIDE_INT offset,
5420 ipa_polymorphic_call_context)
5421{
5422 return offset == -1;
5423}
5424
f25ae20e 5425/* Decide whether to create a special version of NODE for value VAL of parameter
2c9561b5
MJ
5426 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
5427 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
44210a96 5428 KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values. */
2c9561b5 5429
c0cb5055 5430template <typename valtype>
2c9561b5
MJ
5431static bool
5432decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
c0cb5055 5433 ipcp_value<valtype> *val, vec<tree> known_csts,
44210a96 5434 vec<ipa_polymorphic_call_context> known_contexts)
2c9561b5
MJ
5435{
5436 struct ipa_agg_replacement_value *aggvals;
5437 int freq_sum, caller_count;
3995f3a2 5438 profile_count count_sum;
d52f5295 5439 vec<cgraph_edge *> callers;
2c9561b5
MJ
5440
5441 if (val->spec_node)
5442 {
5443 perhaps_add_new_callers (node, val);
5444 return false;
5445 }
f7725a48 5446 else if (val->local_size_cost + overall_size > get_max_overall_size (node))
2c9561b5
MJ
5447 {
5448 if (dump_file && (dump_flags & TDF_DETAILS))
5449 fprintf (dump_file, " Ignoring candidate value because "
f7725a48 5450 "maximum unit size would be reached with %li.\n",
2c9561b5
MJ
5451 val->local_size_cost + overall_size);
5452 return false;
5453 }
47f4756e 5454 else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
2c9561b5
MJ
5455 &caller_count))
5456 return false;
5457
5458 if (dump_file && (dump_flags & TDF_DETAILS))
5459 {
5460 fprintf (dump_file, " - considering value ");
5461 print_ipcp_constant_value (dump_file, val->value);
0e8853ee
JH
5462 fprintf (dump_file, " for ");
5463 ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
2c9561b5
MJ
5464 if (offset != -1)
5465 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
5466 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
5467 }
5468
5469 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
5470 freq_sum, count_sum,
5471 val->local_size_cost)
5472 && !good_cloning_opportunity_p (node,
5473 val->local_time_benefit
5474 + val->prop_time_benefit,
5475 freq_sum, count_sum,
5476 val->local_size_cost
5477 + val->prop_size_cost))
5478 return false;
5479
5480 if (dump_file)
464d0118
ML
5481 fprintf (dump_file, " Creating a specialized node of %s.\n",
5482 node->dump_name ());
2c9561b5 5483
47f4756e 5484 callers = gather_edges_for_value (val, node, caller_count);
2c9561b5 5485 if (offset == -1)
44210a96
MJ
5486 modify_known_vectors_with_val (&known_csts, &known_contexts, val, index);
5487 else
5488 {
5489 known_csts = known_csts.copy ();
5490 known_contexts = copy_useful_known_contexts (known_contexts);
5491 }
5492 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5493 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
2c9561b5 5494 aggvals = find_aggregate_values_for_callers_subset (node, callers);
44210a96
MJ
5495 gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
5496 offset, val->value));
5497 val->spec_node = create_specialized_node (node, known_csts, known_contexts,
5498 aggvals, callers);
2c9561b5
MJ
5499 overall_size += val->local_size_cost;
5500
5501 /* TODO: If for some lattice there is only one other known value
5502 left, make a special node for it too. */
5503
5504 return true;
5505}
5e45130d 5506
310bc633 5507/* Decide whether and what specialized clones of NODE should be created. */
5e45130d 5508
310bc633
MJ
5509static bool
5510decide_whether_version_node (struct cgraph_node *node)
5511{
99b1c316 5512 class ipa_node_params *info = IPA_NODE_REF (node);
310bc633 5513 int i, count = ipa_get_param_count (info);
44210a96
MJ
5514 vec<tree> known_csts;
5515 vec<ipa_polymorphic_call_context> known_contexts;
310bc633 5516 bool ret = false;
5e45130d 5517
310bc633
MJ
5518 if (count == 0)
5519 return false;
5e45130d 5520
310bc633 5521 if (dump_file && (dump_flags & TDF_DETAILS))
464d0118
ML
5522 fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
5523 node->dump_name ());
5e45130d 5524
44210a96 5525 gather_context_independent_values (info, &known_csts, &known_contexts,
eb270950 5526 NULL, NULL);
5e45130d 5527
155c9907 5528 for (i = 0; i < count;i++)
310bc633 5529 {
99b1c316 5530 class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055 5531 ipcp_lattice<tree> *lat = &plats->itself;
44210a96 5532 ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
5e45130d 5533
2c9561b5 5534 if (!lat->bottom
44210a96
MJ
5535 && !known_csts[i])
5536 {
5537 ipcp_value<tree> *val;
5538 for (val = lat->values; val; val = val->next)
5539 ret |= decide_about_value (node, i, -1, val, known_csts,
5540 known_contexts);
5541 }
61e03ffc 5542
eb20b778 5543 if (!plats->aggs_bottom)
518dc859 5544 {
2c9561b5 5545 struct ipcp_agg_lattice *aglat;
c0cb5055 5546 ipcp_value<tree> *val;
2c9561b5
MJ
5547 for (aglat = plats->aggs; aglat; aglat = aglat->next)
5548 if (!aglat->bottom && aglat->values
5549 /* If the following is false, the one value is in
5550 known_aggs. */
5551 && (plats->aggs_contain_variable
c0cb5055 5552 || !aglat->is_single_const ()))
2c9561b5
MJ
5553 for (val = aglat->values; val; val = val->next)
5554 ret |= decide_about_value (node, i, aglat->offset, val,
44210a96 5555 known_csts, known_contexts);
cc58ceee 5556 }
44210a96
MJ
5557
5558 if (!ctxlat->bottom
5559 && known_contexts[i].useless_p ())
5560 {
5561 ipcp_value<ipa_polymorphic_call_context> *val;
5562 for (val = ctxlat->values; val; val = val->next)
5563 ret |= decide_about_value (node, i, -1, val, known_csts,
5564 known_contexts);
5565 }
5566
155c9907 5567 info = IPA_NODE_REF (node);
310bc633 5568 }
cc58ceee 5569
eb20b778 5570 if (info->do_clone_for_all_contexts)
310bc633 5571 {
eb20b778 5572 struct cgraph_node *clone;
a0f6a8cb
FX
5573 vec<cgraph_edge *> callers = node->collect_callers ();
5574
5575 for (int i = callers.length () - 1; i >= 0; i--)
5576 {
5577 cgraph_edge *cs = callers[i];
5578 class ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
5579
5580 if (caller_info && caller_info->node_dead)
5581 callers.unordered_remove (i);
5582 }
5583
5584 if (!adjust_callers_for_value_intersection (callers, node))
5585 {
5586 /* If node is not called by anyone, or all its caller edges are
5587 self-recursive, the node is not really be in use, no need to
5588 do cloning. */
5589 callers.release ();
5590 known_csts.release ();
5591 known_contexts.release ();
5592 info->do_clone_for_all_contexts = false;
5593 return ret;
5594 }
cc58ceee 5595
310bc633 5596 if (dump_file)
464d0118
ML
5597 fprintf (dump_file, " - Creating a specialized node of %s "
5598 "for all known contexts.\n", node->dump_name ());
5e45130d 5599
7b668576
MJ
5600 find_more_scalar_values_for_callers_subset (node, known_csts, callers);
5601 find_more_contexts_for_caller_subset (node, &known_contexts, callers);
5602 ipa_agg_replacement_value *aggvals
5603 = find_aggregate_values_for_callers_subset (node, callers);
44210a96
MJ
5604
5605 if (!known_contexts_useful_p (known_contexts))
5606 {
5607 known_contexts.release ();
5608 known_contexts = vNULL;
5609 }
5610 clone = create_specialized_node (node, known_csts, known_contexts,
7b668576 5611 aggvals, callers);
310bc633 5612 info = IPA_NODE_REF (node);
eb20b778
MJ
5613 info->do_clone_for_all_contexts = false;
5614 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
310bc633
MJ
5615 ret = true;
5616 }
5617 else
44210a96
MJ
5618 {
5619 known_csts.release ();
5620 known_contexts.release ();
5621 }
5e45130d 5622
310bc633
MJ
5623 return ret;
5624}
9187e02d 5625
310bc633 5626/* Transitively mark all callees of NODE within the same SCC as not dead. */
3949c4a7 5627
310bc633
MJ
5628static void
5629spread_undeadness (struct cgraph_node *node)
5630{
5631 struct cgraph_edge *cs;
5e45130d 5632
310bc633 5633 for (cs = node->callees; cs; cs = cs->next_callee)
4cb13597 5634 if (ipa_edge_within_scc (cs))
310bc633
MJ
5635 {
5636 struct cgraph_node *callee;
99b1c316 5637 class ipa_node_params *info;
129a37fc 5638
d52f5295 5639 callee = cs->callee->function_symbol (NULL);
310bc633 5640 info = IPA_NODE_REF (callee);
5e45130d 5641
3c4fa8a8 5642 if (info && info->node_dead)
310bc633
MJ
5643 {
5644 info->node_dead = 0;
5645 spread_undeadness (callee);
5646 }
5647 }
5648}
5649
5650/* Return true if NODE has a caller from outside of its SCC that is not
5651 dead. Worker callback for cgraph_for_node_and_aliases. */
5652
5653static bool
5654has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
155c9907 5655 void *data ATTRIBUTE_UNUSED)
310bc633
MJ
5656{
5657 struct cgraph_edge *cs;
5658
5659 for (cs = node->callers; cs; cs = cs->next_caller)
5660 if (cs->caller->thunk.thunk_p
d52f5295
ML
5661 && cs->caller->call_for_symbol_thunks_and_aliases
5662 (has_undead_caller_from_outside_scc_p, NULL, true))
310bc633 5663 return true;
4cb13597 5664 else if (!ipa_edge_within_scc (cs)
310bc633
MJ
5665 && !IPA_NODE_REF (cs->caller)->node_dead)
5666 return true;
5667 return false;
5668}
5669
5670
5671/* Identify nodes within the same SCC as NODE which are no longer needed
5672 because of new clones and will be removed as unreachable. */
5673
5674static void
5675identify_dead_nodes (struct cgraph_node *node)
5676{
5677 struct cgraph_node *v;
155c9907 5678 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
87f94429 5679 if (v->local
3c4fa8a8 5680 && IPA_NODE_REF (v)
d52f5295
ML
5681 && !v->call_for_symbol_thunks_and_aliases
5682 (has_undead_caller_from_outside_scc_p, NULL, true))
310bc633
MJ
5683 IPA_NODE_REF (v)->node_dead = 1;
5684
155c9907 5685 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
3c4fa8a8 5686 if (IPA_NODE_REF (v) && !IPA_NODE_REF (v)->node_dead)
310bc633
MJ
5687 spread_undeadness (v);
5688
5689 if (dump_file && (dump_flags & TDF_DETAILS))
5690 {
155c9907 5691 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
3c4fa8a8 5692 if (IPA_NODE_REF (v) && IPA_NODE_REF (v)->node_dead)
464d0118 5693 fprintf (dump_file, " Marking node as dead: %s.\n", v->dump_name ());
5e45130d 5694 }
310bc633
MJ
5695}
5696
5697/* The decision stage. Iterate over the topological order of call graph nodes
5698 TOPO and make specialized clones if deemed beneficial. */
5699
5700static void
99b1c316 5701ipcp_decision_stage (class ipa_topo_info *topo)
310bc633
MJ
5702{
5703 int i;
5704
5705 if (dump_file)
5706 fprintf (dump_file, "\nIPA decision stage:\n\n");
5e45130d 5707
310bc633 5708 for (i = topo->nnodes - 1; i >= 0; i--)
5e45130d 5709 {
310bc633
MJ
5710 struct cgraph_node *node = topo->order[i];
5711 bool change = false, iterate = true;
5712
5713 while (iterate)
5714 {
5715 struct cgraph_node *v;
5716 iterate = false;
155c9907 5717 for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
d52f5295 5718 if (v->has_gimple_body_p ()
310bc633
MJ
5719 && ipcp_versionable_function_p (v))
5720 iterate |= decide_whether_version_node (v);
5721
5722 change |= iterate;
5723 }
5724 if (change)
5725 identify_dead_nodes (node);
518dc859 5726 }
518dc859
RL
5727}
5728
209ca542
PK
5729/* Look up all the bits information that we have discovered and copy it over
5730 to the transformation summary. */
5731
5732static void
5733ipcp_store_bits_results (void)
5734{
5735 cgraph_node *node;
5736
5737 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
5738 {
5739 ipa_node_params *info = IPA_NODE_REF (node);
5740 bool dumped_sth = false;
5741 bool found_useful_result = false;
5742
6cf67b62 5743 if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
209ca542
PK
5744 {
5745 if (dump_file)
5746 fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
15bbb5cc 5747 "; -fipa-bit-cp: disabled.\n",
3629ff8a 5748 node->dump_name ());
209ca542
PK
5749 continue;
5750 }
5751
5752 if (info->ipcp_orig_node)
5753 info = IPA_NODE_REF (info->ipcp_orig_node);
68188fff
MJ
5754 if (!info->lattices)
5755 /* Newly expanded artificial thunks do not have lattices. */
5756 continue;
209ca542
PK
5757
5758 unsigned count = ipa_get_param_count (info);
5759 for (unsigned i = 0; i < count; i++)
5760 {
5761 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5762 if (plats->bits_lattice.constant_p ())
5763 {
5764 found_useful_result = true;
5765 break;
5766 }
5767 }
5768
155c9907
JJ
5769 if (!found_useful_result)
5770 continue;
209ca542 5771
9d3e0adc
ML
5772 ipcp_transformation_initialize ();
5773 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
155c9907 5774 vec_safe_reserve_exact (ts->bits, count);
209ca542 5775
155c9907
JJ
5776 for (unsigned i = 0; i < count; i++)
5777 {
5778 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
86cd0334 5779 ipa_bits *jfbits;
209ca542 5780
155c9907 5781 if (plats->bits_lattice.constant_p ())
86cd0334
MJ
5782 jfbits
5783 = ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
5784 plats->bits_lattice.get_mask ());
155c9907 5785 else
86cd0334 5786 jfbits = NULL;
209ca542 5787
86cd0334
MJ
5788 ts->bits->quick_push (jfbits);
5789 if (!dump_file || !jfbits)
155c9907
JJ
5790 continue;
5791 if (!dumped_sth)
5792 {
464d0118
ML
5793 fprintf (dump_file, "Propagated bits info for function %s:\n",
5794 node->dump_name ());
155c9907
JJ
5795 dumped_sth = true;
5796 }
5797 fprintf (dump_file, " param %i: value = ", i);
86cd0334 5798 print_hex (jfbits->value, dump_file);
155c9907 5799 fprintf (dump_file, ", mask = ");
86cd0334 5800 print_hex (jfbits->mask, dump_file);
155c9907
JJ
5801 fprintf (dump_file, "\n");
5802 }
209ca542
PK
5803 }
5804}
8bc5448f
KV
5805
5806/* Look up all VR information that we have discovered and copy it over
5807 to the transformation summary. */
5808
5809static void
5810ipcp_store_vr_results (void)
5811{
5812 cgraph_node *node;
5813
5814 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
155c9907
JJ
5815 {
5816 ipa_node_params *info = IPA_NODE_REF (node);
5817 bool found_useful_result = false;
8bc5448f 5818
a09ccc22 5819 if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
155c9907
JJ
5820 {
5821 if (dump_file)
5822 fprintf (dump_file, "Not considering %s for VR discovery "
5823 "and propagate; -fipa-ipa-vrp: disabled.\n",
3629ff8a 5824 node->dump_name ());
155c9907
JJ
5825 continue;
5826 }
8bc5448f 5827
155c9907
JJ
5828 if (info->ipcp_orig_node)
5829 info = IPA_NODE_REF (info->ipcp_orig_node);
68188fff
MJ
5830 if (!info->lattices)
5831 /* Newly expanded artificial thunks do not have lattices. */
5832 continue;
8bc5448f 5833
155c9907
JJ
5834 unsigned count = ipa_get_param_count (info);
5835 for (unsigned i = 0; i < count; i++)
5836 {
5837 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5838 if (!plats->m_value_range.bottom_p ()
5839 && !plats->m_value_range.top_p ())
5840 {
5841 found_useful_result = true;
5842 break;
5843 }
5844 }
5845 if (!found_useful_result)
5846 continue;
8bc5448f 5847
9d3e0adc
ML
5848 ipcp_transformation_initialize ();
5849 ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
155c9907 5850 vec_safe_reserve_exact (ts->m_vr, count);
8bc5448f 5851
155c9907
JJ
5852 for (unsigned i = 0; i < count; i++)
5853 {
5854 ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
5855 ipa_vr vr;
8bc5448f 5856
155c9907
JJ
5857 if (!plats->m_value_range.bottom_p ()
5858 && !plats->m_value_range.top_p ())
5859 {
5860 vr.known = true;
54994253
AH
5861 vr.type = plats->m_value_range.m_vr.kind ();
5862 vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
5863 vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
155c9907
JJ
5864 }
5865 else
5866 {
5867 vr.known = false;
5868 vr.type = VR_VARYING;
5869 vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
5870 }
5871 ts->m_vr->quick_push (vr);
5872 }
5873 }
8bc5448f
KV
5874}
5875
518dc859 5876/* The IPCP driver. */
310bc633 5877
3cc1cccc 5878static unsigned int
518dc859
RL
5879ipcp_driver (void)
5880{
99b1c316 5881 class ipa_topo_info topo;
310bc633 5882
1ac2bdb4
ML
5883 if (edge_clone_summaries == NULL)
5884 edge_clone_summaries = new edge_clone_summary_t (symtab);
5885
310bc633
MJ
5886 ipa_check_create_node_params ();
5887 ipa_check_create_edge_args ();
9e0b0ec3 5888 clone_num_suffixes = new hash_map<const char *, unsigned>;
aef83682 5889
518dc859
RL
5890 if (dump_file)
5891 {
ca30a539
JH
5892 fprintf (dump_file, "\nIPA structures before propagation:\n");
5893 if (dump_flags & TDF_DETAILS)
155c9907 5894 ipa_print_all_params (dump_file);
ca30a539 5895 ipa_print_all_jump_functions (dump_file);
518dc859 5896 }
310bc633
MJ
5897
5898 /* Topological sort. */
5899 build_toporder_info (&topo);
5900 /* Do the interprocedural propagation. */
5901 ipcp_propagate_stage (&topo);
5902 /* Decide what constant propagation and cloning should be performed. */
5903 ipcp_decision_stage (&topo);
209ca542
PK
5904 /* Store results of bits propagation. */
5905 ipcp_store_bits_results ();
8bc5448f
KV
5906 /* Store results of value range propagation. */
5907 ipcp_store_vr_results ();
310bc633 5908
518dc859 5909 /* Free all IPCP structures. */
53aedcce 5910 delete clone_num_suffixes;
310bc633 5911 free_toporder_info (&topo);
1ac2bdb4 5912 delete edge_clone_summaries;
e67343d7 5913 edge_clone_summaries = NULL;
e33c6cd6 5914 ipa_free_all_structures_after_ipa_cp ();
518dc859
RL
5915 if (dump_file)
5916 fprintf (dump_file, "\nIPA constant propagation end\n");
c2924966 5917 return 0;
518dc859
RL
5918}
5919
3949c4a7
MJ
5920/* Initialization and computation of IPCP data structures. This is the initial
5921 intraprocedural analysis of functions, which gathers information to be
5922 propagated later on. */
5923
129a37fc
JH
5924static void
5925ipcp_generate_summary (void)
5926{
3949c4a7
MJ
5927 struct cgraph_node *node;
5928
129a37fc
JH
5929 if (dump_file)
5930 fprintf (dump_file, "\nIPA constant propagation start:\n");
129a37fc 5931 ipa_register_cgraph_hooks ();
3949c4a7 5932
c47d0034 5933 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
7e729474 5934 ipa_analyze_node (node);
129a37fc
JH
5935}
5936
fb3f88cc 5937/* Write ipcp summary for nodes in SET. */
310bc633 5938
fb3f88cc 5939static void
f27c1867 5940ipcp_write_summary (void)
fb3f88cc 5941{
f27c1867 5942 ipa_prop_write_jump_functions ();
fb3f88cc
JH
5943}
5944
5945/* Read ipcp summary. */
310bc633 5946
fb3f88cc
JH
5947static void
5948ipcp_read_summary (void)
5949{
5950 ipa_prop_read_jump_functions ();
5951}
5952
27a4cd48
DM
5953namespace {
5954
5955const pass_data pass_data_ipa_cp =
5956{
5957 IPA_PASS, /* type */
5958 "cp", /* name */
5959 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
5960 TV_IPA_CONSTANT_PROP, /* tv_id */
5961 0, /* properties_required */
5962 0, /* properties_provided */
5963 0, /* properties_destroyed */
5964 0, /* todo_flags_start */
5965 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
518dc859 5966};
27a4cd48
DM
5967
5968class pass_ipa_cp : public ipa_opt_pass_d
5969{
5970public:
c3284718
RS
5971 pass_ipa_cp (gcc::context *ctxt)
5972 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
5973 ipcp_generate_summary, /* generate_summary */
5974 ipcp_write_summary, /* write_summary */
5975 ipcp_read_summary, /* read_summary */
04be694e 5976 ipcp_write_transformation_summaries, /*
c3284718 5977 write_optimization_summary */
04be694e 5978 ipcp_read_transformation_summaries, /*
c3284718
RS
5979 read_optimization_summary */
5980 NULL, /* stmt_fixup */
5981 0, /* function_transform_todo_flags_start */
5982 ipcp_transform_function, /* function_transform */
5983 NULL) /* variable_transform */
27a4cd48
DM
5984 {}
5985
5986 /* opt_pass methods: */
1a3d085c
TS
5987 virtual bool gate (function *)
5988 {
5989 /* FIXME: We should remove the optimize check after we ensure we never run
5990 IPA passes when not optimizing. */
2bf86c84 5991 return (flag_ipa_cp && optimize) || in_lto_p;
1a3d085c
TS
5992 }
5993
be55bfe6 5994 virtual unsigned int execute (function *) { return ipcp_driver (); }
27a4cd48
DM
5995
5996}; // class pass_ipa_cp
5997
5998} // anon namespace
5999
6000ipa_opt_pass_d *
6001make_pass_ipa_cp (gcc::context *ctxt)
6002{
6003 return new pass_ipa_cp (ctxt);
6004}
3edf64aa
DM
6005
6006/* Reset all state within ipa-cp.c so that we can rerun the compiler
6007 within the same process. For use by toplev::finalize. */
6008
6009void
6010ipa_cp_c_finalize (void)
6011{
e7a74006 6012 max_count = profile_count::uninitialized ();
3edf64aa 6013 overall_size = 0;
f7725a48 6014 orig_overall_size = 0;
12e088ba 6015 ipcp_free_transformation_sum ();
3edf64aa 6016}
This page took 6.385606 seconds and 5 git commands to generate.