comparison gcc/ipa-cp.c @ 111:04ced10e8804

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