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