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