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