]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-cp.c
ipa-cp.c (ipcp_value_source): Converted to a template class.
[thirdparty/gcc.git] / gcc / ipa-cp.c
CommitLineData
518dc859 1/* Interprocedural constant propagation
23a5b65a 2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
310bc633
MJ
3
4 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
5 <mjambor@suse.cz>
b8698a0f 6
518dc859 7This file is part of GCC.
b8698a0f 8
518dc859
RL
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
9dcd6f09 11Software Foundation; either version 3, or (at your option) any later
518dc859 12version.
b8698a0f 13
518dc859
RL
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
b8698a0f 18
518dc859 19You should have received a copy of the GNU General Public License
9dcd6f09
NC
20along with GCC; see the file COPYING3. If not see
21<http://www.gnu.org/licenses/>. */
518dc859 22
310bc633 23/* Interprocedural constant propagation (IPA-CP).
b8698a0f 24
310bc633 25 The goal of this transformation is to
c43f07af 26
310bc633
MJ
27 1) discover functions which are always invoked with some arguments with the
28 same known constant values and modify the functions so that the
29 subsequent optimizations can take advantage of the knowledge, and
c43f07af 30
310bc633
MJ
31 2) partial specialization - create specialized versions of functions
32 transformed in this way if some parameters are known constants only in
33 certain contexts but the estimated tradeoff between speedup and cost size
34 is deemed good.
b8698a0f 35
310bc633
MJ
36 The algorithm also propagates types and attempts to perform type based
37 devirtualization. Types are propagated much like constants.
b8698a0f 38
310bc633
MJ
39 The algorithm basically consists of three stages. In the first, functions
40 are analyzed one at a time and jump functions are constructed for all known
41 call-sites. In the second phase, the pass propagates information from the
42 jump functions across the call to reveal what values are available at what
43 call sites, performs estimations of effects of known values on functions and
44 their callees, and finally decides what specialized extra versions should be
45 created. In the third, the special versions materialize and appropriate
46 calls are redirected.
c43f07af 47
310bc633
MJ
48 The algorithm used is to a certain extent based on "Interprocedural Constant
49 Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
50 Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
51 Cooper, Mary W. Hall, and Ken Kennedy.
b8698a0f 52
518dc859
RL
53
54 First stage - intraprocedural analysis
55 =======================================
310bc633 56
c43f07af 57 This phase computes jump_function and modification flags.
b8698a0f 58
310bc633
MJ
59 A jump function for a call-site represents the values passed as an actual
60 arguments of a given call-site. In principle, there are three types of
61 values:
62
63 Pass through - the caller's formal parameter is passed as an actual
64 argument, plus an operation on it can be performed.
ea2c620c 65 Constant - a constant is passed as an actual argument.
518dc859 66 Unknown - neither of the above.
b8698a0f 67
310bc633
MJ
68 All jump function types are described in detail in ipa-prop.h, together with
69 the data structures that represent them and methods of accessing them.
b8698a0f 70
310bc633 71 ipcp_generate_summary() is the main function of the first stage.
518dc859
RL
72
73 Second stage - interprocedural analysis
74 ========================================
b8698a0f 75
310bc633
MJ
76 This stage is itself divided into two phases. In the first, we propagate
77 known values over the call graph, in the second, we make cloning decisions.
78 It uses a different algorithm than the original Callahan's paper.
b8698a0f 79
310bc633
MJ
80 First, we traverse the functions topologically from callers to callees and,
81 for each strongly connected component (SCC), we propagate constants
82 according to previously computed jump functions. We also record what known
83 values depend on other known values and estimate local effects. Finally, we
073a8998 84 propagate cumulative information about these effects from dependent values
310bc633 85 to those on which they depend.
518dc859 86
310bc633
MJ
87 Second, we again traverse the call graph in the same topological order and
88 make clones for functions which we know are called with the same values in
89 all contexts and decide about extra specialized clones of functions just for
90 some contexts - these decisions are based on both local estimates and
91 cumulative estimates propagated from callees.
518dc859 92
310bc633
MJ
93 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
94 third stage.
95
96 Third phase - materialization of clones, call statement updates.
518dc859 97 ============================================
310bc633
MJ
98
99 This stage is currently performed by call graph code (mainly in cgraphunit.c
100 and tree-inline.c) according to instructions inserted to the call graph by
101 the second stage. */
518dc859
RL
102
103#include "config.h"
104#include "system.h"
105#include "coretypes.h"
106#include "tree.h"
2fb9a547
AM
107#include "gimple-fold.h"
108#include "gimple-expr.h"
518dc859 109#include "target.h"
60393bbc
AM
110#include "predict.h"
111#include "basic-block.h"
c582198b
AM
112#include "vec.h"
113#include "hash-map.h"
114#include "is-a.h"
115#include "plugin-api.h"
116#include "hashtab.h"
117#include "hash-set.h"
118#include "machmode.h"
119#include "tm.h"
120#include "hard-reg-set.h"
121#include "input.h"
122#include "function.h"
123#include "ipa-ref.h"
124#include "cgraph.h"
125#include "alloc-pool.h"
518dc859 126#include "ipa-prop.h"
442b4905 127#include "bitmap.h"
518dc859
RL
128#include "tree-pass.h"
129#include "flags.h"
518dc859 130#include "diagnostic.h"
cf835838 131#include "tree-pretty-print.h"
3cc1cccc 132#include "tree-inline.h"
5e45130d 133#include "params.h"
10a5dd5d 134#include "ipa-inline.h"
310bc633 135#include "ipa-utils.h"
518dc859 136
c0cb5055 137template <typename valtype> class ipcp_value;
ca30a539 138
310bc633 139/* Describes a particular source for an IPA-CP value. */
ca30a539 140
c0cb5055
MJ
141template <typename valtype>
142class ipcp_value_source
310bc633 143{
c0cb5055 144public:
2c9561b5
MJ
145 /* Aggregate offset of the source, negative if the source is scalar value of
146 the argument itself. */
147 HOST_WIDE_INT offset;
310bc633 148 /* The incoming edge that brought the value. */
c0cb5055 149 cgraph_edge *cs;
310bc633
MJ
150 /* If the jump function that resulted into his value was a pass-through or an
151 ancestor, this is the ipcp_value of the caller from which the described
152 value has been derived. Otherwise it is NULL. */
c0cb5055 153 ipcp_value<valtype> *val;
310bc633 154 /* Next pointer in a linked list of sources of a value. */
c0cb5055 155 ipcp_value_source *next;
310bc633
MJ
156 /* If the jump function that resulted into his value was a pass-through or an
157 ancestor, this is the index of the parameter of the caller the jump
158 function references. */
159 int index;
160};
ca30a539 161
c0cb5055
MJ
162/* Common ancestor for all ipcp_value instantiations. */
163
164class ipcp_value_base
165{
166public:
167 /* Time benefit and size cost that specializing the function for this value
168 would bring about in this function alone. */
169 int local_time_benefit, local_size_cost;
170 /* Time benefit and size cost that specializing the function for this value
171 can bring about in it's callees (transitively). */
172 int prop_time_benefit, prop_size_cost;
173};
174
310bc633 175/* Describes one particular value stored in struct ipcp_lattice. */
ca30a539 176
c0cb5055
MJ
177template <typename valtype>
178class ipcp_value : public ipcp_value_base
518dc859 179{
c0cb5055
MJ
180public:
181 /* The actual value for the given parameter. */
182 valtype value;
310bc633 183 /* The list of sources from which this value originates. */
c0cb5055 184 ipcp_value_source <valtype> *sources;
310bc633 185 /* Next pointers in a linked list of all values in a lattice. */
c0cb5055 186 ipcp_value *next;
310bc633
MJ
187 /* Next pointers in a linked list of values in a strongly connected component
188 of values. */
c0cb5055 189 ipcp_value *scc_next;
310bc633
MJ
190 /* Next pointers in a linked list of SCCs of values sorted topologically
191 according their sources. */
c0cb5055 192 ipcp_value *topo_next;
310bc633
MJ
193 /* A specialized node created for this value, NULL if none has been (so far)
194 created. */
c0cb5055 195 cgraph_node *spec_node;
310bc633
MJ
196 /* Depth first search number and low link for topological sorting of
197 values. */
198 int dfs, low_link;
310bc633
MJ
199 /* True if this valye is currently on the topo-sort stack. */
200 bool on_stack;
c0cb5055
MJ
201
202 void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
203 HOST_WIDE_INT offset);
310bc633 204};
518dc859 205
2c9561b5
MJ
206/* Lattice describing potential values of a formal parameter of a function, or
207 a part of an aggreagate. TOP is represented by a lattice with zero values
208 and with contains_variable and bottom flags cleared. BOTTOM is represented
209 by a lattice with the bottom flag set. In that case, values and
310bc633
MJ
210 contains_variable flag should be disregarded. */
211
c0cb5055
MJ
212template <typename valtype>
213class ipcp_lattice
518dc859 214{
c0cb5055 215public:
310bc633
MJ
216 /* The list of known values and types in this lattice. Note that values are
217 not deallocated if a lattice is set to bottom because there may be value
218 sources referencing them. */
c0cb5055 219 ipcp_value<valtype> *values;
310bc633
MJ
220 /* Number of known values and types in this lattice. */
221 int values_count;
2c9561b5 222 /* The lattice contains a variable component (in addition to values). */
310bc633
MJ
223 bool contains_variable;
224 /* The value of the lattice is bottom (i.e. variable and unusable for any
225 propagation). */
226 bool bottom;
c0cb5055
MJ
227
228 inline bool is_single_const ();
229 inline bool set_to_bottom ();
230 inline bool set_contains_variable ();
231 bool add_value (valtype newval, cgraph_edge *cs,
232 ipcp_value<valtype> *src_val = NULL,
233 int src_idx = 0, HOST_WIDE_INT offset = -1);
234 void print (FILE * f, bool dump_sources, bool dump_benefits);
2c9561b5
MJ
235};
236
c0cb5055
MJ
237/* Lattice of tree values with an offset to describe a part of an
238 aggregate. */
2c9561b5 239
c0cb5055 240class ipcp_agg_lattice : public ipcp_lattice<tree>
2c9561b5 241{
c0cb5055 242public:
2c9561b5
MJ
243 /* Offset that is being described by this lattice. */
244 HOST_WIDE_INT offset;
245 /* Size so that we don't have to re-compute it every time we traverse the
246 list. Must correspond to TYPE_SIZE of all lat values. */
247 HOST_WIDE_INT size;
248 /* Next element of the linked list. */
249 struct ipcp_agg_lattice *next;
250};
251
252/* Structure containing lattices for a parameter itself and for pieces of
253 aggregates that are passed in the parameter or by a reference in a parameter
254 plus some other useful flags. */
255
c0cb5055 256class ipcp_param_lattices
2c9561b5 257{
c0cb5055 258public:
2c9561b5 259 /* Lattice describing the value of the parameter itself. */
c0cb5055 260 ipcp_lattice<tree> itself;
2c9561b5 261 /* Lattices describing aggregate parts. */
c0cb5055 262 ipcp_agg_lattice *aggs;
2c9561b5
MJ
263 /* Number of aggregate lattices */
264 int aggs_count;
265 /* True if aggregate data were passed by reference (as opposed to by
266 value). */
267 bool aggs_by_ref;
268 /* All aggregate lattices contain a variable component (in addition to
269 values). */
270 bool aggs_contain_variable;
271 /* The value of all aggregate lattices is bottom (i.e. variable and unusable
272 for any propagation). */
273 bool aggs_bottom;
274
310bc633
MJ
275 /* There is a virtual call based on this parameter. */
276 bool virt_call;
277};
518dc859 278
2c9561b5
MJ
279/* Allocation pools for values and their sources in ipa-cp. */
280
281alloc_pool ipcp_values_pool;
282alloc_pool ipcp_sources_pool;
283alloc_pool ipcp_agg_lattice_pool;
284
310bc633
MJ
285/* Maximal count found in program. */
286
287static gcov_type max_count;
288
289/* Original overall size of the program. */
290
291static long overall_size, max_new_size;
292
2c9561b5
MJ
293/* Return the param lattices structure corresponding to the Ith formal
294 parameter of the function described by INFO. */
295static inline struct ipcp_param_lattices *
296ipa_get_parm_lattices (struct ipa_node_params *info, int i)
518dc859 297{
d7da5cc8 298 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
310bc633
MJ
299 gcc_checking_assert (!info->ipcp_orig_node);
300 gcc_checking_assert (info->lattices);
301 return &(info->lattices[i]);
518dc859
RL
302}
303
2c9561b5
MJ
304/* Return the lattice corresponding to the scalar value of the Ith formal
305 parameter of the function described by INFO. */
c0cb5055 306static inline ipcp_lattice<tree> *
2c9561b5
MJ
307ipa_get_scalar_lat (struct ipa_node_params *info, int i)
308{
309 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
310 return &plats->itself;
311}
312
310bc633
MJ
313/* Return whether LAT is a lattice with a single constant and without an
314 undefined value. */
315
c0cb5055
MJ
316template <typename valtype>
317inline bool
318ipcp_lattice<valtype>::is_single_const ()
518dc859 319{
c0cb5055 320 if (bottom || contains_variable || values_count != 1)
518dc859 321 return false;
310bc633
MJ
322 else
323 return true;
518dc859
RL
324}
325
310bc633
MJ
326/* Print V which is extracted from a value in a lattice to F. */
327
518dc859 328static void
310bc633 329print_ipcp_constant_value (FILE * f, tree v)
518dc859 330{
310bc633 331 if (TREE_CODE (v) == TREE_BINFO)
518dc859 332 {
310bc633
MJ
333 fprintf (f, "BINFO ");
334 print_generic_expr (f, BINFO_TYPE (v), 0);
518dc859 335 }
310bc633
MJ
336 else if (TREE_CODE (v) == ADDR_EXPR
337 && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
518dc859 338 {
310bc633
MJ
339 fprintf (f, "& ");
340 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)), 0);
518dc859 341 }
310bc633
MJ
342 else
343 print_generic_expr (f, v, 0);
518dc859
RL
344}
345
2c9561b5
MJ
346/* Print a lattice LAT to F. */
347
c0cb5055
MJ
348template <typename valtype>
349void
350ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
2c9561b5 351{
c0cb5055 352 ipcp_value<valtype> *val;
2c9561b5
MJ
353 bool prev = false;
354
c0cb5055 355 if (bottom)
2c9561b5
MJ
356 {
357 fprintf (f, "BOTTOM\n");
358 return;
359 }
360
c0cb5055 361 if (!values_count && !contains_variable)
2c9561b5
MJ
362 {
363 fprintf (f, "TOP\n");
364 return;
365 }
366
c0cb5055 367 if (contains_variable)
2c9561b5
MJ
368 {
369 fprintf (f, "VARIABLE");
370 prev = true;
371 if (dump_benefits)
372 fprintf (f, "\n");
373 }
374
c0cb5055 375 for (val = values; val; val = val->next)
2c9561b5
MJ
376 {
377 if (dump_benefits && prev)
378 fprintf (f, " ");
379 else if (!dump_benefits && prev)
380 fprintf (f, ", ");
381 else
382 prev = true;
383
384 print_ipcp_constant_value (f, val->value);
385
386 if (dump_sources)
387 {
c0cb5055 388 ipcp_value_source<valtype> *s;
2c9561b5
MJ
389
390 fprintf (f, " [from:");
391 for (s = val->sources; s; s = s->next)
67348ccc 392 fprintf (f, " %i(%i)", s->cs->caller->order,
9de04252 393 s->cs->frequency);
2c9561b5
MJ
394 fprintf (f, "]");
395 }
396
397 if (dump_benefits)
398 fprintf (f, " [loc_time: %i, loc_size: %i, "
399 "prop_time: %i, prop_size: %i]\n",
400 val->local_time_benefit, val->local_size_cost,
401 val->prop_time_benefit, val->prop_size_cost);
402 }
403 if (!dump_benefits)
404 fprintf (f, "\n");
405}
406
c43f07af 407/* Print all ipcp_lattices of all functions to F. */
310bc633 408
518dc859 409static void
310bc633 410print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
518dc859
RL
411{
412 struct cgraph_node *node;
413 int i, count;
3cc1cccc 414
310bc633
MJ
415 fprintf (f, "\nLattices:\n");
416 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
518dc859 417 {
0eae6bab
MJ
418 struct ipa_node_params *info;
419
0eae6bab 420 info = IPA_NODE_REF (node);
fec39fa6 421 fprintf (f, " Node: %s/%i:\n", node->name (),
67348ccc 422 node->order);
c43f07af 423 count = ipa_get_param_count (info);
518dc859
RL
424 for (i = 0; i < count; i++)
425 {
2c9561b5
MJ
426 struct ipcp_agg_lattice *aglat;
427 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
ca30a539 428 fprintf (f, " param [%d]: ", i);
c0cb5055 429 plats->itself.print (f, dump_sources, dump_benefits);
310bc633 430
2c9561b5
MJ
431 if (plats->virt_call)
432 fprintf (f, " virt_call flag set\n");
433
434 if (plats->aggs_bottom)
310bc633 435 {
2c9561b5 436 fprintf (f, " AGGS BOTTOM\n");
310bc633
MJ
437 continue;
438 }
2c9561b5
MJ
439 if (plats->aggs_contain_variable)
440 fprintf (f, " AGGS VARIABLE\n");
441 for (aglat = plats->aggs; aglat; aglat = aglat->next)
310bc633 442 {
2c9561b5
MJ
443 fprintf (f, " %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
444 plats->aggs_by_ref ? "ref " : "", aglat->offset);
c0cb5055 445 aglat->print (f, dump_sources, dump_benefits);
310bc633 446 }
518dc859
RL
447 }
448 }
449}
450
310bc633
MJ
451/* Determine whether it is at all technically possible to create clones of NODE
452 and store this information in the ipa_node_params structure associated
453 with NODE. */
27dbd3ac 454
310bc633
MJ
455static void
456determine_versionability (struct cgraph_node *node)
27dbd3ac 457{
310bc633 458 const char *reason = NULL;
0818c24c 459
aa229804
MJ
460 /* There are a number of generic reasons functions cannot be versioned. We
461 also cannot remove parameters if there are type attributes such as fnspec
462 present. */
67348ccc 463 if (node->alias || node->thunk.thunk_p)
310bc633 464 reason = "alias or thunk";
124f1be6 465 else if (!node->local.versionable)
d7da5cc8 466 reason = "not a tree_versionable_function";
d52f5295 467 else if (node->get_availability () <= AVAIL_INTERPOSABLE)
310bc633 468 reason = "insufficient body availability";
d31d42c7
JJ
469 else if (!opt_for_fn (node->decl, optimize)
470 || !opt_for_fn (node->decl, flag_ipa_cp))
471 reason = "non-optimized function";
0136f8f0
AH
472 else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
473 {
474 /* Ideally we should clone the SIMD clones themselves and create
475 vector copies of them, so IPA-cp and SIMD clones can happily
476 coexist, but that may not be worth the effort. */
477 reason = "function has SIMD clones";
478 }
1f26ac87
JM
479 /* Don't clone decls local to a comdat group; it breaks and for C++
480 decloned constructors, inlining is always better anyway. */
d52f5295 481 else if (node->comdat_local_p ())
1f26ac87 482 reason = "comdat-local function";
27dbd3ac 483
67348ccc 484 if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
310bc633 485 fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
fec39fa6 486 node->name (), node->order, reason);
27dbd3ac 487
124f1be6 488 node->local.versionable = (reason == NULL);
27dbd3ac
RH
489}
490
310bc633
MJ
491/* Return true if it is at all technically possible to create clones of a
492 NODE. */
493
ca30a539 494static bool
310bc633 495ipcp_versionable_function_p (struct cgraph_node *node)
ca30a539 496{
124f1be6 497 return node->local.versionable;
310bc633 498}
ca30a539 499
310bc633 500/* Structure holding accumulated information about callers of a node. */
749f25d8 501
310bc633
MJ
502struct caller_statistics
503{
504 gcov_type count_sum;
505 int n_calls, n_hot_calls, freq_sum;
506};
ca30a539 507
310bc633 508/* Initialize fields of STAT to zeroes. */
530f3a1b 509
310bc633
MJ
510static inline void
511init_caller_stats (struct caller_statistics *stats)
512{
513 stats->count_sum = 0;
514 stats->n_calls = 0;
515 stats->n_hot_calls = 0;
516 stats->freq_sum = 0;
517}
518
519/* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
520 non-thunk incoming edges to NODE. */
521
522static bool
523gather_caller_stats (struct cgraph_node *node, void *data)
524{
525 struct caller_statistics *stats = (struct caller_statistics *) data;
526 struct cgraph_edge *cs;
527
528 for (cs = node->callers; cs; cs = cs->next_caller)
529 if (cs->caller->thunk.thunk_p)
d52f5295
ML
530 cs->caller->call_for_symbol_thunks_and_aliases (gather_caller_stats,
531 stats, false);
310bc633
MJ
532 else
533 {
534 stats->count_sum += cs->count;
535 stats->freq_sum += cs->frequency;
536 stats->n_calls++;
3dafb85c 537 if (cs->maybe_hot_p ())
310bc633
MJ
538 stats->n_hot_calls ++;
539 }
540 return false;
541
542}
543
544/* Return true if this NODE is viable candidate for cloning. */
545
546static bool
547ipcp_cloning_candidate_p (struct cgraph_node *node)
548{
549 struct caller_statistics stats;
550
d52f5295 551 gcc_checking_assert (node->has_gimple_body_p ());
b8698a0f 552
310bc633 553 if (!flag_ipa_cp_clone)
ca30a539
JH
554 {
555 if (dump_file)
310bc633
MJ
556 fprintf (dump_file, "Not considering %s for cloning; "
557 "-fipa-cp-clone disabled.\n",
fec39fa6 558 node->name ());
ca30a539
JH
559 return false;
560 }
ca30a539 561
67348ccc 562 if (!optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
ca30a539
JH
563 {
564 if (dump_file)
310bc633
MJ
565 fprintf (dump_file, "Not considering %s for cloning; "
566 "optimizing it for size.\n",
fec39fa6 567 node->name ());
ca30a539
JH
568 return false;
569 }
570
310bc633 571 init_caller_stats (&stats);
d52f5295 572 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
310bc633
MJ
573
574 if (inline_summary (node)->self_size < stats.n_calls)
ca30a539
JH
575 {
576 if (dump_file)
310bc633 577 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
fec39fa6 578 node->name ());
310bc633 579 return true;
ca30a539
JH
580 }
581
582 /* When profile is available and function is hot, propagate into it even if
583 calls seems cold; constant propagation can improve function's speed
61502ca8 584 significantly. */
ca30a539
JH
585 if (max_count)
586 {
310bc633 587 if (stats.count_sum > node->count * 90 / 100)
ca30a539
JH
588 {
589 if (dump_file)
310bc633
MJ
590 fprintf (dump_file, "Considering %s for cloning; "
591 "usually called directly.\n",
fec39fa6 592 node->name ());
ca30a539
JH
593 return true;
594 }
595 }
310bc633 596 if (!stats.n_hot_calls)
ca30a539
JH
597 {
598 if (dump_file)
599 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
fec39fa6 600 node->name ());
ed102b70 601 return false;
ca30a539
JH
602 }
603 if (dump_file)
604 fprintf (dump_file, "Considering %s for cloning.\n",
fec39fa6 605 node->name ());
ca30a539
JH
606 return true;
607}
608
c0cb5055
MJ
609template <typename valtype>
610class value_topo_info
611{
612public:
613 /* Head of the linked list of topologically sorted values. */
614 ipcp_value<valtype> *values_topo;
615 /* Stack for creating SCCs, represented by a linked list too. */
616 ipcp_value<valtype> *stack;
617 /* Counter driving the algorithm in add_val_to_toposort. */
618 int dfs_counter;
619
620 value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
621 {}
622 void add_val (ipcp_value<valtype> *cur_val);
623 void propagate_effects ();
624};
625
310bc633 626/* Arrays representing a topological ordering of call graph nodes and a stack
c0cb5055
MJ
627 of nodes used during constant propagation and also data required to perform
628 topological sort of values and propagation of benefits in the determined
629 order. */
3949c4a7 630
c0cb5055 631class ipa_topo_info
3949c4a7 632{
c0cb5055
MJ
633public:
634 /* Array with obtained topological order of cgraph nodes. */
310bc633 635 struct cgraph_node **order;
c0cb5055
MJ
636 /* Stack of cgraph nodes used during propagation within SCC until all values
637 in the SCC stabilize. */
310bc633
MJ
638 struct cgraph_node **stack;
639 int nnodes, stack_top;
c0cb5055
MJ
640
641 value_topo_info<tree> constants;
642
643 ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
644 constants ()
645 {}
310bc633
MJ
646};
647
648/* Allocate the arrays in TOPO and topologically sort the nodes into order. */
649
650static void
11478306 651build_toporder_info (struct ipa_topo_info *topo)
310bc633 652{
3dafb85c
ML
653 topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
654 topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
655
c0cb5055 656 gcc_checking_assert (topo->stack_top == 0);
310bc633 657 topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL);
3949c4a7
MJ
658}
659
310bc633
MJ
660/* Free information about strongly connected components and the arrays in
661 TOPO. */
662
518dc859 663static void
11478306 664free_toporder_info (struct ipa_topo_info *topo)
310bc633
MJ
665{
666 ipa_free_postorder_info ();
667 free (topo->order);
668 free (topo->stack);
669}
670
671/* Add NODE to the stack in TOPO, unless it is already there. */
672
673static inline void
11478306 674push_node_to_stack (struct ipa_topo_info *topo, struct cgraph_node *node)
518dc859 675{
c43f07af 676 struct ipa_node_params *info = IPA_NODE_REF (node);
310bc633
MJ
677 if (info->node_enqueued)
678 return;
679 info->node_enqueued = 1;
680 topo->stack[topo->stack_top++] = node;
681}
518dc859 682
310bc633
MJ
683/* Pop a node from the stack in TOPO and return it or return NULL if the stack
684 is empty. */
ca30a539 685
310bc633 686static struct cgraph_node *
11478306 687pop_node_from_stack (struct ipa_topo_info *topo)
310bc633
MJ
688{
689 if (topo->stack_top)
3949c4a7 690 {
310bc633
MJ
691 struct cgraph_node *node;
692 topo->stack_top--;
693 node = topo->stack[topo->stack_top];
694 IPA_NODE_REF (node)->node_enqueued = 0;
695 return node;
3949c4a7 696 }
310bc633
MJ
697 else
698 return NULL;
518dc859
RL
699}
700
310bc633
MJ
701/* Set lattice LAT to bottom and return true if it previously was not set as
702 such. */
703
c0cb5055
MJ
704template <typename valtype>
705inline bool
706ipcp_lattice<valtype>::set_to_bottom ()
518dc859 707{
c0cb5055
MJ
708 bool ret = !bottom;
709 bottom = true;
310bc633
MJ
710 return ret;
711}
518dc859 712
310bc633
MJ
713/* Mark lattice as containing an unknown value and return true if it previously
714 was not marked as such. */
129a37fc 715
c0cb5055
MJ
716template <typename valtype>
717inline bool
718ipcp_lattice<valtype>::set_contains_variable ()
310bc633 719{
c0cb5055
MJ
720 bool ret = !contains_variable;
721 contains_variable = true;
310bc633 722 return ret;
518dc859
RL
723}
724
2c9561b5
MJ
725/* Set all aggegate lattices in PLATS to bottom and return true if they were
726 not previously set as such. */
727
728static inline bool
729set_agg_lats_to_bottom (struct ipcp_param_lattices *plats)
730{
731 bool ret = !plats->aggs_bottom;
732 plats->aggs_bottom = true;
733 return ret;
734}
735
736/* Mark all aggegate lattices in PLATS as containing an unknown value and
737 return true if they were not previously marked as such. */
738
739static inline bool
740set_agg_lats_contain_variable (struct ipcp_param_lattices *plats)
741{
742 bool ret = !plats->aggs_contain_variable;
743 plats->aggs_contain_variable = true;
744 return ret;
745}
746
747/* Mark bot aggregate and scalar lattices as containing an unknown variable,
748 return true is any of them has not been marked as such so far. */
749
750static inline bool
751set_all_contains_variable (struct ipcp_param_lattices *plats)
752{
753 bool ret = !plats->itself.contains_variable || !plats->aggs_contain_variable;
754 plats->itself.contains_variable = true;
755 plats->aggs_contain_variable = true;
756 return ret;
757}
758
310bc633 759/* Initialize ipcp_lattices. */
43558bcc 760
518dc859 761static void
310bc633 762initialize_node_lattices (struct cgraph_node *node)
518dc859 763{
310bc633
MJ
764 struct ipa_node_params *info = IPA_NODE_REF (node);
765 struct cgraph_edge *ie;
766 bool disable = false, variable = false;
767 int i;
518dc859 768
d52f5295 769 gcc_checking_assert (node->has_gimple_body_p ());
d5e254e1 770 if (!cgraph_local_p (node))
310bc633
MJ
771 {
772 /* When cloning is allowed, we can assume that externally visible
773 functions are not called. We will compensate this by cloning
774 later. */
775 if (ipcp_versionable_function_p (node)
776 && ipcp_cloning_candidate_p (node))
777 variable = true;
778 else
779 disable = true;
780 }
518dc859 781
310bc633
MJ
782 if (disable || variable)
783 {
784 for (i = 0; i < ipa_get_param_count (info) ; i++)
785 {
2c9561b5 786 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
310bc633 787 if (disable)
2c9561b5 788 {
c0cb5055 789 plats->itself.set_to_bottom ();
2c9561b5
MJ
790 set_agg_lats_to_bottom (plats);
791 }
310bc633 792 else
2c9561b5 793 set_all_contains_variable (plats);
310bc633
MJ
794 }
795 if (dump_file && (dump_flags & TDF_DETAILS)
67348ccc 796 && !node->alias && !node->thunk.thunk_p)
310bc633 797 fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
fec39fa6 798 node->name (), node->order,
310bc633
MJ
799 disable ? "BOTTOM" : "VARIABLE");
800 }
518dc859 801
310bc633 802 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1d5755ef
JH
803 if (ie->indirect_info->polymorphic
804 && ie->indirect_info->param_index >= 0)
0818c24c 805 {
310bc633 806 gcc_checking_assert (ie->indirect_info->param_index >= 0);
2c9561b5
MJ
807 ipa_get_parm_lattices (info,
808 ie->indirect_info->param_index)->virt_call = 1;
0818c24c 809 }
518dc859
RL
810}
811
310bc633
MJ
812/* Return the result of a (possibly arithmetic) pass through jump function
813 JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be
b8f6e610 814 determined or be considered an interprocedural invariant. */
3949c4a7 815
310bc633
MJ
816static tree
817ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
3949c4a7 818{
310bc633 819 tree restype, res;
3949c4a7 820
b8f6e610
MJ
821 if (TREE_CODE (input) == TREE_BINFO)
822 {
823 if (ipa_get_jf_pass_through_type_preserved (jfunc))
824 {
825 gcc_checking_assert (ipa_get_jf_pass_through_operation (jfunc)
826 == NOP_EXPR);
827 return input;
828 }
829 return NULL_TREE;
830 }
831
7b872d9e 832 if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
310bc633 833 return input;
3949c4a7 834
7b872d9e
MJ
835 gcc_checking_assert (is_gimple_ip_invariant (input));
836 if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
310bc633
MJ
837 == tcc_comparison)
838 restype = boolean_type_node;
839 else
840 restype = TREE_TYPE (input);
7b872d9e
MJ
841 res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
842 input, ipa_get_jf_pass_through_operand (jfunc));
3949c4a7 843
310bc633
MJ
844 if (res && !is_gimple_ip_invariant (res))
845 return NULL_TREE;
3949c4a7 846
310bc633 847 return res;
3949c4a7
MJ
848}
849
310bc633
MJ
850/* Return the result of an ancestor jump function JFUNC on the constant value
851 INPUT. Return NULL_TREE if that cannot be determined. */
3949c4a7 852
310bc633
MJ
853static tree
854ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
3949c4a7 855{
7b872d9e 856 if (TREE_CODE (input) == TREE_BINFO)
b8f6e610
MJ
857 {
858 if (!ipa_get_jf_ancestor_type_preserved (jfunc))
859 return NULL;
01a92e70
JH
860 /* FIXME: At LTO we can't propagate to non-polymorphic type, because
861 we have no ODR equivalency on those. This should be fixed by
862 propagating on types rather than binfos that would make type
863 matching here unnecesary. */
864 if (in_lto_p
865 && (TREE_CODE (ipa_get_jf_ancestor_type (jfunc)) != RECORD_TYPE
866 || !TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc))
867 || !BINFO_VTABLE (TYPE_BINFO (ipa_get_jf_ancestor_type (jfunc)))))
868 {
869 if (!ipa_get_jf_ancestor_offset (jfunc))
870 return input;
871 return NULL;
872 }
b8f6e610
MJ
873 return get_binfo_at_offset (input,
874 ipa_get_jf_ancestor_offset (jfunc),
875 ipa_get_jf_ancestor_type (jfunc));
876 }
7b872d9e 877 else if (TREE_CODE (input) == ADDR_EXPR)
3949c4a7 878 {
310bc633
MJ
879 tree t = TREE_OPERAND (input, 0);
880 t = build_ref_for_offset (EXPR_LOCATION (t), t,
7b872d9e 881 ipa_get_jf_ancestor_offset (jfunc),
0a2550e7
JH
882 ipa_get_jf_ancestor_type (jfunc)
883 ? ipa_get_jf_ancestor_type (jfunc)
884 : ptr_type_node, NULL, false);
310bc633 885 return build_fold_addr_expr (t);
3949c4a7
MJ
886 }
887 else
310bc633
MJ
888 return NULL_TREE;
889}
3949c4a7 890
310bc633
MJ
891/* Determine whether JFUNC evaluates to a known value (that is either a
892 constant or a binfo) and if so, return it. Otherwise return NULL. INFO
893 describes the caller node so that pass-through jump functions can be
894 evaluated. */
895
d2d668fb 896tree
310bc633
MJ
897ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
898{
899 if (jfunc->type == IPA_JF_CONST)
7b872d9e 900 return ipa_get_jf_constant (jfunc);
310bc633 901 else if (jfunc->type == IPA_JF_KNOWN_TYPE)
e248d83f 902 return ipa_binfo_from_known_type_jfunc (jfunc);
310bc633
MJ
903 else if (jfunc->type == IPA_JF_PASS_THROUGH
904 || jfunc->type == IPA_JF_ANCESTOR)
3949c4a7 905 {
310bc633
MJ
906 tree input;
907 int idx;
3949c4a7 908
310bc633 909 if (jfunc->type == IPA_JF_PASS_THROUGH)
7b872d9e 910 idx = ipa_get_jf_pass_through_formal_id (jfunc);
310bc633 911 else
7b872d9e 912 idx = ipa_get_jf_ancestor_formal_id (jfunc);
3949c4a7 913
310bc633 914 if (info->ipcp_orig_node)
9771b263 915 input = info->known_vals[idx];
310bc633 916 else
3949c4a7 917 {
c0cb5055 918 ipcp_lattice<tree> *lat;
310bc633
MJ
919
920 if (!info->lattices)
3949c4a7 921 {
310bc633
MJ
922 gcc_checking_assert (!flag_ipa_cp);
923 return NULL_TREE;
3949c4a7 924 }
2c9561b5 925 lat = ipa_get_scalar_lat (info, idx);
c0cb5055 926 if (!lat->is_single_const ())
310bc633
MJ
927 return NULL_TREE;
928 input = lat->values->value;
929 }
930
931 if (!input)
932 return NULL_TREE;
933
934 if (jfunc->type == IPA_JF_PASS_THROUGH)
7b872d9e 935 return ipa_get_jf_pass_through_result (jfunc, input);
310bc633 936 else
7b872d9e 937 return ipa_get_jf_ancestor_result (jfunc, input);
3949c4a7 938 }
310bc633
MJ
939 else
940 return NULL_TREE;
3949c4a7
MJ
941}
942
3949c4a7 943
310bc633
MJ
944/* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
945 bottom, not containing a variable component and without any known value at
946 the same time. */
3949c4a7 947
310bc633
MJ
948DEBUG_FUNCTION void
949ipcp_verify_propagated_values (void)
518dc859 950{
310bc633 951 struct cgraph_node *node;
ca30a539 952
310bc633 953 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
518dc859 954 {
c43f07af 955 struct ipa_node_params *info = IPA_NODE_REF (node);
310bc633 956 int i, count = ipa_get_param_count (info);
c43f07af 957
310bc633 958 for (i = 0; i < count; i++)
518dc859 959 {
c0cb5055 960 ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
c43f07af 961
310bc633
MJ
962 if (!lat->bottom
963 && !lat->contains_variable
964 && lat->values_count == 0)
518dc859 965 {
310bc633 966 if (dump_file)
518dc859 967 {
d52f5295 968 symtab_node::dump_table (dump_file);
310bc633 969 fprintf (dump_file, "\nIPA lattices after constant "
5bed50e8 970 "propagation, before gcc_unreachable:\n");
310bc633 971 print_all_lattices (dump_file, true, false);
518dc859 972 }
3949c4a7 973
310bc633 974 gcc_unreachable ();
518dc859
RL
975 }
976 }
977 }
978}
979
310bc633
MJ
980/* Return true iff X and Y should be considered equal values by IPA-CP. */
981
982static bool
983values_equal_for_ipcp_p (tree x, tree y)
984{
985 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
986
987 if (x == y)
988 return true;
989
990 if (TREE_CODE (x) == TREE_BINFO || TREE_CODE (y) == TREE_BINFO)
991 return false;
992
993 if (TREE_CODE (x) == ADDR_EXPR
994 && TREE_CODE (y) == ADDR_EXPR
995 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
996 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
997 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
998 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
999 else
1000 return operand_equal_p (x, y, 0);
1001}
1002
c0cb5055
MJ
1003/* Add a new value source to the value represented by THIS, marking that a
1004 value comes from edge CS and (if the underlying jump function is a
1005 pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1006 parameter described by SRC_INDEX. OFFSET is negative if the source was the
1007 scalar value of the parameter itself or the offset within an aggregate. */
310bc633 1008
c0cb5055
MJ
1009template <typename valtype>
1010void
1011ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
1012 int src_idx, HOST_WIDE_INT offset)
518dc859 1013{
c0cb5055 1014 ipcp_value_source<valtype> *src;
ca30a539 1015
c0cb5055 1016 src = new (pool_alloc (ipcp_sources_pool)) ipcp_value_source<valtype>;
2c9561b5 1017 src->offset = offset;
310bc633
MJ
1018 src->cs = cs;
1019 src->val = src_val;
1020 src->index = src_idx;
fb3f88cc 1021
c0cb5055
MJ
1022 src->next = sources;
1023 sources = src;
310bc633
MJ
1024}
1025
c0cb5055
MJ
1026/* Allocate a new ipcp_value holding a tree constant, initialize its value to
1027 SOURCE and clear all other fields. */
310bc633 1028
c0cb5055
MJ
1029static ipcp_value<tree> *
1030allocate_and_init_ipcp_value (tree source)
310bc633 1031{
c0cb5055 1032 ipcp_value<tree> *val;
310bc633 1033
c0cb5055
MJ
1034 val = new (pool_alloc (ipcp_values_pool)) ipcp_value<tree>;
1035 memset (val, 0, sizeof (*val));
1036 val->value = source;
1037 return val;
1038}
1039
1040/* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it. CS,
1041 SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1042 meaning. OFFSET -1 means the source is scalar and not a part of an
1043 aggregate. */
1044
1045template <typename valtype>
1046bool
1047ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1048 ipcp_value<valtype> *src_val,
1049 int src_idx, HOST_WIDE_INT offset)
1050{
1051 ipcp_value<valtype> *val;
1052
1053 if (bottom)
310bc633
MJ
1054 return false;
1055
c0cb5055 1056 for (val = values; val; val = val->next)
310bc633
MJ
1057 if (values_equal_for_ipcp_p (val->value, newval))
1058 {
4cb13597 1059 if (ipa_edge_within_scc (cs))
310bc633 1060 {
c0cb5055 1061 ipcp_value_source<valtype> *s;
310bc633
MJ
1062 for (s = val->sources; s ; s = s->next)
1063 if (s->cs == cs)
1064 break;
1065 if (s)
1066 return false;
1067 }
1068
c0cb5055 1069 val->add_source (cs, src_val, src_idx, offset);
310bc633
MJ
1070 return false;
1071 }
1072
c0cb5055 1073 if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))
310bc633
MJ
1074 {
1075 /* We can only free sources, not the values themselves, because sources
1076 of other values in this this SCC might point to them. */
c0cb5055 1077 for (val = values; val; val = val->next)
310bc633
MJ
1078 {
1079 while (val->sources)
1080 {
c0cb5055 1081 ipcp_value_source<valtype> *src = val->sources;
310bc633
MJ
1082 val->sources = src->next;
1083 pool_free (ipcp_sources_pool, src);
1084 }
1085 }
1086
c0cb5055
MJ
1087 values = NULL;
1088 return set_to_bottom ();
310bc633
MJ
1089 }
1090
c0cb5055
MJ
1091 values_count++;
1092 val = allocate_and_init_ipcp_value (newval);
1093 val->add_source (cs, src_val, src_idx, offset);
1094 val->next = values;
1095 values = val;
310bc633
MJ
1096 return true;
1097}
fb3f88cc 1098
310bc633
MJ
1099/* Propagate values through a pass-through jump function JFUNC associated with
1100 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1101 is the index of the source parameter. */
1102
1103static bool
c0cb5055
MJ
1104propagate_vals_accross_pass_through (cgraph_edge *cs,
1105 ipa_jump_func *jfunc,
1106 ipcp_lattice<tree> *src_lat,
1107 ipcp_lattice<tree> *dest_lat,
310bc633
MJ
1108 int src_idx)
1109{
c0cb5055 1110 ipcp_value<tree> *src_val;
310bc633
MJ
1111 bool ret = false;
1112
310bc633 1113 /* Do not create new values when propagating within an SCC because if there
7b872d9e
MJ
1114 are arithmetic functions with circular dependencies, there is infinite
1115 number of them and we would just make lattices bottom. */
b8f6e610 1116 if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
4cb13597 1117 && ipa_edge_within_scc (cs))
c0cb5055 1118 ret = dest_lat->set_contains_variable ();
310bc633
MJ
1119 else
1120 for (src_val = src_lat->values; src_val; src_val = src_val->next)
0818c24c 1121 {
b8f6e610 1122 tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value);
310bc633
MJ
1123
1124 if (cstval)
c0cb5055 1125 ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
310bc633 1126 else
c0cb5055 1127 ret |= dest_lat->set_contains_variable ();
0818c24c 1128 }
310bc633
MJ
1129
1130 return ret;
1131}
1132
1133/* Propagate values through an ancestor jump function JFUNC associated with
1134 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
1135 is the index of the source parameter. */
1136
1137static bool
1138propagate_vals_accross_ancestor (struct cgraph_edge *cs,
1139 struct ipa_jump_func *jfunc,
c0cb5055
MJ
1140 ipcp_lattice<tree> *src_lat,
1141 ipcp_lattice<tree> *dest_lat,
310bc633
MJ
1142 int src_idx)
1143{
c0cb5055 1144 ipcp_value<tree> *src_val;
310bc633
MJ
1145 bool ret = false;
1146
4cb13597 1147 if (ipa_edge_within_scc (cs))
c0cb5055 1148 return dest_lat->set_contains_variable ();
310bc633
MJ
1149
1150 for (src_val = src_lat->values; src_val; src_val = src_val->next)
1151 {
7b872d9e 1152 tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
310bc633
MJ
1153
1154 if (t)
c0cb5055 1155 ret |= dest_lat->add_value (t, cs, src_val, src_idx);
310bc633 1156 else
c0cb5055 1157 ret |= dest_lat->set_contains_variable ();
310bc633
MJ
1158 }
1159
1160 return ret;
1161}
1162
2c9561b5
MJ
1163/* Propagate scalar values across jump function JFUNC that is associated with
1164 edge CS and put the values into DEST_LAT. */
310bc633
MJ
1165
1166static bool
2c9561b5
MJ
1167propagate_scalar_accross_jump_function (struct cgraph_edge *cs,
1168 struct ipa_jump_func *jfunc,
c0cb5055 1169 ipcp_lattice<tree> *dest_lat)
310bc633
MJ
1170{
1171 if (dest_lat->bottom)
1172 return false;
1173
1174 if (jfunc->type == IPA_JF_CONST
1175 || jfunc->type == IPA_JF_KNOWN_TYPE)
1176 {
1177 tree val;
1178
1179 if (jfunc->type == IPA_JF_KNOWN_TYPE)
c7573249 1180 {
e248d83f 1181 val = ipa_binfo_from_known_type_jfunc (jfunc);
c7573249 1182 if (!val)
c0cb5055 1183 return dest_lat->set_contains_variable ();
c7573249 1184 }
310bc633 1185 else
7b872d9e 1186 val = ipa_get_jf_constant (jfunc);
c0cb5055 1187 return dest_lat->add_value (val, cs, NULL, 0);
310bc633
MJ
1188 }
1189 else if (jfunc->type == IPA_JF_PASS_THROUGH
1190 || jfunc->type == IPA_JF_ANCESTOR)
1191 {
1192 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
c0cb5055 1193 ipcp_lattice<tree> *src_lat;
310bc633
MJ
1194 int src_idx;
1195 bool ret;
1196
1197 if (jfunc->type == IPA_JF_PASS_THROUGH)
7b872d9e 1198 src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
310bc633 1199 else
7b872d9e 1200 src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
310bc633 1201
2c9561b5 1202 src_lat = ipa_get_scalar_lat (caller_info, src_idx);
310bc633 1203 if (src_lat->bottom)
c0cb5055 1204 return dest_lat->set_contains_variable ();
310bc633
MJ
1205
1206 /* If we would need to clone the caller and cannot, do not propagate. */
1207 if (!ipcp_versionable_function_p (cs->caller)
1208 && (src_lat->contains_variable
1209 || (src_lat->values_count > 1)))
c0cb5055 1210 return dest_lat->set_contains_variable ();
310bc633
MJ
1211
1212 if (jfunc->type == IPA_JF_PASS_THROUGH)
1213 ret = propagate_vals_accross_pass_through (cs, jfunc, src_lat,
1214 dest_lat, src_idx);
1215 else
1216 ret = propagate_vals_accross_ancestor (cs, jfunc, src_lat, dest_lat,
1217 src_idx);
1218
1219 if (src_lat->contains_variable)
c0cb5055 1220 ret |= dest_lat->set_contains_variable ();
310bc633
MJ
1221
1222 return ret;
1223 }
1224
1225 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
1226 use it for indirect inlining), we should propagate them too. */
c0cb5055 1227 return dest_lat->set_contains_variable ();
310bc633
MJ
1228}
1229
2c9561b5
MJ
1230/* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
1231 NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
1232 other cases, return false). If there are no aggregate items, set
1233 aggs_by_ref to NEW_AGGS_BY_REF. */
1234
1235static bool
1236set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats,
1237 bool new_aggs_by_ref)
1238{
1239 if (dest_plats->aggs)
1240 {
1241 if (dest_plats->aggs_by_ref != new_aggs_by_ref)
1242 {
1243 set_agg_lats_to_bottom (dest_plats);
1244 return true;
1245 }
1246 }
1247 else
1248 dest_plats->aggs_by_ref = new_aggs_by_ref;
1249 return false;
1250}
1251
1252/* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
1253 already existing lattice for the given OFFSET and SIZE, marking all skipped
1254 lattices as containing variable and checking for overlaps. If there is no
1255 already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
1256 it with offset, size and contains_variable to PRE_EXISTING, and return true,
1257 unless there are too many already. If there are two many, return false. If
1258 there are overlaps turn whole DEST_PLATS to bottom and return false. If any
1259 skipped lattices were newly marked as containing variable, set *CHANGE to
1260 true. */
1261
1262static bool
1263merge_agg_lats_step (struct ipcp_param_lattices *dest_plats,
1264 HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
1265 struct ipcp_agg_lattice ***aglat,
1266 bool pre_existing, bool *change)
1267{
1268 gcc_checking_assert (offset >= 0);
1269
1270 while (**aglat && (**aglat)->offset < offset)
1271 {
1272 if ((**aglat)->offset + (**aglat)->size > offset)
1273 {
1274 set_agg_lats_to_bottom (dest_plats);
1275 return false;
1276 }
c0cb5055 1277 *change |= (**aglat)->set_contains_variable ();
2c9561b5
MJ
1278 *aglat = &(**aglat)->next;
1279 }
1280
1281 if (**aglat && (**aglat)->offset == offset)
1282 {
1283 if ((**aglat)->size != val_size
1284 || ((**aglat)->next
1285 && (**aglat)->next->offset < offset + val_size))
1286 {
1287 set_agg_lats_to_bottom (dest_plats);
1288 return false;
1289 }
1290 gcc_checking_assert (!(**aglat)->next
1291 || (**aglat)->next->offset >= offset + val_size);
1292 return true;
1293 }
1294 else
1295 {
1296 struct ipcp_agg_lattice *new_al;
1297
1298 if (**aglat && (**aglat)->offset < offset + val_size)
1299 {
1300 set_agg_lats_to_bottom (dest_plats);
1301 return false;
1302 }
1303 if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
1304 return false;
1305 dest_plats->aggs_count++;
1306 new_al = (struct ipcp_agg_lattice *) pool_alloc (ipcp_agg_lattice_pool);
1307 memset (new_al, 0, sizeof (*new_al));
1308
1309 new_al->offset = offset;
1310 new_al->size = val_size;
1311 new_al->contains_variable = pre_existing;
1312
1313 new_al->next = **aglat;
1314 **aglat = new_al;
1315 return true;
1316 }
1317}
1318
1319/* Set all AGLAT and all other aggregate lattices reachable by next pointers as
1320 containing an unknown value. */
1321
1322static bool
1323set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
1324{
1325 bool ret = false;
1326 while (aglat)
1327 {
c0cb5055 1328 ret |= aglat->set_contains_variable ();
2c9561b5
MJ
1329 aglat = aglat->next;
1330 }
1331 return ret;
1332}
1333
1334/* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
1335 DELTA_OFFSET. CS is the call graph edge and SRC_IDX the index of the source
1336 parameter used for lattice value sources. Return true if DEST_PLATS changed
1337 in any way. */
1338
1339static bool
1340merge_aggregate_lattices (struct cgraph_edge *cs,
1341 struct ipcp_param_lattices *dest_plats,
1342 struct ipcp_param_lattices *src_plats,
1343 int src_idx, HOST_WIDE_INT offset_delta)
1344{
1345 bool pre_existing = dest_plats->aggs != NULL;
1346 struct ipcp_agg_lattice **dst_aglat;
1347 bool ret = false;
1348
1349 if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
1350 return true;
1351 if (src_plats->aggs_bottom)
1352 return set_agg_lats_contain_variable (dest_plats);
3e452a28
MJ
1353 if (src_plats->aggs_contain_variable)
1354 ret |= set_agg_lats_contain_variable (dest_plats);
2c9561b5
MJ
1355 dst_aglat = &dest_plats->aggs;
1356
1357 for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
1358 src_aglat;
1359 src_aglat = src_aglat->next)
1360 {
1361 HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
1362
1363 if (new_offset < 0)
1364 continue;
1365 if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
1366 &dst_aglat, pre_existing, &ret))
1367 {
1368 struct ipcp_agg_lattice *new_al = *dst_aglat;
1369
1370 dst_aglat = &(*dst_aglat)->next;
1371 if (src_aglat->bottom)
1372 {
c0cb5055 1373 ret |= new_al->set_contains_variable ();
2c9561b5
MJ
1374 continue;
1375 }
1376 if (src_aglat->contains_variable)
c0cb5055
MJ
1377 ret |= new_al->set_contains_variable ();
1378 for (ipcp_value<tree> *val = src_aglat->values;
2c9561b5
MJ
1379 val;
1380 val = val->next)
c0cb5055
MJ
1381 ret |= new_al->add_value (val->value, cs, val, src_idx,
1382 src_aglat->offset);
2c9561b5
MJ
1383 }
1384 else if (dest_plats->aggs_bottom)
1385 return true;
1386 }
1387 ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
1388 return ret;
1389}
1390
324e93f1
MJ
1391/* Determine whether there is anything to propagate FROM SRC_PLATS through a
1392 pass-through JFUNC and if so, whether it has conform and conforms to the
1393 rules about propagating values passed by reference. */
1394
1395static bool
1396agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats,
1397 struct ipa_jump_func *jfunc)
1398{
1399 return src_plats->aggs
1400 && (!src_plats->aggs_by_ref
1401 || ipa_get_jf_pass_through_agg_preserved (jfunc));
1402}
1403
2c9561b5
MJ
1404/* Propagate scalar values across jump function JFUNC that is associated with
1405 edge CS and put the values into DEST_LAT. */
1406
1407static bool
1408propagate_aggs_accross_jump_function (struct cgraph_edge *cs,
1409 struct ipa_jump_func *jfunc,
1410 struct ipcp_param_lattices *dest_plats)
1411{
1412 bool ret = false;
1413
1414 if (dest_plats->aggs_bottom)
1415 return false;
1416
1417 if (jfunc->type == IPA_JF_PASS_THROUGH
1418 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
1419 {
1420 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1421 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
1422 struct ipcp_param_lattices *src_plats;
1423
1424 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
324e93f1 1425 if (agg_pass_through_permissible_p (src_plats, jfunc))
2c9561b5
MJ
1426 {
1427 /* Currently we do not produce clobber aggregate jump
1428 functions, replace with merging when we do. */
1429 gcc_assert (!jfunc->agg.items);
1430 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
1431 src_idx, 0);
1432 }
1433 else
1434 ret |= set_agg_lats_contain_variable (dest_plats);
1435 }
1436 else if (jfunc->type == IPA_JF_ANCESTOR
1437 && ipa_get_jf_ancestor_agg_preserved (jfunc))
1438 {
1439 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1440 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1441 struct ipcp_param_lattices *src_plats;
1442
1443 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
1444 if (src_plats->aggs && src_plats->aggs_by_ref)
1445 {
1446 /* Currently we do not produce clobber aggregate jump
1447 functions, replace with merging when we do. */
1448 gcc_assert (!jfunc->agg.items);
1449 ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
1450 ipa_get_jf_ancestor_offset (jfunc));
1451 }
1452 else if (!src_plats->aggs_by_ref)
1453 ret |= set_agg_lats_to_bottom (dest_plats);
1454 else
1455 ret |= set_agg_lats_contain_variable (dest_plats);
1456 }
1457 else if (jfunc->agg.items)
1458 {
1459 bool pre_existing = dest_plats->aggs != NULL;
1460 struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
1461 struct ipa_agg_jf_item *item;
1462 int i;
1463
1464 if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
1465 return true;
1466
9771b263 1467 FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
2c9561b5
MJ
1468 {
1469 HOST_WIDE_INT val_size;
1470
1471 if (item->offset < 0)
1472 continue;
1473 gcc_checking_assert (is_gimple_ip_invariant (item->value));
ae7e9ddd 1474 val_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (item->value)));
2c9561b5
MJ
1475
1476 if (merge_agg_lats_step (dest_plats, item->offset, val_size,
1477 &aglat, pre_existing, &ret))
1478 {
c0cb5055 1479 ret |= (*aglat)->add_value (item->value, cs, NULL, 0, 0);
2c9561b5
MJ
1480 aglat = &(*aglat)->next;
1481 }
1482 else if (dest_plats->aggs_bottom)
1483 return true;
1484 }
1485
1486 ret |= set_chain_of_aglats_contains_variable (*aglat);
1487 }
1488 else
1489 ret |= set_agg_lats_contain_variable (dest_plats);
1490
1491 return ret;
1492}
1493
310bc633
MJ
1494/* Propagate constants from the caller to the callee of CS. INFO describes the
1495 caller. */
1496
1497static bool
1498propagate_constants_accross_call (struct cgraph_edge *cs)
1499{
1500 struct ipa_node_params *callee_info;
1501 enum availability availability;
1502 struct cgraph_node *callee, *alias_or_thunk;
1503 struct ipa_edge_args *args;
1504 bool ret = false;
d7da5cc8 1505 int i, args_count, parms_count;
310bc633 1506
d52f5295 1507 callee = cs->callee->function_symbol (&availability);
67348ccc 1508 if (!callee->definition)
310bc633 1509 return false;
d52f5295 1510 gcc_checking_assert (callee->has_gimple_body_p ());
310bc633 1511 callee_info = IPA_NODE_REF (callee);
310bc633
MJ
1512
1513 args = IPA_EDGE_REF (cs);
d7da5cc8
MJ
1514 args_count = ipa_get_cs_argument_count (args);
1515 parms_count = ipa_get_param_count (callee_info);
f3fec19f
MJ
1516 if (parms_count == 0)
1517 return false;
310bc633 1518
d5e254e1
IE
1519 /* No propagation through instrumentation thunks is available yet.
1520 It should be possible with proper mapping of call args and
1521 instrumented callee params in the propagation loop below. But
1522 this case mostly occurs when legacy code calls instrumented code
1523 and it is not a primary target for optimizations.
1524 We detect instrumentation thunks in aliases and thunks chain by
1525 checking instrumentation_clone flag for chain source and target.
1526 Going through instrumentation thunks we always have it changed
1527 from 0 to 1 and all other nodes do not change it. */
1528 if (!cs->callee->instrumentation_clone
1529 && callee->instrumentation_clone)
1530 {
1531 for (i = 0; i < parms_count; i++)
1532 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1533 i));
1534 return ret;
1535 }
1536
310bc633
MJ
1537 /* If this call goes through a thunk we must not propagate to the first (0th)
1538 parameter. However, we might need to uncover a thunk from below a series
1539 of aliases first. */
1540 alias_or_thunk = cs->callee;
67348ccc 1541 while (alias_or_thunk->alias)
d52f5295 1542 alias_or_thunk = alias_or_thunk->get_alias_target ();
310bc633
MJ
1543 if (alias_or_thunk->thunk.thunk_p)
1544 {
2c9561b5
MJ
1545 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1546 0));
310bc633
MJ
1547 i = 1;
1548 }
1549 else
1550 i = 0;
1551
d7da5cc8 1552 for (; (i < args_count) && (i < parms_count); i++)
310bc633
MJ
1553 {
1554 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
2c9561b5 1555 struct ipcp_param_lattices *dest_plats;
310bc633 1556
2c9561b5 1557 dest_plats = ipa_get_parm_lattices (callee_info, i);
d52f5295 1558 if (availability == AVAIL_INTERPOSABLE)
2c9561b5 1559 ret |= set_all_contains_variable (dest_plats);
310bc633 1560 else
2c9561b5
MJ
1561 {
1562 ret |= propagate_scalar_accross_jump_function (cs, jump_func,
1563 &dest_plats->itself);
1564 ret |= propagate_aggs_accross_jump_function (cs, jump_func,
1565 dest_plats);
1566 }
310bc633 1567 }
d7da5cc8 1568 for (; i < parms_count; i++)
2c9561b5 1569 ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
d7da5cc8 1570
310bc633
MJ
1571 return ret;
1572}
1573
1574/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
162712de
MJ
1575 (which can contain both constants and binfos), KNOWN_BINFOS, KNOWN_AGGS or
1576 AGG_REPS return the destination. The latter three can be NULL. If AGG_REPS
1577 is not NULL, KNOWN_AGGS is ignored. */
310bc633 1578
162712de
MJ
1579static tree
1580ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
1581 vec<tree> known_vals,
1582 vec<tree> known_binfos,
1583 vec<ipa_agg_jump_function_p> known_aggs,
1584 struct ipa_agg_replacement_value *agg_reps)
310bc633
MJ
1585{
1586 int param_index = ie->indirect_info->param_index;
1587 HOST_WIDE_INT token, anc_offset;
1588 tree otr_type;
1589 tree t;
85942f45 1590 tree target = NULL;
310bc633 1591
97756c0e
MJ
1592 if (param_index == -1
1593 || known_vals.length () <= (unsigned int) param_index)
310bc633
MJ
1594 return NULL_TREE;
1595
1596 if (!ie->indirect_info->polymorphic)
1597 {
8810cc52
MJ
1598 tree t;
1599
1600 if (ie->indirect_info->agg_contents)
1601 {
162712de
MJ
1602 if (agg_reps)
1603 {
1604 t = NULL;
1605 while (agg_reps)
1606 {
1607 if (agg_reps->index == param_index
7b920a9a
MJ
1608 && agg_reps->offset == ie->indirect_info->offset
1609 && agg_reps->by_ref == ie->indirect_info->by_ref)
162712de
MJ
1610 {
1611 t = agg_reps->value;
1612 break;
1613 }
1614 agg_reps = agg_reps->next;
1615 }
1616 }
1617 else if (known_aggs.length () > (unsigned int) param_index)
8810cc52
MJ
1618 {
1619 struct ipa_agg_jump_function *agg;
9771b263 1620 agg = known_aggs[param_index];
8810cc52
MJ
1621 t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
1622 ie->indirect_info->by_ref);
1623 }
1624 else
1625 t = NULL;
1626 }
1627 else
97756c0e 1628 t = known_vals[param_index];
8810cc52 1629
310bc633
MJ
1630 if (t &&
1631 TREE_CODE (t) == ADDR_EXPR
1632 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
81fa35bd 1633 return TREE_OPERAND (t, 0);
310bc633
MJ
1634 else
1635 return NULL_TREE;
1636 }
1637
85942f45
JH
1638 if (!flag_devirtualize)
1639 return NULL_TREE;
1640
8810cc52 1641 gcc_assert (!ie->indirect_info->agg_contents);
310bc633 1642 token = ie->indirect_info->otr_token;
8b7773a4 1643 anc_offset = ie->indirect_info->offset;
310bc633
MJ
1644 otr_type = ie->indirect_info->otr_type;
1645
85942f45
JH
1646 t = NULL;
1647
1648 /* Try to work out value of virtual table pointer value in replacemnets. */
0127c169
JH
1649 if (!t && agg_reps && !ie->indirect_info->by_ref
1650 && !ie->indirect_info->vptr_changed)
85942f45
JH
1651 {
1652 while (agg_reps)
1653 {
1654 if (agg_reps->index == param_index
1655 && agg_reps->offset == ie->indirect_info->offset
1656 && agg_reps->by_ref)
1657 {
1658 t = agg_reps->value;
1659 break;
1660 }
1661 agg_reps = agg_reps->next;
1662 }
1663 }
1664
1665 /* Try to work out value of virtual table pointer value in known
1666 aggregate values. */
1667 if (!t && known_aggs.length () > (unsigned int) param_index
0127c169
JH
1668 && !ie->indirect_info->by_ref
1669 && !ie->indirect_info->vptr_changed)
85942f45
JH
1670 {
1671 struct ipa_agg_jump_function *agg;
1672 agg = known_aggs[param_index];
1673 t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
1674 true);
1675 }
1676
9de2f554 1677 /* If we found the virtual table pointer, lookup the target. */
85942f45 1678 if (t)
9de2f554
JH
1679 {
1680 tree vtable;
1681 unsigned HOST_WIDE_INT offset;
1682 if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
1683 {
1684 target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
1685 vtable, offset);
8472fa80 1686 if (target)
9de2f554 1687 {
8472fa80
MT
1688 if ((TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE
1689 && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
1690 || !possible_polymorphic_call_target_p
d52f5295 1691 (ie, cgraph_node::get (target)))
72972c22 1692 target = ipa_impossible_devirt_target (ie, target);
8472fa80 1693 return target;
9de2f554 1694 }
9de2f554
JH
1695 }
1696 }
85942f45
JH
1697
1698 /* Did we work out BINFO via type propagation? */
9771b263
DN
1699 if (!t && known_binfos.length () > (unsigned int) param_index)
1700 t = known_binfos[param_index];
85942f45
JH
1701 /* Or do we know the constant value of pointer? */
1702 if (!t)
1703 t = known_vals[param_index];
310bc633
MJ
1704 if (!t)
1705 return NULL_TREE;
1706
1707 if (TREE_CODE (t) != TREE_BINFO)
1708 {
6f8091fc
JH
1709 ipa_polymorphic_call_context context (t, ie->indirect_info->otr_type,
1710 anc_offset);
5bccb77a
JH
1711 vec <cgraph_node *>targets;
1712 bool final;
1713
5bccb77a
JH
1714 targets = possible_polymorphic_call_targets
1715 (ie->indirect_info->otr_type,
1716 ie->indirect_info->otr_token,
1717 context, &final);
1718 if (!final || targets.length () > 1)
310bc633 1719 return NULL_TREE;
5bccb77a
JH
1720 if (targets.length () == 1)
1721 target = targets[0]->decl;
1722 else
72972c22 1723 target = ipa_impossible_devirt_target (ie, NULL_TREE);
310bc633
MJ
1724 }
1725 else
1726 {
1727 tree binfo;
1728
1729 binfo = get_binfo_at_offset (t, anc_offset, otr_type);
1730 if (!binfo)
1731 return NULL_TREE;
450ad0cd 1732 target = gimple_get_virt_method_for_binfo (token, binfo);
310bc633 1733 }
b5165eb0
MJ
1734
1735 if (target && !possible_polymorphic_call_target_p (ie,
d52f5295 1736 cgraph_node::get (target)))
72972c22 1737 target = ipa_impossible_devirt_target (ie, target);
450ad0cd
JH
1738
1739 return target;
310bc633
MJ
1740}
1741
162712de
MJ
1742
1743/* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
1744 (which can contain both constants and binfos), KNOWN_BINFOS (which can be
1745 NULL) or KNOWN_AGGS (which also can be NULL) return the destination. */
1746
1747tree
1748ipa_get_indirect_edge_target (struct cgraph_edge *ie,
1749 vec<tree> known_vals,
1750 vec<tree> known_binfos,
1751 vec<ipa_agg_jump_function_p> known_aggs)
1752{
1753 return ipa_get_indirect_edge_target_1 (ie, known_vals, known_binfos,
1754 known_aggs, NULL);
1755}
1756
310bc633
MJ
1757/* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
1758 and KNOWN_BINFOS. */
1759
1760static int
1761devirtualization_time_bonus (struct cgraph_node *node,
9771b263 1762 vec<tree> known_csts,
162712de
MJ
1763 vec<tree> known_binfos,
1764 vec<ipa_agg_jump_function_p> known_aggs)
310bc633
MJ
1765{
1766 struct cgraph_edge *ie;
1767 int res = 0;
1768
1769 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1770 {
1771 struct cgraph_node *callee;
1772 struct inline_summary *isummary;
8ad274d2 1773 enum availability avail;
81fa35bd 1774 tree target;
310bc633 1775
8810cc52 1776 target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos,
162712de 1777 known_aggs);
310bc633
MJ
1778 if (!target)
1779 continue;
1780
1781 /* Only bare minimum benefit for clearly un-inlineable targets. */
1782 res += 1;
d52f5295 1783 callee = cgraph_node::get (target);
67348ccc 1784 if (!callee || !callee->definition)
310bc633 1785 continue;
d52f5295 1786 callee = callee->function_symbol (&avail);
8ad274d2
JH
1787 if (avail < AVAIL_AVAILABLE)
1788 continue;
310bc633
MJ
1789 isummary = inline_summary (callee);
1790 if (!isummary->inlinable)
1791 continue;
1792
1793 /* FIXME: The values below need re-considering and perhaps also
1794 integrating into the cost metrics, at lest in some very basic way. */
1795 if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
1796 res += 31;
1797 else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
1798 res += 15;
1799 else if (isummary->size <= MAX_INLINE_INSNS_AUTO
67348ccc 1800 || DECL_DECLARED_INLINE_P (callee->decl))
310bc633
MJ
1801 res += 7;
1802 }
1803
1804 return res;
1805}
1806
2c9561b5
MJ
1807/* Return time bonus incurred because of HINTS. */
1808
1809static int
1810hint_time_bonus (inline_hints hints)
1811{
19321415 1812 int result = 0;
2c9561b5 1813 if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
19321415
MJ
1814 result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);
1815 if (hints & INLINE_HINT_array_index)
1816 result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
1817 return result;
2c9561b5
MJ
1818}
1819
310bc633
MJ
1820/* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
1821 and SIZE_COST and with the sum of frequencies of incoming edges to the
1822 potential new clone in FREQUENCIES. */
1823
1824static bool
1825good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
1826 int freq_sum, gcov_type count_sum, int size_cost)
1827{
1828 if (time_benefit == 0
1829 || !flag_ipa_cp_clone
67348ccc 1830 || !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
310bc633
MJ
1831 return false;
1832
df0227c4 1833 gcc_assert (size_cost > 0);
310bc633 1834
310bc633
MJ
1835 if (max_count)
1836 {
df0227c4 1837 int factor = (count_sum * 1000) / max_count;
a9243bfc 1838 int64_t evaluation = (((int64_t) time_benefit * factor)
df0227c4 1839 / size_cost);
310bc633
MJ
1840
1841 if (dump_file && (dump_flags & TDF_DETAILS))
1842 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
1843 "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
a9243bfc 1844 ") -> evaluation: " "%"PRId64
df0227c4 1845 ", threshold: %i\n",
310bc633 1846 time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
7a92038b 1847 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
310bc633
MJ
1848
1849 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
1850 }
1851 else
1852 {
a9243bfc 1853 int64_t evaluation = (((int64_t) time_benefit * freq_sum)
df0227c4 1854 / size_cost);
310bc633
MJ
1855
1856 if (dump_file && (dump_flags & TDF_DETAILS))
1857 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
df0227c4 1858 "size: %i, freq_sum: %i) -> evaluation: "
a9243bfc 1859 "%"PRId64 ", threshold: %i\n",
310bc633 1860 time_benefit, size_cost, freq_sum, evaluation,
7a92038b 1861 PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
310bc633
MJ
1862
1863 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
1864 }
1865}
1866
2c9561b5
MJ
1867/* Return all context independent values from aggregate lattices in PLATS in a
1868 vector. Return NULL if there are none. */
1869
84562394 1870static vec<ipa_agg_jf_item, va_gc> *
2c9561b5
MJ
1871context_independent_aggregate_values (struct ipcp_param_lattices *plats)
1872{
84562394 1873 vec<ipa_agg_jf_item, va_gc> *res = NULL;
2c9561b5
MJ
1874
1875 if (plats->aggs_bottom
1876 || plats->aggs_contain_variable
1877 || plats->aggs_count == 0)
1878 return NULL;
1879
1880 for (struct ipcp_agg_lattice *aglat = plats->aggs;
1881 aglat;
1882 aglat = aglat->next)
c0cb5055 1883 if (aglat->is_single_const ())
2c9561b5
MJ
1884 {
1885 struct ipa_agg_jf_item item;
1886 item.offset = aglat->offset;
1887 item.value = aglat->values->value;
9771b263 1888 vec_safe_push (res, item);
2c9561b5
MJ
1889 }
1890 return res;
1891}
310bc633 1892
2c9561b5
MJ
1893/* Allocate KNOWN_CSTS, KNOWN_BINFOS and, if non-NULL, KNOWN_AGGS and populate
1894 them with values of parameters that are known independent of the context.
1895 INFO describes the function. If REMOVABLE_PARAMS_COST is non-NULL, the
1896 movement cost of all removable parameters will be stored in it. */
310bc633
MJ
1897
1898static bool
1899gather_context_independent_values (struct ipa_node_params *info,
9771b263
DN
1900 vec<tree> *known_csts,
1901 vec<tree> *known_binfos,
84562394 1902 vec<ipa_agg_jump_function> *known_aggs,
2c9561b5 1903 int *removable_params_cost)
310bc633
MJ
1904{
1905 int i, count = ipa_get_param_count (info);
1906 bool ret = false;
1907
9771b263
DN
1908 known_csts->create (0);
1909 known_binfos->create (0);
1910 known_csts->safe_grow_cleared (count);
1911 known_binfos->safe_grow_cleared (count);
2c9561b5
MJ
1912 if (known_aggs)
1913 {
9771b263
DN
1914 known_aggs->create (0);
1915 known_aggs->safe_grow_cleared (count);
2c9561b5 1916 }
310bc633
MJ
1917
1918 if (removable_params_cost)
1919 *removable_params_cost = 0;
1920
1921 for (i = 0; i < count ; i++)
1922 {
2c9561b5 1923 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055 1924 ipcp_lattice<tree> *lat = &plats->itself;
310bc633 1925
c0cb5055 1926 if (lat->is_single_const ())
310bc633 1927 {
c0cb5055 1928 ipcp_value<tree> *val = lat->values;
310bc633
MJ
1929 if (TREE_CODE (val->value) != TREE_BINFO)
1930 {
9771b263 1931 (*known_csts)[i] = val->value;
310bc633
MJ
1932 if (removable_params_cost)
1933 *removable_params_cost
b4c9af96 1934 += estimate_move_cost (TREE_TYPE (val->value), false);
310bc633
MJ
1935 ret = true;
1936 }
2c9561b5 1937 else if (plats->virt_call)
310bc633 1938 {
9771b263 1939 (*known_binfos)[i] = val->value;
310bc633
MJ
1940 ret = true;
1941 }
1942 else if (removable_params_cost
1943 && !ipa_is_param_used (info, i))
0e8853ee 1944 *removable_params_cost += ipa_get_param_move_cost (info, i);
310bc633
MJ
1945 }
1946 else if (removable_params_cost
1947 && !ipa_is_param_used (info, i))
1948 *removable_params_cost
0e8853ee 1949 += ipa_get_param_move_cost (info, i);
2c9561b5
MJ
1950
1951 if (known_aggs)
1952 {
84562394 1953 vec<ipa_agg_jf_item, va_gc> *agg_items;
2c9561b5
MJ
1954 struct ipa_agg_jump_function *ajf;
1955
1956 agg_items = context_independent_aggregate_values (plats);
9771b263 1957 ajf = &(*known_aggs)[i];
2c9561b5
MJ
1958 ajf->items = agg_items;
1959 ajf->by_ref = plats->aggs_by_ref;
1960 ret |= agg_items != NULL;
1961 }
310bc633
MJ
1962 }
1963
1964 return ret;
1965}
1966
2c9561b5
MJ
1967/* The current interface in ipa-inline-analysis requires a pointer vector.
1968 Create it.
1969
1970 FIXME: That interface should be re-worked, this is slightly silly. Still,
1971 I'd like to discuss how to change it first and this demonstrates the
1972 issue. */
1973
9771b263 1974static vec<ipa_agg_jump_function_p>
84562394 1975agg_jmp_p_vec_for_t_vec (vec<ipa_agg_jump_function> known_aggs)
2c9561b5 1976{
9771b263 1977 vec<ipa_agg_jump_function_p> ret;
2c9561b5
MJ
1978 struct ipa_agg_jump_function *ajf;
1979 int i;
1980
9771b263
DN
1981 ret.create (known_aggs.length ());
1982 FOR_EACH_VEC_ELT (known_aggs, i, ajf)
1983 ret.quick_push (ajf);
2c9561b5
MJ
1984 return ret;
1985}
1986
c0cb5055
MJ
1987/* Perform time and size measurement of NODE with the context given in
1988 KNOWN_CSTS, KNOWN_BINFOS and KNOWN_AGGS, calculate the benefit and cost
1989 given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
1990 all context-independent removable parameters and EST_MOVE_COST of estimated
1991 movement of the considered parameter and store it into VAL. */
1992
1993static void
1994perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
1995 vec<tree> known_binfos,
1996 vec<ipa_agg_jump_function_p> known_aggs_ptrs,
1997 int base_time, int removable_params_cost,
1998 int est_move_cost, ipcp_value_base *val)
1999{
2000 int time, size, time_benefit;
2001 inline_hints hints;
2002
2003 estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
2004 known_aggs_ptrs, &size, &time,
2005 &hints);
2006 time_benefit = base_time - time
2007 + devirtualization_time_bonus (node, known_csts, known_binfos,
2008 known_aggs_ptrs)
2009 + hint_time_bonus (hints)
2010 + removable_params_cost + est_move_cost;
2011
2012 gcc_checking_assert (size >=0);
2013 /* The inliner-heuristics based estimates may think that in certain
2014 contexts some functions do not have any size at all but we want
2015 all specializations to have at least a tiny cost, not least not to
2016 divide by zero. */
2017 if (size == 0)
2018 size = 1;
2019
2020 val->local_time_benefit = time_benefit;
2021 val->local_size_cost = size;
2022}
2023
310bc633
MJ
2024/* Iterate over known values of parameters of NODE and estimate the local
2025 effects in terms of time and size they have. */
2026
2027static void
2028estimate_local_effects (struct cgraph_node *node)
2029{
2030 struct ipa_node_params *info = IPA_NODE_REF (node);
2031 int i, count = ipa_get_param_count (info);
9771b263 2032 vec<tree> known_csts, known_binfos;
84562394 2033 vec<ipa_agg_jump_function> known_aggs;
9771b263 2034 vec<ipa_agg_jump_function_p> known_aggs_ptrs;
310bc633
MJ
2035 bool always_const;
2036 int base_time = inline_summary (node)->time;
2037 int removable_params_cost;
2038
2039 if (!count || !ipcp_versionable_function_p (node))
2040 return;
2041
ca30a539 2042 if (dump_file && (dump_flags & TDF_DETAILS))
310bc633 2043 fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %i.\n",
fec39fa6 2044 node->name (), node->order, base_time);
310bc633
MJ
2045
2046 always_const = gather_context_independent_values (info, &known_csts,
2c9561b5 2047 &known_binfos, &known_aggs,
310bc633 2048 &removable_params_cost);
2c9561b5 2049 known_aggs_ptrs = agg_jmp_p_vec_for_t_vec (known_aggs);
310bc633 2050 if (always_const)
ca30a539 2051 {
310bc633 2052 struct caller_statistics stats;
2c9561b5 2053 inline_hints hints;
310bc633
MJ
2054 int time, size;
2055
2056 init_caller_stats (&stats);
d52f5295
ML
2057 node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2058 false);
d2d668fb 2059 estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
2c9561b5 2060 known_aggs_ptrs, &size, &time, &hints);
162712de
MJ
2061 time -= devirtualization_time_bonus (node, known_csts, known_binfos,
2062 known_aggs_ptrs);
2c9561b5 2063 time -= hint_time_bonus (hints);
310bc633
MJ
2064 time -= removable_params_cost;
2065 size -= stats.n_calls * removable_params_cost;
2066
2067 if (dump_file)
2068 fprintf (dump_file, " - context independent values, size: %i, "
2069 "time_benefit: %i\n", size, base_time - time);
2070
2071 if (size <= 0
d52f5295 2072 || node->will_be_removed_from_program_if_no_direct_calls_p ())
310bc633 2073 {
eb20b778 2074 info->do_clone_for_all_contexts = true;
310bc633
MJ
2075 base_time = time;
2076
2077 if (dump_file)
2078 fprintf (dump_file, " Decided to specialize for all "
2079 "known contexts, code not going to grow.\n");
2080 }
2081 else if (good_cloning_opportunity_p (node, base_time - time,
2082 stats.freq_sum, stats.count_sum,
2083 size))
2084 {
2085 if (size + overall_size <= max_new_size)
2086 {
eb20b778 2087 info->do_clone_for_all_contexts = true;
310bc633
MJ
2088 base_time = time;
2089 overall_size += size;
2090
2091 if (dump_file)
2092 fprintf (dump_file, " Decided to specialize for all "
2093 "known contexts, growth deemed beneficial.\n");
2094 }
2095 else if (dump_file && (dump_flags & TDF_DETAILS))
2096 fprintf (dump_file, " Not cloning for all contexts because "
2097 "max_new_size would be reached with %li.\n",
2098 size + overall_size);
2099 }
ca30a539
JH
2100 }
2101
310bc633 2102 for (i = 0; i < count ; i++)
ca30a539 2103 {
2c9561b5 2104 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055
MJ
2105 ipcp_lattice<tree> *lat = &plats->itself;
2106 ipcp_value<tree> *val;
310bc633
MJ
2107 int emc;
2108
2109 if (lat->bottom
2110 || !lat->values
9771b263
DN
2111 || known_csts[i]
2112 || known_binfos[i])
310bc633
MJ
2113 continue;
2114
2115 for (val = lat->values; val; val = val->next)
2116 {
310bc633
MJ
2117 if (TREE_CODE (val->value) != TREE_BINFO)
2118 {
9771b263
DN
2119 known_csts[i] = val->value;
2120 known_binfos[i] = NULL_TREE;
b4c9af96 2121 emc = estimate_move_cost (TREE_TYPE (val->value), true);
310bc633 2122 }
2c9561b5 2123 else if (plats->virt_call)
310bc633 2124 {
9771b263
DN
2125 known_csts[i] = NULL_TREE;
2126 known_binfos[i] = val->value;
310bc633
MJ
2127 emc = 0;
2128 }
2129 else
2130 continue;
2131
c0cb5055
MJ
2132 perform_estimation_of_a_value (node, known_csts, known_binfos,
2133 known_aggs_ptrs, base_time,
2134 removable_params_cost, emc, val);
0318fc77 2135
310bc633
MJ
2136 if (dump_file && (dump_flags & TDF_DETAILS))
2137 {
2138 fprintf (dump_file, " - estimates for value ");
2139 print_ipcp_constant_value (dump_file, val->value);
0e8853ee
JH
2140 fprintf (dump_file, " for ");
2141 ipa_dump_param (dump_file, info, i);
310bc633 2142 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
c0cb5055 2143 val->local_time_benefit, val->local_size_cost);
310bc633 2144 }
310bc633 2145 }
9771b263
DN
2146 known_binfos[i] = NULL_TREE;
2147 known_csts[i] = NULL_TREE;
2c9561b5
MJ
2148 }
2149
2150 for (i = 0; i < count ; i++)
2151 {
2152 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2153 struct ipa_agg_jump_function *ajf;
2154 struct ipcp_agg_lattice *aglat;
2155
2156 if (plats->aggs_bottom || !plats->aggs)
2157 continue;
2158
9771b263 2159 ajf = &known_aggs[i];
2c9561b5
MJ
2160 for (aglat = plats->aggs; aglat; aglat = aglat->next)
2161 {
c0cb5055 2162 ipcp_value<tree> *val;
2c9561b5
MJ
2163 if (aglat->bottom || !aglat->values
2164 /* If the following is true, the one value is in known_aggs. */
2165 || (!plats->aggs_contain_variable
c0cb5055 2166 && aglat->is_single_const ()))
2c9561b5
MJ
2167 continue;
2168
2169 for (val = aglat->values; val; val = val->next)
2170 {
2c9561b5 2171 struct ipa_agg_jf_item item;
2c9561b5
MJ
2172
2173 item.offset = aglat->offset;
2174 item.value = val->value;
9771b263 2175 vec_safe_push (ajf->items, item);
2c9561b5 2176
c0cb5055
MJ
2177 perform_estimation_of_a_value (node, known_csts, known_binfos,
2178 known_aggs_ptrs, base_time,
2179 removable_params_cost, 0, val);
2c9561b5
MJ
2180
2181 if (dump_file && (dump_flags & TDF_DETAILS))
2182 {
2183 fprintf (dump_file, " - estimates for value ");
2184 print_ipcp_constant_value (dump_file, val->value);
0e8853ee
JH
2185 fprintf (dump_file, " for ");
2186 ipa_dump_param (dump_file, info, i);
2c9561b5 2187 fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
c0cb5055
MJ
2188 "]: time_benefit: %i, size: %i\n",
2189 plats->aggs_by_ref ? "ref " : "",
2190 aglat->offset,
2191 val->local_time_benefit, val->local_size_cost);
2c9561b5
MJ
2192 }
2193
9771b263 2194 ajf->items->pop ();
2c9561b5
MJ
2195 }
2196 }
2197 }
2198
2199 for (i = 0; i < count ; i++)
9771b263 2200 vec_free (known_aggs[i].items);
310bc633 2201
9771b263
DN
2202 known_csts.release ();
2203 known_binfos.release ();
2204 known_aggs.release ();
2205 known_aggs_ptrs.release ();
310bc633
MJ
2206}
2207
2208
2209/* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
2210 topological sort of values. */
2211
c0cb5055
MJ
2212template <typename valtype>
2213void
2214value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
310bc633 2215{
c0cb5055 2216 ipcp_value_source<valtype> *src;
310bc633
MJ
2217
2218 if (cur_val->dfs)
2219 return;
2220
2221 dfs_counter++;
2222 cur_val->dfs = dfs_counter;
2223 cur_val->low_link = dfs_counter;
2224
2225 cur_val->topo_next = stack;
2226 stack = cur_val;
2227 cur_val->on_stack = true;
2228
2229 for (src = cur_val->sources; src; src = src->next)
2230 if (src->val)
2231 {
2232 if (src->val->dfs == 0)
2233 {
c0cb5055 2234 add_val (src->val);
310bc633
MJ
2235 if (src->val->low_link < cur_val->low_link)
2236 cur_val->low_link = src->val->low_link;
2237 }
2238 else if (src->val->on_stack
2239 && src->val->dfs < cur_val->low_link)
2240 cur_val->low_link = src->val->dfs;
2241 }
2242
2243 if (cur_val->dfs == cur_val->low_link)
ca30a539 2244 {
c0cb5055 2245 ipcp_value<valtype> *v, *scc_list = NULL;
310bc633
MJ
2246
2247 do
2248 {
2249 v = stack;
2250 stack = v->topo_next;
2251 v->on_stack = false;
2252
2253 v->scc_next = scc_list;
2254 scc_list = v;
2255 }
2256 while (v != cur_val);
2257
2258 cur_val->topo_next = values_topo;
2259 values_topo = cur_val;
ca30a539 2260 }
518dc859
RL
2261}
2262
310bc633
MJ
2263/* Add all values in lattices associated with NODE to the topological sort if
2264 they are not there yet. */
2265
2266static void
c0cb5055 2267add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
518dc859 2268{
310bc633
MJ
2269 struct ipa_node_params *info = IPA_NODE_REF (node);
2270 int i, count = ipa_get_param_count (info);
2271
2272 for (i = 0; i < count ; i++)
2273 {
2c9561b5 2274 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055 2275 ipcp_lattice<tree> *lat = &plats->itself;
2c9561b5 2276 struct ipcp_agg_lattice *aglat;
c0cb5055 2277 ipcp_value<tree> *val;
310bc633 2278
2c9561b5
MJ
2279 if (!lat->bottom)
2280 for (val = lat->values; val; val = val->next)
c0cb5055 2281 topo->constants.add_val (val);
2c9561b5
MJ
2282
2283 if (!plats->aggs_bottom)
2284 for (aglat = plats->aggs; aglat; aglat = aglat->next)
2285 if (!aglat->bottom)
2286 for (val = aglat->values; val; val = val->next)
c0cb5055 2287 topo->constants.add_val (val);
310bc633 2288 }
518dc859
RL
2289}
2290
310bc633
MJ
2291/* One pass of constants propagation along the call graph edges, from callers
2292 to callees (requires topological ordering in TOPO), iterate over strongly
2293 connected components. */
2294
518dc859 2295static void
11478306 2296propagate_constants_topo (struct ipa_topo_info *topo)
518dc859 2297{
310bc633 2298 int i;
518dc859 2299
310bc633 2300 for (i = topo->nnodes - 1; i >= 0; i--)
518dc859 2301 {
39e87baf 2302 unsigned j;
310bc633 2303 struct cgraph_node *v, *node = topo->order[i];
d52f5295 2304 vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
310bc633 2305
310bc633
MJ
2306 /* First, iteratively propagate within the strongly connected component
2307 until all lattices stabilize. */
39e87baf 2308 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
d52f5295 2309 if (v->has_gimple_body_p ())
310bc633 2310 push_node_to_stack (topo, v);
310bc633 2311
39e87baf 2312 v = pop_node_from_stack (topo);
310bc633
MJ
2313 while (v)
2314 {
2315 struct cgraph_edge *cs;
2316
2317 for (cs = v->callees; cs; cs = cs->next_callee)
4cb13597 2318 if (ipa_edge_within_scc (cs)
310bc633
MJ
2319 && propagate_constants_accross_call (cs))
2320 push_node_to_stack (topo, cs->callee);
2321 v = pop_node_from_stack (topo);
2322 }
2323
2324 /* Afterwards, propagate along edges leading out of the SCC, calculates
2325 the local effects of the discovered constants and all valid values to
2326 their topological sort. */
39e87baf 2327 FOR_EACH_VEC_ELT (cycle_nodes, j, v)
d52f5295 2328 if (v->has_gimple_body_p ())
39e87baf
MJ
2329 {
2330 struct cgraph_edge *cs;
310bc633 2331
39e87baf 2332 estimate_local_effects (v);
c0cb5055 2333 add_all_node_vals_to_toposort (v, topo);
39e87baf 2334 for (cs = v->callees; cs; cs = cs->next_callee)
4cb13597 2335 if (!ipa_edge_within_scc (cs))
39e87baf
MJ
2336 propagate_constants_accross_call (cs);
2337 }
2338 cycle_nodes.release ();
518dc859
RL
2339 }
2340}
2341
df0227c4
MJ
2342
2343/* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
2344 the bigger one if otherwise. */
2345
2346static int
2347safe_add (int a, int b)
2348{
2349 if (a > INT_MAX/2 || b > INT_MAX/2)
2350 return a > b ? a : b;
2351 else
2352 return a + b;
2353}
2354
2355
310bc633 2356/* Propagate the estimated effects of individual values along the topological
073a8998 2357 from the dependent values to those they depend on. */
310bc633 2358
c0cb5055
MJ
2359template <typename valtype>
2360void
2361value_topo_info<valtype>::propagate_effects ()
518dc859 2362{
c0cb5055 2363 ipcp_value<valtype> *base;
518dc859 2364
310bc633 2365 for (base = values_topo; base; base = base->topo_next)
518dc859 2366 {
c0cb5055
MJ
2367 ipcp_value_source<valtype> *src;
2368 ipcp_value<valtype> *val;
310bc633
MJ
2369 int time = 0, size = 0;
2370
2371 for (val = base; val; val = val->scc_next)
2372 {
df0227c4
MJ
2373 time = safe_add (time,
2374 val->local_time_benefit + val->prop_time_benefit);
2375 size = safe_add (size, val->local_size_cost + val->prop_size_cost);
310bc633
MJ
2376 }
2377
2378 for (val = base; val; val = val->scc_next)
2379 for (src = val->sources; src; src = src->next)
2380 if (src->val
3dafb85c 2381 && src->cs->maybe_hot_p ())
310bc633 2382 {
df0227c4
MJ
2383 src->val->prop_time_benefit = safe_add (time,
2384 src->val->prop_time_benefit);
2385 src->val->prop_size_cost = safe_add (size,
2386 src->val->prop_size_cost);
310bc633 2387 }
518dc859
RL
2388 }
2389}
2390
310bc633
MJ
2391
2392/* Propagate constants, binfos and their effects from the summaries
2393 interprocedurally. */
2394
518dc859 2395static void
11478306 2396ipcp_propagate_stage (struct ipa_topo_info *topo)
518dc859
RL
2397{
2398 struct cgraph_node *node;
518dc859 2399
310bc633
MJ
2400 if (dump_file)
2401 fprintf (dump_file, "\n Propagating constants:\n\n");
2402
2403 if (in_lto_p)
2404 ipa_update_after_lto_read ();
2405
2406
2407 FOR_EACH_DEFINED_FUNCTION (node)
2408 {
2409 struct ipa_node_params *info = IPA_NODE_REF (node);
2410
2411 determine_versionability (node);
d52f5295 2412 if (node->has_gimple_body_p ())
310bc633 2413 {
2c9561b5 2414 info->lattices = XCNEWVEC (struct ipcp_param_lattices,
310bc633
MJ
2415 ipa_get_param_count (info));
2416 initialize_node_lattices (node);
2417 }
67348ccc 2418 if (node->definition && !node->alias)
e70670cf 2419 overall_size += inline_summary (node)->self_size;
310bc633
MJ
2420 if (node->count > max_count)
2421 max_count = node->count;
310bc633
MJ
2422 }
2423
2424 max_new_size = overall_size;
2425 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
2426 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
2427 max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
2428
2429 if (dump_file)
2430 fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
2431 overall_size, max_new_size);
2432
2433 propagate_constants_topo (topo);
2434#ifdef ENABLE_CHECKING
2435 ipcp_verify_propagated_values ();
2436#endif
c0cb5055 2437 topo->constants.propagate_effects ();
310bc633
MJ
2438
2439 if (dump_file)
2440 {
2441 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
2442 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
2443 }
2444}
2445
2446/* Discover newly direct outgoing edges from NODE which is a new clone with
2447 known KNOWN_VALS and make them direct. */
2448
2449static void
2450ipcp_discover_new_direct_edges (struct cgraph_node *node,
162712de
MJ
2451 vec<tree> known_vals,
2452 struct ipa_agg_replacement_value *aggvals)
310bc633
MJ
2453{
2454 struct cgraph_edge *ie, *next_ie;
0f378cb5 2455 bool found = false;
310bc633
MJ
2456
2457 for (ie = node->indirect_calls; ie; ie = next_ie)
2458 {
81fa35bd 2459 tree target;
310bc633
MJ
2460
2461 next_ie = ie->next_callee;
162712de
MJ
2462 target = ipa_get_indirect_edge_target_1 (ie, known_vals, vNULL, vNULL,
2463 aggvals);
310bc633 2464 if (target)
0f378cb5 2465 {
042ae7d2
JH
2466 bool agg_contents = ie->indirect_info->agg_contents;
2467 bool polymorphic = ie->indirect_info->polymorphic;
a4e33812 2468 int param_index = ie->indirect_info->param_index;
4502fe8d 2469 struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target);
0f378cb5 2470 found = true;
4502fe8d 2471
042ae7d2 2472 if (cs && !agg_contents && !polymorphic)
4502fe8d
MJ
2473 {
2474 struct ipa_node_params *info = IPA_NODE_REF (node);
4502fe8d
MJ
2475 int c = ipa_get_controlled_uses (info, param_index);
2476 if (c != IPA_UNDESCRIBED_USE)
2477 {
2478 struct ipa_ref *to_del;
2479
2480 c--;
2481 ipa_set_controlled_uses (info, param_index, c);
2482 if (dump_file && (dump_flags & TDF_DETAILS))
2483 fprintf (dump_file, " controlled uses count of param "
2484 "%i bumped down to %i\n", param_index, c);
2485 if (c == 0
d122681a 2486 && (to_del = node->find_reference (cs->callee, NULL, 0)))
4502fe8d
MJ
2487 {
2488 if (dump_file && (dump_flags & TDF_DETAILS))
2489 fprintf (dump_file, " and even removing its "
2490 "cloning-created reference\n");
d122681a 2491 to_del->remove_reference ();
4502fe8d
MJ
2492 }
2493 }
2494 }
0f378cb5 2495 }
310bc633 2496 }
0f378cb5
JH
2497 /* Turning calls to direct calls will improve overall summary. */
2498 if (found)
2499 inline_update_overall_summary (node);
310bc633
MJ
2500}
2501
2502/* Vector of pointers which for linked lists of clones of an original crgaph
2503 edge. */
2504
d52f5295
ML
2505static vec<cgraph_edge *> next_edge_clone;
2506static vec<cgraph_edge *> prev_edge_clone;
310bc633
MJ
2507
2508static inline void
aef83682 2509grow_edge_clone_vectors (void)
310bc633 2510{
9771b263 2511 if (next_edge_clone.length ()
3dafb85c
ML
2512 <= (unsigned) symtab->edges_max_uid)
2513 next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
aef83682 2514 if (prev_edge_clone.length ()
3dafb85c
ML
2515 <= (unsigned) symtab->edges_max_uid)
2516 prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
310bc633
MJ
2517}
2518
2519/* Edge duplication hook to grow the appropriate linked list in
2520 next_edge_clone. */
2521
2522static void
2523ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
aef83682 2524 void *)
310bc633 2525{
aef83682
MJ
2526 grow_edge_clone_vectors ();
2527
2528 struct cgraph_edge *old_next = next_edge_clone[src->uid];
2529 if (old_next)
2530 prev_edge_clone[old_next->uid] = dst;
2531 prev_edge_clone[dst->uid] = src;
2532
2533 next_edge_clone[dst->uid] = old_next;
9771b263 2534 next_edge_clone[src->uid] = dst;
310bc633
MJ
2535}
2536
aef83682
MJ
2537/* Hook that is called by cgraph.c when an edge is removed. */
2538
2539static void
2540ipcp_edge_removal_hook (struct cgraph_edge *cs, void *)
2541{
2542 grow_edge_clone_vectors ();
2543
2544 struct cgraph_edge *prev = prev_edge_clone[cs->uid];
2545 struct cgraph_edge *next = next_edge_clone[cs->uid];
2546 if (prev)
2547 next_edge_clone[prev->uid] = next;
2548 if (next)
2549 prev_edge_clone[next->uid] = prev;
2550}
2551
2c9561b5
MJ
2552/* See if NODE is a clone with a known aggregate value at a given OFFSET of a
2553 parameter with the given INDEX. */
310bc633 2554
2c9561b5 2555static tree
a9243bfc 2556get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
2c9561b5 2557 int index)
310bc633 2558{
2c9561b5
MJ
2559 struct ipa_agg_replacement_value *aggval;
2560
2561 aggval = ipa_get_agg_replacements_for_node (node);
2562 while (aggval)
2563 {
2564 if (aggval->offset == offset
2565 && aggval->index == index)
2566 return aggval->value;
2567 aggval = aggval->next;
2568 }
2569 return NULL_TREE;
310bc633
MJ
2570}
2571
2572/* Return true if edge CS does bring about the value described by SRC. */
2573
2574static bool
2575cgraph_edge_brings_value_p (struct cgraph_edge *cs,
c0cb5055 2576 ipcp_value_source<tree> *src)
310bc633
MJ
2577{
2578 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
d52f5295 2579 cgraph_node *real_dest = cs->callee->function_symbol ();
d3fb5cf0 2580 struct ipa_node_params *dst_info = IPA_NODE_REF (real_dest);
310bc633 2581
eb20b778 2582 if ((dst_info->ipcp_orig_node && !dst_info->is_all_contexts_clone)
310bc633
MJ
2583 || caller_info->node_dead)
2584 return false;
2585 if (!src->val)
2586 return true;
2587
2588 if (caller_info->ipcp_orig_node)
2589 {
2c9561b5
MJ
2590 tree t;
2591 if (src->offset == -1)
9771b263 2592 t = caller_info->known_vals[src->index];
2c9561b5
MJ
2593 else
2594 t = get_clone_agg_value (cs->caller, src->offset, src->index);
310bc633
MJ
2595 return (t != NULL_TREE
2596 && values_equal_for_ipcp_p (src->val->value, t));
2597 }
2598 else
518dc859 2599 {
2c9561b5
MJ
2600 struct ipcp_agg_lattice *aglat;
2601 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
2602 src->index);
2603 if (src->offset == -1)
c0cb5055 2604 return (plats->itself.is_single_const ()
2c9561b5
MJ
2605 && values_equal_for_ipcp_p (src->val->value,
2606 plats->itself.values->value));
310bc633 2607 else
2c9561b5
MJ
2608 {
2609 if (plats->aggs_bottom || plats->aggs_contain_variable)
2610 return false;
2611 for (aglat = plats->aggs; aglat; aglat = aglat->next)
2612 if (aglat->offset == src->offset)
c0cb5055 2613 return (aglat->is_single_const ()
2c9561b5
MJ
2614 && values_equal_for_ipcp_p (src->val->value,
2615 aglat->values->value));
2616 }
2617 return false;
310bc633
MJ
2618 }
2619}
2620
2c9561b5
MJ
2621/* Get the next clone in the linked list of clones of an edge. */
2622
2623static inline struct cgraph_edge *
2624get_next_cgraph_edge_clone (struct cgraph_edge *cs)
2625{
9771b263 2626 return next_edge_clone[cs->uid];
2c9561b5
MJ
2627}
2628
310bc633
MJ
2629/* Given VAL, iterate over all its sources and if they still hold, add their
2630 edge frequency and their number into *FREQUENCY and *CALLER_COUNT
2631 respectively. */
2632
c0cb5055 2633template <typename valtype>
310bc633 2634static bool
c0cb5055 2635get_info_about_necessary_edges (ipcp_value<valtype> *val, int *freq_sum,
310bc633
MJ
2636 gcov_type *count_sum, int *caller_count)
2637{
c0cb5055 2638 ipcp_value_source<valtype> *src;
310bc633
MJ
2639 int freq = 0, count = 0;
2640 gcov_type cnt = 0;
2641 bool hot = false;
2642
2643 for (src = val->sources; src; src = src->next)
2644 {
2645 struct cgraph_edge *cs = src->cs;
2646 while (cs)
518dc859 2647 {
310bc633
MJ
2648 if (cgraph_edge_brings_value_p (cs, src))
2649 {
2650 count++;
2651 freq += cs->frequency;
2652 cnt += cs->count;
3dafb85c 2653 hot |= cs->maybe_hot_p ();
310bc633
MJ
2654 }
2655 cs = get_next_cgraph_edge_clone (cs);
518dc859
RL
2656 }
2657 }
310bc633
MJ
2658
2659 *freq_sum = freq;
2660 *count_sum = cnt;
2661 *caller_count = count;
2662 return hot;
518dc859
RL
2663}
2664
310bc633
MJ
2665/* Return a vector of incoming edges that do bring value VAL. It is assumed
2666 their number is known and equal to CALLER_COUNT. */
2667
c0cb5055 2668template <typename valtype>
d52f5295 2669static vec<cgraph_edge *>
c0cb5055 2670gather_edges_for_value (ipcp_value<valtype> *val, int caller_count)
518dc859 2671{
c0cb5055 2672 ipcp_value_source<valtype> *src;
d52f5295 2673 vec<cgraph_edge *> ret;
310bc633 2674
9771b263 2675 ret.create (caller_count);
310bc633
MJ
2676 for (src = val->sources; src; src = src->next)
2677 {
2678 struct cgraph_edge *cs = src->cs;
2679 while (cs)
2680 {
2681 if (cgraph_edge_brings_value_p (cs, src))
9771b263 2682 ret.quick_push (cs);
310bc633
MJ
2683 cs = get_next_cgraph_edge_clone (cs);
2684 }
2685 }
2686
2687 return ret;
518dc859
RL
2688}
2689
310bc633
MJ
2690/* Construct a replacement map for a know VALUE for a formal parameter PARAM.
2691 Return it or NULL if for some reason it cannot be created. */
2692
518dc859 2693static struct ipa_replace_map *
0e8853ee 2694get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
518dc859
RL
2695{
2696 struct ipa_replace_map *replace_map;
518dc859 2697
310bc633 2698
766090c2 2699 replace_map = ggc_alloc<ipa_replace_map> ();
c6f7cfc1
JH
2700 if (dump_file)
2701 {
0e8853ee
JH
2702 fprintf (dump_file, " replacing ");
2703 ipa_dump_param (dump_file, info, parm_num);
2704
c6f7cfc1 2705 fprintf (dump_file, " with const ");
310bc633 2706 print_generic_expr (dump_file, value, 0);
c6f7cfc1
JH
2707 fprintf (dump_file, "\n");
2708 }
49bde175
JH
2709 replace_map->old_tree = NULL;
2710 replace_map->parm_num = parm_num;
310bc633 2711 replace_map->new_tree = value;
0f1961a2
JH
2712 replace_map->replace_p = true;
2713 replace_map->ref_p = false;
518dc859
RL
2714
2715 return replace_map;
2716}
2717
310bc633 2718/* Dump new profiling counts */
518dc859 2719
518dc859 2720static void
310bc633
MJ
2721dump_profile_updates (struct cgraph_node *orig_node,
2722 struct cgraph_node *new_node)
518dc859 2723{
310bc633 2724 struct cgraph_edge *cs;
518dc859 2725
310bc633
MJ
2726 fprintf (dump_file, " setting count of the specialized node to "
2727 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count);
2728 for (cs = new_node->callees; cs ; cs = cs->next_callee)
2729 fprintf (dump_file, " edge to %s has count "
2730 HOST_WIDE_INT_PRINT_DEC "\n",
fec39fa6 2731 cs->callee->name (), (HOST_WIDE_INT) cs->count);
310bc633
MJ
2732
2733 fprintf (dump_file, " setting count of the original node to "
2734 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count);
2735 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
2736 fprintf (dump_file, " edge to %s is left with "
2737 HOST_WIDE_INT_PRINT_DEC "\n",
fec39fa6 2738 cs->callee->name (), (HOST_WIDE_INT) cs->count);
310bc633 2739}
c6f7cfc1 2740
310bc633
MJ
2741/* After a specialized NEW_NODE version of ORIG_NODE has been created, update
2742 their profile information to reflect this. */
518dc859 2743
518dc859 2744static void
310bc633
MJ
2745update_profiling_info (struct cgraph_node *orig_node,
2746 struct cgraph_node *new_node)
518dc859 2747{
518dc859 2748 struct cgraph_edge *cs;
310bc633
MJ
2749 struct caller_statistics stats;
2750 gcov_type new_sum, orig_sum;
2751 gcov_type remainder, orig_node_count = orig_node->count;
2752
2753 if (orig_node_count == 0)
2754 return;
518dc859 2755
310bc633 2756 init_caller_stats (&stats);
d52f5295
ML
2757 orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2758 false);
310bc633
MJ
2759 orig_sum = stats.count_sum;
2760 init_caller_stats (&stats);
d52f5295
ML
2761 new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2762 false);
310bc633
MJ
2763 new_sum = stats.count_sum;
2764
2765 if (orig_node_count < orig_sum + new_sum)
518dc859 2766 {
310bc633
MJ
2767 if (dump_file)
2768 fprintf (dump_file, " Problem: node %s/%i has too low count "
2769 HOST_WIDE_INT_PRINT_DEC " while the sum of incoming "
2770 "counts is " HOST_WIDE_INT_PRINT_DEC "\n",
fec39fa6 2771 orig_node->name (), orig_node->order,
310bc633
MJ
2772 (HOST_WIDE_INT) orig_node_count,
2773 (HOST_WIDE_INT) (orig_sum + new_sum));
2774
2775 orig_node_count = (orig_sum + new_sum) * 12 / 10;
2776 if (dump_file)
2777 fprintf (dump_file, " proceeding by pretending it was "
2778 HOST_WIDE_INT_PRINT_DEC "\n",
2779 (HOST_WIDE_INT) orig_node_count);
518dc859 2780 }
310bc633
MJ
2781
2782 new_node->count = new_sum;
2783 remainder = orig_node_count - new_sum;
2784 orig_node->count = remainder;
2785
2786 for (cs = new_node->callees; cs ; cs = cs->next_callee)
2787 if (cs->frequency)
8ddb5a29
TJ
2788 cs->count = apply_probability (cs->count,
2789 GCOV_COMPUTE_SCALE (new_sum,
2790 orig_node_count));
310bc633
MJ
2791 else
2792 cs->count = 0;
2793
2794 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
8ddb5a29
TJ
2795 cs->count = apply_probability (cs->count,
2796 GCOV_COMPUTE_SCALE (remainder,
2797 orig_node_count));
310bc633
MJ
2798
2799 if (dump_file)
2800 dump_profile_updates (orig_node, new_node);
518dc859
RL
2801}
2802
310bc633
MJ
2803/* Update the respective profile of specialized NEW_NODE and the original
2804 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
2805 have been redirected to the specialized version. */
2806
2807static void
2808update_specialized_profile (struct cgraph_node *new_node,
2809 struct cgraph_node *orig_node,
2810 gcov_type redirected_sum)
5e45130d 2811{
a065d52e 2812 struct cgraph_edge *cs;
310bc633 2813 gcov_type new_node_count, orig_node_count = orig_node->count;
5e45130d 2814
310bc633
MJ
2815 if (dump_file)
2816 fprintf (dump_file, " the sum of counts of redirected edges is "
2817 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum);
2818 if (orig_node_count == 0)
2819 return;
a065d52e 2820
310bc633 2821 gcc_assert (orig_node_count >= redirected_sum);
5e45130d 2822
310bc633
MJ
2823 new_node_count = new_node->count;
2824 new_node->count += redirected_sum;
2825 orig_node->count -= redirected_sum;
a065d52e 2826
310bc633
MJ
2827 for (cs = new_node->callees; cs ; cs = cs->next_callee)
2828 if (cs->frequency)
8ddb5a29
TJ
2829 cs->count += apply_probability (cs->count,
2830 GCOV_COMPUTE_SCALE (redirected_sum,
2831 new_node_count));
310bc633
MJ
2832 else
2833 cs->count = 0;
a065d52e 2834
310bc633
MJ
2835 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
2836 {
8ddb5a29
TJ
2837 gcov_type dec = apply_probability (cs->count,
2838 GCOV_COMPUTE_SCALE (redirected_sum,
2839 orig_node_count));
310bc633
MJ
2840 if (dec < cs->count)
2841 cs->count -= dec;
2842 else
2843 cs->count = 0;
2844 }
a065d52e 2845
310bc633
MJ
2846 if (dump_file)
2847 dump_profile_updates (orig_node, new_node);
5e45130d
JH
2848}
2849
310bc633
MJ
2850/* Create a specialized version of NODE with known constants and types of
2851 parameters in KNOWN_VALS and redirect all edges in CALLERS to it. */
a065d52e 2852
310bc633
MJ
2853static struct cgraph_node *
2854create_specialized_node (struct cgraph_node *node,
9771b263 2855 vec<tree> known_vals,
2c9561b5 2856 struct ipa_agg_replacement_value *aggvals,
d52f5295 2857 vec<cgraph_edge *> callers)
5e45130d 2858{
310bc633 2859 struct ipa_node_params *new_info, *info = IPA_NODE_REF (node);
d52f5295 2860 vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
79ee9826 2861 struct ipa_agg_replacement_value *av;
310bc633
MJ
2862 struct cgraph_node *new_node;
2863 int i, count = ipa_get_param_count (info);
2864 bitmap args_to_skip;
5e45130d 2865
310bc633
MJ
2866 gcc_assert (!info->ipcp_orig_node);
2867
2868 if (node->local.can_change_signature)
5e45130d 2869 {
310bc633
MJ
2870 args_to_skip = BITMAP_GGC_ALLOC ();
2871 for (i = 0; i < count; i++)
2872 {
9771b263 2873 tree t = known_vals[i];
310bc633
MJ
2874
2875 if ((t && TREE_CODE (t) != TREE_BINFO)
2876 || !ipa_is_param_used (info, i))
2877 bitmap_set_bit (args_to_skip, i);
2878 }
2879 }
2880 else
d7da5cc8
MJ
2881 {
2882 args_to_skip = NULL;
2883 if (dump_file && (dump_flags & TDF_DETAILS))
2884 fprintf (dump_file, " cannot change function signature\n");
2885 }
310bc633
MJ
2886
2887 for (i = 0; i < count ; i++)
2888 {
9771b263 2889 tree t = known_vals[i];
310bc633
MJ
2890 if (t && TREE_CODE (t) != TREE_BINFO)
2891 {
2892 struct ipa_replace_map *replace_map;
2893
0e8853ee 2894 replace_map = get_replacement_map (info, t, i);
310bc633 2895 if (replace_map)
9771b263 2896 vec_safe_push (replace_trees, replace_map);
310bc633 2897 }
5e45130d
JH
2898 }
2899
d52f5295
ML
2900 new_node = node->create_virtual_clone (callers, replace_trees,
2901 args_to_skip, "constprop");
2c9561b5 2902 ipa_set_node_agg_value_chain (new_node, aggvals);
79ee9826 2903 for (av = aggvals; av; av = av->next)
3dafb85c 2904 new_node->maybe_create_reference (av->value, IPA_REF_ADDR, NULL);
79ee9826 2905
310bc633 2906 if (dump_file && (dump_flags & TDF_DETAILS))
2c9561b5
MJ
2907 {
2908 fprintf (dump_file, " the new node is %s/%i.\n",
fec39fa6 2909 new_node->name (), new_node->order);
2c9561b5
MJ
2910 if (aggvals)
2911 ipa_dump_agg_replacement_values (dump_file, aggvals);
2912 }
9de6f6c3 2913 ipa_check_create_node_params ();
310bc633
MJ
2914 update_profiling_info (node, new_node);
2915 new_info = IPA_NODE_REF (new_node);
2916 new_info->ipcp_orig_node = node;
2917 new_info->known_vals = known_vals;
5e45130d 2918
162712de 2919 ipcp_discover_new_direct_edges (new_node, known_vals, aggvals);
310bc633 2920
9771b263 2921 callers.release ();
310bc633 2922 return new_node;
5e45130d
JH
2923}
2924
310bc633
MJ
2925/* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
2926 KNOWN_VALS with constants and types that are also known for all of the
2927 CALLERS. */
3949c4a7
MJ
2928
2929static void
2c9561b5 2930find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
9771b263 2931 vec<tree> known_vals,
d52f5295 2932 vec<cgraph_edge *> callers)
3949c4a7
MJ
2933{
2934 struct ipa_node_params *info = IPA_NODE_REF (node);
310bc633 2935 int i, count = ipa_get_param_count (info);
3949c4a7 2936
310bc633 2937 for (i = 0; i < count ; i++)
3949c4a7 2938 {
310bc633
MJ
2939 struct cgraph_edge *cs;
2940 tree newval = NULL_TREE;
2941 int j;
3949c4a7 2942
9771b263 2943 if (ipa_get_scalar_lat (info, i)->bottom || known_vals[i])
3949c4a7
MJ
2944 continue;
2945
9771b263 2946 FOR_EACH_VEC_ELT (callers, j, cs)
49c471e3 2947 {
310bc633
MJ
2948 struct ipa_jump_func *jump_func;
2949 tree t;
40591473 2950
128c61ee
MJ
2951 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
2952 {
2953 newval = NULL_TREE;
2954 break;
2955 }
310bc633 2956 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
310bc633
MJ
2957 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
2958 if (!t
2959 || (newval
2960 && !values_equal_for_ipcp_p (t, newval)))
3949c4a7 2961 {
310bc633
MJ
2962 newval = NULL_TREE;
2963 break;
3949c4a7 2964 }
310bc633
MJ
2965 else
2966 newval = t;
3949c4a7
MJ
2967 }
2968
310bc633
MJ
2969 if (newval)
2970 {
2971 if (dump_file && (dump_flags & TDF_DETAILS))
2972 {
2c9561b5 2973 fprintf (dump_file, " adding an extra known scalar value ");
310bc633 2974 print_ipcp_constant_value (dump_file, newval);
0e8853ee
JH
2975 fprintf (dump_file, " for ");
2976 ipa_dump_param (dump_file, info, i);
310bc633
MJ
2977 fprintf (dump_file, "\n");
2978 }
5e45130d 2979
9771b263 2980 known_vals[i] = newval;
310bc633 2981 }
5e45130d 2982 }
5e45130d
JH
2983}
2984
2c9561b5
MJ
2985/* Go through PLATS and create a vector of values consisting of values and
2986 offsets (minus OFFSET) of lattices that contain only a single value. */
2987
84562394 2988static vec<ipa_agg_jf_item>
2c9561b5
MJ
2989copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset)
2990{
84562394 2991 vec<ipa_agg_jf_item> res = vNULL;
2c9561b5
MJ
2992
2993 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
6e1aa848 2994 return vNULL;
2c9561b5
MJ
2995
2996 for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
c0cb5055 2997 if (aglat->is_single_const ())
2c9561b5
MJ
2998 {
2999 struct ipa_agg_jf_item ti;
3000 ti.offset = aglat->offset - offset;
3001 ti.value = aglat->values->value;
9771b263 3002 res.safe_push (ti);
2c9561b5
MJ
3003 }
3004 return res;
3005}
3006
3007/* Intersect all values in INTER with single value lattices in PLATS (while
3008 subtracting OFFSET). */
3009
3010static void
3011intersect_with_plats (struct ipcp_param_lattices *plats,
84562394 3012 vec<ipa_agg_jf_item> *inter,
2c9561b5
MJ
3013 HOST_WIDE_INT offset)
3014{
3015 struct ipcp_agg_lattice *aglat;
3016 struct ipa_agg_jf_item *item;
3017 int k;
3018
3019 if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
3020 {
9771b263 3021 inter->release ();
2c9561b5
MJ
3022 return;
3023 }
3024
3025 aglat = plats->aggs;
9771b263 3026 FOR_EACH_VEC_ELT (*inter, k, item)
2c9561b5
MJ
3027 {
3028 bool found = false;
3029 if (!item->value)
3030 continue;
3031 while (aglat)
3032 {
3033 if (aglat->offset - offset > item->offset)
3034 break;
3035 if (aglat->offset - offset == item->offset)
3036 {
3037 gcc_checking_assert (item->value);
3038 if (values_equal_for_ipcp_p (item->value, aglat->values->value))
3039 found = true;
3040 break;
3041 }
3042 aglat = aglat->next;
3043 }
3044 if (!found)
3045 item->value = NULL_TREE;
3046 }
3047}
3048
3049/* Copy agggregate replacement values of NODE (which is an IPA-CP clone) to the
3050 vector result while subtracting OFFSET from the individual value offsets. */
3051
84562394 3052static vec<ipa_agg_jf_item>
0fd44da3
MJ
3053agg_replacements_to_vector (struct cgraph_node *node, int index,
3054 HOST_WIDE_INT offset)
2c9561b5
MJ
3055{
3056 struct ipa_agg_replacement_value *av;
84562394 3057 vec<ipa_agg_jf_item> res = vNULL;
2c9561b5
MJ
3058
3059 for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
0fd44da3
MJ
3060 if (av->index == index
3061 && (av->offset - offset) >= 0)
2c9561b5
MJ
3062 {
3063 struct ipa_agg_jf_item item;
3064 gcc_checking_assert (av->value);
3065 item.offset = av->offset - offset;
3066 item.value = av->value;
9771b263 3067 res.safe_push (item);
2c9561b5
MJ
3068 }
3069
3070 return res;
3071}
3072
3073/* Intersect all values in INTER with those that we have already scheduled to
3074 be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
3075 (while subtracting OFFSET). */
3076
3077static void
3078intersect_with_agg_replacements (struct cgraph_node *node, int index,
84562394 3079 vec<ipa_agg_jf_item> *inter,
2c9561b5
MJ
3080 HOST_WIDE_INT offset)
3081{
3082 struct ipa_agg_replacement_value *srcvals;
3083 struct ipa_agg_jf_item *item;
3084 int i;
3085
3086 srcvals = ipa_get_agg_replacements_for_node (node);
3087 if (!srcvals)
3088 {
9771b263 3089 inter->release ();
2c9561b5
MJ
3090 return;
3091 }
3092
9771b263 3093 FOR_EACH_VEC_ELT (*inter, i, item)
2c9561b5
MJ
3094 {
3095 struct ipa_agg_replacement_value *av;
3096 bool found = false;
3097 if (!item->value)
3098 continue;
3099 for (av = srcvals; av; av = av->next)
3100 {
3101 gcc_checking_assert (av->value);
3102 if (av->index == index
3103 && av->offset - offset == item->offset)
3104 {
3105 if (values_equal_for_ipcp_p (item->value, av->value))
3106 found = true;
3107 break;
3108 }
3109 }
3110 if (!found)
3111 item->value = NULL_TREE;
3112 }
3113}
3114
7e9f2b6e
MJ
3115/* Intersect values in INTER with aggregate values that come along edge CS to
3116 parameter number INDEX and return it. If INTER does not actually exist yet,
3117 copy all incoming values to it. If we determine we ended up with no values
3118 whatsoever, return a released vector. */
3119
84562394 3120static vec<ipa_agg_jf_item>
7e9f2b6e 3121intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
84562394 3122 vec<ipa_agg_jf_item> inter)
7e9f2b6e
MJ
3123{
3124 struct ipa_jump_func *jfunc;
3125 jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
3126 if (jfunc->type == IPA_JF_PASS_THROUGH
3127 && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3128 {
3129 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3130 int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
3131
3132 if (caller_info->ipcp_orig_node)
3133 {
3134 struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
3135 struct ipcp_param_lattices *orig_plats;
3136 orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
3137 src_idx);
3138 if (agg_pass_through_permissible_p (orig_plats, jfunc))
3139 {
3140 if (!inter.exists ())
0fd44da3 3141 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
7e9f2b6e
MJ
3142 else
3143 intersect_with_agg_replacements (cs->caller, src_idx,
3144 &inter, 0);
3145 }
c8f40352
MJ
3146 else
3147 {
3148 inter.release ();
3149 return vNULL;
3150 }
7e9f2b6e
MJ
3151 }
3152 else
3153 {
3154 struct ipcp_param_lattices *src_plats;
3155 src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3156 if (agg_pass_through_permissible_p (src_plats, jfunc))
3157 {
3158 /* Currently we do not produce clobber aggregate jump
3159 functions, adjust when we do. */
3160 gcc_checking_assert (!jfunc->agg.items);
3161 if (!inter.exists ())
3162 inter = copy_plats_to_inter (src_plats, 0);
3163 else
3164 intersect_with_plats (src_plats, &inter, 0);
3165 }
c8f40352
MJ
3166 else
3167 {
3168 inter.release ();
3169 return vNULL;
3170 }
7e9f2b6e
MJ
3171 }
3172 }
3173 else if (jfunc->type == IPA_JF_ANCESTOR
3174 && ipa_get_jf_ancestor_agg_preserved (jfunc))
3175 {
3176 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3177 int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
3178 struct ipcp_param_lattices *src_plats;
3179 HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
3180
3181 if (caller_info->ipcp_orig_node)
3182 {
3183 if (!inter.exists ())
0fd44da3 3184 inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
7e9f2b6e 3185 else
0fd44da3 3186 intersect_with_agg_replacements (cs->caller, src_idx, &inter,
7e9f2b6e
MJ
3187 delta);
3188 }
3189 else
3190 {
3191 src_plats = ipa_get_parm_lattices (caller_info, src_idx);;
3192 /* Currently we do not produce clobber aggregate jump
3193 functions, adjust when we do. */
3194 gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
3195 if (!inter.exists ())
3196 inter = copy_plats_to_inter (src_plats, delta);
3197 else
3198 intersect_with_plats (src_plats, &inter, delta);
3199 }
3200 }
3201 else if (jfunc->agg.items)
3202 {
3203 struct ipa_agg_jf_item *item;
3204 int k;
3205
3206 if (!inter.exists ())
3207 for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
3208 inter.safe_push ((*jfunc->agg.items)[i]);
3209 else
3210 FOR_EACH_VEC_ELT (inter, k, item)
3211 {
3212 int l = 0;
3213 bool found = false;;
3214
3215 if (!item->value)
3216 continue;
3217
3218 while ((unsigned) l < jfunc->agg.items->length ())
3219 {
3220 struct ipa_agg_jf_item *ti;
3221 ti = &(*jfunc->agg.items)[l];
3222 if (ti->offset > item->offset)
3223 break;
3224 if (ti->offset == item->offset)
3225 {
3226 gcc_checking_assert (ti->value);
3227 if (values_equal_for_ipcp_p (item->value,
3228 ti->value))
3229 found = true;
3230 break;
3231 }
3232 l++;
3233 }
3234 if (!found)
3235 item->value = NULL;
3236 }
3237 }
3238 else
3239 {
c3284718 3240 inter.release ();
84562394 3241 return vec<ipa_agg_jf_item>();
7e9f2b6e
MJ
3242 }
3243 return inter;
3244}
3245
2c9561b5
MJ
3246/* Look at edges in CALLERS and collect all known aggregate values that arrive
3247 from all of them. */
3248
3249static struct ipa_agg_replacement_value *
3250find_aggregate_values_for_callers_subset (struct cgraph_node *node,
d52f5295 3251 vec<cgraph_edge *> callers)
2c9561b5 3252{
dffdd6e5 3253 struct ipa_node_params *dest_info = IPA_NODE_REF (node);
6f9549ee
MJ
3254 struct ipa_agg_replacement_value *res;
3255 struct ipa_agg_replacement_value **tail = &res;
2c9561b5 3256 struct cgraph_edge *cs;
dffdd6e5 3257 int i, j, count = ipa_get_param_count (dest_info);
2c9561b5 3258
9771b263 3259 FOR_EACH_VEC_ELT (callers, j, cs)
2c9561b5
MJ
3260 {
3261 int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
3262 if (c < count)
3263 count = c;
3264 }
3265
3266 for (i = 0; i < count ; i++)
3267 {
3268 struct cgraph_edge *cs;
84562394 3269 vec<ipa_agg_jf_item> inter = vNULL;
2c9561b5 3270 struct ipa_agg_jf_item *item;
7b920a9a 3271 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
2c9561b5
MJ
3272 int j;
3273
3274 /* Among other things, the following check should deal with all by_ref
3275 mismatches. */
7b920a9a 3276 if (plats->aggs_bottom)
2c9561b5
MJ
3277 continue;
3278
9771b263 3279 FOR_EACH_VEC_ELT (callers, j, cs)
2c9561b5 3280 {
7e9f2b6e 3281 inter = intersect_aggregates_with_edge (cs, i, inter);
2c9561b5 3282
9771b263 3283 if (!inter.exists ())
2c9561b5
MJ
3284 goto next_param;
3285 }
3286
9771b263 3287 FOR_EACH_VEC_ELT (inter, j, item)
2c9561b5
MJ
3288 {
3289 struct ipa_agg_replacement_value *v;
3290
3291 if (!item->value)
3292 continue;
3293
766090c2 3294 v = ggc_alloc<ipa_agg_replacement_value> ();
2c9561b5
MJ
3295 v->index = i;
3296 v->offset = item->offset;
3297 v->value = item->value;
7b920a9a 3298 v->by_ref = plats->aggs_by_ref;
6f9549ee
MJ
3299 *tail = v;
3300 tail = &v->next;
2c9561b5
MJ
3301 }
3302
3303 next_param:
9771b263
DN
3304 if (inter.exists ())
3305 inter.release ();
2c9561b5 3306 }
6f9549ee 3307 *tail = NULL;
2c9561b5
MJ
3308 return res;
3309}
3310
3311/* Turn KNOWN_AGGS into a list of aggreate replacement values. */
3312
3313static struct ipa_agg_replacement_value *
84562394 3314known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs)
2c9561b5 3315{
6f9549ee
MJ
3316 struct ipa_agg_replacement_value *res;
3317 struct ipa_agg_replacement_value **tail = &res;
2c9561b5
MJ
3318 struct ipa_agg_jump_function *aggjf;
3319 struct ipa_agg_jf_item *item;
3320 int i, j;
3321
9771b263
DN
3322 FOR_EACH_VEC_ELT (known_aggs, i, aggjf)
3323 FOR_EACH_VEC_SAFE_ELT (aggjf->items, j, item)
2c9561b5
MJ
3324 {
3325 struct ipa_agg_replacement_value *v;
766090c2 3326 v = ggc_alloc<ipa_agg_replacement_value> ();
2c9561b5
MJ
3327 v->index = i;
3328 v->offset = item->offset;
3329 v->value = item->value;
7b920a9a 3330 v->by_ref = aggjf->by_ref;
6f9549ee
MJ
3331 *tail = v;
3332 tail = &v->next;
2c9561b5 3333 }
6f9549ee 3334 *tail = NULL;
2c9561b5
MJ
3335 return res;
3336}
3337
3338/* Determine whether CS also brings all scalar values that the NODE is
3339 specialized for. */
3340
3341static bool
3342cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
3343 struct cgraph_node *node)
3344{
3345 struct ipa_node_params *dest_info = IPA_NODE_REF (node);
3346 int count = ipa_get_param_count (dest_info);
3347 struct ipa_node_params *caller_info;
3348 struct ipa_edge_args *args;
3349 int i;
3350
3351 caller_info = IPA_NODE_REF (cs->caller);
3352 args = IPA_EDGE_REF (cs);
3353 for (i = 0; i < count; i++)
3354 {
3355 struct ipa_jump_func *jump_func;
3356 tree val, t;
3357
9771b263 3358 val = dest_info->known_vals[i];
2c9561b5
MJ
3359 if (!val)
3360 continue;
3361
3362 if (i >= ipa_get_cs_argument_count (args))
3363 return false;
3364 jump_func = ipa_get_ith_jump_func (args, i);
3365 t = ipa_value_from_jfunc (caller_info, jump_func);
3366 if (!t || !values_equal_for_ipcp_p (val, t))
3367 return false;
3368 }
3369 return true;
3370}
3371
3372/* Determine whether CS also brings all aggregate values that NODE is
3373 specialized for. */
3374static bool
3375cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
3376 struct cgraph_node *node)
3377{
7e9f2b6e 3378 struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller);
9576e7b1 3379 struct ipa_node_params *orig_node_info;
2c9561b5 3380 struct ipa_agg_replacement_value *aggval;
7e9f2b6e 3381 int i, ec, count;
2c9561b5
MJ
3382
3383 aggval = ipa_get_agg_replacements_for_node (node);
7e9f2b6e
MJ
3384 if (!aggval)
3385 return true;
3386
3387 count = ipa_get_param_count (IPA_NODE_REF (node));
3388 ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
3389 if (ec < count)
3390 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3391 if (aggval->index >= ec)
3392 return false;
3393
9576e7b1 3394 orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
7e9f2b6e
MJ
3395 if (orig_caller_info->ipcp_orig_node)
3396 orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node);
3397
3398 for (i = 0; i < count; i++)
2c9561b5 3399 {
84562394 3400 static vec<ipa_agg_jf_item> values = vec<ipa_agg_jf_item>();
2c9561b5 3401 struct ipcp_param_lattices *plats;
7e9f2b6e
MJ
3402 bool interesting = false;
3403 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3404 if (aggval->index == i)
3405 {
3406 interesting = true;
3407 break;
3408 }
3409 if (!interesting)
3410 continue;
3411
9576e7b1 3412 plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
7e9f2b6e 3413 if (plats->aggs_bottom)
2c9561b5 3414 return false;
2c9561b5 3415
7e9f2b6e 3416 values = intersect_aggregates_with_edge (cs, i, values);
c3284718 3417 if (!values.exists ())
2c9561b5
MJ
3418 return false;
3419
7e9f2b6e
MJ
3420 for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3421 if (aggval->index == i)
3422 {
3423 struct ipa_agg_jf_item *item;
3424 int j;
3425 bool found = false;
3426 FOR_EACH_VEC_ELT (values, j, item)
3427 if (item->value
3428 && item->offset == av->offset
3429 && values_equal_for_ipcp_p (item->value, av->value))
c3272a92
PCC
3430 {
3431 found = true;
3432 break;
3433 }
7e9f2b6e
MJ
3434 if (!found)
3435 {
c3284718 3436 values.release ();
7e9f2b6e
MJ
3437 return false;
3438 }
3439 }
2c9561b5
MJ
3440 }
3441 return true;
3442}
3443
310bc633
MJ
3444/* Given an original NODE and a VAL for which we have already created a
3445 specialized clone, look whether there are incoming edges that still lead
3446 into the old node but now also bring the requested value and also conform to
3447 all other criteria such that they can be redirected the the special node.
3448 This function can therefore redirect the final edge in a SCC. */
3e66255c 3449
c0cb5055 3450template <typename valtype>
3e66255c 3451static void
c0cb5055 3452perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
3e66255c 3453{
c0cb5055 3454 ipcp_value_source<valtype> *src;
310bc633 3455 gcov_type redirected_sum = 0;
3e66255c 3456
310bc633 3457 for (src = val->sources; src; src = src->next)
3e66255c 3458 {
310bc633
MJ
3459 struct cgraph_edge *cs = src->cs;
3460 while (cs)
3461 {
3462 enum availability availability;
d52f5295 3463 struct cgraph_node *dst = cs->callee->function_symbol (&availability);
eb20b778 3464 if ((dst == node || IPA_NODE_REF (dst)->is_all_contexts_clone)
d52f5295 3465 && availability > AVAIL_INTERPOSABLE
310bc633
MJ
3466 && cgraph_edge_brings_value_p (cs, src))
3467 {
2c9561b5
MJ
3468 if (cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
3469 && cgraph_edge_brings_all_agg_vals_for_node (cs,
3470 val->spec_node))
310bc633
MJ
3471 {
3472 if (dump_file)
3473 fprintf (dump_file, " - adding an extra caller %s/%i"
3474 " of %s/%i\n",
fec39fa6 3475 xstrdup (cs->caller->name ()),
67348ccc 3476 cs->caller->order,
fec39fa6 3477 xstrdup (val->spec_node->name ()),
67348ccc 3478 val->spec_node->order);
310bc633 3479
3dafb85c 3480 cs->redirect_callee (val->spec_node);
310bc633
MJ
3481 redirected_sum += cs->count;
3482 }
3483 }
3484 cs = get_next_cgraph_edge_clone (cs);
3485 }
3e66255c 3486 }
310bc633
MJ
3487
3488 if (redirected_sum)
3489 update_specialized_profile (val->spec_node, node, redirected_sum);
3e66255c
MJ
3490}
3491
3492
310bc633
MJ
3493/* Copy KNOWN_BINFOS to KNOWN_VALS. */
3494
518dc859 3495static void
9771b263
DN
3496move_binfos_to_values (vec<tree> known_vals,
3497 vec<tree> known_binfos)
518dc859 3498{
310bc633 3499 tree t;
5e45130d 3500 int i;
518dc859 3501
9771b263 3502 for (i = 0; known_binfos.iterate (i, &t); i++)
310bc633 3503 if (t)
9771b263 3504 known_vals[i] = t;
310bc633 3505}
5e45130d 3506
2c9561b5
MJ
3507/* Return true if there is a replacement equivalent to VALUE, INDEX and OFFSET
3508 among those in the AGGVALS list. */
3509
3510DEBUG_FUNCTION bool
3511ipcp_val_in_agg_replacements_p (struct ipa_agg_replacement_value *aggvals,
3512 int index, HOST_WIDE_INT offset, tree value)
3513{
3514 while (aggvals)
3515 {
3516 if (aggvals->index == index
3517 && aggvals->offset == offset
3518 && values_equal_for_ipcp_p (aggvals->value, value))
3519 return true;
3520 aggvals = aggvals->next;
3521 }
3522 return false;
3523}
3524
3525/* Decide wheter to create a special version of NODE for value VAL of parameter
3526 at the given INDEX. If OFFSET is -1, the value is for the parameter itself,
3527 otherwise it is stored at the given OFFSET of the parameter. KNOWN_CSTS,
3528 KNOWN_BINFOS and KNOWN_AGGS describe the other already known values. */
3529
c0cb5055 3530template <typename valtype>
2c9561b5
MJ
3531static bool
3532decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
c0cb5055 3533 ipcp_value<valtype> *val, vec<tree> known_csts,
9771b263 3534 vec<tree> known_binfos)
2c9561b5
MJ
3535{
3536 struct ipa_agg_replacement_value *aggvals;
3537 int freq_sum, caller_count;
3538 gcov_type count_sum;
d52f5295 3539 vec<cgraph_edge *> callers;
9771b263 3540 vec<tree> kv;
2c9561b5
MJ
3541
3542 if (val->spec_node)
3543 {
3544 perhaps_add_new_callers (node, val);
3545 return false;
3546 }
3547 else if (val->local_size_cost + overall_size > max_new_size)
3548 {
3549 if (dump_file && (dump_flags & TDF_DETAILS))
3550 fprintf (dump_file, " Ignoring candidate value because "
3551 "max_new_size would be reached with %li.\n",
3552 val->local_size_cost + overall_size);
3553 return false;
3554 }
3555 else if (!get_info_about_necessary_edges (val, &freq_sum, &count_sum,
3556 &caller_count))
3557 return false;
3558
3559 if (dump_file && (dump_flags & TDF_DETAILS))
3560 {
3561 fprintf (dump_file, " - considering value ");
3562 print_ipcp_constant_value (dump_file, val->value);
0e8853ee
JH
3563 fprintf (dump_file, " for ");
3564 ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
2c9561b5
MJ
3565 if (offset != -1)
3566 fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
3567 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
3568 }
3569
3570 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
3571 freq_sum, count_sum,
3572 val->local_size_cost)
3573 && !good_cloning_opportunity_p (node,
3574 val->local_time_benefit
3575 + val->prop_time_benefit,
3576 freq_sum, count_sum,
3577 val->local_size_cost
3578 + val->prop_size_cost))
3579 return false;
3580
3581 if (dump_file)
3582 fprintf (dump_file, " Creating a specialized node of %s/%i.\n",
fec39fa6 3583 node->name (), node->order);
2c9561b5
MJ
3584
3585 callers = gather_edges_for_value (val, caller_count);
9771b263 3586 kv = known_csts.copy ();
2c9561b5
MJ
3587 move_binfos_to_values (kv, known_binfos);
3588 if (offset == -1)
9771b263 3589 kv[index] = val->value;
2c9561b5
MJ
3590 find_more_scalar_values_for_callers_subset (node, kv, callers);
3591 aggvals = find_aggregate_values_for_callers_subset (node, callers);
3592 gcc_checking_assert (offset == -1
3593 || ipcp_val_in_agg_replacements_p (aggvals, index,
3594 offset, val->value));
3595 val->spec_node = create_specialized_node (node, kv, aggvals, callers);
3596 overall_size += val->local_size_cost;
3597
3598 /* TODO: If for some lattice there is only one other known value
3599 left, make a special node for it too. */
3600
3601 return true;
3602}
5e45130d 3603
310bc633 3604/* Decide whether and what specialized clones of NODE should be created. */
5e45130d 3605
310bc633
MJ
3606static bool
3607decide_whether_version_node (struct cgraph_node *node)
3608{
3609 struct ipa_node_params *info = IPA_NODE_REF (node);
3610 int i, count = ipa_get_param_count (info);
9771b263 3611 vec<tree> known_csts, known_binfos;
84562394 3612 vec<ipa_agg_jump_function> known_aggs = vNULL;
310bc633 3613 bool ret = false;
5e45130d 3614
310bc633
MJ
3615 if (count == 0)
3616 return false;
5e45130d 3617
310bc633
MJ
3618 if (dump_file && (dump_flags & TDF_DETAILS))
3619 fprintf (dump_file, "\nEvaluating opportunities for %s/%i.\n",
fec39fa6 3620 node->name (), node->order);
5e45130d 3621
310bc633 3622 gather_context_independent_values (info, &known_csts, &known_binfos,
eb20b778
MJ
3623 info->do_clone_for_all_contexts ? &known_aggs
3624 : NULL, NULL);
5e45130d 3625
2c9561b5 3626 for (i = 0; i < count ;i++)
310bc633 3627 {
2c9561b5 3628 struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
c0cb5055
MJ
3629 ipcp_lattice<tree> *lat = &plats->itself;
3630 ipcp_value<tree> *val;
5e45130d 3631
2c9561b5 3632 if (!lat->bottom
9771b263
DN
3633 && !known_csts[i]
3634 && !known_binfos[i])
2c9561b5
MJ
3635 for (val = lat->values; val; val = val->next)
3636 ret |= decide_about_value (node, i, -1, val, known_csts,
3637 known_binfos);
61e03ffc 3638
eb20b778 3639 if (!plats->aggs_bottom)
518dc859 3640 {
2c9561b5 3641 struct ipcp_agg_lattice *aglat;
c0cb5055 3642 ipcp_value<tree> *val;
2c9561b5
MJ
3643 for (aglat = plats->aggs; aglat; aglat = aglat->next)
3644 if (!aglat->bottom && aglat->values
3645 /* If the following is false, the one value is in
3646 known_aggs. */
3647 && (plats->aggs_contain_variable
c0cb5055 3648 || !aglat->is_single_const ()))
2c9561b5
MJ
3649 for (val = aglat->values; val; val = val->next)
3650 ret |= decide_about_value (node, i, aglat->offset, val,
3651 known_csts, known_binfos);
cc58ceee 3652 }
2c9561b5 3653 info = IPA_NODE_REF (node);
310bc633 3654 }
cc58ceee 3655
eb20b778 3656 if (info->do_clone_for_all_contexts)
310bc633 3657 {
eb20b778 3658 struct cgraph_node *clone;
d52f5295 3659 vec<cgraph_edge *> callers;
cc58ceee 3660
310bc633
MJ
3661 if (dump_file)
3662 fprintf (dump_file, " - Creating a specialized node of %s/%i "
fec39fa6 3663 "for all known contexts.\n", node->name (),
67348ccc 3664 node->order);
5e45130d 3665
d52f5295 3666 callers = node->collect_callers ();
310bc633 3667 move_binfos_to_values (known_csts, known_binfos);
eb20b778 3668 clone = create_specialized_node (node, known_csts,
2c9561b5
MJ
3669 known_aggs_to_agg_replacement_list (known_aggs),
3670 callers);
310bc633 3671 info = IPA_NODE_REF (node);
eb20b778
MJ
3672 info->do_clone_for_all_contexts = false;
3673 IPA_NODE_REF (clone)->is_all_contexts_clone = true;
90e709fd
JJ
3674 for (i = 0; i < count ; i++)
3675 vec_free (known_aggs[i].items);
3676 known_aggs.release ();
310bc633
MJ
3677 ret = true;
3678 }
3679 else
9771b263 3680 known_csts.release ();
5e45130d 3681
9771b263 3682 known_binfos.release ();
310bc633
MJ
3683 return ret;
3684}
9187e02d 3685
310bc633 3686/* Transitively mark all callees of NODE within the same SCC as not dead. */
3949c4a7 3687
310bc633
MJ
3688static void
3689spread_undeadness (struct cgraph_node *node)
3690{
3691 struct cgraph_edge *cs;
5e45130d 3692
310bc633 3693 for (cs = node->callees; cs; cs = cs->next_callee)
4cb13597 3694 if (ipa_edge_within_scc (cs))
310bc633
MJ
3695 {
3696 struct cgraph_node *callee;
3697 struct ipa_node_params *info;
129a37fc 3698
d52f5295 3699 callee = cs->callee->function_symbol (NULL);
310bc633 3700 info = IPA_NODE_REF (callee);
5e45130d 3701
310bc633
MJ
3702 if (info->node_dead)
3703 {
3704 info->node_dead = 0;
3705 spread_undeadness (callee);
3706 }
3707 }
3708}
3709
3710/* Return true if NODE has a caller from outside of its SCC that is not
3711 dead. Worker callback for cgraph_for_node_and_aliases. */
3712
3713static bool
3714has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
3715 void *data ATTRIBUTE_UNUSED)
3716{
3717 struct cgraph_edge *cs;
3718
3719 for (cs = node->callers; cs; cs = cs->next_caller)
3720 if (cs->caller->thunk.thunk_p
d52f5295
ML
3721 && cs->caller->call_for_symbol_thunks_and_aliases
3722 (has_undead_caller_from_outside_scc_p, NULL, true))
310bc633 3723 return true;
4cb13597 3724 else if (!ipa_edge_within_scc (cs)
310bc633
MJ
3725 && !IPA_NODE_REF (cs->caller)->node_dead)
3726 return true;
3727 return false;
3728}
3729
3730
3731/* Identify nodes within the same SCC as NODE which are no longer needed
3732 because of new clones and will be removed as unreachable. */
3733
3734static void
3735identify_dead_nodes (struct cgraph_node *node)
3736{
3737 struct cgraph_node *v;
67348ccc 3738 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
d52f5295
ML
3739 if (v->will_be_removed_from_program_if_no_direct_calls_p ()
3740 && !v->call_for_symbol_thunks_and_aliases
3741 (has_undead_caller_from_outside_scc_p, NULL, true))
310bc633
MJ
3742 IPA_NODE_REF (v)->node_dead = 1;
3743
67348ccc 3744 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
310bc633
MJ
3745 if (!IPA_NODE_REF (v)->node_dead)
3746 spread_undeadness (v);
3747
3748 if (dump_file && (dump_flags & TDF_DETAILS))
3749 {
67348ccc 3750 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
310bc633
MJ
3751 if (IPA_NODE_REF (v)->node_dead)
3752 fprintf (dump_file, " Marking node as dead: %s/%i.\n",
fec39fa6 3753 v->name (), v->order);
5e45130d 3754 }
310bc633
MJ
3755}
3756
3757/* The decision stage. Iterate over the topological order of call graph nodes
3758 TOPO and make specialized clones if deemed beneficial. */
3759
3760static void
11478306 3761ipcp_decision_stage (struct ipa_topo_info *topo)
310bc633
MJ
3762{
3763 int i;
3764
3765 if (dump_file)
3766 fprintf (dump_file, "\nIPA decision stage:\n\n");
5e45130d 3767
310bc633 3768 for (i = topo->nnodes - 1; i >= 0; i--)
5e45130d 3769 {
310bc633
MJ
3770 struct cgraph_node *node = topo->order[i];
3771 bool change = false, iterate = true;
3772
3773 while (iterate)
3774 {
3775 struct cgraph_node *v;
3776 iterate = false;
67348ccc 3777 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
d52f5295 3778 if (v->has_gimple_body_p ()
310bc633
MJ
3779 && ipcp_versionable_function_p (v))
3780 iterate |= decide_whether_version_node (v);
3781
3782 change |= iterate;
3783 }
3784 if (change)
3785 identify_dead_nodes (node);
518dc859 3786 }
518dc859
RL
3787}
3788
3789/* The IPCP driver. */
310bc633 3790
3cc1cccc 3791static unsigned int
518dc859
RL
3792ipcp_driver (void)
3793{
310bc633 3794 struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
aef83682 3795 struct cgraph_edge_hook_list *edge_removal_hook_holder;
11478306 3796 struct ipa_topo_info topo;
310bc633 3797
310bc633
MJ
3798 ipa_check_create_node_params ();
3799 ipa_check_create_edge_args ();
aef83682 3800 grow_edge_clone_vectors ();
310bc633 3801 edge_duplication_hook_holder =
3dafb85c 3802 symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
aef83682 3803 edge_removal_hook_holder =
3dafb85c 3804 symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
aef83682 3805
310bc633 3806 ipcp_values_pool = create_alloc_pool ("IPA-CP values",
c0cb5055 3807 sizeof (ipcp_value<tree>), 32);
310bc633 3808 ipcp_sources_pool = create_alloc_pool ("IPA-CP value sources",
c0cb5055 3809 sizeof (ipcp_value_source<tree>), 64);
2c9561b5
MJ
3810 ipcp_agg_lattice_pool = create_alloc_pool ("IPA_CP aggregate lattices",
3811 sizeof (struct ipcp_agg_lattice),
3812 32);
518dc859
RL
3813 if (dump_file)
3814 {
ca30a539
JH
3815 fprintf (dump_file, "\nIPA structures before propagation:\n");
3816 if (dump_flags & TDF_DETAILS)
3817 ipa_print_all_params (dump_file);
3818 ipa_print_all_jump_functions (dump_file);
518dc859 3819 }
310bc633
MJ
3820
3821 /* Topological sort. */
3822 build_toporder_info (&topo);
3823 /* Do the interprocedural propagation. */
3824 ipcp_propagate_stage (&topo);
3825 /* Decide what constant propagation and cloning should be performed. */
3826 ipcp_decision_stage (&topo);
3827
518dc859 3828 /* Free all IPCP structures. */
310bc633 3829 free_toporder_info (&topo);
9771b263 3830 next_edge_clone.release ();
3dafb85c
ML
3831 symtab->remove_edge_removal_hook (edge_removal_hook_holder);
3832 symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
e33c6cd6 3833 ipa_free_all_structures_after_ipa_cp ();
518dc859
RL
3834 if (dump_file)
3835 fprintf (dump_file, "\nIPA constant propagation end\n");
c2924966 3836 return 0;
518dc859
RL
3837}
3838
3949c4a7
MJ
3839/* Initialization and computation of IPCP data structures. This is the initial
3840 intraprocedural analysis of functions, which gathers information to be
3841 propagated later on. */
3842
129a37fc
JH
3843static void
3844ipcp_generate_summary (void)
3845{
3949c4a7
MJ
3846 struct cgraph_node *node;
3847
129a37fc
JH
3848 if (dump_file)
3849 fprintf (dump_file, "\nIPA constant propagation start:\n");
129a37fc 3850 ipa_register_cgraph_hooks ();
3949c4a7 3851
c47d0034 3852 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
3949c4a7 3853 {
960bfb69 3854 node->local.versionable
67348ccc 3855 = tree_versionable_function_p (node->decl);
3949c4a7
MJ
3856 ipa_analyze_node (node);
3857 }
129a37fc
JH
3858}
3859
fb3f88cc 3860/* Write ipcp summary for nodes in SET. */
310bc633 3861
fb3f88cc 3862static void
f27c1867 3863ipcp_write_summary (void)
fb3f88cc 3864{
f27c1867 3865 ipa_prop_write_jump_functions ();
fb3f88cc
JH
3866}
3867
3868/* Read ipcp summary. */
310bc633 3869
fb3f88cc
JH
3870static void
3871ipcp_read_summary (void)
3872{
3873 ipa_prop_read_jump_functions ();
3874}
3875
27a4cd48
DM
3876namespace {
3877
3878const pass_data pass_data_ipa_cp =
3879{
3880 IPA_PASS, /* type */
3881 "cp", /* name */
3882 OPTGROUP_NONE, /* optinfo_flags */
27a4cd48
DM
3883 TV_IPA_CONSTANT_PROP, /* tv_id */
3884 0, /* properties_required */
3885 0, /* properties_provided */
3886 0, /* properties_destroyed */
3887 0, /* todo_flags_start */
3888 ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
518dc859 3889};
27a4cd48
DM
3890
3891class pass_ipa_cp : public ipa_opt_pass_d
3892{
3893public:
c3284718
RS
3894 pass_ipa_cp (gcc::context *ctxt)
3895 : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
3896 ipcp_generate_summary, /* generate_summary */
3897 ipcp_write_summary, /* write_summary */
3898 ipcp_read_summary, /* read_summary */
3899 ipa_prop_write_all_agg_replacement, /*
3900 write_optimization_summary */
3901 ipa_prop_read_all_agg_replacement, /*
3902 read_optimization_summary */
3903 NULL, /* stmt_fixup */
3904 0, /* function_transform_todo_flags_start */
3905 ipcp_transform_function, /* function_transform */
3906 NULL) /* variable_transform */
27a4cd48
DM
3907 {}
3908
3909 /* opt_pass methods: */
1a3d085c
TS
3910 virtual bool gate (function *)
3911 {
3912 /* FIXME: We should remove the optimize check after we ensure we never run
3913 IPA passes when not optimizing. */
3914 return flag_ipa_cp && optimize;
3915 }
3916
be55bfe6 3917 virtual unsigned int execute (function *) { return ipcp_driver (); }
27a4cd48
DM
3918
3919}; // class pass_ipa_cp
3920
3921} // anon namespace
3922
3923ipa_opt_pass_d *
3924make_pass_ipa_cp (gcc::context *ctxt)
3925{
3926 return new pass_ipa_cp (ctxt);
3927}
3edf64aa
DM
3928
3929/* Reset all state within ipa-cp.c so that we can rerun the compiler
3930 within the same process. For use by toplev::finalize. */
3931
3932void
3933ipa_cp_c_finalize (void)
3934{
3935 max_count = 0;
3936 overall_size = 0;
3937 max_new_size = 0;
3edf64aa 3938}