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