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