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