This patch suppresses the messages printed when the primary module is not found.
[official-gcc.git] / gcc-4_7 / gcc / ipa-cp.c
blob87f126ea12828430ea2005b935b0d921a9944a49
1 /* Interprocedural constant propagation
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
5 Contributed by Razya Ladelsky <RAZYA@il.ibm.com> and Martin Jambor
6 <mjambor@suse.cz>
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 /* Interprocedural constant propagation (IPA-CP).
26 The goal of this transformation is to
28 1) discover functions which are always invoked with some arguments with the
29 same known constant values and modify the functions so that the
30 subsequent optimizations can take advantage of the knowledge, and
32 2) partial specialization - create specialized versions of functions
33 transformed in this way if some parameters are known constants only in
34 certain contexts but the estimated tradeoff between speedup and cost size
35 is deemed good.
37 The algorithm also propagates types and attempts to perform type based
38 devirtualization. Types are propagated much like constants.
40 The algorithm basically consists of three stages. In the first, functions
41 are analyzed one at a time and jump functions are constructed for all known
42 call-sites. In the second phase, the pass propagates information from the
43 jump functions across the call to reveal what values are available at what
44 call sites, performs estimations of effects of known values on functions and
45 their callees, and finally decides what specialized extra versions should be
46 created. In the third, the special versions materialize and appropriate
47 calls are redirected.
49 The algorithm used is to a certain extent based on "Interprocedural Constant
50 Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
51 Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
52 Cooper, Mary W. Hall, and Ken Kennedy.
55 First stage - intraprocedural analysis
56 =======================================
58 This phase computes jump_function and modification flags.
60 A jump function for a call-site represents the values passed as an actual
61 arguments of a given call-site. In principle, there are three types of
62 values:
64 Pass through - the caller's formal parameter is passed as an actual
65 argument, plus an operation on it can be performed.
66 Constant - a constant is passed as an actual argument.
67 Unknown - neither of the above.
69 All jump function types are described in detail in ipa-prop.h, together with
70 the data structures that represent them and methods of accessing them.
72 ipcp_generate_summary() is the main function of the first stage.
74 Second stage - interprocedural analysis
75 ========================================
77 This stage is itself divided into two phases. In the first, we propagate
78 known values over the call graph, in the second, we make cloning decisions.
79 It uses a different algorithm than the original Callahan's paper.
81 First, we traverse the functions topologically from callers to callees and,
82 for each strongly connected component (SCC), we propagate constants
83 according to previously computed jump functions. We also record what known
84 values depend on other known values and estimate local effects. Finally, we
85 propagate cumulative information about these effects from dependant values
86 to those on which they depend.
88 Second, we again traverse the call graph in the same topological order and
89 make clones for functions which we know are called with the same values in
90 all contexts and decide about extra specialized clones of functions just for
91 some contexts - these decisions are based on both local estimates and
92 cumulative estimates propagated from callees.
94 ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
95 third stage.
97 Third phase - materialization of clones, call statement updates.
98 ============================================
100 This stage is currently performed by call graph code (mainly in cgraphunit.c
101 and tree-inline.c) according to instructions inserted to the call graph by
102 the second stage. */
104 #include "config.h"
105 #include "system.h"
106 #include "coretypes.h"
107 #include "tree.h"
108 #include "target.h"
109 #include "gimple.h"
110 #include "cgraph.h"
111 #include "ipa-prop.h"
112 #include "tree-flow.h"
113 #include "tree-pass.h"
114 #include "flags.h"
115 #include "timevar.h"
116 #include "diagnostic.h"
117 #include "tree-pretty-print.h"
118 #include "tree-dump.h"
119 #include "tree-inline.h"
120 #include "fibheap.h"
121 #include "params.h"
122 #include "dbgcnt.h"
123 #include "ipa-inline.h"
124 #include "ipa-utils.h"
126 struct ipcp_value;
128 /* Describes a particular source for an IPA-CP value. */
130 struct ipcp_value_source
132 /* The incoming edge that brought the value. */
133 struct cgraph_edge *cs;
134 /* If the jump function that resulted into his value was a pass-through or an
135 ancestor, this is the ipcp_value of the caller from which the described
136 value has been derived. Otherwise it is NULL. */
137 struct ipcp_value *val;
138 /* Next pointer in a linked list of sources of a value. */
139 struct ipcp_value_source *next;
140 /* If the jump function that resulted into his value was a pass-through or an
141 ancestor, this is the index of the parameter of the caller the jump
142 function references. */
143 int index;
146 /* Describes one particular value stored in struct ipcp_lattice. */
148 struct ipcp_value
150 /* The actual value for the given parameter. This is either an IPA invariant
151 or a TREE_BINFO describing a type that can be used for
152 devirtualization. */
153 tree value;
154 /* The list of sources from which this value originates. */
155 struct ipcp_value_source *sources;
156 /* Next pointers in a linked list of all values in a lattice. */
157 struct ipcp_value *next;
158 /* Next pointers in a linked list of values in a strongly connected component
159 of values. */
160 struct ipcp_value *scc_next;
161 /* Next pointers in a linked list of SCCs of values sorted topologically
162 according their sources. */
163 struct ipcp_value *topo_next;
164 /* A specialized node created for this value, NULL if none has been (so far)
165 created. */
166 struct cgraph_node *spec_node;
167 /* Depth first search number and low link for topological sorting of
168 values. */
169 int dfs, low_link;
170 /* Time benefit and size cost that specializing the function for this value
171 would bring about in this function alone. */
172 int local_time_benefit, local_size_cost;
173 /* Time benefit and size cost that specializing the function for this value
174 can bring about in it's callees (transitively). */
175 int prop_time_benefit, prop_size_cost;
176 /* True if this valye is currently on the topo-sort stack. */
177 bool on_stack;
180 /* Allocation pools for values and their sources in ipa-cp. */
182 alloc_pool ipcp_values_pool;
183 alloc_pool ipcp_sources_pool;
185 /* Lattice describing potential values of a formal parameter of a function and
186 some of their other properties. TOP is represented by a lattice with zero
187 values and with contains_variable and bottom flags cleared. BOTTOM is
188 represented by a lattice with the bottom flag set. In that case, values and
189 contains_variable flag should be disregarded. */
191 struct ipcp_lattice
193 /* The list of known values and types in this lattice. Note that values are
194 not deallocated if a lattice is set to bottom because there may be value
195 sources referencing them. */
196 struct ipcp_value *values;
197 /* Number of known values and types in this lattice. */
198 int values_count;
199 /* The lattice contains a variable component (in addition to values). */
200 bool contains_variable;
201 /* The value of the lattice is bottom (i.e. variable and unusable for any
202 propagation). */
203 bool bottom;
204 /* There is a virtual call based on this parameter. */
205 bool virt_call;
208 /* Maximal count found in program. */
210 static gcov_type max_count;
212 /* Original overall size of the program. */
214 static long overall_size, max_new_size;
216 /* Head of the linked list of topologically sorted values. */
218 static struct ipcp_value *values_topo;
220 /* Return the lattice corresponding to the Ith formal parameter of the function
221 described by INFO. */
222 static inline struct ipcp_lattice *
223 ipa_get_lattice (struct ipa_node_params *info, int i)
225 gcc_assert (i >= 0 && i < ipa_get_param_count (info));
226 gcc_checking_assert (!info->ipcp_orig_node);
227 gcc_checking_assert (info->lattices);
228 return &(info->lattices[i]);
231 /* Return whether LAT is a lattice with a single constant and without an
232 undefined value. */
234 static inline bool
235 ipa_lat_is_single_const (struct ipcp_lattice *lat)
237 if (lat->bottom
238 || lat->contains_variable
239 || lat->values_count != 1)
240 return false;
241 else
242 return true;
245 /* Return true iff the CS is an edge within a strongly connected component as
246 computed by ipa_reduced_postorder. */
248 static inline bool
249 edge_within_scc (struct cgraph_edge *cs)
251 struct ipa_dfs_info *caller_dfs = (struct ipa_dfs_info *) cs->caller->aux;
252 struct ipa_dfs_info *callee_dfs;
253 struct cgraph_node *callee = cgraph_function_node (cs->callee, NULL);
255 callee_dfs = (struct ipa_dfs_info *) callee->aux;
256 return (caller_dfs
257 && callee_dfs
258 && caller_dfs->scc_no == callee_dfs->scc_no);
261 /* Print V which is extracted from a value in a lattice to F. */
263 static void
264 print_ipcp_constant_value (FILE * f, tree v)
266 if (TREE_CODE (v) == TREE_BINFO)
268 fprintf (f, "BINFO ");
269 print_generic_expr (f, BINFO_TYPE (v), 0);
271 else if (TREE_CODE (v) == ADDR_EXPR
272 && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
274 fprintf (f, "& ");
275 print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)), 0);
277 else
278 print_generic_expr (f, v, 0);
281 /* Print all ipcp_lattices of all functions to F. */
283 static void
284 print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
286 struct cgraph_node *node;
287 int i, count;
289 fprintf (f, "\nLattices:\n");
290 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
292 struct ipa_node_params *info;
294 info = IPA_NODE_REF (node);
295 fprintf (f, " Node: %s/%i:\n", cgraph_node_name (node), node->uid);
296 count = ipa_get_param_count (info);
297 for (i = 0; i < count; i++)
299 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
300 struct ipcp_value *val;
301 bool prev = false;
303 fprintf (f, " param [%d]: ", i);
304 if (lat->bottom)
306 fprintf (f, "BOTTOM\n");
307 continue;
310 if (!lat->values_count && !lat->contains_variable)
312 fprintf (f, "TOP\n");
313 continue;
316 if (lat->contains_variable)
318 fprintf (f, "VARIABLE");
319 prev = true;
320 if (dump_benefits)
321 fprintf (f, "\n");
324 for (val = lat->values; val; val = val->next)
326 if (dump_benefits && prev)
327 fprintf (f, " ");
328 else if (!dump_benefits && prev)
329 fprintf (f, ", ");
330 else
331 prev = true;
333 print_ipcp_constant_value (f, val->value);
335 if (dump_sources)
337 struct ipcp_value_source *s;
339 fprintf (f, " [from:");
340 for (s = val->sources; s; s = s->next)
341 fprintf (f, " %i(%i)", s->cs->caller->uid,s->cs->frequency);
342 fprintf (f, "]");
345 if (dump_benefits)
346 fprintf (f, " [loc_time: %i, loc_size: %i, "
347 "prop_time: %i, prop_size: %i]\n",
348 val->local_time_benefit, val->local_size_cost,
349 val->prop_time_benefit, val->prop_size_cost);
351 if (!dump_benefits)
352 fprintf (f, "\n");
357 /* Determine whether it is at all technically possible to create clones of NODE
358 and store this information in the ipa_node_params structure associated
359 with NODE. */
361 static void
362 determine_versionability (struct cgraph_node *node)
364 const char *reason = NULL;
366 /* There are a number of generic reasons functions cannot be versioned. We
367 also cannot remove parameters if there are type attributes such as fnspec
368 present. */
369 if (node->alias || node->thunk.thunk_p)
370 reason = "alias or thunk";
371 else if (!node->local.versionable)
372 reason = "not a tree_versionable_function";
373 else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
374 reason = "insufficient body availability";
376 if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
377 fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
378 cgraph_node_name (node), node->uid, reason);
380 node->local.versionable = (reason == NULL);
383 /* Return true if it is at all technically possible to create clones of a
384 NODE. */
386 static bool
387 ipcp_versionable_function_p (struct cgraph_node *node)
389 return node->local.versionable;
392 /* Structure holding accumulated information about callers of a node. */
394 struct caller_statistics
396 gcov_type count_sum;
397 int n_calls, n_hot_calls, freq_sum;
400 /* Initialize fields of STAT to zeroes. */
402 static inline void
403 init_caller_stats (struct caller_statistics *stats)
405 stats->count_sum = 0;
406 stats->n_calls = 0;
407 stats->n_hot_calls = 0;
408 stats->freq_sum = 0;
411 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
412 non-thunk incoming edges to NODE. */
414 static bool
415 gather_caller_stats (struct cgraph_node *node, void *data)
417 struct caller_statistics *stats = (struct caller_statistics *) data;
418 struct cgraph_edge *cs;
420 for (cs = node->callers; cs; cs = cs->next_caller)
421 if (cs->caller->thunk.thunk_p)
422 cgraph_for_node_and_aliases (cs->caller, gather_caller_stats,
423 stats, false);
424 else
426 stats->count_sum += cs->count;
427 stats->freq_sum += cs->frequency;
428 stats->n_calls++;
429 if (cgraph_maybe_hot_edge_p (cs))
430 stats->n_hot_calls ++;
432 return false;
436 /* Return true if this NODE is viable candidate for cloning. */
438 static bool
439 ipcp_cloning_candidate_p (struct cgraph_node *node)
441 struct caller_statistics stats;
443 gcc_checking_assert (cgraph_function_with_gimple_body_p (node));
445 if (!flag_ipa_cp_clone)
447 if (dump_file)
448 fprintf (dump_file, "Not considering %s for cloning; "
449 "-fipa-cp-clone disabled.\n",
450 cgraph_node_name (node));
451 return false;
454 if (!optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
456 if (dump_file)
457 fprintf (dump_file, "Not considering %s for cloning; "
458 "optimizing it for size.\n",
459 cgraph_node_name (node));
460 return false;
463 init_caller_stats (&stats);
464 cgraph_for_node_and_aliases (node, gather_caller_stats, &stats, false);
466 if (inline_summary (node)->self_size < stats.n_calls)
468 if (dump_file)
469 fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
470 cgraph_node_name (node));
471 return true;
474 /* When profile is available and function is hot, propagate into it even if
475 calls seems cold; constant propagation can improve function's speed
476 significantly. */
477 if (max_count)
479 if (stats.count_sum > node->count * 90 / 100)
481 if (dump_file)
482 fprintf (dump_file, "Considering %s for cloning; "
483 "usually called directly.\n",
484 cgraph_node_name (node));
485 return true;
488 if (!stats.n_hot_calls)
490 if (dump_file)
491 fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
492 cgraph_node_name (node));
493 return false;
495 if (dump_file)
496 fprintf (dump_file, "Considering %s for cloning.\n",
497 cgraph_node_name (node));
498 return true;
501 /* Arrays representing a topological ordering of call graph nodes and a stack
502 of noes used during constant propagation. */
504 struct topo_info
506 struct cgraph_node **order;
507 struct cgraph_node **stack;
508 int nnodes, stack_top;
511 /* Allocate the arrays in TOPO and topologically sort the nodes into order. */
513 static void
514 build_toporder_info (struct topo_info *topo)
516 topo->order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
517 topo->stack = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
518 topo->stack_top = 0;
519 topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL);
522 /* Free information about strongly connected components and the arrays in
523 TOPO. */
525 static void
526 free_toporder_info (struct topo_info *topo)
528 ipa_free_postorder_info ();
529 free (topo->order);
530 free (topo->stack);
533 /* Add NODE to the stack in TOPO, unless it is already there. */
535 static inline void
536 push_node_to_stack (struct topo_info *topo, struct cgraph_node *node)
538 struct ipa_node_params *info = IPA_NODE_REF (node);
539 if (info->node_enqueued)
540 return;
541 info->node_enqueued = 1;
542 topo->stack[topo->stack_top++] = node;
545 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
546 is empty. */
548 static struct cgraph_node *
549 pop_node_from_stack (struct topo_info *topo)
551 if (topo->stack_top)
553 struct cgraph_node *node;
554 topo->stack_top--;
555 node = topo->stack[topo->stack_top];
556 IPA_NODE_REF (node)->node_enqueued = 0;
557 return node;
559 else
560 return NULL;
563 /* Set lattice LAT to bottom and return true if it previously was not set as
564 such. */
566 static inline bool
567 set_lattice_to_bottom (struct ipcp_lattice *lat)
569 bool ret = !lat->bottom;
570 lat->bottom = true;
571 return ret;
574 /* Mark lattice as containing an unknown value and return true if it previously
575 was not marked as such. */
577 static inline bool
578 set_lattice_contains_variable (struct ipcp_lattice *lat)
580 bool ret = !lat->contains_variable;
581 lat->contains_variable = true;
582 return ret;
585 /* Initialize ipcp_lattices. */
587 static void
588 initialize_node_lattices (struct cgraph_node *node)
590 struct ipa_node_params *info = IPA_NODE_REF (node);
591 struct cgraph_edge *ie;
592 bool disable = false, variable = false;
593 int i;
595 gcc_checking_assert (cgraph_function_with_gimple_body_p (node));
596 if (!node->local.local)
598 /* When cloning is allowed, we can assume that externally visible
599 functions are not called. We will compensate this by cloning
600 later. */
601 if (ipcp_versionable_function_p (node)
602 && ipcp_cloning_candidate_p (node))
603 variable = true;
604 else
605 disable = true;
608 if (disable || variable)
610 for (i = 0; i < ipa_get_param_count (info) ; i++)
612 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
613 if (disable)
614 set_lattice_to_bottom (lat);
615 else
616 set_lattice_contains_variable (lat);
618 if (dump_file && (dump_flags & TDF_DETAILS)
619 && node->alias && node->thunk.thunk_p)
620 fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
621 cgraph_node_name (node), node->uid,
622 disable ? "BOTTOM" : "VARIABLE");
625 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
626 if (ie->indirect_info->polymorphic)
628 gcc_checking_assert (ie->indirect_info->param_index >= 0);
629 ipa_get_lattice (info, ie->indirect_info->param_index)->virt_call = 1;
633 /* Return the result of a (possibly arithmetic) pass through jump function
634 JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be
635 determined or itself is considered an interprocedural invariant. */
637 static tree
638 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
640 tree restype, res;
642 gcc_checking_assert (is_gimple_ip_invariant (input));
643 if (jfunc->value.pass_through.operation == NOP_EXPR)
644 return input;
646 if (TREE_CODE_CLASS (jfunc->value.pass_through.operation)
647 == tcc_comparison)
648 restype = boolean_type_node;
649 else
650 restype = TREE_TYPE (input);
651 res = fold_binary (jfunc->value.pass_through.operation, restype,
652 input, jfunc->value.pass_through.operand);
654 if (res && !is_gimple_ip_invariant (res))
655 return NULL_TREE;
657 return res;
660 /* Return the result of an ancestor jump function JFUNC on the constant value
661 INPUT. Return NULL_TREE if that cannot be determined. */
663 static tree
664 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
666 if (TREE_CODE (input) == ADDR_EXPR)
668 tree t = TREE_OPERAND (input, 0);
669 t = build_ref_for_offset (EXPR_LOCATION (t), t,
670 jfunc->value.ancestor.offset,
671 jfunc->value.ancestor.type, NULL, false);
672 return build_fold_addr_expr (t);
674 else
675 return NULL_TREE;
678 /* Extract the acual BINFO being described by JFUNC which must be a known type
679 jump function. */
681 static tree
682 ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc)
684 tree base_binfo = TYPE_BINFO (jfunc->value.known_type.base_type);
685 if (!base_binfo)
686 return NULL_TREE;
687 return get_binfo_at_offset (base_binfo,
688 jfunc->value.known_type.offset,
689 jfunc->value.known_type.component_type);
692 /* Determine whether JFUNC evaluates to a known value (that is either a
693 constant or a binfo) and if so, return it. Otherwise return NULL. INFO
694 describes the caller node so that pass-through jump functions can be
695 evaluated. */
697 tree
698 ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
700 if (jfunc->type == IPA_JF_CONST)
701 return jfunc->value.constant;
702 else if (jfunc->type == IPA_JF_KNOWN_TYPE)
703 return ipa_value_from_known_type_jfunc (jfunc);
704 else if (jfunc->type == IPA_JF_PASS_THROUGH
705 || jfunc->type == IPA_JF_ANCESTOR)
707 tree input;
708 int idx;
710 if (jfunc->type == IPA_JF_PASS_THROUGH)
711 idx = jfunc->value.pass_through.formal_id;
712 else
713 idx = jfunc->value.ancestor.formal_id;
715 if (info->ipcp_orig_node)
716 input = VEC_index (tree, info->known_vals, idx);
717 else
719 struct ipcp_lattice *lat;
721 if (!info->lattices)
723 gcc_checking_assert (!flag_ipa_cp);
724 return NULL_TREE;
726 lat = ipa_get_lattice (info, idx);
727 if (!ipa_lat_is_single_const (lat))
728 return NULL_TREE;
729 input = lat->values->value;
732 if (!input)
733 return NULL_TREE;
735 if (jfunc->type == IPA_JF_PASS_THROUGH)
737 if (jfunc->value.pass_through.operation == NOP_EXPR)
738 return input;
739 else if (TREE_CODE (input) == TREE_BINFO)
740 return NULL_TREE;
741 else
742 return ipa_get_jf_pass_through_result (jfunc, input);
744 else
746 if (TREE_CODE (input) == TREE_BINFO)
747 return get_binfo_at_offset (input, jfunc->value.ancestor.offset,
748 jfunc->value.ancestor.type);
749 else
750 return ipa_get_jf_ancestor_result (jfunc, input);
753 else
754 return NULL_TREE;
758 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
759 bottom, not containing a variable component and without any known value at
760 the same time. */
762 DEBUG_FUNCTION void
763 ipcp_verify_propagated_values (void)
765 struct cgraph_node *node;
767 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
769 struct ipa_node_params *info = IPA_NODE_REF (node);
770 int i, count = ipa_get_param_count (info);
772 for (i = 0; i < count; i++)
774 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
776 if (!lat->bottom
777 && !lat->contains_variable
778 && lat->values_count == 0)
780 if (dump_file)
782 fprintf (dump_file, "\nIPA lattices after constant "
783 "propagation:\n");
784 print_all_lattices (dump_file, true, false);
787 gcc_unreachable ();
793 /* Return true iff X and Y should be considered equal values by IPA-CP. */
795 static bool
796 values_equal_for_ipcp_p (tree x, tree y)
798 gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
800 if (x == y)
801 return true;
803 if (TREE_CODE (x) == TREE_BINFO || TREE_CODE (y) == TREE_BINFO)
804 return false;
806 if (TREE_CODE (x) == ADDR_EXPR
807 && TREE_CODE (y) == ADDR_EXPR
808 && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
809 && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
810 return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
811 DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
812 else
813 return operand_equal_p (x, y, 0);
816 /* Add a new value source to VAL, marking that a value comes from edge CS and
817 (if the underlying jump function is a pass-through or an ancestor one) from
818 a caller value SRC_VAL of a caller parameter described by SRC_INDEX. */
820 static void
821 add_value_source (struct ipcp_value *val, struct cgraph_edge *cs,
822 struct ipcp_value *src_val, int src_idx)
824 struct ipcp_value_source *src;
826 src = (struct ipcp_value_source *) pool_alloc (ipcp_sources_pool);
827 src->cs = cs;
828 src->val = src_val;
829 src->index = src_idx;
831 src->next = val->sources;
832 val->sources = src;
836 /* Try to add NEWVAL to LAT, potentially creating a new struct ipcp_value for
837 it. CS, SRC_VAL and SRC_INDEX are meant for add_value_source and have the
838 same meaning. */
840 static bool
841 add_value_to_lattice (struct ipcp_lattice *lat, tree newval,
842 struct cgraph_edge *cs, struct ipcp_value *src_val,
843 int src_idx)
845 struct ipcp_value *val;
847 if (lat->bottom)
848 return false;
851 for (val = lat->values; val; val = val->next)
852 if (values_equal_for_ipcp_p (val->value, newval))
854 if (edge_within_scc (cs))
856 struct ipcp_value_source *s;
857 for (s = val->sources; s ; s = s->next)
858 if (s->cs == cs)
859 break;
860 if (s)
861 return false;
864 add_value_source (val, cs, src_val, src_idx);
865 return false;
868 if (lat->values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))
870 /* We can only free sources, not the values themselves, because sources
871 of other values in this this SCC might point to them. */
872 for (val = lat->values; val; val = val->next)
874 while (val->sources)
876 struct ipcp_value_source *src = val->sources;
877 val->sources = src->next;
878 pool_free (ipcp_sources_pool, src);
882 lat->values = NULL;
883 return set_lattice_to_bottom (lat);
886 lat->values_count++;
887 val = (struct ipcp_value *) pool_alloc (ipcp_values_pool);
888 memset (val, 0, sizeof (*val));
890 add_value_source (val, cs, src_val, src_idx);
891 val->value = newval;
892 val->next = lat->values;
893 lat->values = val;
894 return true;
897 /* Propagate values through a pass-through jump function JFUNC associated with
898 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
899 is the index of the source parameter. */
901 static bool
902 propagate_vals_accross_pass_through (struct cgraph_edge *cs,
903 struct ipa_jump_func *jfunc,
904 struct ipcp_lattice *src_lat,
905 struct ipcp_lattice *dest_lat,
906 int src_idx)
908 struct ipcp_value *src_val;
909 bool ret = false;
911 if (jfunc->value.pass_through.operation == NOP_EXPR)
912 for (src_val = src_lat->values; src_val; src_val = src_val->next)
913 ret |= add_value_to_lattice (dest_lat, src_val->value, cs,
914 src_val, src_idx);
915 /* Do not create new values when propagating within an SCC because if there
916 arithmetic functions with circular dependencies, there is infinite number
917 of them and we would just make lattices bottom. */
918 else if (edge_within_scc (cs))
919 ret = set_lattice_contains_variable (dest_lat);
920 else
921 for (src_val = src_lat->values; src_val; src_val = src_val->next)
923 tree cstval = src_val->value;
925 if (TREE_CODE (cstval) == TREE_BINFO)
927 ret |= set_lattice_contains_variable (dest_lat);
928 continue;
930 cstval = ipa_get_jf_pass_through_result (jfunc, cstval);
932 if (cstval)
933 ret |= add_value_to_lattice (dest_lat, cstval, cs, src_val, src_idx);
934 else
935 ret |= set_lattice_contains_variable (dest_lat);
938 return ret;
941 /* Propagate values through an ancestor jump function JFUNC associated with
942 edge CS, taking values from SRC_LAT and putting them into DEST_LAT. SRC_IDX
943 is the index of the source parameter. */
945 static bool
946 propagate_vals_accross_ancestor (struct cgraph_edge *cs,
947 struct ipa_jump_func *jfunc,
948 struct ipcp_lattice *src_lat,
949 struct ipcp_lattice *dest_lat,
950 int src_idx)
952 struct ipcp_value *src_val;
953 bool ret = false;
955 if (edge_within_scc (cs))
956 return set_lattice_contains_variable (dest_lat);
958 for (src_val = src_lat->values; src_val; src_val = src_val->next)
960 tree t = src_val->value;
962 if (TREE_CODE (t) == TREE_BINFO)
963 t = get_binfo_at_offset (t, jfunc->value.ancestor.offset,
964 jfunc->value.ancestor.type);
965 else
966 t = ipa_get_jf_ancestor_result (jfunc, t);
968 if (t)
969 ret |= add_value_to_lattice (dest_lat, t, cs, src_val, src_idx);
970 else
971 ret |= set_lattice_contains_variable (dest_lat);
974 return ret;
977 /* Propagate values across jump function JFUNC that is associated with edge CS
978 and put the values into DEST_LAT. */
980 static bool
981 propagate_accross_jump_function (struct cgraph_edge *cs,
982 struct ipa_jump_func *jfunc,
983 struct ipcp_lattice *dest_lat)
985 if (dest_lat->bottom)
986 return false;
988 if (jfunc->type == IPA_JF_CONST
989 || jfunc->type == IPA_JF_KNOWN_TYPE)
991 tree val;
993 if (jfunc->type == IPA_JF_KNOWN_TYPE)
995 val = ipa_value_from_known_type_jfunc (jfunc);
996 if (!val)
997 return set_lattice_contains_variable (dest_lat);
999 else
1000 val = jfunc->value.constant;
1001 return add_value_to_lattice (dest_lat, val, cs, NULL, 0);
1003 else if (jfunc->type == IPA_JF_PASS_THROUGH
1004 || jfunc->type == IPA_JF_ANCESTOR)
1006 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1007 struct ipcp_lattice *src_lat;
1008 int src_idx;
1009 bool ret;
1011 if (jfunc->type == IPA_JF_PASS_THROUGH)
1012 src_idx = jfunc->value.pass_through.formal_id;
1013 else
1014 src_idx = jfunc->value.ancestor.formal_id;
1016 src_lat = ipa_get_lattice (caller_info, src_idx);
1017 if (src_lat->bottom)
1018 return set_lattice_contains_variable (dest_lat);
1020 /* If we would need to clone the caller and cannot, do not propagate. */
1021 if (!ipcp_versionable_function_p (cs->caller)
1022 && (src_lat->contains_variable
1023 || (src_lat->values_count > 1)))
1024 return set_lattice_contains_variable (dest_lat);
1026 if (jfunc->type == IPA_JF_PASS_THROUGH)
1027 ret = propagate_vals_accross_pass_through (cs, jfunc, src_lat,
1028 dest_lat, src_idx);
1029 else
1030 ret = propagate_vals_accross_ancestor (cs, jfunc, src_lat, dest_lat,
1031 src_idx);
1033 if (src_lat->contains_variable)
1034 ret |= set_lattice_contains_variable (dest_lat);
1036 return ret;
1039 /* TODO: We currently do not handle member method pointers in IPA-CP (we only
1040 use it for indirect inlining), we should propagate them too. */
1041 return set_lattice_contains_variable (dest_lat);
1044 /* Propagate constants from the caller to the callee of CS. INFO describes the
1045 caller. */
1047 static bool
1048 propagate_constants_accross_call (struct cgraph_edge *cs)
1050 struct ipa_node_params *callee_info;
1051 enum availability availability;
1052 struct cgraph_node *callee, *alias_or_thunk;
1053 struct ipa_edge_args *args;
1054 bool ret = false;
1055 int i, args_count, parms_count;
1057 callee = cgraph_function_node (cs->callee, &availability);
1058 if (!callee->analyzed)
1059 return false;
1060 gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
1061 callee_info = IPA_NODE_REF (callee);
1063 args = IPA_EDGE_REF (cs);
1064 args_count = ipa_get_cs_argument_count (args);
1065 parms_count = ipa_get_param_count (callee_info);
1067 /* If this call goes through a thunk we must not propagate to the first (0th)
1068 parameter. However, we might need to uncover a thunk from below a series
1069 of aliases first. */
1070 alias_or_thunk = cs->callee;
1071 while (alias_or_thunk->alias)
1072 alias_or_thunk = cgraph_alias_aliased_node (alias_or_thunk);
1073 if (alias_or_thunk->thunk.thunk_p)
1075 ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, 0));
1076 i = 1;
1078 else
1079 i = 0;
1081 for (; (i < args_count) && (i < parms_count); i++)
1083 struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
1084 struct ipcp_lattice *dest_lat = ipa_get_lattice (callee_info, i);
1086 if (availability == AVAIL_OVERWRITABLE)
1087 ret |= set_lattice_contains_variable (dest_lat);
1088 else
1089 ret |= propagate_accross_jump_function (cs, jump_func, dest_lat);
1091 for (; i < parms_count; i++)
1092 ret |= set_lattice_contains_variable (ipa_get_lattice (callee_info, i));
1094 return ret;
1097 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
1098 (which can contain both constants and binfos) or KNOWN_BINFOS (which can be
1099 NULL) return the destination. */
1101 tree
1102 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
1103 VEC (tree, heap) *known_vals,
1104 VEC (tree, heap) *known_binfos)
1106 int param_index = ie->indirect_info->param_index;
1107 HOST_WIDE_INT token, anc_offset;
1108 tree otr_type;
1109 tree t;
1111 if (param_index == -1)
1112 return NULL_TREE;
1114 if (!ie->indirect_info->polymorphic)
1116 tree t = (VEC_length (tree, known_vals) > (unsigned int) param_index
1117 ? VEC_index (tree, known_vals, param_index) : NULL);
1118 if (t &&
1119 TREE_CODE (t) == ADDR_EXPR
1120 && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
1121 return TREE_OPERAND (t, 0);
1122 else
1123 return NULL_TREE;
1126 token = ie->indirect_info->otr_token;
1127 anc_offset = ie->indirect_info->anc_offset;
1128 otr_type = ie->indirect_info->otr_type;
1130 t = VEC_index (tree, known_vals, param_index);
1131 if (!t && known_binfos
1132 && VEC_length (tree, known_binfos) > (unsigned int) param_index)
1133 t = VEC_index (tree, known_binfos, param_index);
1134 if (!t)
1135 return NULL_TREE;
1137 if (TREE_CODE (t) != TREE_BINFO)
1139 tree binfo;
1140 binfo = gimple_extract_devirt_binfo_from_cst (t);
1141 if (!binfo)
1142 return NULL_TREE;
1143 binfo = get_binfo_at_offset (binfo, anc_offset, otr_type);
1144 if (!binfo)
1145 return NULL_TREE;
1146 return gimple_get_virt_method_for_binfo (token, binfo);
1148 else
1150 tree binfo;
1152 binfo = get_binfo_at_offset (t, anc_offset, otr_type);
1153 if (!binfo)
1154 return NULL_TREE;
1155 return gimple_get_virt_method_for_binfo (token, binfo);
1159 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
1160 and KNOWN_BINFOS. */
1162 static int
1163 devirtualization_time_bonus (struct cgraph_node *node,
1164 VEC (tree, heap) *known_csts,
1165 VEC (tree, heap) *known_binfos)
1167 struct cgraph_edge *ie;
1168 int res = 0;
1170 for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1172 struct cgraph_node *callee;
1173 struct inline_summary *isummary;
1174 tree target;
1176 target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos);
1177 if (!target)
1178 continue;
1180 /* Only bare minimum benefit for clearly un-inlineable targets. */
1181 res += 1;
1182 callee = cgraph_get_node (target);
1183 if (!callee || !callee->analyzed)
1184 continue;
1185 isummary = inline_summary (callee);
1186 if (!isummary->inlinable)
1187 continue;
1189 /* FIXME: The values below need re-considering and perhaps also
1190 integrating into the cost metrics, at lest in some very basic way. */
1191 if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
1192 res += 31;
1193 else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
1194 res += 15;
1195 else if (isummary->size <= MAX_INLINE_INSNS_AUTO
1196 || DECL_DECLARED_INLINE_P (callee->decl))
1197 res += 7;
1200 return res;
1203 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
1204 and SIZE_COST and with the sum of frequencies of incoming edges to the
1205 potential new clone in FREQUENCIES. */
1207 static bool
1208 good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
1209 int freq_sum, gcov_type count_sum, int size_cost)
1211 if (time_benefit == 0
1212 || !flag_ipa_cp_clone
1213 || !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
1214 return false;
1216 gcc_assert (size_cost > 0);
1218 if (max_count)
1220 int factor = (count_sum * 1000) / max_count;
1221 HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * factor)
1222 / size_cost);
1224 if (dump_file && (dump_flags & TDF_DETAILS))
1225 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
1226 "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
1227 ") -> evaluation: " HOST_WIDEST_INT_PRINT_DEC
1228 ", threshold: %i\n",
1229 time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
1230 evaluation, 500);
1232 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
1234 else
1236 HOST_WIDEST_INT evaluation = (((HOST_WIDEST_INT) time_benefit * freq_sum)
1237 / size_cost);
1239 if (dump_file && (dump_flags & TDF_DETAILS))
1240 fprintf (dump_file, " good_cloning_opportunity_p (time: %i, "
1241 "size: %i, freq_sum: %i) -> evaluation: "
1242 HOST_WIDEST_INT_PRINT_DEC ", threshold: %i\n",
1243 time_benefit, size_cost, freq_sum, evaluation,
1244 CGRAPH_FREQ_BASE /2);
1246 return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
1251 /* Allocate KNOWN_CSTS and KNOWN_BINFOS and populate them with values of
1252 parameters that are known independent of the context. INFO describes the
1253 function. If REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all
1254 removable parameters will be stored in it. */
1256 static bool
1257 gather_context_independent_values (struct ipa_node_params *info,
1258 VEC (tree, heap) **known_csts,
1259 VEC (tree, heap) **known_binfos,
1260 int *removable_params_cost)
1262 int i, count = ipa_get_param_count (info);
1263 bool ret = false;
1265 *known_csts = NULL;
1266 *known_binfos = NULL;
1267 VEC_safe_grow_cleared (tree, heap, *known_csts, count);
1268 VEC_safe_grow_cleared (tree, heap, *known_binfos, count);
1270 if (removable_params_cost)
1271 *removable_params_cost = 0;
1273 for (i = 0; i < count ; i++)
1275 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
1277 if (ipa_lat_is_single_const (lat))
1279 struct ipcp_value *val = lat->values;
1280 if (TREE_CODE (val->value) != TREE_BINFO)
1282 VEC_replace (tree, *known_csts, i, val->value);
1283 if (removable_params_cost)
1284 *removable_params_cost
1285 += estimate_move_cost (TREE_TYPE (val->value));
1286 ret = true;
1288 else if (lat->virt_call)
1290 VEC_replace (tree, *known_binfos, i, val->value);
1291 ret = true;
1293 else if (removable_params_cost
1294 && !ipa_is_param_used (info, i))
1295 *removable_params_cost
1296 += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i)));
1298 else if (removable_params_cost
1299 && !ipa_is_param_used (info, i))
1300 *removable_params_cost
1301 += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i)));
1304 return ret;
1307 /* Iterate over known values of parameters of NODE and estimate the local
1308 effects in terms of time and size they have. */
1310 static void
1311 estimate_local_effects (struct cgraph_node *node)
1313 struct ipa_node_params *info = IPA_NODE_REF (node);
1314 int i, count = ipa_get_param_count (info);
1315 VEC (tree, heap) *known_csts, *known_binfos;
1316 bool always_const;
1317 int base_time = inline_summary (node)->time;
1318 int removable_params_cost;
1320 if (!count || !ipcp_versionable_function_p (node))
1321 return;
1323 if (dump_file && (dump_flags & TDF_DETAILS))
1324 fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %i.\n",
1325 cgraph_node_name (node), node->uid, base_time);
1327 always_const = gather_context_independent_values (info, &known_csts,
1328 &known_binfos,
1329 &removable_params_cost);
1330 if (always_const)
1332 struct caller_statistics stats;
1333 int time, size;
1335 init_caller_stats (&stats);
1336 cgraph_for_node_and_aliases (node, gather_caller_stats, &stats, false);
1337 estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
1338 &size, &time);
1339 time -= devirtualization_time_bonus (node, known_csts, known_binfos);
1340 time -= removable_params_cost;
1341 size -= stats.n_calls * removable_params_cost;
1343 if (dump_file)
1344 fprintf (dump_file, " - context independent values, size: %i, "
1345 "time_benefit: %i\n", size, base_time - time);
1347 if (size <= 0
1348 || cgraph_will_be_removed_from_program_if_no_direct_calls (node))
1350 info->clone_for_all_contexts = true;
1351 base_time = time;
1353 if (dump_file)
1354 fprintf (dump_file, " Decided to specialize for all "
1355 "known contexts, code not going to grow.\n");
1357 else if (good_cloning_opportunity_p (node, base_time - time,
1358 stats.freq_sum, stats.count_sum,
1359 size))
1361 if (size + overall_size <= max_new_size)
1363 info->clone_for_all_contexts = true;
1364 base_time = time;
1365 overall_size += size;
1367 if (dump_file)
1368 fprintf (dump_file, " Decided to specialize for all "
1369 "known contexts, growth deemed beneficial.\n");
1371 else if (dump_file && (dump_flags & TDF_DETAILS))
1372 fprintf (dump_file, " Not cloning for all contexts because "
1373 "max_new_size would be reached with %li.\n",
1374 size + overall_size);
1378 for (i = 0; i < count ; i++)
1380 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
1381 struct ipcp_value *val;
1382 int emc;
1384 if (lat->bottom
1385 || !lat->values
1386 || VEC_index (tree, known_csts, i)
1387 || VEC_index (tree, known_binfos, i))
1388 continue;
1390 for (val = lat->values; val; val = val->next)
1392 int time, size, time_benefit;
1394 if (TREE_CODE (val->value) != TREE_BINFO)
1396 VEC_replace (tree, known_csts, i, val->value);
1397 VEC_replace (tree, known_binfos, i, NULL_TREE);
1398 emc = estimate_move_cost (TREE_TYPE (val->value));
1400 else if (lat->virt_call)
1402 VEC_replace (tree, known_csts, i, NULL_TREE);
1403 VEC_replace (tree, known_binfos, i, val->value);
1404 emc = 0;
1406 else
1407 continue;
1409 estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
1410 &size, &time);
1411 time_benefit = base_time - time
1412 + devirtualization_time_bonus (node, known_csts, known_binfos)
1413 + removable_params_cost + emc;
1415 gcc_checking_assert (size >=0);
1416 /* The inliner-heuristics based estimates may think that in certain
1417 contexts some functions do not have any size at all but we want
1418 all specializations to have at least a tiny cost, not least not to
1419 divide by zero. */
1420 if (size == 0)
1421 size = 1;
1423 if (dump_file && (dump_flags & TDF_DETAILS))
1425 fprintf (dump_file, " - estimates for value ");
1426 print_ipcp_constant_value (dump_file, val->value);
1427 fprintf (dump_file, " for parameter ");
1428 print_generic_expr (dump_file, ipa_get_param (info, i), 0);
1429 fprintf (dump_file, ": time_benefit: %i, size: %i\n",
1430 time_benefit, size);
1433 val->local_time_benefit = time_benefit;
1434 val->local_size_cost = size;
1438 VEC_free (tree, heap, known_csts);
1439 VEC_free (tree, heap, known_binfos);
1443 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
1444 topological sort of values. */
1446 static void
1447 add_val_to_toposort (struct ipcp_value *cur_val)
1449 static int dfs_counter = 0;
1450 static struct ipcp_value *stack;
1451 struct ipcp_value_source *src;
1453 if (cur_val->dfs)
1454 return;
1456 dfs_counter++;
1457 cur_val->dfs = dfs_counter;
1458 cur_val->low_link = dfs_counter;
1460 cur_val->topo_next = stack;
1461 stack = cur_val;
1462 cur_val->on_stack = true;
1464 for (src = cur_val->sources; src; src = src->next)
1465 if (src->val)
1467 if (src->val->dfs == 0)
1469 add_val_to_toposort (src->val);
1470 if (src->val->low_link < cur_val->low_link)
1471 cur_val->low_link = src->val->low_link;
1473 else if (src->val->on_stack
1474 && src->val->dfs < cur_val->low_link)
1475 cur_val->low_link = src->val->dfs;
1478 if (cur_val->dfs == cur_val->low_link)
1480 struct ipcp_value *v, *scc_list = NULL;
1484 v = stack;
1485 stack = v->topo_next;
1486 v->on_stack = false;
1488 v->scc_next = scc_list;
1489 scc_list = v;
1491 while (v != cur_val);
1493 cur_val->topo_next = values_topo;
1494 values_topo = cur_val;
1498 /* Add all values in lattices associated with NODE to the topological sort if
1499 they are not there yet. */
1501 static void
1502 add_all_node_vals_to_toposort (struct cgraph_node *node)
1504 struct ipa_node_params *info = IPA_NODE_REF (node);
1505 int i, count = ipa_get_param_count (info);
1507 for (i = 0; i < count ; i++)
1509 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
1510 struct ipcp_value *val;
1512 if (lat->bottom || !lat->values)
1513 continue;
1514 for (val = lat->values; val; val = val->next)
1515 add_val_to_toposort (val);
1519 /* One pass of constants propagation along the call graph edges, from callers
1520 to callees (requires topological ordering in TOPO), iterate over strongly
1521 connected components. */
1523 static void
1524 propagate_constants_topo (struct topo_info *topo)
1526 int i;
1528 for (i = topo->nnodes - 1; i >= 0; i--)
1530 struct cgraph_node *v, *node = topo->order[i];
1531 struct ipa_dfs_info *node_dfs_info;
1533 if (!cgraph_function_with_gimple_body_p (node))
1534 continue;
1536 node_dfs_info = (struct ipa_dfs_info *) node->aux;
1537 /* First, iteratively propagate within the strongly connected component
1538 until all lattices stabilize. */
1539 v = node_dfs_info->next_cycle;
1540 while (v)
1542 push_node_to_stack (topo, v);
1543 v = ((struct ipa_dfs_info *) v->aux)->next_cycle;
1546 v = node;
1547 while (v)
1549 struct cgraph_edge *cs;
1551 for (cs = v->callees; cs; cs = cs->next_callee)
1552 if (edge_within_scc (cs)
1553 && propagate_constants_accross_call (cs))
1554 push_node_to_stack (topo, cs->callee);
1555 v = pop_node_from_stack (topo);
1558 /* Afterwards, propagate along edges leading out of the SCC, calculates
1559 the local effects of the discovered constants and all valid values to
1560 their topological sort. */
1561 v = node;
1562 while (v)
1564 struct cgraph_edge *cs;
1566 estimate_local_effects (v);
1567 add_all_node_vals_to_toposort (v);
1568 for (cs = v->callees; cs; cs = cs->next_callee)
1569 if (!edge_within_scc (cs))
1570 propagate_constants_accross_call (cs);
1572 v = ((struct ipa_dfs_info *) v->aux)->next_cycle;
1578 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
1579 the bigger one if otherwise. */
1581 static int
1582 safe_add (int a, int b)
1584 if (a > INT_MAX/2 || b > INT_MAX/2)
1585 return a > b ? a : b;
1586 else
1587 return a + b;
1591 /* Propagate the estimated effects of individual values along the topological
1592 from the dependant values to those they depend on. */
1594 static void
1595 propagate_effects (void)
1597 struct ipcp_value *base;
1599 for (base = values_topo; base; base = base->topo_next)
1601 struct ipcp_value_source *src;
1602 struct ipcp_value *val;
1603 int time = 0, size = 0;
1605 for (val = base; val; val = val->scc_next)
1607 time = safe_add (time,
1608 val->local_time_benefit + val->prop_time_benefit);
1609 size = safe_add (size, val->local_size_cost + val->prop_size_cost);
1612 for (val = base; val; val = val->scc_next)
1613 for (src = val->sources; src; src = src->next)
1614 if (src->val
1615 && cgraph_maybe_hot_edge_p (src->cs))
1617 src->val->prop_time_benefit = safe_add (time,
1618 src->val->prop_time_benefit);
1619 src->val->prop_size_cost = safe_add (size,
1620 src->val->prop_size_cost);
1626 /* Propagate constants, binfos and their effects from the summaries
1627 interprocedurally. */
1629 static void
1630 ipcp_propagate_stage (struct topo_info *topo)
1632 struct cgraph_node *node;
1634 if (dump_file)
1635 fprintf (dump_file, "\n Propagating constants:\n\n");
1637 if (in_lto_p)
1638 ipa_update_after_lto_read ();
1641 FOR_EACH_DEFINED_FUNCTION (node)
1643 struct ipa_node_params *info = IPA_NODE_REF (node);
1645 determine_versionability (node);
1646 if (cgraph_function_with_gimple_body_p (node))
1648 info->lattices = XCNEWVEC (struct ipcp_lattice,
1649 ipa_get_param_count (info));
1650 initialize_node_lattices (node);
1652 if (node->count > max_count)
1653 max_count = node->count;
1654 overall_size += inline_summary (node)->self_size;
1657 max_new_size = overall_size;
1658 if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
1659 max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
1660 max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
1662 if (dump_file)
1663 fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
1664 overall_size, max_new_size);
1666 propagate_constants_topo (topo);
1667 #ifdef ENABLE_CHECKING
1668 ipcp_verify_propagated_values ();
1669 #endif
1670 propagate_effects ();
1672 if (dump_file)
1674 fprintf (dump_file, "\nIPA lattices after all propagation:\n");
1675 print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
1679 /* Discover newly direct outgoing edges from NODE which is a new clone with
1680 known KNOWN_VALS and make them direct. */
1682 static void
1683 ipcp_discover_new_direct_edges (struct cgraph_node *node,
1684 VEC (tree, heap) *known_vals)
1686 struct cgraph_edge *ie, *next_ie;
1688 for (ie = node->indirect_calls; ie; ie = next_ie)
1690 tree target;
1692 next_ie = ie->next_callee;
1693 target = ipa_get_indirect_edge_target (ie, known_vals, NULL);
1694 if (target)
1695 ipa_make_edge_direct_to_target (ie, target);
1699 /* Vector of pointers which for linked lists of clones of an original crgaph
1700 edge. */
1702 static VEC (cgraph_edge_p, heap) *next_edge_clone;
1704 static inline void
1705 grow_next_edge_clone_vector (void)
1707 if (VEC_length (cgraph_edge_p, next_edge_clone)
1708 <= (unsigned) cgraph_edge_max_uid)
1709 VEC_safe_grow_cleared (cgraph_edge_p, heap, next_edge_clone,
1710 cgraph_edge_max_uid + 1);
1713 /* Edge duplication hook to grow the appropriate linked list in
1714 next_edge_clone. */
1716 static void
1717 ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
1718 __attribute__((unused)) void *data)
1720 grow_next_edge_clone_vector ();
1721 VEC_replace (cgraph_edge_p, next_edge_clone, dst->uid,
1722 VEC_index (cgraph_edge_p, next_edge_clone, src->uid));
1723 VEC_replace (cgraph_edge_p, next_edge_clone, src->uid, dst);
1726 /* Get the next clone in the linked list of clones of an edge. */
1728 static inline struct cgraph_edge *
1729 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
1731 return VEC_index (cgraph_edge_p, next_edge_clone, cs->uid);
1734 /* Return true if edge CS does bring about the value described by SRC. */
1736 static bool
1737 cgraph_edge_brings_value_p (struct cgraph_edge *cs,
1738 struct ipcp_value_source *src)
1740 struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1742 if (IPA_NODE_REF (cs->callee)->ipcp_orig_node
1743 || caller_info->node_dead)
1744 return false;
1745 if (!src->val)
1746 return true;
1748 if (caller_info->ipcp_orig_node)
1750 tree t = VEC_index (tree, caller_info->known_vals, src->index);
1751 return (t != NULL_TREE
1752 && values_equal_for_ipcp_p (src->val->value, t));
1754 else
1756 struct ipcp_lattice *lat = ipa_get_lattice (caller_info, src->index);
1757 if (ipa_lat_is_single_const (lat)
1758 && values_equal_for_ipcp_p (src->val->value, lat->values->value))
1759 return true;
1760 else
1761 return false;
1765 /* Given VAL, iterate over all its sources and if they still hold, add their
1766 edge frequency and their number into *FREQUENCY and *CALLER_COUNT
1767 respectively. */
1769 static bool
1770 get_info_about_necessary_edges (struct ipcp_value *val, int *freq_sum,
1771 gcov_type *count_sum, int *caller_count)
1773 struct ipcp_value_source *src;
1774 int freq = 0, count = 0;
1775 gcov_type cnt = 0;
1776 bool hot = false;
1778 for (src = val->sources; src; src = src->next)
1780 struct cgraph_edge *cs = src->cs;
1781 while (cs)
1783 if (cgraph_edge_brings_value_p (cs, src))
1785 count++;
1786 freq += cs->frequency;
1787 cnt += cs->count;
1788 hot |= cgraph_maybe_hot_edge_p (cs);
1790 cs = get_next_cgraph_edge_clone (cs);
1794 *freq_sum = freq;
1795 *count_sum = cnt;
1796 *caller_count = count;
1797 return hot;
1800 /* Return a vector of incoming edges that do bring value VAL. It is assumed
1801 their number is known and equal to CALLER_COUNT. */
1803 static VEC (cgraph_edge_p,heap) *
1804 gather_edges_for_value (struct ipcp_value *val, int caller_count)
1806 struct ipcp_value_source *src;
1807 VEC (cgraph_edge_p,heap) *ret;
1809 ret = VEC_alloc (cgraph_edge_p, heap, caller_count);
1810 for (src = val->sources; src; src = src->next)
1812 struct cgraph_edge *cs = src->cs;
1813 while (cs)
1815 if (cgraph_edge_brings_value_p (cs, src))
1816 VEC_quick_push (cgraph_edge_p, ret, cs);
1817 cs = get_next_cgraph_edge_clone (cs);
1821 return ret;
1824 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
1825 Return it or NULL if for some reason it cannot be created. */
1827 static struct ipa_replace_map *
1828 get_replacement_map (tree value, tree parm)
1830 tree req_type = TREE_TYPE (parm);
1831 struct ipa_replace_map *replace_map;
1833 if (!useless_type_conversion_p (req_type, TREE_TYPE (value)))
1835 if (fold_convertible_p (req_type, value))
1836 value = fold_build1 (NOP_EXPR, req_type, value);
1837 else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (value)))
1838 value = fold_build1 (VIEW_CONVERT_EXPR, req_type, value);
1839 else
1841 if (dump_file)
1843 fprintf (dump_file, " const ");
1844 print_generic_expr (dump_file, value, 0);
1845 fprintf (dump_file, " can't be converted to param ");
1846 print_generic_expr (dump_file, parm, 0);
1847 fprintf (dump_file, "\n");
1849 return NULL;
1853 replace_map = ggc_alloc_ipa_replace_map ();
1854 if (dump_file)
1856 fprintf (dump_file, " replacing param ");
1857 print_generic_expr (dump_file, parm, 0);
1858 fprintf (dump_file, " with const ");
1859 print_generic_expr (dump_file, value, 0);
1860 fprintf (dump_file, "\n");
1862 replace_map->old_tree = parm;
1863 replace_map->new_tree = value;
1864 replace_map->replace_p = true;
1865 replace_map->ref_p = false;
1867 return replace_map;
1870 /* Dump new profiling counts */
1872 static void
1873 dump_profile_updates (struct cgraph_node *orig_node,
1874 struct cgraph_node *new_node)
1876 struct cgraph_edge *cs;
1878 fprintf (dump_file, " setting count of the specialized node to "
1879 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count);
1880 for (cs = new_node->callees; cs ; cs = cs->next_callee)
1881 fprintf (dump_file, " edge to %s has count "
1882 HOST_WIDE_INT_PRINT_DEC "\n",
1883 cgraph_node_name (cs->callee), (HOST_WIDE_INT) cs->count);
1885 fprintf (dump_file, " setting count of the original node to "
1886 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count);
1887 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
1888 fprintf (dump_file, " edge to %s is left with "
1889 HOST_WIDE_INT_PRINT_DEC "\n",
1890 cgraph_node_name (cs->callee), (HOST_WIDE_INT) cs->count);
1893 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
1894 their profile information to reflect this. */
1896 static void
1897 update_profiling_info (struct cgraph_node *orig_node,
1898 struct cgraph_node *new_node)
1900 struct cgraph_edge *cs;
1901 struct caller_statistics stats;
1902 gcov_type new_sum, orig_sum;
1903 gcov_type remainder, orig_node_count = orig_node->count;
1905 if (orig_node_count == 0)
1906 return;
1908 init_caller_stats (&stats);
1909 cgraph_for_node_and_aliases (orig_node, gather_caller_stats, &stats, false);
1910 orig_sum = stats.count_sum;
1911 init_caller_stats (&stats);
1912 cgraph_for_node_and_aliases (new_node, gather_caller_stats, &stats, false);
1913 new_sum = stats.count_sum;
1915 if (orig_node_count < orig_sum + new_sum)
1917 if (dump_file)
1918 fprintf (dump_file, " Problem: node %s/%i has too low count "
1919 HOST_WIDE_INT_PRINT_DEC " while the sum of incoming "
1920 "counts is " HOST_WIDE_INT_PRINT_DEC "\n",
1921 cgraph_node_name (orig_node), orig_node->uid,
1922 (HOST_WIDE_INT) orig_node_count,
1923 (HOST_WIDE_INT) (orig_sum + new_sum));
1925 orig_node_count = (orig_sum + new_sum) * 12 / 10;
1926 if (dump_file)
1927 fprintf (dump_file, " proceeding by pretending it was "
1928 HOST_WIDE_INT_PRINT_DEC "\n",
1929 (HOST_WIDE_INT) orig_node_count);
1932 new_node->count = new_sum;
1933 remainder = orig_node_count - new_sum;
1934 orig_node->count = remainder;
1936 for (cs = new_node->callees; cs ; cs = cs->next_callee)
1937 if (cs->frequency)
1938 cs->count = cs->count * (new_sum * REG_BR_PROB_BASE
1939 / orig_node_count) / REG_BR_PROB_BASE;
1940 else
1941 cs->count = 0;
1943 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
1944 cs->count = cs->count * (remainder * REG_BR_PROB_BASE
1945 / orig_node_count) / REG_BR_PROB_BASE;
1947 if (dump_file)
1948 dump_profile_updates (orig_node, new_node);
1951 /* Update the respective profile of specialized NEW_NODE and the original
1952 ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
1953 have been redirected to the specialized version. */
1955 static void
1956 update_specialized_profile (struct cgraph_node *new_node,
1957 struct cgraph_node *orig_node,
1958 gcov_type redirected_sum)
1960 struct cgraph_edge *cs;
1961 gcov_type new_node_count, orig_node_count = orig_node->count;
1963 if (dump_file)
1964 fprintf (dump_file, " the sum of counts of redirected edges is "
1965 HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum);
1966 if (orig_node_count == 0)
1967 return;
1969 gcc_assert (orig_node_count >= redirected_sum);
1971 new_node_count = new_node->count;
1972 new_node->count += redirected_sum;
1973 orig_node->count -= redirected_sum;
1975 for (cs = new_node->callees; cs ; cs = cs->next_callee)
1976 if (cs->frequency)
1977 cs->count += cs->count * redirected_sum / new_node_count;
1978 else
1979 cs->count = 0;
1981 for (cs = orig_node->callees; cs ; cs = cs->next_callee)
1983 gcov_type dec = cs->count * (redirected_sum * REG_BR_PROB_BASE
1984 / orig_node_count) / REG_BR_PROB_BASE;
1985 if (dec < cs->count)
1986 cs->count -= dec;
1987 else
1988 cs->count = 0;
1991 if (dump_file)
1992 dump_profile_updates (orig_node, new_node);
1995 /* Create a specialized version of NODE with known constants and types of
1996 parameters in KNOWN_VALS and redirect all edges in CALLERS to it. */
1998 static struct cgraph_node *
1999 create_specialized_node (struct cgraph_node *node,
2000 VEC (tree, heap) *known_vals,
2001 VEC (cgraph_edge_p,heap) *callers)
2003 struct ipa_node_params *new_info, *info = IPA_NODE_REF (node);
2004 VEC (ipa_replace_map_p,gc)* replace_trees = NULL;
2005 struct cgraph_node *new_node;
2006 int i, count = ipa_get_param_count (info);
2007 bitmap args_to_skip;
2009 gcc_assert (!info->ipcp_orig_node);
2011 if (node->local.can_change_signature)
2013 args_to_skip = BITMAP_GGC_ALLOC ();
2014 for (i = 0; i < count; i++)
2016 tree t = VEC_index (tree, known_vals, i);
2018 if ((t && TREE_CODE (t) != TREE_BINFO)
2019 || !ipa_is_param_used (info, i))
2020 bitmap_set_bit (args_to_skip, i);
2023 else
2025 args_to_skip = NULL;
2026 if (dump_file && (dump_flags & TDF_DETAILS))
2027 fprintf (dump_file, " cannot change function signature\n");
2030 for (i = 0; i < count ; i++)
2032 tree t = VEC_index (tree, known_vals, i);
2033 if (t && TREE_CODE (t) != TREE_BINFO)
2035 struct ipa_replace_map *replace_map;
2037 replace_map = get_replacement_map (t, ipa_get_param (info, i));
2038 if (replace_map)
2039 VEC_safe_push (ipa_replace_map_p, gc, replace_trees, replace_map);
2043 new_node = cgraph_create_virtual_clone (node, callers, replace_trees,
2044 args_to_skip, "constprop");
2045 if (dump_file && (dump_flags & TDF_DETAILS))
2046 fprintf (dump_file, " the new node is %s/%i.\n",
2047 cgraph_node_name (new_node), new_node->uid);
2048 gcc_checking_assert (ipa_node_params_vector
2049 && (VEC_length (ipa_node_params_t,
2050 ipa_node_params_vector)
2051 > (unsigned) cgraph_max_uid));
2052 update_profiling_info (node, new_node);
2053 new_info = IPA_NODE_REF (new_node);
2054 new_info->ipcp_orig_node = node;
2055 new_info->known_vals = known_vals;
2057 ipcp_discover_new_direct_edges (new_node, known_vals);
2059 VEC_free (cgraph_edge_p, heap, callers);
2060 return new_node;
2063 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
2064 KNOWN_VALS with constants and types that are also known for all of the
2065 CALLERS. */
2067 static void
2068 find_more_values_for_callers_subset (struct cgraph_node *node,
2069 VEC (tree, heap) *known_vals,
2070 VEC (cgraph_edge_p,heap) *callers)
2072 struct ipa_node_params *info = IPA_NODE_REF (node);
2073 int i, count = ipa_get_param_count (info);
2075 for (i = 0; i < count ; i++)
2077 struct cgraph_edge *cs;
2078 tree newval = NULL_TREE;
2079 int j;
2081 if (ipa_get_lattice (info, i)->bottom
2082 || VEC_index (tree, known_vals, i))
2083 continue;
2085 FOR_EACH_VEC_ELT (cgraph_edge_p, callers, j, cs)
2087 struct ipa_jump_func *jump_func;
2088 tree t;
2090 if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
2092 newval = NULL_TREE;
2093 break;
2095 jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
2096 t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
2097 if (!t
2098 || (newval
2099 && !values_equal_for_ipcp_p (t, newval)))
2101 newval = NULL_TREE;
2102 break;
2104 else
2105 newval = t;
2108 if (newval)
2110 if (dump_file && (dump_flags & TDF_DETAILS))
2112 fprintf (dump_file, " adding an extra known value ");
2113 print_ipcp_constant_value (dump_file, newval);
2114 fprintf (dump_file, " for parameter ");
2115 print_generic_expr (dump_file, ipa_get_param (info, i), 0);
2116 fprintf (dump_file, "\n");
2119 VEC_replace (tree, known_vals, i, newval);
2124 /* Given an original NODE and a VAL for which we have already created a
2125 specialized clone, look whether there are incoming edges that still lead
2126 into the old node but now also bring the requested value and also conform to
2127 all other criteria such that they can be redirected the the special node.
2128 This function can therefore redirect the final edge in a SCC. */
2130 static void
2131 perhaps_add_new_callers (struct cgraph_node *node, struct ipcp_value *val)
2133 struct ipa_node_params *dest_info = IPA_NODE_REF (val->spec_node);
2134 struct ipcp_value_source *src;
2135 int count = ipa_get_param_count (dest_info);
2136 gcov_type redirected_sum = 0;
2138 for (src = val->sources; src; src = src->next)
2140 struct cgraph_edge *cs = src->cs;
2141 while (cs)
2143 enum availability availability;
2144 bool insufficient = false;
2146 if (cgraph_function_node (cs->callee, &availability) == node
2147 && availability > AVAIL_OVERWRITABLE
2148 && cgraph_edge_brings_value_p (cs, src))
2150 struct ipa_node_params *caller_info;
2151 struct ipa_edge_args *args;
2152 int i;
2154 caller_info = IPA_NODE_REF (cs->caller);
2155 args = IPA_EDGE_REF (cs);
2156 for (i = 0; i < count; i++)
2158 struct ipa_jump_func *jump_func;
2159 tree val, t;
2161 val = VEC_index (tree, dest_info->known_vals, i);
2162 if (!val)
2163 continue;
2165 if (i >= ipa_get_cs_argument_count (args))
2167 insufficient = true;
2168 break;
2170 jump_func = ipa_get_ith_jump_func (args, i);
2171 t = ipa_value_from_jfunc (caller_info, jump_func);
2172 if (!t || !values_equal_for_ipcp_p (val, t))
2174 insufficient = true;
2175 break;
2179 if (!insufficient)
2181 if (dump_file)
2182 fprintf (dump_file, " - adding an extra caller %s/%i"
2183 " of %s/%i\n",
2184 xstrdup (cgraph_node_name (cs->caller)),
2185 cs->caller->uid,
2186 xstrdup (cgraph_node_name (val->spec_node)),
2187 val->spec_node->uid);
2189 cgraph_redirect_edge_callee (cs, val->spec_node);
2190 redirected_sum += cs->count;
2193 cs = get_next_cgraph_edge_clone (cs);
2197 if (redirected_sum)
2198 update_specialized_profile (val->spec_node, node, redirected_sum);
2202 /* Copy KNOWN_BINFOS to KNOWN_VALS. */
2204 static void
2205 move_binfos_to_values (VEC (tree, heap) *known_vals,
2206 VEC (tree, heap) *known_binfos)
2208 tree t;
2209 int i;
2211 for (i = 0; VEC_iterate (tree, known_binfos, i, t); i++)
2212 if (t)
2213 VEC_replace (tree, known_vals, i, t);
2217 /* Decide whether and what specialized clones of NODE should be created. */
2219 static bool
2220 decide_whether_version_node (struct cgraph_node *node)
2222 struct ipa_node_params *info = IPA_NODE_REF (node);
2223 int i, count = ipa_get_param_count (info);
2224 VEC (tree, heap) *known_csts, *known_binfos;
2225 bool ret = false;
2227 if (count == 0)
2228 return false;
2230 if (dump_file && (dump_flags & TDF_DETAILS))
2231 fprintf (dump_file, "\nEvaluating opportunities for %s/%i.\n",
2232 cgraph_node_name (node), node->uid);
2234 gather_context_independent_values (info, &known_csts, &known_binfos,
2235 NULL);
2237 for (i = 0; i < count ; i++)
2239 struct ipcp_lattice *lat = ipa_get_lattice (info, i);
2240 struct ipcp_value *val;
2242 if (lat->bottom
2243 || VEC_index (tree, known_csts, i)
2244 || VEC_index (tree, known_binfos, i))
2245 continue;
2247 for (val = lat->values; val; val = val->next)
2249 int freq_sum, caller_count;
2250 gcov_type count_sum;
2251 VEC (cgraph_edge_p, heap) *callers;
2252 VEC (tree, heap) *kv;
2254 if (val->spec_node)
2256 perhaps_add_new_callers (node, val);
2257 continue;
2259 else if (val->local_size_cost + overall_size > max_new_size)
2261 if (dump_file && (dump_flags & TDF_DETAILS))
2262 fprintf (dump_file, " Ignoring candidate value because "
2263 "max_new_size would be reached with %li.\n",
2264 val->local_size_cost + overall_size);
2265 continue;
2267 else if (!get_info_about_necessary_edges (val, &freq_sum, &count_sum,
2268 &caller_count))
2269 continue;
2271 if (dump_file && (dump_flags & TDF_DETAILS))
2273 fprintf (dump_file, " - considering value ");
2274 print_ipcp_constant_value (dump_file, val->value);
2275 fprintf (dump_file, " for parameter ");
2276 print_generic_expr (dump_file, ipa_get_param (info, i), 0);
2277 fprintf (dump_file, " (caller_count: %i)\n", caller_count);
2281 if (!good_cloning_opportunity_p (node, val->local_time_benefit,
2282 freq_sum, count_sum,
2283 val->local_size_cost)
2284 && !good_cloning_opportunity_p (node,
2285 val->local_time_benefit
2286 + val->prop_time_benefit,
2287 freq_sum, count_sum,
2288 val->local_size_cost
2289 + val->prop_size_cost))
2290 continue;
2292 if (dump_file)
2293 fprintf (dump_file, " Creating a specialized node of %s/%i.\n",
2294 cgraph_node_name (node), node->uid);
2296 callers = gather_edges_for_value (val, caller_count);
2297 kv = VEC_copy (tree, heap, known_csts);
2298 move_binfos_to_values (kv, known_binfos);
2299 VEC_replace (tree, kv, i, val->value);
2300 find_more_values_for_callers_subset (node, kv, callers);
2301 val->spec_node = create_specialized_node (node, kv, callers);
2302 overall_size += val->local_size_cost;
2303 info = IPA_NODE_REF (node);
2305 /* TODO: If for some lattice there is only one other known value
2306 left, make a special node for it too. */
2307 ret = true;
2309 VEC_replace (tree, kv, i, val->value);
2313 if (info->clone_for_all_contexts)
2315 VEC (cgraph_edge_p, heap) *callers;
2317 if (dump_file)
2318 fprintf (dump_file, " - Creating a specialized node of %s/%i "
2319 "for all known contexts.\n", cgraph_node_name (node),
2320 node->uid);
2322 callers = collect_callers_of_node (node);
2323 move_binfos_to_values (known_csts, known_binfos);
2324 create_specialized_node (node, known_csts, callers);
2325 info = IPA_NODE_REF (node);
2326 info->clone_for_all_contexts = false;
2327 ret = true;
2329 else
2330 VEC_free (tree, heap, known_csts);
2332 VEC_free (tree, heap, known_binfos);
2333 return ret;
2336 /* Transitively mark all callees of NODE within the same SCC as not dead. */
2338 static void
2339 spread_undeadness (struct cgraph_node *node)
2341 struct cgraph_edge *cs;
2343 for (cs = node->callees; cs; cs = cs->next_callee)
2344 if (edge_within_scc (cs))
2346 struct cgraph_node *callee;
2347 struct ipa_node_params *info;
2349 callee = cgraph_function_node (cs->callee, NULL);
2350 info = IPA_NODE_REF (callee);
2352 if (info->node_dead)
2354 info->node_dead = 0;
2355 spread_undeadness (callee);
2360 /* Return true if NODE has a caller from outside of its SCC that is not
2361 dead. Worker callback for cgraph_for_node_and_aliases. */
2363 static bool
2364 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
2365 void *data ATTRIBUTE_UNUSED)
2367 struct cgraph_edge *cs;
2369 for (cs = node->callers; cs; cs = cs->next_caller)
2370 if (cs->caller->thunk.thunk_p
2371 && cgraph_for_node_and_aliases (cs->caller,
2372 has_undead_caller_from_outside_scc_p,
2373 NULL, true))
2374 return true;
2375 else if (!edge_within_scc (cs)
2376 && !IPA_NODE_REF (cs->caller)->node_dead)
2377 return true;
2378 return false;
2382 /* Identify nodes within the same SCC as NODE which are no longer needed
2383 because of new clones and will be removed as unreachable. */
2385 static void
2386 identify_dead_nodes (struct cgraph_node *node)
2388 struct cgraph_node *v;
2389 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
2390 if (cgraph_will_be_removed_from_program_if_no_direct_calls (v)
2391 && !cgraph_for_node_and_aliases (v,
2392 has_undead_caller_from_outside_scc_p,
2393 NULL, true))
2394 IPA_NODE_REF (v)->node_dead = 1;
2396 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
2397 if (!IPA_NODE_REF (v)->node_dead)
2398 spread_undeadness (v);
2400 if (dump_file && (dump_flags & TDF_DETAILS))
2402 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
2403 if (IPA_NODE_REF (v)->node_dead)
2404 fprintf (dump_file, " Marking node as dead: %s/%i.\n",
2405 cgraph_node_name (v), v->uid);
2409 /* The decision stage. Iterate over the topological order of call graph nodes
2410 TOPO and make specialized clones if deemed beneficial. */
2412 static void
2413 ipcp_decision_stage (struct topo_info *topo)
2415 int i;
2417 if (dump_file)
2418 fprintf (dump_file, "\nIPA decision stage:\n\n");
2420 for (i = topo->nnodes - 1; i >= 0; i--)
2422 struct cgraph_node *node = topo->order[i];
2423 bool change = false, iterate = true;
2425 while (iterate)
2427 struct cgraph_node *v;
2428 iterate = false;
2429 for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
2430 if (cgraph_function_with_gimple_body_p (v)
2431 && ipcp_versionable_function_p (v))
2432 iterate |= decide_whether_version_node (v);
2434 change |= iterate;
2436 if (change)
2437 identify_dead_nodes (node);
2441 /* The IPCP driver. */
2443 static unsigned int
2444 ipcp_driver (void)
2446 struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
2447 struct topo_info topo;
2449 cgraph_remove_unreachable_nodes (true,dump_file);
2450 ipa_check_create_node_params ();
2451 ipa_check_create_edge_args ();
2452 grow_next_edge_clone_vector ();
2453 edge_duplication_hook_holder =
2454 cgraph_add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
2455 ipcp_values_pool = create_alloc_pool ("IPA-CP values",
2456 sizeof (struct ipcp_value), 32);
2457 ipcp_sources_pool = create_alloc_pool ("IPA-CP value sources",
2458 sizeof (struct ipcp_value_source), 64);
2459 if (dump_file)
2461 fprintf (dump_file, "\nIPA structures before propagation:\n");
2462 if (dump_flags & TDF_DETAILS)
2463 ipa_print_all_params (dump_file);
2464 ipa_print_all_jump_functions (dump_file);
2467 /* Topological sort. */
2468 build_toporder_info (&topo);
2469 /* Do the interprocedural propagation. */
2470 ipcp_propagate_stage (&topo);
2471 /* Decide what constant propagation and cloning should be performed. */
2472 ipcp_decision_stage (&topo);
2474 /* Free all IPCP structures. */
2475 free_toporder_info (&topo);
2476 VEC_free (cgraph_edge_p, heap, next_edge_clone);
2477 cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder);
2478 ipa_free_all_structures_after_ipa_cp ();
2479 if (dump_file)
2480 fprintf (dump_file, "\nIPA constant propagation end\n");
2481 return 0;
2484 /* Initialization and computation of IPCP data structures. This is the initial
2485 intraprocedural analysis of functions, which gathers information to be
2486 propagated later on. */
2488 static void
2489 ipcp_generate_summary (void)
2491 struct cgraph_node *node;
2493 if (dump_file)
2494 fprintf (dump_file, "\nIPA constant propagation start:\n");
2495 ipa_register_cgraph_hooks ();
2497 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
2499 /* Unreachable nodes should have been eliminated before ipcp. */
2500 gcc_assert (node->needed || node->reachable);
2501 node->local.versionable = tree_versionable_function_p (node->decl);
2502 ipa_analyze_node (node);
2506 /* Write ipcp summary for nodes in SET. */
2508 static void
2509 ipcp_write_summary (cgraph_node_set set,
2510 varpool_node_set vset ATTRIBUTE_UNUSED)
2512 ipa_prop_write_jump_functions (set);
2515 /* Read ipcp summary. */
2517 static void
2518 ipcp_read_summary (void)
2520 ipa_prop_read_jump_functions ();
2523 /* Gate for IPCP optimization. */
2525 static bool
2526 cgraph_gate_cp (void)
2528 /* FIXME: We should remove the optimize check after we ensure we never run
2529 IPA passes when not optimizing. */
2530 return flag_ipa_cp && optimize;
2533 struct ipa_opt_pass_d pass_ipa_cp =
2536 IPA_PASS,
2537 "cp", /* name */
2538 cgraph_gate_cp, /* gate */
2539 ipcp_driver, /* execute */
2540 NULL, /* sub */
2541 NULL, /* next */
2542 0, /* static_pass_number */
2543 TV_IPA_CONSTANT_PROP, /* tv_id */
2544 0, /* properties_required */
2545 0, /* properties_provided */
2546 0, /* properties_destroyed */
2547 0, /* todo_flags_start */
2548 TODO_dump_cgraph |
2549 TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */
2551 ipcp_generate_summary, /* generate_summary */
2552 ipcp_write_summary, /* write_summary */
2553 ipcp_read_summary, /* read_summary */
2554 NULL, /* write_optimization_summary */
2555 NULL, /* read_optimization_summary */
2556 NULL, /* stmt_fixup */
2557 0, /* TODOs */
2558 NULL, /* function_transform */
2559 NULL, /* variable_transform */