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