Backport from GCC mainline.
[platform/upstream/linaro-gcc.git] / gcc / ipa-cp.c
1 /* Interprocedural constant propagation
2    Copyright (C) 2005-2016 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 "backend.h"
107 #include "tree.h"
108 #include "gimple-expr.h"
109 #include "predict.h"
110 #include "alloc-pool.h"
111 #include "tree-pass.h"
112 #include "cgraph.h"
113 #include "diagnostic.h"
114 #include "fold-const.h"
115 #include "gimple-fold.h"
116 #include "symbol-summary.h"
117 #include "ipa-prop.h"
118 #include "tree-pretty-print.h"
119 #include "tree-inline.h"
120 #include "params.h"
121 #include "ipa-inline.h"
122 #include "ipa-utils.h"
123
124 template <typename valtype> class ipcp_value;
125
126 /* Describes a particular source for an IPA-CP value.  */
127
128 template <typename valtype>
129 class ipcp_value_source
130 {
131 public:
132   /* Aggregate offset of the source, negative if the source is scalar value of
133      the argument itself.  */
134   HOST_WIDE_INT offset;
135   /* The incoming edge that brought the value.  */
136   cgraph_edge *cs;
137   /* If the jump function that resulted into his value was a pass-through or an
138      ancestor, this is the ipcp_value of the caller from which the described
139      value has been derived.  Otherwise it is NULL.  */
140   ipcp_value<valtype> *val;
141   /* Next pointer in a linked list of sources of a value.  */
142   ipcp_value_source *next;
143   /* If the jump function that resulted into his value was a pass-through or an
144      ancestor, this is the index of the parameter of the caller the jump
145      function references.  */
146   int index;
147 };
148
149 /* Common ancestor for all ipcp_value instantiations.  */
150
151 class ipcp_value_base
152 {
153 public:
154   /* Time benefit and size cost that specializing the function for this value
155      would bring about in this function alone.  */
156   int local_time_benefit, local_size_cost;
157   /* Time benefit and size cost that specializing the function for this value
158      can bring about in it's callees (transitively).  */
159   int prop_time_benefit, prop_size_cost;
160 };
161
162 /* Describes one particular value stored in struct ipcp_lattice.  */
163
164 template <typename valtype>
165 class ipcp_value : public ipcp_value_base
166 {
167 public:
168   /* The actual value for the given parameter.  */
169   valtype value;
170   /* The list of sources from which this value originates.  */
171   ipcp_value_source <valtype> *sources;
172   /* Next pointers in a linked list of all values in a lattice.  */
173   ipcp_value *next;
174   /* Next pointers in a linked list of values in a strongly connected component
175      of values. */
176   ipcp_value *scc_next;
177   /* Next pointers in a linked list of SCCs of values sorted topologically
178      according their sources.  */
179   ipcp_value  *topo_next;
180   /* A specialized node created for this value, NULL if none has been (so far)
181      created.  */
182   cgraph_node *spec_node;
183   /* Depth first search number and low link for topological sorting of
184      values.  */
185   int dfs, low_link;
186   /* True if this valye is currently on the topo-sort stack.  */
187   bool on_stack;
188
189   void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
190                    HOST_WIDE_INT offset);
191 };
192
193 /* Lattice describing potential values of a formal parameter of a function, or
194    a part of an aggreagate.  TOP is represented by a lattice with zero values
195    and with contains_variable and bottom flags cleared.  BOTTOM is represented
196    by a lattice with the bottom flag set.  In that case, values and
197    contains_variable flag should be disregarded.  */
198
199 template <typename valtype>
200 class ipcp_lattice
201 {
202 public:
203   /* The list of known values and types in this lattice.  Note that values are
204      not deallocated if a lattice is set to bottom because there may be value
205      sources referencing them.  */
206   ipcp_value<valtype> *values;
207   /* Number of known values and types in this lattice.  */
208   int values_count;
209   /* The lattice contains a variable component (in addition to values).  */
210   bool contains_variable;
211   /* The value of the lattice is bottom (i.e. variable and unusable for any
212      propagation).  */
213   bool bottom;
214
215   inline bool is_single_const ();
216   inline bool set_to_bottom ();
217   inline bool set_contains_variable ();
218   bool add_value (valtype newval, cgraph_edge *cs,
219                   ipcp_value<valtype> *src_val = NULL,
220                   int src_idx = 0, HOST_WIDE_INT offset = -1);
221   void print (FILE * f, bool dump_sources, bool dump_benefits);
222 };
223
224 /* Lattice of tree values with an offset to describe a part of an
225    aggregate.  */
226
227 class ipcp_agg_lattice : public ipcp_lattice<tree>
228 {
229 public:
230   /* Offset that is being described by this lattice. */
231   HOST_WIDE_INT offset;
232   /* Size so that we don't have to re-compute it every time we traverse the
233      list.  Must correspond to TYPE_SIZE of all lat values.  */
234   HOST_WIDE_INT size;
235   /* Next element of the linked list.  */
236   struct ipcp_agg_lattice *next;
237 };
238
239 /* Lattice of pointer alignment.  Unlike the previous types of lattices, this
240    one is only capable of holding one value.  */
241
242 class ipcp_alignment_lattice
243 {
244 public:
245   /* If bottom and top are both false, these two fields hold values as given by
246      ptr_info_def and get_pointer_alignment_1.  */
247   unsigned align;
248   unsigned misalign;
249
250   inline bool bottom_p () const;
251   inline bool top_p () const;
252   inline bool set_to_bottom ();
253   bool meet_with (unsigned new_align, unsigned new_misalign);
254   bool meet_with (const ipcp_alignment_lattice &other, HOST_WIDE_INT offset);
255   void print (FILE * f);
256 private:
257   /* If set, this lattice is bottom and all other fields should be
258      disregarded.  */
259   bool bottom;
260   /* If bottom and not_top are false, the lattice is TOP.  If not_top is true,
261      the known alignment is stored in the fields align and misalign.  The field
262      is negated so that memset to zero initializes the lattice to TOP
263      state.  */
264   bool not_top;
265
266   bool meet_with_1 (unsigned new_align, unsigned new_misalign);
267 };
268
269 /* Structure containing lattices for a parameter itself and for pieces of
270    aggregates that are passed in the parameter or by a reference in a parameter
271    plus some other useful flags.  */
272
273 class ipcp_param_lattices
274 {
275 public:
276   /* Lattice describing the value of the parameter itself.  */
277   ipcp_lattice<tree> itself;
278   /* Lattice describing the polymorphic contexts of a parameter.  */
279   ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
280   /* Lattices describing aggregate parts.  */
281   ipcp_agg_lattice *aggs;
282   /* Lattice describing known alignment.  */
283   ipcp_alignment_lattice alignment;
284   /* Number of aggregate lattices */
285   int aggs_count;
286   /* True if aggregate data were passed by reference (as opposed to by
287      value).  */
288   bool aggs_by_ref;
289   /* All aggregate lattices contain a variable component (in addition to
290      values).  */
291   bool aggs_contain_variable;
292   /* The value of all aggregate lattices is bottom (i.e. variable and unusable
293      for any propagation).  */
294   bool aggs_bottom;
295
296   /* There is a virtual call based on this parameter.  */
297   bool virt_call;
298 };
299
300 /* Allocation pools for values and their sources in ipa-cp.  */
301
302 object_allocator<ipcp_value<tree> > ipcp_cst_values_pool
303   ("IPA-CP constant values");
304
305 object_allocator<ipcp_value<ipa_polymorphic_call_context> >
306   ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
307
308 object_allocator<ipcp_value_source<tree> > ipcp_sources_pool
309   ("IPA-CP value sources");
310
311 object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
312   ("IPA_CP aggregate lattices");
313
314 /* Maximal count found in program.  */
315
316 static gcov_type max_count;
317
318 /* Original overall size of the program.  */
319
320 static long overall_size, max_new_size;
321
322 /* Return the param lattices structure corresponding to the Ith formal
323    parameter of the function described by INFO.  */
324 static inline struct ipcp_param_lattices *
325 ipa_get_parm_lattices (struct ipa_node_params *info, int i)
326 {
327   gcc_assert (i >= 0 && i < ipa_get_param_count (info));
328   gcc_checking_assert (!info->ipcp_orig_node);
329   gcc_checking_assert (info->lattices);
330   return &(info->lattices[i]);
331 }
332
333 /* Return the lattice corresponding to the scalar value of the Ith formal
334    parameter of the function described by INFO.  */
335 static inline ipcp_lattice<tree> *
336 ipa_get_scalar_lat (struct ipa_node_params *info, int i)
337 {
338   struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
339   return &plats->itself;
340 }
341
342 /* Return the lattice corresponding to the scalar value of the Ith formal
343    parameter of the function described by INFO.  */
344 static inline ipcp_lattice<ipa_polymorphic_call_context> *
345 ipa_get_poly_ctx_lat (struct ipa_node_params *info, int i)
346 {
347   struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
348   return &plats->ctxlat;
349 }
350
351 /* Return whether LAT is a lattice with a single constant and without an
352    undefined value.  */
353
354 template <typename valtype>
355 inline bool
356 ipcp_lattice<valtype>::is_single_const ()
357 {
358   if (bottom || contains_variable || values_count != 1)
359     return false;
360   else
361     return true;
362 }
363
364 /* Print V which is extracted from a value in a lattice to F.  */
365
366 static void
367 print_ipcp_constant_value (FILE * f, tree v)
368 {
369   if (TREE_CODE (v) == ADDR_EXPR
370            && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
371     {
372       fprintf (f, "& ");
373       print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)), 0);
374     }
375   else
376     print_generic_expr (f, v, 0);
377 }
378
379 /* Print V which is extracted from a value in a lattice to F.  */
380
381 static void
382 print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
383 {
384   v.dump(f, false);
385 }
386
387 /* Print a lattice LAT to F.  */
388
389 template <typename valtype>
390 void
391 ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
392 {
393   ipcp_value<valtype> *val;
394   bool prev = false;
395
396   if (bottom)
397     {
398       fprintf (f, "BOTTOM\n");
399       return;
400     }
401
402   if (!values_count && !contains_variable)
403     {
404       fprintf (f, "TOP\n");
405       return;
406     }
407
408   if (contains_variable)
409     {
410       fprintf (f, "VARIABLE");
411       prev = true;
412       if (dump_benefits)
413         fprintf (f, "\n");
414     }
415
416   for (val = values; val; val = val->next)
417     {
418       if (dump_benefits && prev)
419         fprintf (f, "               ");
420       else if (!dump_benefits && prev)
421         fprintf (f, ", ");
422       else
423         prev = true;
424
425       print_ipcp_constant_value (f, val->value);
426
427       if (dump_sources)
428         {
429           ipcp_value_source<valtype> *s;
430
431           fprintf (f, " [from:");
432           for (s = val->sources; s; s = s->next)
433             fprintf (f, " %i(%i)", s->cs->caller->order,
434                      s->cs->frequency);
435           fprintf (f, "]");
436         }
437
438       if (dump_benefits)
439         fprintf (f, " [loc_time: %i, loc_size: %i, "
440                  "prop_time: %i, prop_size: %i]\n",
441                  val->local_time_benefit, val->local_size_cost,
442                  val->prop_time_benefit, val->prop_size_cost);
443     }
444   if (!dump_benefits)
445     fprintf (f, "\n");
446 }
447
448 /* Print alignment lattice to F.  */
449
450 void
451 ipcp_alignment_lattice::print (FILE * f)
452 {
453   if (top_p ())
454     fprintf (f, "         Alignment unknown (TOP)\n");
455   else if (bottom_p ())
456     fprintf (f, "         Alignment unusable (BOTTOM)\n");
457   else
458     fprintf (f, "         Alignment %u, misalignment %u\n", align, misalign);
459 }
460
461 /* Print all ipcp_lattices of all functions to F.  */
462
463 static void
464 print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
465 {
466   struct cgraph_node *node;
467   int i, count;
468
469   fprintf (f, "\nLattices:\n");
470   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
471     {
472       struct ipa_node_params *info;
473
474       info = IPA_NODE_REF (node);
475       fprintf (f, "  Node: %s/%i:\n", node->name (),
476                node->order);
477       count = ipa_get_param_count (info);
478       for (i = 0; i < count; i++)
479         {
480           struct ipcp_agg_lattice *aglat;
481           struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
482           fprintf (f, "    param [%d]: ", i);
483           plats->itself.print (f, dump_sources, dump_benefits);
484           fprintf (f, "         ctxs: ");
485           plats->ctxlat.print (f, dump_sources, dump_benefits);
486           plats->alignment.print (f);
487           if (plats->virt_call)
488             fprintf (f, "        virt_call flag set\n");
489
490           if (plats->aggs_bottom)
491             {
492               fprintf (f, "        AGGS BOTTOM\n");
493               continue;
494             }
495           if (plats->aggs_contain_variable)
496             fprintf (f, "        AGGS VARIABLE\n");
497           for (aglat = plats->aggs; aglat; aglat = aglat->next)
498             {
499               fprintf (f, "        %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
500                        plats->aggs_by_ref ? "ref " : "", aglat->offset);
501               aglat->print (f, dump_sources, dump_benefits);
502             }
503         }
504     }
505 }
506
507 /* Determine whether it is at all technically possible to create clones of NODE
508    and store this information in the ipa_node_params structure associated
509    with NODE.  */
510
511 static void
512 determine_versionability (struct cgraph_node *node,
513                           struct ipa_node_params *info)
514 {
515   const char *reason = NULL;
516
517   /* There are a number of generic reasons functions cannot be versioned.  We
518      also cannot remove parameters if there are type attributes such as fnspec
519      present.  */
520   if (node->alias || node->thunk.thunk_p)
521     reason = "alias or thunk";
522   else if (!node->local.versionable)
523     reason = "not a tree_versionable_function";
524   else if (node->get_availability () <= AVAIL_INTERPOSABLE)
525     reason = "insufficient body availability";
526   else if (!opt_for_fn (node->decl, optimize)
527            || !opt_for_fn (node->decl, flag_ipa_cp))
528     reason = "non-optimized function";
529   else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
530     {
531       /* Ideally we should clone the SIMD clones themselves and create
532          vector copies of them, so IPA-cp and SIMD clones can happily
533          coexist, but that may not be worth the effort.  */
534       reason = "function has SIMD clones";
535     }
536   /* Don't clone decls local to a comdat group; it breaks and for C++
537      decloned constructors, inlining is always better anyway.  */
538   else if (node->comdat_local_p ())
539     reason = "comdat-local function";
540
541   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
542     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
543              node->name (), node->order, reason);
544
545   info->versionable = (reason == NULL);
546 }
547
548 /* Return true if it is at all technically possible to create clones of a
549    NODE.  */
550
551 static bool
552 ipcp_versionable_function_p (struct cgraph_node *node)
553 {
554   return IPA_NODE_REF (node)->versionable;
555 }
556
557 /* Structure holding accumulated information about callers of a node.  */
558
559 struct caller_statistics
560 {
561   gcov_type count_sum;
562   int n_calls, n_hot_calls, freq_sum;
563 };
564
565 /* Initialize fields of STAT to zeroes.  */
566
567 static inline void
568 init_caller_stats (struct caller_statistics *stats)
569 {
570   stats->count_sum = 0;
571   stats->n_calls = 0;
572   stats->n_hot_calls = 0;
573   stats->freq_sum = 0;
574 }
575
576 /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
577    non-thunk incoming edges to NODE.  */
578
579 static bool
580 gather_caller_stats (struct cgraph_node *node, void *data)
581 {
582   struct caller_statistics *stats = (struct caller_statistics *) data;
583   struct cgraph_edge *cs;
584
585   for (cs = node->callers; cs; cs = cs->next_caller)
586     if (!cs->caller->thunk.thunk_p)
587       {
588         stats->count_sum += cs->count;
589         stats->freq_sum += cs->frequency;
590         stats->n_calls++;
591         if (cs->maybe_hot_p ())
592           stats->n_hot_calls ++;
593       }
594   return false;
595
596 }
597
598 /* Return true if this NODE is viable candidate for cloning.  */
599
600 static bool
601 ipcp_cloning_candidate_p (struct cgraph_node *node)
602 {
603   struct caller_statistics stats;
604
605   gcc_checking_assert (node->has_gimple_body_p ());
606
607   if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
608     {
609       if (dump_file)
610         fprintf (dump_file, "Not considering %s for cloning; "
611                  "-fipa-cp-clone disabled.\n",
612                  node->name ());
613       return false;
614     }
615
616   if (node->optimize_for_size_p ())
617     {
618       if (dump_file)
619         fprintf (dump_file, "Not considering %s for cloning; "
620                  "optimizing it for size.\n",
621                  node->name ());
622       return false;
623     }
624
625   init_caller_stats (&stats);
626   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
627
628   if (inline_summaries->get (node)->self_size < stats.n_calls)
629     {
630       if (dump_file)
631         fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
632                  node->name ());
633       return true;
634     }
635
636   /* When profile is available and function is hot, propagate into it even if
637      calls seems cold; constant propagation can improve function's speed
638      significantly.  */
639   if (max_count)
640     {
641       if (stats.count_sum > node->count * 90 / 100)
642         {
643           if (dump_file)
644             fprintf (dump_file, "Considering %s for cloning; "
645                      "usually called directly.\n",
646                      node->name ());
647           return true;
648         }
649     }
650   if (!stats.n_hot_calls)
651     {
652       if (dump_file)
653         fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
654                  node->name ());
655       return false;
656     }
657   if (dump_file)
658     fprintf (dump_file, "Considering %s for cloning.\n",
659              node->name ());
660   return true;
661 }
662
663 template <typename valtype>
664 class value_topo_info
665 {
666 public:
667   /* Head of the linked list of topologically sorted values. */
668   ipcp_value<valtype> *values_topo;
669   /* Stack for creating SCCs, represented by a linked list too.  */
670   ipcp_value<valtype> *stack;
671   /* Counter driving the algorithm in add_val_to_toposort.  */
672   int dfs_counter;
673
674   value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
675   {}
676   void add_val (ipcp_value<valtype> *cur_val);
677   void propagate_effects ();
678 };
679
680 /* Arrays representing a topological ordering of call graph nodes and a stack
681    of nodes used during constant propagation and also data required to perform
682    topological sort of values and propagation of benefits in the determined
683    order.  */
684
685 class ipa_topo_info
686 {
687 public:
688   /* Array with obtained topological order of cgraph nodes.  */
689   struct cgraph_node **order;
690   /* Stack of cgraph nodes used during propagation within SCC until all values
691      in the SCC stabilize.  */
692   struct cgraph_node **stack;
693   int nnodes, stack_top;
694
695   value_topo_info<tree> constants;
696   value_topo_info<ipa_polymorphic_call_context> contexts;
697
698   ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
699     constants ()
700   {}
701 };
702
703 /* Allocate the arrays in TOPO and topologically sort the nodes into order.  */
704
705 static void
706 build_toporder_info (struct ipa_topo_info *topo)
707 {
708   topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
709   topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
710
711   gcc_checking_assert (topo->stack_top == 0);
712   topo->nnodes = ipa_reduced_postorder (topo->order, true, true, NULL);
713 }
714
715 /* Free information about strongly connected components and the arrays in
716    TOPO.  */
717
718 static void
719 free_toporder_info (struct ipa_topo_info *topo)
720 {
721   ipa_free_postorder_info ();
722   free (topo->order);
723   free (topo->stack);
724 }
725
726 /* Add NODE to the stack in TOPO, unless it is already there.  */
727
728 static inline void
729 push_node_to_stack (struct ipa_topo_info *topo, struct cgraph_node *node)
730 {
731   struct ipa_node_params *info = IPA_NODE_REF (node);
732   if (info->node_enqueued)
733     return;
734   info->node_enqueued = 1;
735   topo->stack[topo->stack_top++] = node;
736 }
737
738 /* Pop a node from the stack in TOPO and return it or return NULL if the stack
739    is empty.  */
740
741 static struct cgraph_node *
742 pop_node_from_stack (struct ipa_topo_info *topo)
743 {
744   if (topo->stack_top)
745     {
746       struct cgraph_node *node;
747       topo->stack_top--;
748       node = topo->stack[topo->stack_top];
749       IPA_NODE_REF (node)->node_enqueued = 0;
750       return node;
751     }
752   else
753     return NULL;
754 }
755
756 /* Set lattice LAT to bottom and return true if it previously was not set as
757    such.  */
758
759 template <typename valtype>
760 inline bool
761 ipcp_lattice<valtype>::set_to_bottom ()
762 {
763   bool ret = !bottom;
764   bottom = true;
765   return ret;
766 }
767
768 /* Mark lattice as containing an unknown value and return true if it previously
769    was not marked as such.  */
770
771 template <typename valtype>
772 inline bool
773 ipcp_lattice<valtype>::set_contains_variable ()
774 {
775   bool ret = !contains_variable;
776   contains_variable = true;
777   return ret;
778 }
779
780 /* Set all aggegate lattices in PLATS to bottom and return true if they were
781    not previously set as such.  */
782
783 static inline bool
784 set_agg_lats_to_bottom (struct ipcp_param_lattices *plats)
785 {
786   bool ret = !plats->aggs_bottom;
787   plats->aggs_bottom = true;
788   return ret;
789 }
790
791 /* Mark all aggegate lattices in PLATS as containing an unknown value and
792    return true if they were not previously marked as such.  */
793
794 static inline bool
795 set_agg_lats_contain_variable (struct ipcp_param_lattices *plats)
796 {
797   bool ret = !plats->aggs_contain_variable;
798   plats->aggs_contain_variable = true;
799   return ret;
800 }
801
802 /* Return true if alignment information in the lattice is yet unknown.  */
803
804 bool
805 ipcp_alignment_lattice::top_p () const
806 {
807   return !bottom && !not_top;
808 }
809
810 /* Return true if alignment information in the lattice is known to be
811    unusable.  */
812
813 bool
814 ipcp_alignment_lattice::bottom_p () const
815 {
816   return bottom;
817 }
818
819 /* Set alignment information in the lattice to bottom.  Return true if it
820    previously was in a different state.  */
821
822 bool
823 ipcp_alignment_lattice::set_to_bottom ()
824 {
825   if (bottom_p ())
826     return false;
827   bottom = true;
828   return true;
829 }
830
831 /* Meet the current value of the lattice with alignment described by NEW_ALIGN
832    and NEW_MISALIGN, assuming that we know the current value is neither TOP nor
833    BOTTOM.  Return true if the value of lattice has changed.  */
834
835 bool
836 ipcp_alignment_lattice::meet_with_1 (unsigned new_align, unsigned new_misalign)
837 {
838   gcc_checking_assert (new_align != 0);
839   if (align == new_align && misalign == new_misalign)
840     return false;
841
842   bool changed = false;
843   if (align > new_align)
844     {
845       align = new_align;
846       misalign = misalign % new_align;
847       changed = true;
848     }
849   if (misalign != (new_misalign % align))
850     {
851       int diff = abs ((int) misalign - (int) (new_misalign % align));
852       align = (unsigned) diff & -diff;
853       if (align)
854         misalign = misalign % align;
855       else
856         set_to_bottom ();
857       changed = true;
858     }
859   gcc_checking_assert (bottom_p () || align != 0);
860   return changed;
861 }
862
863 /* Meet the current value of the lattice with alignment described by NEW_ALIGN
864    and NEW_MISALIGN.  Return true if the value of lattice has changed.  */
865
866 bool
867 ipcp_alignment_lattice::meet_with (unsigned new_align, unsigned new_misalign)
868 {
869   gcc_assert (new_align != 0);
870   if (bottom_p ())
871     return false;
872   if (top_p ())
873     {
874       not_top = true;
875       align = new_align;
876       misalign = new_misalign;
877       return true;
878     }
879   return meet_with_1 (new_align, new_misalign);
880 }
881
882 /* Meet the current value of the lattice with OTHER, taking into account that
883    OFFSET has been added to the pointer value.  Return true if the value of
884    lattice has changed.  */
885
886 bool
887 ipcp_alignment_lattice::meet_with (const ipcp_alignment_lattice &other,
888                                    HOST_WIDE_INT offset)
889 {
890   if (other.bottom_p ())
891     return set_to_bottom ();
892   if (bottom_p () || other.top_p ())
893     return false;
894
895   unsigned adjusted_misalign = (other.misalign + offset) % other.align;
896   if (top_p ())
897     {
898       not_top = true;
899       align = other.align;
900       misalign = adjusted_misalign;
901       return true;
902     }
903
904   return meet_with_1 (other.align, adjusted_misalign);
905 }
906
907 /* Mark bot aggregate and scalar lattices as containing an unknown variable,
908    return true is any of them has not been marked as such so far.  */
909
910 static inline bool
911 set_all_contains_variable (struct ipcp_param_lattices *plats)
912 {
913   bool ret;
914   ret = plats->itself.set_contains_variable ();
915   ret |= plats->ctxlat.set_contains_variable ();
916   ret |= set_agg_lats_contain_variable (plats);
917   ret |= plats->alignment.set_to_bottom ();
918   return ret;
919 }
920
921 /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
922    points to by the number of callers to NODE.  */
923
924 static bool
925 count_callers (cgraph_node *node, void *data)
926 {
927   int *caller_count = (int *) data;
928
929   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
930     /* Local thunks can be handled transparently, but if the thunk can not
931        be optimized out, count it as a real use.  */
932     if (!cs->caller->thunk.thunk_p || !cs->caller->local.local)
933       ++*caller_count;
934   return false;
935 }
936
937 /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
938    the one caller of some other node.  Set the caller's corresponding flag.  */
939
940 static bool
941 set_single_call_flag (cgraph_node *node, void *)
942 {
943   cgraph_edge *cs = node->callers;
944   /* Local thunks can be handled transparently, skip them.  */
945   while (cs && cs->caller->thunk.thunk_p && cs->caller->local.local)
946     cs = cs->next_caller;
947   if (cs)
948     {
949       IPA_NODE_REF (cs->caller)->node_calling_single_call = true;
950       return true;
951     }
952   return false;
953 }
954
955 /* Initialize ipcp_lattices.  */
956
957 static void
958 initialize_node_lattices (struct cgraph_node *node)
959 {
960   struct ipa_node_params *info = IPA_NODE_REF (node);
961   struct cgraph_edge *ie;
962   bool disable = false, variable = false;
963   int i;
964
965   gcc_checking_assert (node->has_gimple_body_p ());
966   if (cgraph_local_p (node))
967     {
968       int caller_count = 0;
969       node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
970                                                 true);
971       gcc_checking_assert (caller_count > 0);
972       if (caller_count == 1)
973         node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
974                                                   NULL, true);
975     }
976   else
977     {
978       /* When cloning is allowed, we can assume that externally visible
979          functions are not called.  We will compensate this by cloning
980          later.  */
981       if (ipcp_versionable_function_p (node)
982           && ipcp_cloning_candidate_p (node))
983         variable = true;
984       else
985         disable = true;
986     }
987
988   if (disable || variable)
989     {
990       for (i = 0; i < ipa_get_param_count (info) ; i++)
991         {
992           struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
993           if (disable)
994             {
995               plats->itself.set_to_bottom ();
996               plats->ctxlat.set_to_bottom ();
997               set_agg_lats_to_bottom (plats);
998               plats->alignment.set_to_bottom ();
999             }
1000           else
1001             set_all_contains_variable (plats);
1002         }
1003       if (dump_file && (dump_flags & TDF_DETAILS)
1004           && !node->alias && !node->thunk.thunk_p)
1005         fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
1006                  node->name (), node->order,
1007                  disable ? "BOTTOM" : "VARIABLE");
1008     }
1009
1010   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
1011     if (ie->indirect_info->polymorphic
1012         && ie->indirect_info->param_index >= 0)
1013       {
1014         gcc_checking_assert (ie->indirect_info->param_index >= 0);
1015         ipa_get_parm_lattices (info,
1016                                ie->indirect_info->param_index)->virt_call = 1;
1017       }
1018 }
1019
1020 /* Return the result of a (possibly arithmetic) pass through jump function
1021    JFUNC on the constant value INPUT.  Return NULL_TREE if that cannot be
1022    determined or be considered an interprocedural invariant.  */
1023
1024 static tree
1025 ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
1026 {
1027   tree restype, res;
1028
1029   gcc_checking_assert (is_gimple_ip_invariant (input));
1030   if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
1031     return input;
1032
1033   if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
1034       == tcc_comparison)
1035     restype = boolean_type_node;
1036   else
1037     restype = TREE_TYPE (input);
1038   res = fold_binary (ipa_get_jf_pass_through_operation (jfunc), restype,
1039                      input, ipa_get_jf_pass_through_operand (jfunc));
1040
1041   if (res && !is_gimple_ip_invariant (res))
1042     return NULL_TREE;
1043
1044   return res;
1045 }
1046
1047 /* Return the result of an ancestor jump function JFUNC on the constant value
1048    INPUT.  Return NULL_TREE if that cannot be determined.  */
1049
1050 static tree
1051 ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
1052 {
1053   gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
1054   if (TREE_CODE (input) == ADDR_EXPR)
1055     {
1056       tree t = TREE_OPERAND (input, 0);
1057       t = build_ref_for_offset (EXPR_LOCATION (t), t,
1058                                 ipa_get_jf_ancestor_offset (jfunc), false,
1059                                 ptr_type_node, NULL, false);
1060       return build_fold_addr_expr (t);
1061     }
1062   else
1063     return NULL_TREE;
1064 }
1065
1066 /* Determine whether JFUNC evaluates to a single known constant value and if
1067    so, return it.  Otherwise return NULL.  INFO describes the caller node or
1068    the one it is inlined to, so that pass-through jump functions can be
1069    evaluated.  */
1070
1071 tree
1072 ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
1073 {
1074   if (jfunc->type == IPA_JF_CONST)
1075     return ipa_get_jf_constant (jfunc);
1076   else if (jfunc->type == IPA_JF_PASS_THROUGH
1077            || jfunc->type == IPA_JF_ANCESTOR)
1078     {
1079       tree input;
1080       int idx;
1081
1082       if (jfunc->type == IPA_JF_PASS_THROUGH)
1083         idx = ipa_get_jf_pass_through_formal_id (jfunc);
1084       else
1085         idx = ipa_get_jf_ancestor_formal_id (jfunc);
1086
1087       if (info->ipcp_orig_node)
1088         input = info->known_csts[idx];
1089       else
1090         {
1091           ipcp_lattice<tree> *lat;
1092
1093           if (!info->lattices
1094               || idx >= ipa_get_param_count (info))
1095             return NULL_TREE;
1096           lat = ipa_get_scalar_lat (info, idx);
1097           if (!lat->is_single_const ())
1098             return NULL_TREE;
1099           input = lat->values->value;
1100         }
1101
1102       if (!input)
1103         return NULL_TREE;
1104
1105       if (jfunc->type == IPA_JF_PASS_THROUGH)
1106         return ipa_get_jf_pass_through_result (jfunc, input);
1107       else
1108         return ipa_get_jf_ancestor_result (jfunc, input);
1109     }
1110   else
1111     return NULL_TREE;
1112 }
1113
1114 /* Determie whether JFUNC evaluates to single known polymorphic context, given
1115    that INFO describes the caller node or the one it is inlined to, CS is the
1116    call graph edge corresponding to JFUNC and CSIDX index of the described
1117    parameter.  */
1118
1119 ipa_polymorphic_call_context
1120 ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
1121                         ipa_jump_func *jfunc)
1122 {
1123   ipa_edge_args *args = IPA_EDGE_REF (cs);
1124   ipa_polymorphic_call_context ctx;
1125   ipa_polymorphic_call_context *edge_ctx
1126     = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
1127
1128   if (edge_ctx && !edge_ctx->useless_p ())
1129     ctx = *edge_ctx;
1130
1131   if (jfunc->type == IPA_JF_PASS_THROUGH
1132       || jfunc->type == IPA_JF_ANCESTOR)
1133     {
1134       ipa_polymorphic_call_context srcctx;
1135       int srcidx;
1136       bool type_preserved = true;
1137       if (jfunc->type == IPA_JF_PASS_THROUGH)
1138         {
1139           if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1140             return ctx;
1141           type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1142           srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
1143         }
1144       else
1145         {
1146           type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1147           srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
1148         }
1149       if (info->ipcp_orig_node)
1150         {
1151           if (info->known_contexts.exists ())
1152             srcctx = info->known_contexts[srcidx];
1153         }
1154       else
1155         {
1156           if (!info->lattices
1157               || srcidx >= ipa_get_param_count (info))
1158             return ctx;
1159           ipcp_lattice<ipa_polymorphic_call_context> *lat;
1160           lat = ipa_get_poly_ctx_lat (info, srcidx);
1161           if (!lat->is_single_const ())
1162             return ctx;
1163           srcctx = lat->values->value;
1164         }
1165       if (srcctx.useless_p ())
1166         return ctx;
1167       if (jfunc->type == IPA_JF_ANCESTOR)
1168         srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1169       if (!type_preserved)
1170         srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1171       srcctx.combine_with (ctx);
1172       return srcctx;
1173     }
1174
1175   return ctx;
1176 }
1177
1178 /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
1179    bottom, not containing a variable component and without any known value at
1180    the same time.  */
1181
1182 DEBUG_FUNCTION void
1183 ipcp_verify_propagated_values (void)
1184 {
1185   struct cgraph_node *node;
1186
1187   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
1188     {
1189       struct ipa_node_params *info = IPA_NODE_REF (node);
1190       int i, count = ipa_get_param_count (info);
1191
1192       for (i = 0; i < count; i++)
1193         {
1194           ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
1195
1196           if (!lat->bottom
1197               && !lat->contains_variable
1198               && lat->values_count == 0)
1199             {
1200               if (dump_file)
1201                 {
1202                   symtab_node::dump_table (dump_file);
1203                   fprintf (dump_file, "\nIPA lattices after constant "
1204                            "propagation, before gcc_unreachable:\n");
1205                   print_all_lattices (dump_file, true, false);
1206                 }
1207
1208               gcc_unreachable ();
1209             }
1210         }
1211     }
1212 }
1213
1214 /* Return true iff X and Y should be considered equal values by IPA-CP.  */
1215
1216 static bool
1217 values_equal_for_ipcp_p (tree x, tree y)
1218 {
1219   gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
1220
1221   if (x == y)
1222     return true;
1223
1224   if (TREE_CODE (x) ==  ADDR_EXPR
1225       && TREE_CODE (y) ==  ADDR_EXPR
1226       && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
1227       && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
1228     return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
1229                             DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
1230   else
1231     return operand_equal_p (x, y, 0);
1232 }
1233
1234 /* Return true iff X and Y should be considered equal contexts by IPA-CP.  */
1235
1236 static bool
1237 values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
1238                          ipa_polymorphic_call_context y)
1239 {
1240   return x.equal_to (y);
1241 }
1242
1243
1244 /* Add a new value source to the value represented by THIS, marking that a
1245    value comes from edge CS and (if the underlying jump function is a
1246    pass-through or an ancestor one) from a caller value SRC_VAL of a caller
1247    parameter described by SRC_INDEX.  OFFSET is negative if the source was the
1248    scalar value of the parameter itself or the offset within an aggregate.  */
1249
1250 template <typename valtype>
1251 void
1252 ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
1253                                  int src_idx, HOST_WIDE_INT offset)
1254 {
1255   ipcp_value_source<valtype> *src;
1256
1257   src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
1258   src->offset = offset;
1259   src->cs = cs;
1260   src->val = src_val;
1261   src->index = src_idx;
1262
1263   src->next = sources;
1264   sources = src;
1265 }
1266
1267 /* Allocate a new ipcp_value holding a tree constant, initialize its value to
1268    SOURCE and clear all other fields.  */
1269
1270 static ipcp_value<tree> *
1271 allocate_and_init_ipcp_value (tree source)
1272 {
1273   ipcp_value<tree> *val;
1274
1275   val = ipcp_cst_values_pool.allocate ();
1276   memset (val, 0, sizeof (*val));
1277   val->value = source;
1278   return val;
1279 }
1280
1281 /* Allocate a new ipcp_value holding a polymorphic context, initialize its
1282    value to SOURCE and clear all other fields.  */
1283
1284 static ipcp_value<ipa_polymorphic_call_context> *
1285 allocate_and_init_ipcp_value (ipa_polymorphic_call_context source)
1286 {
1287   ipcp_value<ipa_polymorphic_call_context> *val;
1288
1289   // TODO
1290   val = ipcp_poly_ctx_values_pool.allocate ();
1291   memset (val, 0, sizeof (*val));
1292   val->value = source;
1293   return val;
1294 }
1295
1296 /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it.  CS,
1297    SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
1298    meaning.  OFFSET -1 means the source is scalar and not a part of an
1299    aggregate.  */
1300
1301 template <typename valtype>
1302 bool
1303 ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
1304                                   ipcp_value<valtype> *src_val,
1305                                   int src_idx, HOST_WIDE_INT offset)
1306 {
1307   ipcp_value<valtype> *val;
1308
1309   if (bottom)
1310     return false;
1311
1312   for (val = values; val; val = val->next)
1313     if (values_equal_for_ipcp_p (val->value, newval))
1314       {
1315         if (ipa_edge_within_scc (cs))
1316           {
1317             ipcp_value_source<valtype> *s;
1318             for (s = val->sources; s ; s = s->next)
1319               if (s->cs == cs)
1320                 break;
1321             if (s)
1322               return false;
1323           }
1324
1325         val->add_source (cs, src_val, src_idx, offset);
1326         return false;
1327       }
1328
1329   if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))
1330     {
1331       /* We can only free sources, not the values themselves, because sources
1332          of other values in this SCC might point to them.   */
1333       for (val = values; val; val = val->next)
1334         {
1335           while (val->sources)
1336             {
1337               ipcp_value_source<valtype> *src = val->sources;
1338               val->sources = src->next;
1339               ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
1340             }
1341         }
1342
1343       values = NULL;
1344       return set_to_bottom ();
1345     }
1346
1347   values_count++;
1348   val = allocate_and_init_ipcp_value (newval);
1349   val->add_source (cs, src_val, src_idx, offset);
1350   val->next = values;
1351   values = val;
1352   return true;
1353 }
1354
1355 /* Propagate values through a pass-through jump function JFUNC associated with
1356    edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
1357    is the index of the source parameter.  */
1358
1359 static bool
1360 propagate_vals_accross_pass_through (cgraph_edge *cs,
1361                                      ipa_jump_func *jfunc,
1362                                      ipcp_lattice<tree> *src_lat,
1363                                      ipcp_lattice<tree> *dest_lat,
1364                                      int src_idx)
1365 {
1366   ipcp_value<tree> *src_val;
1367   bool ret = false;
1368
1369   /* Do not create new values when propagating within an SCC because if there
1370      are arithmetic functions with circular dependencies, there is infinite
1371      number of them and we would just make lattices bottom.  */
1372   if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1373       && ipa_edge_within_scc (cs))
1374     ret = dest_lat->set_contains_variable ();
1375   else
1376     for (src_val = src_lat->values; src_val; src_val = src_val->next)
1377       {
1378         tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value);
1379
1380         if (cstval)
1381           ret |= dest_lat->add_value (cstval, cs, src_val, src_idx);
1382         else
1383           ret |= dest_lat->set_contains_variable ();
1384       }
1385
1386   return ret;
1387 }
1388
1389 /* Propagate values through an ancestor jump function JFUNC associated with
1390    edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
1391    is the index of the source parameter.  */
1392
1393 static bool
1394 propagate_vals_accross_ancestor (struct cgraph_edge *cs,
1395                                  struct ipa_jump_func *jfunc,
1396                                  ipcp_lattice<tree> *src_lat,
1397                                  ipcp_lattice<tree> *dest_lat,
1398                                  int src_idx)
1399 {
1400   ipcp_value<tree> *src_val;
1401   bool ret = false;
1402
1403   if (ipa_edge_within_scc (cs))
1404     return dest_lat->set_contains_variable ();
1405
1406   for (src_val = src_lat->values; src_val; src_val = src_val->next)
1407     {
1408       tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
1409
1410       if (t)
1411         ret |= dest_lat->add_value (t, cs, src_val, src_idx);
1412       else
1413         ret |= dest_lat->set_contains_variable ();
1414     }
1415
1416   return ret;
1417 }
1418
1419 /* Propagate scalar values across jump function JFUNC that is associated with
1420    edge CS and put the values into DEST_LAT.  */
1421
1422 static bool
1423 propagate_scalar_accross_jump_function (struct cgraph_edge *cs,
1424                                         struct ipa_jump_func *jfunc,
1425                                         ipcp_lattice<tree> *dest_lat)
1426 {
1427   if (dest_lat->bottom)
1428     return false;
1429
1430   if (jfunc->type == IPA_JF_CONST)
1431     {
1432       tree val = ipa_get_jf_constant (jfunc);
1433       return dest_lat->add_value (val, cs, NULL, 0);
1434     }
1435   else if (jfunc->type == IPA_JF_PASS_THROUGH
1436            || jfunc->type == IPA_JF_ANCESTOR)
1437     {
1438       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1439       ipcp_lattice<tree> *src_lat;
1440       int src_idx;
1441       bool ret;
1442
1443       if (jfunc->type == IPA_JF_PASS_THROUGH)
1444         src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
1445       else
1446         src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1447
1448       src_lat = ipa_get_scalar_lat (caller_info, src_idx);
1449       if (src_lat->bottom)
1450         return dest_lat->set_contains_variable ();
1451
1452       /* If we would need to clone the caller and cannot, do not propagate.  */
1453       if (!ipcp_versionable_function_p (cs->caller)
1454           && (src_lat->contains_variable
1455               || (src_lat->values_count > 1)))
1456         return dest_lat->set_contains_variable ();
1457
1458       if (jfunc->type == IPA_JF_PASS_THROUGH)
1459         ret = propagate_vals_accross_pass_through (cs, jfunc, src_lat,
1460                                                    dest_lat, src_idx);
1461       else
1462         ret = propagate_vals_accross_ancestor (cs, jfunc, src_lat, dest_lat,
1463                                                src_idx);
1464
1465       if (src_lat->contains_variable)
1466         ret |= dest_lat->set_contains_variable ();
1467
1468       return ret;
1469     }
1470
1471   /* TODO: We currently do not handle member method pointers in IPA-CP (we only
1472      use it for indirect inlining), we should propagate them too.  */
1473   return dest_lat->set_contains_variable ();
1474 }
1475
1476 /* Propagate scalar values across jump function JFUNC that is associated with
1477    edge CS and describes argument IDX and put the values into DEST_LAT.  */
1478
1479 static bool
1480 propagate_context_accross_jump_function (cgraph_edge *cs,
1481                           ipa_jump_func *jfunc, int idx,
1482                           ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
1483 {
1484   ipa_edge_args *args = IPA_EDGE_REF (cs);
1485   if (dest_lat->bottom)
1486     return false;
1487   bool ret = false;
1488   bool added_sth = false;
1489   bool type_preserved = true;
1490
1491   ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
1492     = ipa_get_ith_polymorhic_call_context (args, idx);
1493
1494   if (edge_ctx_ptr)
1495     edge_ctx = *edge_ctx_ptr;
1496
1497   if (jfunc->type == IPA_JF_PASS_THROUGH
1498       || jfunc->type == IPA_JF_ANCESTOR)
1499     {
1500       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1501       int src_idx;
1502       ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
1503
1504       /* TODO: Once we figure out how to propagate speculations, it will
1505          probably be a good idea to switch to speculation if type_preserved is
1506          not set instead of punting.  */
1507       if (jfunc->type == IPA_JF_PASS_THROUGH)
1508         {
1509           if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
1510             goto prop_fail;
1511           type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
1512           src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
1513         }
1514       else
1515         {
1516           type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
1517           src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1518         }
1519
1520       src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
1521       /* If we would need to clone the caller and cannot, do not propagate.  */
1522       if (!ipcp_versionable_function_p (cs->caller)
1523           && (src_lat->contains_variable
1524               || (src_lat->values_count > 1)))
1525         goto prop_fail;
1526
1527       ipcp_value<ipa_polymorphic_call_context> *src_val;
1528       for (src_val = src_lat->values; src_val; src_val = src_val->next)
1529         {
1530           ipa_polymorphic_call_context cur = src_val->value;
1531
1532           if (!type_preserved)
1533             cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
1534           if (jfunc->type == IPA_JF_ANCESTOR)
1535             cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
1536           /* TODO: In cases we know how the context is going to be used,
1537              we can improve the result by passing proper OTR_TYPE.  */
1538           cur.combine_with (edge_ctx);
1539           if (!cur.useless_p ())
1540             {
1541               if (src_lat->contains_variable
1542                   && !edge_ctx.equal_to (cur))
1543                 ret |= dest_lat->set_contains_variable ();
1544               ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
1545               added_sth = true;
1546             }
1547         }
1548
1549     }
1550
1551  prop_fail:
1552   if (!added_sth)
1553     {
1554       if (!edge_ctx.useless_p ())
1555         ret |= dest_lat->add_value (edge_ctx, cs);
1556       else
1557         ret |= dest_lat->set_contains_variable ();
1558     }
1559
1560   return ret;
1561 }
1562
1563 /* Propagate alignments across jump function JFUNC that is associated with
1564    edge CS and update DEST_LAT accordingly.  */
1565
1566 static bool
1567 propagate_alignment_accross_jump_function (cgraph_edge *cs,
1568                                            ipa_jump_func *jfunc,
1569                                            ipcp_alignment_lattice *dest_lat)
1570 {
1571   if (dest_lat->bottom_p ())
1572     return false;
1573
1574   if (jfunc->type == IPA_JF_PASS_THROUGH
1575            || jfunc->type == IPA_JF_ANCESTOR)
1576     {
1577       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1578       HOST_WIDE_INT offset = 0;
1579       int src_idx;
1580
1581       if (jfunc->type == IPA_JF_PASS_THROUGH)
1582         {
1583           enum tree_code op = ipa_get_jf_pass_through_operation (jfunc);
1584           if (op != NOP_EXPR)
1585             {
1586               if (op != POINTER_PLUS_EXPR
1587                   && op != PLUS_EXPR)
1588                 return dest_lat->set_to_bottom ();
1589               tree operand = ipa_get_jf_pass_through_operand (jfunc);
1590               if (!tree_fits_shwi_p (operand))
1591                 return dest_lat->set_to_bottom ();
1592               offset = tree_to_shwi (operand);
1593             }
1594           src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
1595         }
1596       else
1597         {
1598           src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1599           offset = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
1600         }
1601
1602       struct ipcp_param_lattices *src_lats;
1603       src_lats = ipa_get_parm_lattices (caller_info, src_idx);
1604       return dest_lat->meet_with (src_lats->alignment, offset);
1605     }
1606   else
1607     {
1608       if (jfunc->alignment.known)
1609         return dest_lat->meet_with (jfunc->alignment.align,
1610                                     jfunc->alignment.misalign);
1611       else
1612         return dest_lat->set_to_bottom ();
1613     }
1614 }
1615
1616 /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
1617    NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
1618    other cases, return false).  If there are no aggregate items, set
1619    aggs_by_ref to NEW_AGGS_BY_REF.  */
1620
1621 static bool
1622 set_check_aggs_by_ref (struct ipcp_param_lattices *dest_plats,
1623                        bool new_aggs_by_ref)
1624 {
1625   if (dest_plats->aggs)
1626     {
1627       if (dest_plats->aggs_by_ref != new_aggs_by_ref)
1628         {
1629           set_agg_lats_to_bottom (dest_plats);
1630           return true;
1631         }
1632     }
1633   else
1634     dest_plats->aggs_by_ref = new_aggs_by_ref;
1635   return false;
1636 }
1637
1638 /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
1639    already existing lattice for the given OFFSET and SIZE, marking all skipped
1640    lattices as containing variable and checking for overlaps.  If there is no
1641    already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
1642    it with offset, size and contains_variable to PRE_EXISTING, and return true,
1643    unless there are too many already.  If there are two many, return false.  If
1644    there are overlaps turn whole DEST_PLATS to bottom and return false.  If any
1645    skipped lattices were newly marked as containing variable, set *CHANGE to
1646    true.  */
1647
1648 static bool
1649 merge_agg_lats_step (struct ipcp_param_lattices *dest_plats,
1650                      HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
1651                      struct ipcp_agg_lattice ***aglat,
1652                      bool pre_existing, bool *change)
1653 {
1654   gcc_checking_assert (offset >= 0);
1655
1656   while (**aglat && (**aglat)->offset < offset)
1657     {
1658       if ((**aglat)->offset + (**aglat)->size > offset)
1659         {
1660           set_agg_lats_to_bottom (dest_plats);
1661           return false;
1662         }
1663       *change |= (**aglat)->set_contains_variable ();
1664       *aglat = &(**aglat)->next;
1665     }
1666
1667   if (**aglat && (**aglat)->offset == offset)
1668     {
1669       if ((**aglat)->size != val_size
1670           || ((**aglat)->next
1671               && (**aglat)->next->offset < offset + val_size))
1672         {
1673           set_agg_lats_to_bottom (dest_plats);
1674           return false;
1675         }
1676       gcc_checking_assert (!(**aglat)->next
1677                            || (**aglat)->next->offset >= offset + val_size);
1678       return true;
1679     }
1680   else
1681     {
1682       struct ipcp_agg_lattice *new_al;
1683
1684       if (**aglat && (**aglat)->offset < offset + val_size)
1685         {
1686           set_agg_lats_to_bottom (dest_plats);
1687           return false;
1688         }
1689       if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
1690         return false;
1691       dest_plats->aggs_count++;
1692       new_al = ipcp_agg_lattice_pool.allocate ();
1693       memset (new_al, 0, sizeof (*new_al));
1694
1695       new_al->offset = offset;
1696       new_al->size = val_size;
1697       new_al->contains_variable = pre_existing;
1698
1699       new_al->next = **aglat;
1700       **aglat = new_al;
1701       return true;
1702     }
1703 }
1704
1705 /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
1706    containing an unknown value.  */
1707
1708 static bool
1709 set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
1710 {
1711   bool ret = false;
1712   while (aglat)
1713     {
1714       ret |= aglat->set_contains_variable ();
1715       aglat = aglat->next;
1716     }
1717   return ret;
1718 }
1719
1720 /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
1721    DELTA_OFFSET.  CS is the call graph edge and SRC_IDX the index of the source
1722    parameter used for lattice value sources.  Return true if DEST_PLATS changed
1723    in any way.  */
1724
1725 static bool
1726 merge_aggregate_lattices (struct cgraph_edge *cs,
1727                           struct ipcp_param_lattices *dest_plats,
1728                           struct ipcp_param_lattices *src_plats,
1729                           int src_idx, HOST_WIDE_INT offset_delta)
1730 {
1731   bool pre_existing = dest_plats->aggs != NULL;
1732   struct ipcp_agg_lattice **dst_aglat;
1733   bool ret = false;
1734
1735   if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
1736     return true;
1737   if (src_plats->aggs_bottom)
1738     return set_agg_lats_contain_variable (dest_plats);
1739   if (src_plats->aggs_contain_variable)
1740     ret |= set_agg_lats_contain_variable (dest_plats);
1741   dst_aglat = &dest_plats->aggs;
1742
1743   for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
1744        src_aglat;
1745        src_aglat = src_aglat->next)
1746     {
1747       HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
1748
1749       if (new_offset < 0)
1750         continue;
1751       if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
1752                                &dst_aglat, pre_existing, &ret))
1753         {
1754           struct ipcp_agg_lattice *new_al = *dst_aglat;
1755
1756           dst_aglat = &(*dst_aglat)->next;
1757           if (src_aglat->bottom)
1758             {
1759               ret |= new_al->set_contains_variable ();
1760               continue;
1761             }
1762           if (src_aglat->contains_variable)
1763             ret |= new_al->set_contains_variable ();
1764           for (ipcp_value<tree> *val = src_aglat->values;
1765                val;
1766                val = val->next)
1767             ret |= new_al->add_value (val->value, cs, val, src_idx,
1768                                       src_aglat->offset);
1769         }
1770       else if (dest_plats->aggs_bottom)
1771         return true;
1772     }
1773   ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
1774   return ret;
1775 }
1776
1777 /* Determine whether there is anything to propagate FROM SRC_PLATS through a
1778    pass-through JFUNC and if so, whether it has conform and conforms to the
1779    rules about propagating values passed by reference.  */
1780
1781 static bool
1782 agg_pass_through_permissible_p (struct ipcp_param_lattices *src_plats,
1783                                 struct ipa_jump_func *jfunc)
1784 {
1785   return src_plats->aggs
1786     && (!src_plats->aggs_by_ref
1787         || ipa_get_jf_pass_through_agg_preserved (jfunc));
1788 }
1789
1790 /* Propagate scalar values across jump function JFUNC that is associated with
1791    edge CS and put the values into DEST_LAT.  */
1792
1793 static bool
1794 propagate_aggs_accross_jump_function (struct cgraph_edge *cs,
1795                                       struct ipa_jump_func *jfunc,
1796                                       struct ipcp_param_lattices *dest_plats)
1797 {
1798   bool ret = false;
1799
1800   if (dest_plats->aggs_bottom)
1801     return false;
1802
1803   if (jfunc->type == IPA_JF_PASS_THROUGH
1804       && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
1805     {
1806       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1807       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
1808       struct ipcp_param_lattices *src_plats;
1809
1810       src_plats = ipa_get_parm_lattices (caller_info, src_idx);
1811       if (agg_pass_through_permissible_p (src_plats, jfunc))
1812         {
1813           /* Currently we do not produce clobber aggregate jump
1814              functions, replace with merging when we do.  */
1815           gcc_assert (!jfunc->agg.items);
1816           ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
1817                                            src_idx, 0);
1818         }
1819       else
1820         ret |= set_agg_lats_contain_variable (dest_plats);
1821     }
1822   else if (jfunc->type == IPA_JF_ANCESTOR
1823            && ipa_get_jf_ancestor_agg_preserved (jfunc))
1824     {
1825       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
1826       int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
1827       struct ipcp_param_lattices *src_plats;
1828
1829       src_plats = ipa_get_parm_lattices (caller_info, src_idx);
1830       if (src_plats->aggs && src_plats->aggs_by_ref)
1831         {
1832           /* Currently we do not produce clobber aggregate jump
1833              functions, replace with merging when we do.  */
1834           gcc_assert (!jfunc->agg.items);
1835           ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
1836                                            ipa_get_jf_ancestor_offset (jfunc));
1837         }
1838       else if (!src_plats->aggs_by_ref)
1839         ret |= set_agg_lats_to_bottom (dest_plats);
1840       else
1841         ret |= set_agg_lats_contain_variable (dest_plats);
1842     }
1843   else if (jfunc->agg.items)
1844     {
1845       bool pre_existing = dest_plats->aggs != NULL;
1846       struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
1847       struct ipa_agg_jf_item *item;
1848       int i;
1849
1850       if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
1851         return true;
1852
1853       FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
1854         {
1855           HOST_WIDE_INT val_size;
1856
1857           if (item->offset < 0)
1858             continue;
1859           gcc_checking_assert (is_gimple_ip_invariant (item->value));
1860           val_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (item->value)));
1861
1862           if (merge_agg_lats_step (dest_plats, item->offset, val_size,
1863                                    &aglat, pre_existing, &ret))
1864             {
1865               ret |= (*aglat)->add_value (item->value, cs, NULL, 0, 0);
1866               aglat = &(*aglat)->next;
1867             }
1868           else if (dest_plats->aggs_bottom)
1869             return true;
1870         }
1871
1872       ret |= set_chain_of_aglats_contains_variable (*aglat);
1873     }
1874   else
1875     ret |= set_agg_lats_contain_variable (dest_plats);
1876
1877   return ret;
1878 }
1879
1880 /* Return true if on the way cfrom CS->caller to the final (non-alias and
1881    non-thunk) destination, the call passes through a thunk.  */
1882
1883 static bool
1884 call_passes_through_thunk_p (cgraph_edge *cs)
1885 {
1886   cgraph_node *alias_or_thunk = cs->callee;
1887   while (alias_or_thunk->alias)
1888     alias_or_thunk = alias_or_thunk->get_alias_target ();
1889   return alias_or_thunk->thunk.thunk_p;
1890 }
1891
1892 /* Propagate constants from the caller to the callee of CS.  INFO describes the
1893    caller.  */
1894
1895 static bool
1896 propagate_constants_accross_call (struct cgraph_edge *cs)
1897 {
1898   struct ipa_node_params *callee_info;
1899   enum availability availability;
1900   cgraph_node *callee;
1901   struct ipa_edge_args *args;
1902   bool ret = false;
1903   int i, args_count, parms_count;
1904
1905   callee = cs->callee->function_symbol (&availability);
1906   if (!callee->definition)
1907     return false;
1908   gcc_checking_assert (callee->has_gimple_body_p ());
1909   callee_info = IPA_NODE_REF (callee);
1910
1911   args = IPA_EDGE_REF (cs);
1912   args_count = ipa_get_cs_argument_count (args);
1913   parms_count = ipa_get_param_count (callee_info);
1914   if (parms_count == 0)
1915     return false;
1916
1917   /* No propagation through instrumentation thunks is available yet.
1918      It should be possible with proper mapping of call args and
1919      instrumented callee params in the propagation loop below.  But
1920      this case mostly occurs when legacy code calls instrumented code
1921      and it is not a primary target for optimizations.
1922      We detect instrumentation thunks in aliases and thunks chain by
1923      checking instrumentation_clone flag for chain source and target.
1924      Going through instrumentation thunks we always have it changed
1925      from 0 to 1 and all other nodes do not change it.  */
1926   if (!cs->callee->instrumentation_clone
1927       && callee->instrumentation_clone)
1928     {
1929       for (i = 0; i < parms_count; i++)
1930         ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1931                                                                  i));
1932       return ret;
1933     }
1934
1935   /* If this call goes through a thunk we must not propagate to the first (0th)
1936      parameter.  However, we might need to uncover a thunk from below a series
1937      of aliases first.  */
1938   if (call_passes_through_thunk_p (cs))
1939     {
1940       ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1941                                                                0));
1942       i = 1;
1943     }
1944   else
1945     i = 0;
1946
1947   for (; (i < args_count) && (i < parms_count); i++)
1948     {
1949       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
1950       struct ipcp_param_lattices *dest_plats;
1951
1952       dest_plats = ipa_get_parm_lattices (callee_info, i);
1953       if (availability == AVAIL_INTERPOSABLE)
1954         ret |= set_all_contains_variable (dest_plats);
1955       else
1956         {
1957           ret |= propagate_scalar_accross_jump_function (cs, jump_func,
1958                                                          &dest_plats->itself);
1959           ret |= propagate_context_accross_jump_function (cs, jump_func, i,
1960                                                           &dest_plats->ctxlat);
1961           ret |= propagate_alignment_accross_jump_function (cs, jump_func,
1962                                                          &dest_plats->alignment);
1963           ret |= propagate_aggs_accross_jump_function (cs, jump_func,
1964                                                        dest_plats);
1965         }
1966     }
1967   for (; i < parms_count; i++)
1968     ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
1969
1970   return ret;
1971 }
1972
1973 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
1974    KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination.  The latter
1975    three can be NULL.  If AGG_REPS is not NULL, KNOWN_AGGS is ignored.  */
1976
1977 static tree
1978 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
1979                                 vec<tree> known_csts,
1980                                 vec<ipa_polymorphic_call_context> known_contexts,
1981                                 vec<ipa_agg_jump_function_p> known_aggs,
1982                                 struct ipa_agg_replacement_value *agg_reps,
1983                                 bool *speculative)
1984 {
1985   int param_index = ie->indirect_info->param_index;
1986   HOST_WIDE_INT anc_offset;
1987   tree t;
1988   tree target = NULL;
1989
1990   *speculative = false;
1991
1992   if (param_index == -1
1993       || known_csts.length () <= (unsigned int) param_index)
1994     return NULL_TREE;
1995
1996   if (!ie->indirect_info->polymorphic)
1997     {
1998       tree t;
1999
2000       if (ie->indirect_info->agg_contents)
2001         {
2002           if (agg_reps)
2003             {
2004               t = NULL;
2005               while (agg_reps)
2006                 {
2007                   if (agg_reps->index == param_index
2008                       && agg_reps->offset == ie->indirect_info->offset
2009                       && agg_reps->by_ref == ie->indirect_info->by_ref)
2010                     {
2011                       t = agg_reps->value;
2012                       break;
2013                     }
2014                   agg_reps = agg_reps->next;
2015                 }
2016             }
2017           else if (known_aggs.length () > (unsigned int) param_index)
2018             {
2019               struct ipa_agg_jump_function *agg;
2020               agg = known_aggs[param_index];
2021               t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
2022                                               ie->indirect_info->by_ref);
2023             }
2024           else
2025             t = NULL;
2026         }
2027       else
2028         t = known_csts[param_index];
2029
2030       if (t &&
2031           TREE_CODE (t) == ADDR_EXPR
2032           && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
2033         return TREE_OPERAND (t, 0);
2034       else
2035         return NULL_TREE;
2036     }
2037
2038   if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
2039     return NULL_TREE;
2040
2041   gcc_assert (!ie->indirect_info->agg_contents);
2042   anc_offset = ie->indirect_info->offset;
2043
2044   t = NULL;
2045
2046   /* Try to work out value of virtual table pointer value in replacemnets.  */
2047   if (!t && agg_reps && !ie->indirect_info->by_ref)
2048     {
2049       while (agg_reps)
2050         {
2051           if (agg_reps->index == param_index
2052               && agg_reps->offset == ie->indirect_info->offset
2053               && agg_reps->by_ref)
2054             {
2055               t = agg_reps->value;
2056               break;
2057             }
2058           agg_reps = agg_reps->next;
2059         }
2060     }
2061
2062   /* Try to work out value of virtual table pointer value in known
2063      aggregate values.  */
2064   if (!t && known_aggs.length () > (unsigned int) param_index
2065       && !ie->indirect_info->by_ref)
2066     {
2067        struct ipa_agg_jump_function *agg;
2068        agg = known_aggs[param_index];
2069        t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
2070                                        true);
2071     }
2072
2073   /* If we found the virtual table pointer, lookup the target.  */
2074   if (t)
2075     {
2076       tree vtable;
2077       unsigned HOST_WIDE_INT offset;
2078       if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
2079         {
2080           bool can_refer;
2081           target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
2082                                                       vtable, offset, &can_refer);
2083           if (can_refer)
2084             {
2085               if (!target
2086                   || (TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE
2087                       && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
2088                   || !possible_polymorphic_call_target_p
2089                        (ie, cgraph_node::get (target)))
2090                 {
2091                   /* Do not speculate builtin_unreachable, it is stupid!  */
2092                   if (ie->indirect_info->vptr_changed)
2093                     return NULL;
2094                   target = ipa_impossible_devirt_target (ie, target);
2095                 }
2096               *speculative = ie->indirect_info->vptr_changed;
2097               if (!*speculative)
2098                 return target;
2099             }
2100         }
2101     }
2102
2103   /* Do we know the constant value of pointer?  */
2104   if (!t)
2105     t = known_csts[param_index];
2106
2107   gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
2108
2109   ipa_polymorphic_call_context context;
2110   if (known_contexts.length () > (unsigned int) param_index)
2111     {
2112       context = known_contexts[param_index];
2113       context.offset_by (anc_offset);
2114       if (ie->indirect_info->vptr_changed)
2115         context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2116                                               ie->indirect_info->otr_type);
2117       if (t)
2118         {
2119           ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
2120             (t, ie->indirect_info->otr_type, anc_offset);
2121           if (!ctx2.useless_p ())
2122             context.combine_with (ctx2, ie->indirect_info->otr_type);
2123         }
2124     }
2125   else if (t)
2126     {
2127       context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
2128                                               anc_offset);
2129       if (ie->indirect_info->vptr_changed)
2130         context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2131                                               ie->indirect_info->otr_type);
2132     }
2133   else
2134     return NULL_TREE;
2135
2136   vec <cgraph_node *>targets;
2137   bool final;
2138
2139   targets = possible_polymorphic_call_targets
2140     (ie->indirect_info->otr_type,
2141      ie->indirect_info->otr_token,
2142      context, &final);
2143   if (!final || targets.length () > 1)
2144     {
2145       struct cgraph_node *node;
2146       if (*speculative)
2147         return target;
2148       if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
2149           || ie->speculative || !ie->maybe_hot_p ())
2150         return NULL;
2151       node = try_speculative_devirtualization (ie->indirect_info->otr_type,
2152                                                ie->indirect_info->otr_token,
2153                                                context);
2154       if (node)
2155         {
2156           *speculative = true;
2157           target = node->decl;
2158         }
2159       else
2160         return NULL;
2161     }
2162   else
2163     {
2164       *speculative = false;
2165       if (targets.length () == 1)
2166         target = targets[0]->decl;
2167       else
2168         target = ipa_impossible_devirt_target (ie, NULL_TREE);
2169     }
2170
2171   if (target && !possible_polymorphic_call_target_p (ie,
2172                                                      cgraph_node::get (target)))
2173     {
2174       if (*speculative)
2175         return NULL;
2176       target = ipa_impossible_devirt_target (ie, target);
2177     }
2178
2179   return target;
2180 }
2181
2182
2183 /* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
2184    KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
2185    return the destination.  */
2186
2187 tree
2188 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
2189                               vec<tree> known_csts,
2190                               vec<ipa_polymorphic_call_context> known_contexts,
2191                               vec<ipa_agg_jump_function_p> known_aggs,
2192                               bool *speculative)
2193 {
2194   return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2195                                          known_aggs, NULL, speculative);
2196 }
2197
2198 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
2199    and KNOWN_CONTEXTS.  */
2200
2201 static int
2202 devirtualization_time_bonus (struct cgraph_node *node,
2203                              vec<tree> known_csts,
2204                              vec<ipa_polymorphic_call_context> known_contexts,
2205                              vec<ipa_agg_jump_function_p> known_aggs)
2206 {
2207   struct cgraph_edge *ie;
2208   int res = 0;
2209
2210   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
2211     {
2212       struct cgraph_node *callee;
2213       struct inline_summary *isummary;
2214       enum availability avail;
2215       tree target;
2216       bool speculative;
2217
2218       target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts,
2219                                              known_aggs, &speculative);
2220       if (!target)
2221         continue;
2222
2223       /* Only bare minimum benefit for clearly un-inlineable targets.  */
2224       res += 1;
2225       callee = cgraph_node::get (target);
2226       if (!callee || !callee->definition)
2227         continue;
2228       callee = callee->function_symbol (&avail);
2229       if (avail < AVAIL_AVAILABLE)
2230         continue;
2231       isummary = inline_summaries->get (callee);
2232       if (!isummary->inlinable)
2233         continue;
2234
2235       /* FIXME: The values below need re-considering and perhaps also
2236          integrating into the cost metrics, at lest in some very basic way.  */
2237       if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
2238         res += 31 / ((int)speculative + 1);
2239       else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
2240         res += 15 / ((int)speculative + 1);
2241       else if (isummary->size <= MAX_INLINE_INSNS_AUTO
2242                || DECL_DECLARED_INLINE_P (callee->decl))
2243         res += 7 / ((int)speculative + 1);
2244     }
2245
2246   return res;
2247 }
2248
2249 /* Return time bonus incurred because of HINTS.  */
2250
2251 static int
2252 hint_time_bonus (inline_hints hints)
2253 {
2254   int result = 0;
2255   if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
2256     result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);
2257   if (hints & INLINE_HINT_array_index)
2258     result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
2259   return result;
2260 }
2261
2262 /* If there is a reason to penalize the function described by INFO in the
2263    cloning goodness evaluation, do so.  */
2264
2265 static inline int64_t
2266 incorporate_penalties (ipa_node_params *info, int64_t evaluation)
2267 {
2268   if (info->node_within_scc)
2269     evaluation = (evaluation
2270                   * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;
2271
2272   if (info->node_calling_single_call)
2273     evaluation = (evaluation
2274                   * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))
2275       / 100;
2276
2277   return evaluation;
2278 }
2279
2280 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
2281    and SIZE_COST and with the sum of frequencies of incoming edges to the
2282    potential new clone in FREQUENCIES.  */
2283
2284 static bool
2285 good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
2286                             int freq_sum, gcov_type count_sum, int size_cost)
2287 {
2288   if (time_benefit == 0
2289       || !opt_for_fn (node->decl, flag_ipa_cp_clone)
2290       || node->optimize_for_size_p ())
2291     return false;
2292
2293   gcc_assert (size_cost > 0);
2294
2295   struct ipa_node_params *info = IPA_NODE_REF (node);
2296   if (max_count)
2297     {
2298       int factor = (count_sum * 1000) / max_count;
2299       int64_t evaluation = (((int64_t) time_benefit * factor)
2300                                     / size_cost);
2301       evaluation = incorporate_penalties (info, evaluation);
2302
2303       if (dump_file && (dump_flags & TDF_DETAILS))
2304         fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
2305                  "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
2306                  "%s%s) -> evaluation: " "%" PRId64
2307                  ", threshold: %i\n",
2308                  time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
2309                  info->node_within_scc ? ", scc" : "",
2310                  info->node_calling_single_call ? ", single_call" : "",
2311                  evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
2312
2313       return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
2314     }
2315   else
2316     {
2317       int64_t evaluation = (((int64_t) time_benefit * freq_sum)
2318                                     / size_cost);
2319       evaluation = incorporate_penalties (info, evaluation);
2320
2321       if (dump_file && (dump_flags & TDF_DETAILS))
2322         fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
2323                  "size: %i, freq_sum: %i%s%s) -> evaluation: "
2324                  "%" PRId64 ", threshold: %i\n",
2325                  time_benefit, size_cost, freq_sum,
2326                  info->node_within_scc ? ", scc" : "",
2327                  info->node_calling_single_call ? ", single_call" : "",
2328                  evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
2329
2330       return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
2331     }
2332 }
2333
2334 /* Return all context independent values from aggregate lattices in PLATS in a
2335    vector.  Return NULL if there are none.  */
2336
2337 static vec<ipa_agg_jf_item, va_gc> *
2338 context_independent_aggregate_values (struct ipcp_param_lattices *plats)
2339 {
2340   vec<ipa_agg_jf_item, va_gc> *res = NULL;
2341
2342   if (plats->aggs_bottom
2343       || plats->aggs_contain_variable
2344       || plats->aggs_count == 0)
2345     return NULL;
2346
2347   for (struct ipcp_agg_lattice *aglat = plats->aggs;
2348        aglat;
2349        aglat = aglat->next)
2350     if (aglat->is_single_const ())
2351       {
2352         struct ipa_agg_jf_item item;
2353         item.offset = aglat->offset;
2354         item.value = aglat->values->value;
2355         vec_safe_push (res, item);
2356       }
2357   return res;
2358 }
2359
2360 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
2361    populate them with values of parameters that are known independent of the
2362    context.  INFO describes the function.  If REMOVABLE_PARAMS_COST is
2363    non-NULL, the movement cost of all removable parameters will be stored in
2364    it.  */
2365
2366 static bool
2367 gather_context_independent_values (struct ipa_node_params *info,
2368                                    vec<tree> *known_csts,
2369                                    vec<ipa_polymorphic_call_context>
2370                                    *known_contexts,
2371                                    vec<ipa_agg_jump_function> *known_aggs,
2372                                    int *removable_params_cost)
2373 {
2374   int i, count = ipa_get_param_count (info);
2375   bool ret = false;
2376
2377   known_csts->create (0);
2378   known_contexts->create (0);
2379   known_csts->safe_grow_cleared (count);
2380   known_contexts->safe_grow_cleared (count);
2381   if (known_aggs)
2382     {
2383       known_aggs->create (0);
2384       known_aggs->safe_grow_cleared (count);
2385     }
2386
2387   if (removable_params_cost)
2388     *removable_params_cost = 0;
2389
2390   for (i = 0; i < count ; i++)
2391     {
2392       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2393       ipcp_lattice<tree> *lat = &plats->itself;
2394
2395       if (lat->is_single_const ())
2396         {
2397           ipcp_value<tree> *val = lat->values;
2398           gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
2399           (*known_csts)[i] = val->value;
2400           if (removable_params_cost)
2401             *removable_params_cost
2402               += estimate_move_cost (TREE_TYPE (val->value), false);
2403           ret = true;
2404         }
2405       else if (removable_params_cost
2406                && !ipa_is_param_used (info, i))
2407         *removable_params_cost
2408           += ipa_get_param_move_cost (info, i);
2409
2410       if (!ipa_is_param_used (info, i))
2411         continue;
2412
2413       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2414       /* Do not account known context as reason for cloning.  We can see
2415          if it permits devirtualization.  */
2416       if (ctxlat->is_single_const ())
2417         (*known_contexts)[i] = ctxlat->values->value;
2418
2419       if (known_aggs)
2420         {
2421           vec<ipa_agg_jf_item, va_gc> *agg_items;
2422           struct ipa_agg_jump_function *ajf;
2423
2424           agg_items = context_independent_aggregate_values (plats);
2425           ajf = &(*known_aggs)[i];
2426           ajf->items = agg_items;
2427           ajf->by_ref = plats->aggs_by_ref;
2428           ret |= agg_items != NULL;
2429         }
2430     }
2431
2432   return ret;
2433 }
2434
2435 /* The current interface in ipa-inline-analysis requires a pointer vector.
2436    Create it.
2437
2438    FIXME: That interface should be re-worked, this is slightly silly.  Still,
2439    I'd like to discuss how to change it first and this demonstrates the
2440    issue.  */
2441
2442 static vec<ipa_agg_jump_function_p>
2443 agg_jmp_p_vec_for_t_vec (vec<ipa_agg_jump_function> known_aggs)
2444 {
2445   vec<ipa_agg_jump_function_p> ret;
2446   struct ipa_agg_jump_function *ajf;
2447   int i;
2448
2449   ret.create (known_aggs.length ());
2450   FOR_EACH_VEC_ELT (known_aggs, i, ajf)
2451     ret.quick_push (ajf);
2452   return ret;
2453 }
2454
2455 /* Perform time and size measurement of NODE with the context given in
2456    KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
2457    given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
2458    all context-independent removable parameters and EST_MOVE_COST of estimated
2459    movement of the considered parameter and store it into VAL.  */
2460
2461 static void
2462 perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
2463                                vec<ipa_polymorphic_call_context> known_contexts,
2464                                vec<ipa_agg_jump_function_p> known_aggs_ptrs,
2465                                int base_time, int removable_params_cost,
2466                                int est_move_cost, ipcp_value_base *val)
2467 {
2468   int time, size, time_benefit;
2469   inline_hints hints;
2470
2471   estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2472                                      known_aggs_ptrs, &size, &time,
2473                                      &hints);
2474   time_benefit = base_time - time
2475     + devirtualization_time_bonus (node, known_csts, known_contexts,
2476                                    known_aggs_ptrs)
2477     + hint_time_bonus (hints)
2478     + removable_params_cost + est_move_cost;
2479
2480   gcc_checking_assert (size >=0);
2481   /* The inliner-heuristics based estimates may think that in certain
2482      contexts some functions do not have any size at all but we want
2483      all specializations to have at least a tiny cost, not least not to
2484      divide by zero.  */
2485   if (size == 0)
2486     size = 1;
2487
2488   val->local_time_benefit = time_benefit;
2489   val->local_size_cost = size;
2490 }
2491
2492 /* Iterate over known values of parameters of NODE and estimate the local
2493    effects in terms of time and size they have.  */
2494
2495 static void
2496 estimate_local_effects (struct cgraph_node *node)
2497 {
2498   struct ipa_node_params *info = IPA_NODE_REF (node);
2499   int i, count = ipa_get_param_count (info);
2500   vec<tree> known_csts;
2501   vec<ipa_polymorphic_call_context> known_contexts;
2502   vec<ipa_agg_jump_function> known_aggs;
2503   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
2504   bool always_const;
2505   int base_time = inline_summaries->get (node)->time;
2506   int removable_params_cost;
2507
2508   if (!count || !ipcp_versionable_function_p (node))
2509     return;
2510
2511   if (dump_file && (dump_flags & TDF_DETAILS))
2512     fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %i.\n",
2513              node->name (), node->order, base_time);
2514
2515   always_const = gather_context_independent_values (info, &known_csts,
2516                                                     &known_contexts, &known_aggs,
2517                                                     &removable_params_cost);
2518   known_aggs_ptrs = agg_jmp_p_vec_for_t_vec (known_aggs);
2519   int devirt_bonus = devirtualization_time_bonus (node, known_csts,
2520                                            known_contexts, known_aggs_ptrs);
2521   if (always_const || devirt_bonus
2522       || (removable_params_cost && node->local.can_change_signature))
2523     {
2524       struct caller_statistics stats;
2525       inline_hints hints;
2526       int time, size;
2527
2528       init_caller_stats (&stats);
2529       node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2530                                               false);
2531       estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2532                                          known_aggs_ptrs, &size, &time, &hints);
2533       time -= devirt_bonus;
2534       time -= hint_time_bonus (hints);
2535       time -= removable_params_cost;
2536       size -= stats.n_calls * removable_params_cost;
2537
2538       if (dump_file)
2539         fprintf (dump_file, " - context independent values, size: %i, "
2540                  "time_benefit: %i\n", size, base_time - time);
2541
2542       if (size <= 0 || node->local.local)
2543         {
2544           info->do_clone_for_all_contexts = true;
2545           base_time = time;
2546
2547           if (dump_file)
2548             fprintf (dump_file, "     Decided to specialize for all "
2549                      "known contexts, code not going to grow.\n");
2550         }
2551       else if (good_cloning_opportunity_p (node, base_time - time,
2552                                            stats.freq_sum, stats.count_sum,
2553                                            size))
2554         {
2555           if (size + overall_size <= max_new_size)
2556             {
2557               info->do_clone_for_all_contexts = true;
2558               base_time = time;
2559               overall_size += size;
2560
2561               if (dump_file)
2562                 fprintf (dump_file, "     Decided to specialize for all "
2563                          "known contexts, growth deemed beneficial.\n");
2564             }
2565           else if (dump_file && (dump_flags & TDF_DETAILS))
2566             fprintf (dump_file, "   Not cloning for all contexts because "
2567                      "max_new_size would be reached with %li.\n",
2568                      size + overall_size);
2569         }
2570       else if (dump_file && (dump_flags & TDF_DETAILS))
2571         fprintf (dump_file, "   Not cloning for all contexts because "
2572                  "!good_cloning_opportunity_p.\n");
2573         
2574     }
2575
2576   for (i = 0; i < count ; i++)
2577     {
2578       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2579       ipcp_lattice<tree> *lat = &plats->itself;
2580       ipcp_value<tree> *val;
2581
2582       if (lat->bottom
2583           || !lat->values
2584           || known_csts[i])
2585         continue;
2586
2587       for (val = lat->values; val; val = val->next)
2588         {
2589           gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
2590           known_csts[i] = val->value;
2591
2592           int emc = estimate_move_cost (TREE_TYPE (val->value), true);
2593           perform_estimation_of_a_value (node, known_csts, known_contexts,
2594                                          known_aggs_ptrs, base_time,
2595                                          removable_params_cost, emc, val);
2596
2597           if (dump_file && (dump_flags & TDF_DETAILS))
2598             {
2599               fprintf (dump_file, " - estimates for value ");
2600               print_ipcp_constant_value (dump_file, val->value);
2601               fprintf (dump_file, " for ");
2602               ipa_dump_param (dump_file, info, i);
2603               fprintf (dump_file, ": time_benefit: %i, size: %i\n",
2604                        val->local_time_benefit, val->local_size_cost);
2605             }
2606         }
2607       known_csts[i] = NULL_TREE;
2608     }
2609
2610   for (i = 0; i < count; i++)
2611     {
2612       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2613
2614       if (!plats->virt_call)
2615         continue;
2616
2617       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2618       ipcp_value<ipa_polymorphic_call_context> *val;
2619
2620       if (ctxlat->bottom
2621           || !ctxlat->values
2622           || !known_contexts[i].useless_p ())
2623         continue;
2624
2625       for (val = ctxlat->values; val; val = val->next)
2626         {
2627           known_contexts[i] = val->value;
2628           perform_estimation_of_a_value (node, known_csts, known_contexts,
2629                                          known_aggs_ptrs, base_time,
2630                                          removable_params_cost, 0, val);
2631
2632           if (dump_file && (dump_flags & TDF_DETAILS))
2633             {
2634               fprintf (dump_file, " - estimates for polymorphic context ");
2635               print_ipcp_constant_value (dump_file, val->value);
2636               fprintf (dump_file, " for ");
2637               ipa_dump_param (dump_file, info, i);
2638               fprintf (dump_file, ": time_benefit: %i, size: %i\n",
2639                        val->local_time_benefit, val->local_size_cost);
2640             }
2641         }
2642       known_contexts[i] = ipa_polymorphic_call_context ();
2643     }
2644
2645   for (i = 0; i < count ; i++)
2646     {
2647       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2648       struct ipa_agg_jump_function *ajf;
2649       struct ipcp_agg_lattice *aglat;
2650
2651       if (plats->aggs_bottom || !plats->aggs)
2652         continue;
2653
2654       ajf = &known_aggs[i];
2655       for (aglat = plats->aggs; aglat; aglat = aglat->next)
2656         {
2657           ipcp_value<tree> *val;
2658           if (aglat->bottom || !aglat->values
2659               /* If the following is true, the one value is in known_aggs.  */
2660               || (!plats->aggs_contain_variable
2661                   && aglat->is_single_const ()))
2662             continue;
2663
2664           for (val = aglat->values; val; val = val->next)
2665             {
2666               struct ipa_agg_jf_item item;
2667
2668               item.offset = aglat->offset;
2669               item.value = val->value;
2670               vec_safe_push (ajf->items, item);
2671
2672               perform_estimation_of_a_value (node, known_csts, known_contexts,
2673                                              known_aggs_ptrs, base_time,
2674                                              removable_params_cost, 0, val);
2675
2676               if (dump_file && (dump_flags & TDF_DETAILS))
2677                 {
2678                   fprintf (dump_file, " - estimates for value ");
2679                   print_ipcp_constant_value (dump_file, val->value);
2680                   fprintf (dump_file, " for ");
2681                   ipa_dump_param (dump_file, info, i);
2682                   fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
2683                            "]: time_benefit: %i, size: %i\n",
2684                            plats->aggs_by_ref ? "ref " : "",
2685                            aglat->offset,
2686                            val->local_time_benefit, val->local_size_cost);
2687                 }
2688
2689               ajf->items->pop ();
2690             }
2691         }
2692     }
2693
2694   for (i = 0; i < count ; i++)
2695     vec_free (known_aggs[i].items);
2696
2697   known_csts.release ();
2698   known_contexts.release ();
2699   known_aggs.release ();
2700   known_aggs_ptrs.release ();
2701 }
2702
2703
2704 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
2705    topological sort of values.  */
2706
2707 template <typename valtype>
2708 void
2709 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
2710 {
2711   ipcp_value_source<valtype> *src;
2712
2713   if (cur_val->dfs)
2714     return;
2715
2716   dfs_counter++;
2717   cur_val->dfs = dfs_counter;
2718   cur_val->low_link = dfs_counter;
2719
2720   cur_val->topo_next = stack;
2721   stack = cur_val;
2722   cur_val->on_stack = true;
2723
2724   for (src = cur_val->sources; src; src = src->next)
2725     if (src->val)
2726       {
2727         if (src->val->dfs == 0)
2728           {
2729             add_val (src->val);
2730             if (src->val->low_link < cur_val->low_link)
2731               cur_val->low_link = src->val->low_link;
2732           }
2733         else if (src->val->on_stack
2734                  && src->val->dfs < cur_val->low_link)
2735           cur_val->low_link = src->val->dfs;
2736       }
2737
2738   if (cur_val->dfs == cur_val->low_link)
2739     {
2740       ipcp_value<valtype> *v, *scc_list = NULL;
2741
2742       do
2743         {
2744           v = stack;
2745           stack = v->topo_next;
2746           v->on_stack = false;
2747
2748           v->scc_next = scc_list;
2749           scc_list = v;
2750         }
2751       while (v != cur_val);
2752
2753       cur_val->topo_next = values_topo;
2754       values_topo = cur_val;
2755     }
2756 }
2757
2758 /* Add all values in lattices associated with NODE to the topological sort if
2759    they are not there yet.  */
2760
2761 static void
2762 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
2763 {
2764   struct ipa_node_params *info = IPA_NODE_REF (node);
2765   int i, count = ipa_get_param_count (info);
2766
2767   for (i = 0; i < count ; i++)
2768     {
2769       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2770       ipcp_lattice<tree> *lat = &plats->itself;
2771       struct ipcp_agg_lattice *aglat;
2772
2773       if (!lat->bottom)
2774         {
2775           ipcp_value<tree> *val;
2776           for (val = lat->values; val; val = val->next)
2777             topo->constants.add_val (val);
2778         }
2779
2780       if (!plats->aggs_bottom)
2781         for (aglat = plats->aggs; aglat; aglat = aglat->next)
2782           if (!aglat->bottom)
2783             {
2784               ipcp_value<tree> *val;
2785               for (val = aglat->values; val; val = val->next)
2786                 topo->constants.add_val (val);
2787             }
2788
2789       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2790       if (!ctxlat->bottom)
2791         {
2792           ipcp_value<ipa_polymorphic_call_context> *ctxval;
2793           for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
2794             topo->contexts.add_val (ctxval);
2795         }
2796     }
2797 }
2798
2799 /* One pass of constants propagation along the call graph edges, from callers
2800    to callees (requires topological ordering in TOPO), iterate over strongly
2801    connected components.  */
2802
2803 static void
2804 propagate_constants_topo (struct ipa_topo_info *topo)
2805 {
2806   int i;
2807
2808   for (i = topo->nnodes - 1; i >= 0; i--)
2809     {
2810       unsigned j;
2811       struct cgraph_node *v, *node = topo->order[i];
2812       vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
2813
2814       /* First, iteratively propagate within the strongly connected component
2815          until all lattices stabilize.  */
2816       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
2817         if (v->has_gimple_body_p ())
2818           push_node_to_stack (topo, v);
2819
2820       v = pop_node_from_stack (topo);
2821       while (v)
2822         {
2823           struct cgraph_edge *cs;
2824
2825           for (cs = v->callees; cs; cs = cs->next_callee)
2826             if (ipa_edge_within_scc (cs))
2827               {
2828                 IPA_NODE_REF (v)->node_within_scc = true;
2829                 if (propagate_constants_accross_call (cs))
2830                   push_node_to_stack (topo, cs->callee->function_symbol ());
2831               }
2832           v = pop_node_from_stack (topo);
2833         }
2834
2835       /* Afterwards, propagate along edges leading out of the SCC, calculates
2836          the local effects of the discovered constants and all valid values to
2837          their topological sort.  */
2838       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
2839         if (v->has_gimple_body_p ())
2840           {
2841             struct cgraph_edge *cs;
2842
2843             estimate_local_effects (v);
2844             add_all_node_vals_to_toposort (v, topo);
2845             for (cs = v->callees; cs; cs = cs->next_callee)
2846               if (!ipa_edge_within_scc (cs))
2847                 propagate_constants_accross_call (cs);
2848           }
2849       cycle_nodes.release ();
2850     }
2851 }
2852
2853
2854 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
2855    the bigger one if otherwise.  */
2856
2857 static int
2858 safe_add (int a, int b)
2859 {
2860   if (a > INT_MAX/2 || b > INT_MAX/2)
2861     return a > b ? a : b;
2862   else
2863     return a + b;
2864 }
2865
2866
2867 /* Propagate the estimated effects of individual values along the topological
2868    from the dependent values to those they depend on.  */
2869
2870 template <typename valtype>
2871 void
2872 value_topo_info<valtype>::propagate_effects ()
2873 {
2874   ipcp_value<valtype> *base;
2875
2876   for (base = values_topo; base; base = base->topo_next)
2877     {
2878       ipcp_value_source<valtype> *src;
2879       ipcp_value<valtype> *val;
2880       int time = 0, size = 0;
2881
2882       for (val = base; val; val = val->scc_next)
2883         {
2884           time = safe_add (time,
2885                            val->local_time_benefit + val->prop_time_benefit);
2886           size = safe_add (size, val->local_size_cost + val->prop_size_cost);
2887         }
2888
2889       for (val = base; val; val = val->scc_next)
2890         for (src = val->sources; src; src = src->next)
2891           if (src->val
2892               && src->cs->maybe_hot_p ())
2893             {
2894               src->val->prop_time_benefit = safe_add (time,
2895                                                 src->val->prop_time_benefit);
2896               src->val->prop_size_cost = safe_add (size,
2897                                                    src->val->prop_size_cost);
2898             }
2899     }
2900 }
2901
2902
2903 /* Propagate constants, polymorphic contexts and their effects from the
2904    summaries interprocedurally.  */
2905
2906 static void
2907 ipcp_propagate_stage (struct ipa_topo_info *topo)
2908 {
2909   struct cgraph_node *node;
2910
2911   if (dump_file)
2912     fprintf (dump_file, "\n Propagating constants:\n\n");
2913
2914   if (in_lto_p)
2915     ipa_update_after_lto_read ();
2916
2917
2918   FOR_EACH_DEFINED_FUNCTION (node)
2919   {
2920     struct ipa_node_params *info = IPA_NODE_REF (node);
2921
2922     determine_versionability (node, info);
2923     if (node->has_gimple_body_p ())
2924       {
2925         info->lattices = XCNEWVEC (struct ipcp_param_lattices,
2926                                    ipa_get_param_count (info));
2927         initialize_node_lattices (node);
2928       }
2929     if (node->definition && !node->alias)
2930       overall_size += inline_summaries->get (node)->self_size;
2931     if (node->count > max_count)
2932       max_count = node->count;
2933   }
2934
2935   max_new_size = overall_size;
2936   if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
2937     max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
2938   max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
2939
2940   if (dump_file)
2941     fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
2942              overall_size, max_new_size);
2943
2944   propagate_constants_topo (topo);
2945   if (flag_checking)
2946     ipcp_verify_propagated_values ();
2947   topo->constants.propagate_effects ();
2948   topo->contexts.propagate_effects ();
2949
2950   if (dump_file)
2951     {
2952       fprintf (dump_file, "\nIPA lattices after all propagation:\n");
2953       print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
2954     }
2955 }
2956
2957 /* Discover newly direct outgoing edges from NODE which is a new clone with
2958    known KNOWN_CSTS and make them direct.  */
2959
2960 static void
2961 ipcp_discover_new_direct_edges (struct cgraph_node *node,
2962                                 vec<tree> known_csts,
2963                                 vec<ipa_polymorphic_call_context>
2964                                 known_contexts,
2965                                 struct ipa_agg_replacement_value *aggvals)
2966 {
2967   struct cgraph_edge *ie, *next_ie;
2968   bool found = false;
2969
2970   for (ie = node->indirect_calls; ie; ie = next_ie)
2971     {
2972       tree target;
2973       bool speculative;
2974
2975       next_ie = ie->next_callee;
2976       target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2977                                                vNULL, aggvals, &speculative);
2978       if (target)
2979         {
2980           bool agg_contents = ie->indirect_info->agg_contents;
2981           bool polymorphic = ie->indirect_info->polymorphic;
2982           int param_index = ie->indirect_info->param_index;
2983           struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
2984                                                                    speculative);
2985           found = true;
2986
2987           if (cs && !agg_contents && !polymorphic)
2988             {
2989               struct ipa_node_params *info = IPA_NODE_REF (node);
2990               int c = ipa_get_controlled_uses (info, param_index);
2991               if (c != IPA_UNDESCRIBED_USE)
2992                 {
2993                   struct ipa_ref *to_del;
2994
2995                   c--;
2996                   ipa_set_controlled_uses (info, param_index, c);
2997                   if (dump_file && (dump_flags & TDF_DETAILS))
2998                     fprintf (dump_file, "     controlled uses count of param "
2999                              "%i bumped down to %i\n", param_index, c);
3000                   if (c == 0
3001                       && (to_del = node->find_reference (cs->callee, NULL, 0)))
3002                     {
3003                       if (dump_file && (dump_flags & TDF_DETAILS))
3004                         fprintf (dump_file, "       and even removing its "
3005                                  "cloning-created reference\n");
3006                       to_del->remove_reference ();
3007                     }
3008                 }
3009             }
3010         }
3011     }
3012   /* Turning calls to direct calls will improve overall summary.  */
3013   if (found)
3014     inline_update_overall_summary (node);
3015 }
3016
3017 /* Vector of pointers which for linked lists of clones of an original crgaph
3018    edge. */
3019
3020 static vec<cgraph_edge *> next_edge_clone;
3021 static vec<cgraph_edge *> prev_edge_clone;
3022
3023 static inline void
3024 grow_edge_clone_vectors (void)
3025 {
3026   if (next_edge_clone.length ()
3027       <=  (unsigned) symtab->edges_max_uid)
3028     next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
3029   if (prev_edge_clone.length ()
3030       <=  (unsigned) symtab->edges_max_uid)
3031     prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
3032 }
3033
3034 /* Edge duplication hook to grow the appropriate linked list in
3035    next_edge_clone. */
3036
3037 static void
3038 ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
3039                             void *)
3040 {
3041   grow_edge_clone_vectors ();
3042
3043   struct cgraph_edge *old_next = next_edge_clone[src->uid];
3044   if (old_next)
3045     prev_edge_clone[old_next->uid] = dst;
3046   prev_edge_clone[dst->uid] = src;
3047
3048   next_edge_clone[dst->uid] = old_next;
3049   next_edge_clone[src->uid] = dst;
3050 }
3051
3052 /* Hook that is called by cgraph.c when an edge is removed.  */
3053
3054 static void
3055 ipcp_edge_removal_hook (struct cgraph_edge *cs, void *)
3056 {
3057   grow_edge_clone_vectors ();
3058
3059   struct cgraph_edge *prev = prev_edge_clone[cs->uid];
3060   struct cgraph_edge *next = next_edge_clone[cs->uid];
3061   if (prev)
3062     next_edge_clone[prev->uid] = next;
3063   if (next)
3064     prev_edge_clone[next->uid] = prev;
3065 }
3066
3067 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
3068    parameter with the given INDEX.  */
3069
3070 static tree
3071 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
3072                      int index)
3073 {
3074   struct ipa_agg_replacement_value *aggval;
3075
3076   aggval = ipa_get_agg_replacements_for_node (node);
3077   while (aggval)
3078     {
3079       if (aggval->offset == offset
3080           && aggval->index == index)
3081         return aggval->value;
3082       aggval = aggval->next;
3083     }
3084   return NULL_TREE;
3085 }
3086
3087 /* Return true is NODE is DEST or its clone for all contexts.  */
3088
3089 static bool
3090 same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
3091 {
3092   if (node == dest)
3093     return true;
3094
3095   struct ipa_node_params *info = IPA_NODE_REF (node);
3096   return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
3097 }
3098
3099 /* Return true if edge CS does bring about the value described by SRC to node
3100    DEST or its clone for all contexts.  */
3101
3102 static bool
3103 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
3104                             cgraph_node *dest)
3105 {
3106   struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3107   enum availability availability;
3108   cgraph_node *real_dest = cs->callee->function_symbol (&availability);
3109
3110   if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
3111       || availability <= AVAIL_INTERPOSABLE
3112       || caller_info->node_dead)
3113     return false;
3114   if (!src->val)
3115     return true;
3116
3117   if (caller_info->ipcp_orig_node)
3118     {
3119       tree t;
3120       if (src->offset == -1)
3121         t = caller_info->known_csts[src->index];
3122       else
3123         t = get_clone_agg_value (cs->caller, src->offset, src->index);
3124       return (t != NULL_TREE
3125               && values_equal_for_ipcp_p (src->val->value, t));
3126     }
3127   else
3128     {
3129       struct ipcp_agg_lattice *aglat;
3130       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3131                                                                  src->index);
3132       if (src->offset == -1)
3133         return (plats->itself.is_single_const ()
3134                 && values_equal_for_ipcp_p (src->val->value,
3135                                             plats->itself.values->value));
3136       else
3137         {
3138           if (plats->aggs_bottom || plats->aggs_contain_variable)
3139             return false;
3140           for (aglat = plats->aggs; aglat; aglat = aglat->next)
3141             if (aglat->offset == src->offset)
3142               return  (aglat->is_single_const ()
3143                        && values_equal_for_ipcp_p (src->val->value,
3144                                                    aglat->values->value));
3145         }
3146       return false;
3147     }
3148 }
3149
3150 /* Return true if edge CS does bring about the value described by SRC to node
3151    DEST or its clone for all contexts.  */
3152
3153 static bool
3154 cgraph_edge_brings_value_p (cgraph_edge *cs,
3155                             ipcp_value_source<ipa_polymorphic_call_context> *src,
3156                             cgraph_node *dest)
3157 {
3158   struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3159   cgraph_node *real_dest = cs->callee->function_symbol ();
3160
3161   if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
3162       || caller_info->node_dead)
3163     return false;
3164   if (!src->val)
3165     return true;
3166
3167   if (caller_info->ipcp_orig_node)
3168     return (caller_info->known_contexts.length () > (unsigned) src->index)
3169       && values_equal_for_ipcp_p (src->val->value,
3170                                   caller_info->known_contexts[src->index]);
3171
3172   struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3173                                                              src->index);
3174   return plats->ctxlat.is_single_const ()
3175     && values_equal_for_ipcp_p (src->val->value,
3176                                 plats->ctxlat.values->value);
3177 }
3178
3179 /* Get the next clone in the linked list of clones of an edge.  */
3180
3181 static inline struct cgraph_edge *
3182 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
3183 {
3184   return next_edge_clone[cs->uid];
3185 }
3186
3187 /* Given VAL that is intended for DEST, iterate over all its sources and if
3188    they still hold, add their edge frequency and their number into *FREQUENCY
3189    and *CALLER_COUNT respectively.  */
3190
3191 template <typename valtype>
3192 static bool
3193 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
3194                                 int *freq_sum,
3195                                 gcov_type *count_sum, int *caller_count)
3196 {
3197   ipcp_value_source<valtype> *src;
3198   int freq = 0, count = 0;
3199   gcov_type cnt = 0;
3200   bool hot = false;
3201
3202   for (src = val->sources; src; src = src->next)
3203     {
3204       struct cgraph_edge *cs = src->cs;
3205       while (cs)
3206         {
3207           if (cgraph_edge_brings_value_p (cs, src, dest))
3208             {
3209               count++;
3210               freq += cs->frequency;
3211               cnt += cs->count;
3212               hot |= cs->maybe_hot_p ();
3213             }
3214           cs = get_next_cgraph_edge_clone (cs);
3215         }
3216     }
3217
3218   *freq_sum = freq;
3219   *count_sum = cnt;
3220   *caller_count = count;
3221   return hot;
3222 }
3223
3224 /* Return a vector of incoming edges that do bring value VAL to node DEST.  It
3225    is assumed their number is known and equal to CALLER_COUNT.  */
3226
3227 template <typename valtype>
3228 static vec<cgraph_edge *>
3229 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
3230                         int caller_count)
3231 {
3232   ipcp_value_source<valtype> *src;
3233   vec<cgraph_edge *> ret;
3234
3235   ret.create (caller_count);
3236   for (src = val->sources; src; src = src->next)
3237     {
3238       struct cgraph_edge *cs = src->cs;
3239       while (cs)
3240         {
3241           if (cgraph_edge_brings_value_p (cs, src, dest))
3242             ret.quick_push (cs);
3243           cs = get_next_cgraph_edge_clone (cs);
3244         }
3245     }
3246
3247   return ret;
3248 }
3249
3250 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3251    Return it or NULL if for some reason it cannot be created.  */
3252
3253 static struct ipa_replace_map *
3254 get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
3255 {
3256   struct ipa_replace_map *replace_map;
3257
3258
3259   replace_map = ggc_alloc<ipa_replace_map> ();
3260   if (dump_file)
3261     {
3262       fprintf (dump_file, "    replacing ");
3263       ipa_dump_param (dump_file, info, parm_num);
3264   
3265       fprintf (dump_file, " with const ");
3266       print_generic_expr (dump_file, value, 0);
3267       fprintf (dump_file, "\n");
3268     }
3269   replace_map->old_tree = NULL;
3270   replace_map->parm_num = parm_num;
3271   replace_map->new_tree = value;
3272   replace_map->replace_p = true;
3273   replace_map->ref_p = false;
3274
3275   return replace_map;
3276 }
3277
3278 /* Dump new profiling counts */
3279
3280 static void
3281 dump_profile_updates (struct cgraph_node *orig_node,
3282                       struct cgraph_node *new_node)
3283 {
3284   struct cgraph_edge *cs;
3285
3286   fprintf (dump_file, "    setting count of the specialized node to "
3287            HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count);
3288   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3289     fprintf (dump_file, "      edge to %s has count "
3290              HOST_WIDE_INT_PRINT_DEC "\n",
3291              cs->callee->name (), (HOST_WIDE_INT) cs->count);
3292
3293   fprintf (dump_file, "    setting count of the original node to "
3294            HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count);
3295   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3296     fprintf (dump_file, "      edge to %s is left with "
3297              HOST_WIDE_INT_PRINT_DEC "\n",
3298              cs->callee->name (), (HOST_WIDE_INT) cs->count);
3299 }
3300
3301 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
3302    their profile information to reflect this.  */
3303
3304 static void
3305 update_profiling_info (struct cgraph_node *orig_node,
3306                        struct cgraph_node *new_node)
3307 {
3308   struct cgraph_edge *cs;
3309   struct caller_statistics stats;
3310   gcov_type new_sum, orig_sum;
3311   gcov_type remainder, orig_node_count = orig_node->count;
3312
3313   if (orig_node_count == 0)
3314     return;
3315
3316   init_caller_stats (&stats);
3317   orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3318                                                false);
3319   orig_sum = stats.count_sum;
3320   init_caller_stats (&stats);
3321   new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3322                                               false);
3323   new_sum = stats.count_sum;
3324
3325   if (orig_node_count < orig_sum + new_sum)
3326     {
3327       if (dump_file)
3328         fprintf (dump_file, "    Problem: node %s/%i has too low count "
3329                  HOST_WIDE_INT_PRINT_DEC " while the sum of incoming "
3330                  "counts is " HOST_WIDE_INT_PRINT_DEC "\n",
3331                  orig_node->name (), orig_node->order,
3332                  (HOST_WIDE_INT) orig_node_count,
3333                  (HOST_WIDE_INT) (orig_sum + new_sum));
3334
3335       orig_node_count = (orig_sum + new_sum) * 12 / 10;
3336       if (dump_file)
3337         fprintf (dump_file, "      proceeding by pretending it was "
3338                  HOST_WIDE_INT_PRINT_DEC "\n",
3339                  (HOST_WIDE_INT) orig_node_count);
3340     }
3341
3342   new_node->count = new_sum;
3343   remainder = orig_node_count - new_sum;
3344   orig_node->count = remainder;
3345
3346   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3347     if (cs->frequency)
3348       cs->count = apply_probability (cs->count,
3349                                      GCOV_COMPUTE_SCALE (new_sum,
3350                                                          orig_node_count));
3351     else
3352       cs->count = 0;
3353
3354   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3355     cs->count = apply_probability (cs->count,
3356                                    GCOV_COMPUTE_SCALE (remainder,
3357                                                        orig_node_count));
3358
3359   if (dump_file)
3360     dump_profile_updates (orig_node, new_node);
3361 }
3362
3363 /* Update the respective profile of specialized NEW_NODE and the original
3364    ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
3365    have been redirected to the specialized version.  */
3366
3367 static void
3368 update_specialized_profile (struct cgraph_node *new_node,
3369                             struct cgraph_node *orig_node,
3370                             gcov_type redirected_sum)
3371 {
3372   struct cgraph_edge *cs;
3373   gcov_type new_node_count, orig_node_count = orig_node->count;
3374
3375   if (dump_file)
3376     fprintf (dump_file, "    the sum of counts of redirected  edges is "
3377              HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum);
3378   if (orig_node_count == 0)
3379     return;
3380
3381   gcc_assert (orig_node_count >= redirected_sum);
3382
3383   new_node_count = new_node->count;
3384   new_node->count += redirected_sum;
3385   orig_node->count -= redirected_sum;
3386
3387   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3388     if (cs->frequency)
3389       cs->count += apply_probability (cs->count,
3390                                       GCOV_COMPUTE_SCALE (redirected_sum,
3391                                                           new_node_count));
3392     else
3393       cs->count = 0;
3394
3395   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3396     {
3397       gcov_type dec = apply_probability (cs->count,
3398                                          GCOV_COMPUTE_SCALE (redirected_sum,
3399                                                              orig_node_count));
3400       if (dec < cs->count)
3401         cs->count -= dec;
3402       else
3403         cs->count = 0;
3404     }
3405
3406   if (dump_file)
3407     dump_profile_updates (orig_node, new_node);
3408 }
3409
3410 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3411    known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3412    redirect all edges in CALLERS to it.  */
3413
3414 static struct cgraph_node *
3415 create_specialized_node (struct cgraph_node *node,
3416                          vec<tree> known_csts,
3417                          vec<ipa_polymorphic_call_context> known_contexts,
3418                          struct ipa_agg_replacement_value *aggvals,
3419                          vec<cgraph_edge *> callers)
3420 {
3421   struct ipa_node_params *new_info, *info = IPA_NODE_REF (node);
3422   vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
3423   struct ipa_agg_replacement_value *av;
3424   struct cgraph_node *new_node;
3425   int i, count = ipa_get_param_count (info);
3426   bitmap args_to_skip;
3427
3428   gcc_assert (!info->ipcp_orig_node);
3429
3430   if (node->local.can_change_signature)
3431     {
3432       args_to_skip = BITMAP_GGC_ALLOC ();
3433       for (i = 0; i < count; i++)
3434         {
3435           tree t = known_csts[i];
3436
3437           if (t || !ipa_is_param_used (info, i))
3438             bitmap_set_bit (args_to_skip, i);
3439         }
3440     }
3441   else
3442     {
3443       args_to_skip = NULL;
3444       if (dump_file && (dump_flags & TDF_DETAILS))
3445         fprintf (dump_file, "      cannot change function signature\n");
3446     }
3447
3448   for (i = 0; i < count ; i++)
3449     {
3450       tree t = known_csts[i];
3451       if (t)
3452         {
3453           struct ipa_replace_map *replace_map;
3454
3455           gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
3456           replace_map = get_replacement_map (info, t, i);
3457           if (replace_map)
3458             vec_safe_push (replace_trees, replace_map);
3459         }
3460     }
3461
3462   new_node = node->create_virtual_clone (callers, replace_trees,
3463                                          args_to_skip, "constprop");
3464   ipa_set_node_agg_value_chain (new_node, aggvals);
3465   for (av = aggvals; av; av = av->next)
3466     new_node->maybe_create_reference (av->value, IPA_REF_ADDR, NULL);
3467
3468   if (dump_file && (dump_flags & TDF_DETAILS))
3469     {
3470       fprintf (dump_file, "     the new node is %s/%i.\n",
3471                new_node->name (), new_node->order);
3472       if (known_contexts.exists ())
3473         {
3474           for (i = 0; i < count ; i++)
3475             if (!known_contexts[i].useless_p ())
3476               {
3477                 fprintf (dump_file, "     known ctx %i is ", i);
3478                 known_contexts[i].dump (dump_file);
3479               }
3480         }
3481       if (aggvals)
3482         ipa_dump_agg_replacement_values (dump_file, aggvals);
3483     }
3484   ipa_check_create_node_params ();
3485   update_profiling_info (node, new_node);
3486   new_info = IPA_NODE_REF (new_node);
3487   new_info->ipcp_orig_node = node;
3488   new_info->known_csts = known_csts;
3489   new_info->known_contexts = known_contexts;
3490
3491   ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
3492
3493   callers.release ();
3494   return new_node;
3495 }
3496
3497 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3498    KNOWN_CSTS with constants that are also known for all of the CALLERS.  */
3499
3500 static void
3501 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
3502                                             vec<tree> known_csts,
3503                                             vec<cgraph_edge *> callers)
3504 {
3505   struct ipa_node_params *info = IPA_NODE_REF (node);
3506   int i, count = ipa_get_param_count (info);
3507
3508   for (i = 0; i < count ; i++)
3509     {
3510       struct cgraph_edge *cs;
3511       tree newval = NULL_TREE;
3512       int j;
3513       bool first = true;
3514
3515       if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
3516         continue;
3517
3518       FOR_EACH_VEC_ELT (callers, j, cs)
3519         {
3520           struct ipa_jump_func *jump_func;
3521           tree t;
3522
3523           if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
3524               || (i == 0
3525                   && call_passes_through_thunk_p (cs))
3526               || (!cs->callee->instrumentation_clone
3527                   && cs->callee->function_symbol ()->instrumentation_clone))
3528             {
3529               newval = NULL_TREE;
3530               break;
3531             }
3532           jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
3533           t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
3534           if (!t
3535               || (newval
3536                   && !values_equal_for_ipcp_p (t, newval))
3537               || (!first && !newval))
3538             {
3539               newval = NULL_TREE;
3540               break;
3541             }
3542           else
3543             newval = t;
3544           first = false;
3545         }
3546
3547       if (newval)
3548         {
3549           if (dump_file && (dump_flags & TDF_DETAILS))
3550             {
3551               fprintf (dump_file, "    adding an extra known scalar value ");
3552               print_ipcp_constant_value (dump_file, newval);
3553               fprintf (dump_file, " for ");
3554               ipa_dump_param (dump_file, info, i);
3555               fprintf (dump_file, "\n");
3556             }
3557
3558           known_csts[i] = newval;
3559         }
3560     }
3561 }
3562
3563 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
3564    KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
3565    CALLERS.  */
3566
3567 static void
3568 find_more_contexts_for_caller_subset (cgraph_node *node,
3569                                       vec<ipa_polymorphic_call_context>
3570                                       *known_contexts,
3571                                       vec<cgraph_edge *> callers)
3572 {
3573   ipa_node_params *info = IPA_NODE_REF (node);
3574   int i, count = ipa_get_param_count (info);
3575
3576   for (i = 0; i < count ; i++)
3577     {
3578       cgraph_edge *cs;
3579
3580       if (ipa_get_poly_ctx_lat (info, i)->bottom
3581           || (known_contexts->exists ()
3582               && !(*known_contexts)[i].useless_p ()))
3583         continue;
3584
3585       ipa_polymorphic_call_context newval;
3586       bool first = true;
3587       int j;
3588
3589       FOR_EACH_VEC_ELT (callers, j, cs)
3590         {
3591           if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
3592             return;
3593           ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
3594                                                             i);
3595           ipa_polymorphic_call_context ctx;
3596           ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
3597                                         jfunc);
3598           if (first)
3599             {
3600               newval = ctx;
3601               first = false;
3602             }
3603           else
3604             newval.meet_with (ctx);
3605           if (newval.useless_p ())
3606             break;
3607         }
3608
3609       if (!newval.useless_p ())
3610         {
3611           if (dump_file && (dump_flags & TDF_DETAILS))
3612             {
3613               fprintf (dump_file, "    adding an extra known polymorphic "
3614                        "context ");
3615               print_ipcp_constant_value (dump_file, newval);
3616               fprintf (dump_file, " for ");
3617               ipa_dump_param (dump_file, info, i);
3618               fprintf (dump_file, "\n");
3619             }
3620
3621           if (!known_contexts->exists ())
3622             known_contexts->safe_grow_cleared (ipa_get_param_count (info));
3623           (*known_contexts)[i] = newval;
3624         }
3625
3626     }
3627 }
3628
3629 /* Go through PLATS and create a vector of values consisting of values and
3630    offsets (minus OFFSET) of lattices that contain only a single value.  */
3631
3632 static vec<ipa_agg_jf_item>
3633 copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset)
3634 {
3635   vec<ipa_agg_jf_item> res = vNULL;
3636
3637   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
3638     return vNULL;
3639
3640   for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
3641     if (aglat->is_single_const ())
3642       {
3643         struct ipa_agg_jf_item ti;
3644         ti.offset = aglat->offset - offset;
3645         ti.value = aglat->values->value;
3646         res.safe_push (ti);
3647       }
3648   return res;
3649 }
3650
3651 /* Intersect all values in INTER with single value lattices in PLATS (while
3652    subtracting OFFSET).  */
3653
3654 static void
3655 intersect_with_plats (struct ipcp_param_lattices *plats,
3656                       vec<ipa_agg_jf_item> *inter,
3657                       HOST_WIDE_INT offset)
3658 {
3659   struct ipcp_agg_lattice *aglat;
3660   struct ipa_agg_jf_item *item;
3661   int k;
3662
3663   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
3664     {
3665       inter->release ();
3666       return;
3667     }
3668
3669   aglat = plats->aggs;
3670   FOR_EACH_VEC_ELT (*inter, k, item)
3671     {
3672       bool found = false;
3673       if (!item->value)
3674         continue;
3675       while (aglat)
3676         {
3677           if (aglat->offset - offset > item->offset)
3678             break;
3679           if (aglat->offset - offset == item->offset)
3680             {
3681               gcc_checking_assert (item->value);
3682               if (values_equal_for_ipcp_p (item->value, aglat->values->value))
3683                 found = true;
3684               break;
3685             }
3686           aglat = aglat->next;
3687         }
3688       if (!found)
3689         item->value = NULL_TREE;
3690     }
3691 }
3692
3693 /* Copy agggregate replacement values of NODE (which is an IPA-CP clone) to the
3694    vector result while subtracting OFFSET from the individual value offsets.  */
3695
3696 static vec<ipa_agg_jf_item>
3697 agg_replacements_to_vector (struct cgraph_node *node, int index,
3698                             HOST_WIDE_INT offset)
3699 {
3700   struct ipa_agg_replacement_value *av;
3701   vec<ipa_agg_jf_item> res = vNULL;
3702
3703   for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
3704     if (av->index == index
3705         && (av->offset - offset) >= 0)
3706     {
3707       struct ipa_agg_jf_item item;
3708       gcc_checking_assert (av->value);
3709       item.offset = av->offset - offset;
3710       item.value = av->value;
3711       res.safe_push (item);
3712     }
3713
3714   return res;
3715 }
3716
3717 /* Intersect all values in INTER with those that we have already scheduled to
3718    be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
3719    (while subtracting OFFSET).  */
3720
3721 static void
3722 intersect_with_agg_replacements (struct cgraph_node *node, int index,
3723                                  vec<ipa_agg_jf_item> *inter,
3724                                  HOST_WIDE_INT offset)
3725 {
3726   struct ipa_agg_replacement_value *srcvals;
3727   struct ipa_agg_jf_item *item;
3728   int i;
3729
3730   srcvals = ipa_get_agg_replacements_for_node (node);
3731   if (!srcvals)
3732     {
3733       inter->release ();
3734       return;
3735     }
3736
3737   FOR_EACH_VEC_ELT (*inter, i, item)
3738     {
3739       struct ipa_agg_replacement_value *av;
3740       bool found = false;
3741       if (!item->value)
3742         continue;
3743       for (av = srcvals; av; av = av->next)
3744         {
3745           gcc_checking_assert (av->value);
3746           if (av->index == index
3747               && av->offset - offset == item->offset)
3748             {
3749               if (values_equal_for_ipcp_p (item->value, av->value))
3750                 found = true;
3751               break;
3752             }
3753         }
3754       if (!found)
3755         item->value = NULL_TREE;
3756     }
3757 }
3758
3759 /* Intersect values in INTER with aggregate values that come along edge CS to
3760    parameter number INDEX and return it.  If INTER does not actually exist yet,
3761    copy all incoming values to it.  If we determine we ended up with no values
3762    whatsoever, return a released vector.  */
3763
3764 static vec<ipa_agg_jf_item>
3765 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
3766                                 vec<ipa_agg_jf_item> inter)
3767 {
3768   struct ipa_jump_func *jfunc;
3769   jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
3770   if (jfunc->type == IPA_JF_PASS_THROUGH
3771       && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3772     {
3773       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3774       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
3775
3776       if (caller_info->ipcp_orig_node)
3777         {
3778           struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
3779           struct ipcp_param_lattices *orig_plats;
3780           orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
3781                                               src_idx);
3782           if (agg_pass_through_permissible_p (orig_plats, jfunc))
3783             {
3784               if (!inter.exists ())
3785                 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
3786               else
3787                 intersect_with_agg_replacements (cs->caller, src_idx,
3788                                                  &inter, 0);
3789             }
3790           else
3791             {
3792               inter.release ();
3793               return vNULL;
3794             }
3795         }
3796       else
3797         {
3798           struct ipcp_param_lattices *src_plats;
3799           src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3800           if (agg_pass_through_permissible_p (src_plats, jfunc))
3801             {
3802               /* Currently we do not produce clobber aggregate jump
3803                  functions, adjust when we do.  */
3804               gcc_checking_assert (!jfunc->agg.items);
3805               if (!inter.exists ())
3806                 inter = copy_plats_to_inter (src_plats, 0);
3807               else
3808                 intersect_with_plats (src_plats, &inter, 0);
3809             }
3810           else
3811             {
3812               inter.release ();
3813               return vNULL;
3814             }
3815         }
3816     }
3817   else if (jfunc->type == IPA_JF_ANCESTOR
3818            && ipa_get_jf_ancestor_agg_preserved (jfunc))
3819     {
3820       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3821       int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
3822       struct ipcp_param_lattices *src_plats;
3823       HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
3824
3825       if (caller_info->ipcp_orig_node)
3826         {
3827           if (!inter.exists ())
3828             inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
3829           else
3830             intersect_with_agg_replacements (cs->caller, src_idx, &inter,
3831                                              delta);
3832         }
3833       else
3834         {
3835           src_plats = ipa_get_parm_lattices (caller_info, src_idx);;
3836           /* Currently we do not produce clobber aggregate jump
3837              functions, adjust when we do.  */
3838           gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
3839           if (!inter.exists ())
3840             inter = copy_plats_to_inter (src_plats, delta);
3841           else
3842             intersect_with_plats (src_plats, &inter, delta);
3843         }
3844     }
3845   else if (jfunc->agg.items)
3846     {
3847       struct ipa_agg_jf_item *item;
3848       int k;
3849
3850       if (!inter.exists ())
3851         for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
3852           inter.safe_push ((*jfunc->agg.items)[i]);
3853       else
3854         FOR_EACH_VEC_ELT (inter, k, item)
3855           {
3856             int l = 0;
3857             bool found = false;;
3858
3859             if (!item->value)
3860               continue;
3861
3862             while ((unsigned) l < jfunc->agg.items->length ())
3863               {
3864                 struct ipa_agg_jf_item *ti;
3865                 ti = &(*jfunc->agg.items)[l];
3866                 if (ti->offset > item->offset)
3867                   break;
3868                 if (ti->offset == item->offset)
3869                   {
3870                     gcc_checking_assert (ti->value);
3871                     if (values_equal_for_ipcp_p (item->value,
3872                                                  ti->value))
3873                       found = true;
3874                     break;
3875                   }
3876                 l++;
3877               }
3878             if (!found)
3879               item->value = NULL;
3880           }
3881     }
3882   else
3883     {
3884       inter.release ();
3885       return vec<ipa_agg_jf_item>();
3886     }
3887   return inter;
3888 }
3889
3890 /* Look at edges in CALLERS and collect all known aggregate values that arrive
3891    from all of them.  */
3892
3893 static struct ipa_agg_replacement_value *
3894 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
3895                                           vec<cgraph_edge *> callers)
3896 {
3897   struct ipa_node_params *dest_info = IPA_NODE_REF (node);
3898   struct ipa_agg_replacement_value *res;
3899   struct ipa_agg_replacement_value **tail = &res;
3900   struct cgraph_edge *cs;
3901   int i, j, count = ipa_get_param_count (dest_info);
3902
3903   FOR_EACH_VEC_ELT (callers, j, cs)
3904     {
3905       int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
3906       if (c < count)
3907         count = c;
3908     }
3909
3910   for (i = 0; i < count ; i++)
3911     {
3912       struct cgraph_edge *cs;
3913       vec<ipa_agg_jf_item> inter = vNULL;
3914       struct ipa_agg_jf_item *item;
3915       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
3916       int j;
3917
3918       /* Among other things, the following check should deal with all by_ref
3919          mismatches.  */
3920       if (plats->aggs_bottom)
3921         continue;
3922
3923       FOR_EACH_VEC_ELT (callers, j, cs)
3924         {
3925           inter = intersect_aggregates_with_edge (cs, i, inter);
3926
3927           if (!inter.exists ())
3928             goto next_param;
3929         }
3930
3931       FOR_EACH_VEC_ELT (inter, j, item)
3932         {
3933           struct ipa_agg_replacement_value *v;
3934
3935           if (!item->value)
3936             continue;
3937
3938           v = ggc_alloc<ipa_agg_replacement_value> ();
3939           v->index = i;
3940           v->offset = item->offset;
3941           v->value = item->value;
3942           v->by_ref = plats->aggs_by_ref;
3943           *tail = v;
3944           tail = &v->next;
3945         }
3946
3947     next_param:
3948       if (inter.exists ())
3949         inter.release ();
3950     }
3951   *tail = NULL;
3952   return res;
3953 }
3954
3955 /* Turn KNOWN_AGGS into a list of aggreate replacement values.  */
3956
3957 static struct ipa_agg_replacement_value *
3958 known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs)
3959 {
3960   struct ipa_agg_replacement_value *res;
3961   struct ipa_agg_replacement_value **tail = &res;
3962   struct ipa_agg_jump_function *aggjf;
3963   struct ipa_agg_jf_item *item;
3964   int i, j;
3965
3966   FOR_EACH_VEC_ELT (known_aggs, i, aggjf)
3967     FOR_EACH_VEC_SAFE_ELT (aggjf->items, j, item)
3968       {
3969         struct ipa_agg_replacement_value *v;
3970         v = ggc_alloc<ipa_agg_replacement_value> ();
3971         v->index = i;
3972         v->offset = item->offset;
3973         v->value = item->value;
3974         v->by_ref = aggjf->by_ref;
3975         *tail = v;
3976         tail = &v->next;
3977       }
3978   *tail = NULL;
3979   return res;
3980 }
3981
3982 /* Determine whether CS also brings all scalar values that the NODE is
3983    specialized for.  */
3984
3985 static bool
3986 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
3987                                          struct cgraph_node *node)
3988 {
3989   struct ipa_node_params *dest_info = IPA_NODE_REF (node);
3990   int count = ipa_get_param_count (dest_info);
3991   struct ipa_node_params *caller_info;
3992   struct ipa_edge_args *args;
3993   int i;
3994
3995   caller_info = IPA_NODE_REF (cs->caller);
3996   args = IPA_EDGE_REF (cs);
3997   for (i = 0; i < count; i++)
3998     {
3999       struct ipa_jump_func *jump_func;
4000       tree val, t;
4001
4002       val = dest_info->known_csts[i];
4003       if (!val)
4004         continue;
4005
4006       if (i >= ipa_get_cs_argument_count (args))
4007         return false;
4008       jump_func = ipa_get_ith_jump_func (args, i);
4009       t = ipa_value_from_jfunc (caller_info, jump_func);
4010       if (!t || !values_equal_for_ipcp_p (val, t))
4011         return false;
4012     }
4013   return true;
4014 }
4015
4016 /* Determine whether CS also brings all aggregate values that NODE is
4017    specialized for.  */
4018 static bool
4019 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
4020                                           struct cgraph_node *node)
4021 {
4022   struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller);
4023   struct ipa_node_params *orig_node_info;
4024   struct ipa_agg_replacement_value *aggval;
4025   int i, ec, count;
4026
4027   aggval = ipa_get_agg_replacements_for_node (node);
4028   if (!aggval)
4029     return true;
4030
4031   count = ipa_get_param_count (IPA_NODE_REF (node));
4032   ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
4033   if (ec < count)
4034     for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4035       if (aggval->index >= ec)
4036         return false;
4037
4038   orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
4039   if (orig_caller_info->ipcp_orig_node)
4040     orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node);
4041
4042   for (i = 0; i < count; i++)
4043     {
4044       static vec<ipa_agg_jf_item> values = vec<ipa_agg_jf_item>();
4045       struct ipcp_param_lattices *plats;
4046       bool interesting = false;
4047       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4048         if (aggval->index == i)
4049           {
4050             interesting = true;
4051             break;
4052           }
4053       if (!interesting)
4054         continue;
4055
4056       plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
4057       if (plats->aggs_bottom)
4058         return false;
4059
4060       values = intersect_aggregates_with_edge (cs, i, values);
4061       if (!values.exists ())
4062         return false;
4063
4064       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
4065         if (aggval->index == i)
4066           {
4067             struct ipa_agg_jf_item *item;
4068             int j;
4069             bool found = false;
4070             FOR_EACH_VEC_ELT (values, j, item)
4071               if (item->value
4072                   && item->offset == av->offset
4073                   && values_equal_for_ipcp_p (item->value, av->value))
4074                 {
4075                   found = true;
4076                   break;
4077                 }
4078             if (!found)
4079               {
4080                 values.release ();
4081                 return false;
4082               }
4083           }
4084     }
4085   return true;
4086 }
4087
4088 /* Given an original NODE and a VAL for which we have already created a
4089    specialized clone, look whether there are incoming edges that still lead
4090    into the old node but now also bring the requested value and also conform to
4091    all other criteria such that they can be redirected the special node.
4092    This function can therefore redirect the final edge in a SCC.  */
4093
4094 template <typename valtype>
4095 static void
4096 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
4097 {
4098   ipcp_value_source<valtype> *src;
4099   gcov_type redirected_sum = 0;
4100
4101   for (src = val->sources; src; src = src->next)
4102     {
4103       struct cgraph_edge *cs = src->cs;
4104       while (cs)
4105         {
4106           if (cgraph_edge_brings_value_p (cs, src, node)
4107               && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
4108               && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
4109             {
4110               if (dump_file)
4111                 fprintf (dump_file, " - adding an extra caller %s/%i"
4112                          " of %s/%i\n",
4113                          xstrdup_for_dump (cs->caller->name ()),
4114                          cs->caller->order,
4115                          xstrdup_for_dump (val->spec_node->name ()),
4116                          val->spec_node->order);
4117
4118               cs->redirect_callee_duplicating_thunks (val->spec_node);
4119               val->spec_node->expand_all_artificial_thunks ();
4120               redirected_sum += cs->count;
4121             }
4122           cs = get_next_cgraph_edge_clone (cs);
4123         }
4124     }
4125
4126   if (redirected_sum)
4127     update_specialized_profile (val->spec_node, node, redirected_sum);
4128 }
4129
4130 /* Return true if KNOWN_CONTEXTS contain at least one useful context.  */
4131
4132 static bool
4133 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
4134 {
4135   ipa_polymorphic_call_context *ctx;
4136   int i;
4137
4138   FOR_EACH_VEC_ELT (known_contexts, i, ctx)
4139     if (!ctx->useless_p ())
4140       return true;
4141   return false;
4142 }
4143
4144 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL.  */
4145
4146 static vec<ipa_polymorphic_call_context>
4147 copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
4148 {
4149   if (known_contexts_useful_p (known_contexts))
4150     return known_contexts.copy ();
4151   else
4152     return vNULL;
4153 }
4154
4155 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX.  If
4156    non-empty, replace KNOWN_CONTEXTS with its copy too.  */
4157
4158 static void
4159 modify_known_vectors_with_val (vec<tree> *known_csts,
4160                                vec<ipa_polymorphic_call_context> *known_contexts,
4161                                ipcp_value<tree> *val,
4162                                int index)
4163 {
4164   *known_csts = known_csts->copy ();
4165   *known_contexts = copy_useful_known_contexts (*known_contexts);
4166   (*known_csts)[index] = val->value;
4167 }
4168
4169 /* Replace KNOWN_CSTS with its copy.  Also copy KNOWN_CONTEXTS and modify the
4170    copy according to VAL and INDEX.  */
4171
4172 static void
4173 modify_known_vectors_with_val (vec<tree> *known_csts,
4174                                vec<ipa_polymorphic_call_context> *known_contexts,
4175                                ipcp_value<ipa_polymorphic_call_context> *val,
4176                                int index)
4177 {
4178   *known_csts = known_csts->copy ();
4179   *known_contexts = known_contexts->copy ();
4180   (*known_contexts)[index] = val->value;
4181 }
4182
4183 /* Return true if OFFSET indicates this was not an aggregate value or there is
4184    a replacement equivalent to VALUE, INDEX and OFFSET among those in the
4185    AGGVALS list.  */
4186
4187 DEBUG_FUNCTION bool
4188 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
4189                                int index, HOST_WIDE_INT offset, tree value)
4190 {
4191   if (offset == -1)
4192     return true;
4193
4194   while (aggvals)
4195     {
4196       if (aggvals->index == index
4197           && aggvals->offset == offset
4198           && values_equal_for_ipcp_p (aggvals->value, value))
4199         return true;
4200       aggvals = aggvals->next;
4201     }
4202   return false;
4203 }
4204
4205 /* Return true if offset is minus one because source of a polymorphic contect
4206    cannot be an aggregate value.  */
4207
4208 DEBUG_FUNCTION bool
4209 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
4210                                int , HOST_WIDE_INT offset,
4211                                ipa_polymorphic_call_context)
4212 {
4213   return offset == -1;
4214 }
4215
4216 /* Decide wheter to create a special version of NODE for value VAL of parameter
4217    at the given INDEX.  If OFFSET is -1, the value is for the parameter itself,
4218    otherwise it is stored at the given OFFSET of the parameter.  KNOWN_CSTS,
4219    KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values.  */
4220
4221 template <typename valtype>
4222 static bool
4223 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
4224                     ipcp_value<valtype> *val, vec<tree> known_csts,
4225                     vec<ipa_polymorphic_call_context> known_contexts)
4226 {
4227   struct ipa_agg_replacement_value *aggvals;
4228   int freq_sum, caller_count;
4229   gcov_type count_sum;
4230   vec<cgraph_edge *> callers;
4231
4232   if (val->spec_node)
4233     {
4234       perhaps_add_new_callers (node, val);
4235       return false;
4236     }
4237   else if (val->local_size_cost + overall_size > max_new_size)
4238     {
4239       if (dump_file && (dump_flags & TDF_DETAILS))
4240         fprintf (dump_file, "   Ignoring candidate value because "
4241                  "max_new_size would be reached with %li.\n",
4242                  val->local_size_cost + overall_size);
4243       return false;
4244     }
4245   else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
4246                                             &caller_count))
4247     return false;
4248
4249   if (dump_file && (dump_flags & TDF_DETAILS))
4250     {
4251       fprintf (dump_file, " - considering value ");
4252       print_ipcp_constant_value (dump_file, val->value);
4253       fprintf (dump_file, " for ");
4254       ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
4255       if (offset != -1)
4256         fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
4257       fprintf (dump_file, " (caller_count: %i)\n", caller_count);
4258     }
4259
4260   if (!good_cloning_opportunity_p (node, val->local_time_benefit,
4261                                    freq_sum, count_sum,
4262                                    val->local_size_cost)
4263       && !good_cloning_opportunity_p (node,
4264                                       val->local_time_benefit
4265                                       + val->prop_time_benefit,
4266                                       freq_sum, count_sum,
4267                                       val->local_size_cost
4268                                       + val->prop_size_cost))
4269     return false;
4270
4271   if (dump_file)
4272     fprintf (dump_file, "  Creating a specialized node of %s/%i.\n",
4273              node->name (), node->order);
4274
4275   callers = gather_edges_for_value (val, node, caller_count);
4276   if (offset == -1)
4277     modify_known_vectors_with_val (&known_csts, &known_contexts, val, index);
4278   else
4279     {
4280       known_csts = known_csts.copy ();
4281       known_contexts = copy_useful_known_contexts (known_contexts);
4282     }
4283   find_more_scalar_values_for_callers_subset (node, known_csts, callers);
4284   find_more_contexts_for_caller_subset (node, &known_contexts, callers);
4285   aggvals = find_aggregate_values_for_callers_subset (node, callers);
4286   gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
4287                                                       offset, val->value));
4288   val->spec_node = create_specialized_node (node, known_csts, known_contexts,
4289                                             aggvals, callers);
4290   overall_size += val->local_size_cost;
4291
4292   /* TODO: If for some lattice there is only one other known value
4293      left, make a special node for it too. */
4294
4295   return true;
4296 }
4297
4298 /* Decide whether and what specialized clones of NODE should be created.  */
4299
4300 static bool
4301 decide_whether_version_node (struct cgraph_node *node)
4302 {
4303   struct ipa_node_params *info = IPA_NODE_REF (node);
4304   int i, count = ipa_get_param_count (info);
4305   vec<tree> known_csts;
4306   vec<ipa_polymorphic_call_context> known_contexts;
4307   vec<ipa_agg_jump_function> known_aggs = vNULL;
4308   bool ret = false;
4309
4310   if (count == 0)
4311     return false;
4312
4313   if (dump_file && (dump_flags & TDF_DETAILS))
4314     fprintf (dump_file, "\nEvaluating opportunities for %s/%i.\n",
4315              node->name (), node->order);
4316
4317   gather_context_independent_values (info, &known_csts, &known_contexts,
4318                                   info->do_clone_for_all_contexts ? &known_aggs
4319                                   : NULL, NULL);
4320
4321   for (i = 0; i < count ;i++)
4322     {
4323       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4324       ipcp_lattice<tree> *lat = &plats->itself;
4325       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
4326
4327       if (!lat->bottom
4328           && !known_csts[i])
4329         {
4330           ipcp_value<tree> *val;
4331           for (val = lat->values; val; val = val->next)
4332             ret |= decide_about_value (node, i, -1, val, known_csts,
4333                                        known_contexts);
4334         }
4335
4336       if (!plats->aggs_bottom)
4337         {
4338           struct ipcp_agg_lattice *aglat;
4339           ipcp_value<tree> *val;
4340           for (aglat = plats->aggs; aglat; aglat = aglat->next)
4341             if (!aglat->bottom && aglat->values
4342                 /* If the following is false, the one value is in
4343                    known_aggs.  */
4344                 && (plats->aggs_contain_variable
4345                     || !aglat->is_single_const ()))
4346               for (val = aglat->values; val; val = val->next)
4347                 ret |= decide_about_value (node, i, aglat->offset, val,
4348                                            known_csts, known_contexts);
4349         }
4350
4351       if (!ctxlat->bottom
4352           && known_contexts[i].useless_p ())
4353         {
4354           ipcp_value<ipa_polymorphic_call_context> *val;
4355           for (val = ctxlat->values; val; val = val->next)
4356             ret |= decide_about_value (node, i, -1, val, known_csts,
4357                                        known_contexts);
4358         }
4359
4360         info = IPA_NODE_REF (node);
4361     }
4362
4363   if (info->do_clone_for_all_contexts)
4364     {
4365       struct cgraph_node *clone;
4366       vec<cgraph_edge *> callers;
4367
4368       if (dump_file)
4369         fprintf (dump_file, " - Creating a specialized node of %s/%i "
4370                  "for all known contexts.\n", node->name (),
4371                  node->order);
4372
4373       callers = node->collect_callers ();
4374
4375       if (!known_contexts_useful_p (known_contexts))
4376         {
4377           known_contexts.release ();
4378           known_contexts = vNULL;
4379         }
4380       clone = create_specialized_node (node, known_csts, known_contexts,
4381                                known_aggs_to_agg_replacement_list (known_aggs),
4382                                callers);
4383       info = IPA_NODE_REF (node);
4384       info->do_clone_for_all_contexts = false;
4385       IPA_NODE_REF (clone)->is_all_contexts_clone = true;
4386       for (i = 0; i < count ; i++)
4387         vec_free (known_aggs[i].items);
4388       known_aggs.release ();
4389       ret = true;
4390     }
4391   else
4392     {
4393       known_csts.release ();
4394       known_contexts.release ();
4395     }
4396
4397   return ret;
4398 }
4399
4400 /* Transitively mark all callees of NODE within the same SCC as not dead.  */
4401
4402 static void
4403 spread_undeadness (struct cgraph_node *node)
4404 {
4405   struct cgraph_edge *cs;
4406
4407   for (cs = node->callees; cs; cs = cs->next_callee)
4408     if (ipa_edge_within_scc (cs))
4409       {
4410         struct cgraph_node *callee;
4411         struct ipa_node_params *info;
4412
4413         callee = cs->callee->function_symbol (NULL);
4414         info = IPA_NODE_REF (callee);
4415
4416         if (info->node_dead)
4417           {
4418             info->node_dead = 0;
4419             spread_undeadness (callee);
4420           }
4421       }
4422 }
4423
4424 /* Return true if NODE has a caller from outside of its SCC that is not
4425    dead.  Worker callback for cgraph_for_node_and_aliases.  */
4426
4427 static bool
4428 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
4429                                      void *data ATTRIBUTE_UNUSED)
4430 {
4431   struct cgraph_edge *cs;
4432
4433   for (cs = node->callers; cs; cs = cs->next_caller)
4434     if (cs->caller->thunk.thunk_p
4435         && cs->caller->call_for_symbol_thunks_and_aliases
4436           (has_undead_caller_from_outside_scc_p, NULL, true))
4437       return true;
4438     else if (!ipa_edge_within_scc (cs)
4439              && !IPA_NODE_REF (cs->caller)->node_dead)
4440       return true;
4441   return false;
4442 }
4443
4444
4445 /* Identify nodes within the same SCC as NODE which are no longer needed
4446    because of new clones and will be removed as unreachable.  */
4447
4448 static void
4449 identify_dead_nodes (struct cgraph_node *node)
4450 {
4451   struct cgraph_node *v;
4452   for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4453     if (v->local.local
4454         && !v->call_for_symbol_thunks_and_aliases
4455              (has_undead_caller_from_outside_scc_p, NULL, true))
4456       IPA_NODE_REF (v)->node_dead = 1;
4457
4458   for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4459     if (!IPA_NODE_REF (v)->node_dead)
4460       spread_undeadness (v);
4461
4462   if (dump_file && (dump_flags & TDF_DETAILS))
4463     {
4464       for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4465         if (IPA_NODE_REF (v)->node_dead)
4466           fprintf (dump_file, "  Marking node as dead: %s/%i.\n",
4467                    v->name (), v->order);
4468     }
4469 }
4470
4471 /* The decision stage.  Iterate over the topological order of call graph nodes
4472    TOPO and make specialized clones if deemed beneficial.  */
4473
4474 static void
4475 ipcp_decision_stage (struct ipa_topo_info *topo)
4476 {
4477   int i;
4478
4479   if (dump_file)
4480     fprintf (dump_file, "\nIPA decision stage:\n\n");
4481
4482   for (i = topo->nnodes - 1; i >= 0; i--)
4483     {
4484       struct cgraph_node *node = topo->order[i];
4485       bool change = false, iterate = true;
4486
4487       while (iterate)
4488         {
4489           struct cgraph_node *v;
4490           iterate = false;
4491           for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4492             if (v->has_gimple_body_p ()
4493                 && ipcp_versionable_function_p (v))
4494               iterate |= decide_whether_version_node (v);
4495
4496           change |= iterate;
4497         }
4498       if (change)
4499         identify_dead_nodes (node);
4500     }
4501 }
4502
4503 /* Look up all alignment information that we have discovered and copy it over
4504    to the transformation summary.  */
4505
4506 static void
4507 ipcp_store_alignment_results (void)
4508 {
4509   cgraph_node *node;
4510
4511   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
4512   {
4513     ipa_node_params *info = IPA_NODE_REF (node);
4514     bool dumped_sth = false;
4515     bool found_useful_result = false;
4516
4517     if (!opt_for_fn (node->decl, flag_ipa_cp_alignment))
4518       {
4519         if (dump_file)
4520           fprintf (dump_file, "Not considering %s for alignment discovery "
4521                    "and propagate; -fipa-cp-alignment: disabled.\n",
4522                    node->name ());
4523         continue;
4524       }
4525
4526    if (info->ipcp_orig_node)
4527       info = IPA_NODE_REF (info->ipcp_orig_node);
4528
4529    unsigned count = ipa_get_param_count (info);
4530    for (unsigned i = 0; i < count ; i++)
4531      {
4532        ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4533        if (!plats->alignment.bottom_p ()
4534            && !plats->alignment.top_p ())
4535          {
4536            gcc_checking_assert (plats->alignment.align > 0);
4537            found_useful_result = true;
4538            break;
4539          }
4540      }
4541    if (!found_useful_result)
4542      continue;
4543
4544    ipcp_grow_transformations_if_necessary ();
4545    ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
4546    vec_safe_reserve_exact (ts->alignments, count);
4547
4548    for (unsigned i = 0; i < count ; i++)
4549      {
4550        ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4551        ipa_alignment al;
4552
4553        if (!plats->alignment.bottom_p ()
4554            && !plats->alignment.top_p ())
4555          {
4556            al.known = true;
4557            al.align = plats->alignment.align;
4558            al.misalign = plats->alignment.misalign;
4559          }
4560        else
4561          al.known = false;
4562
4563        ts->alignments->quick_push (al);
4564        if (!dump_file || !al.known)
4565          continue;
4566        if (!dumped_sth)
4567          {
4568            fprintf (dump_file, "Propagated alignment info for function %s/%i:\n",
4569                     node->name (), node->order);
4570            dumped_sth = true;
4571          }
4572        fprintf (dump_file, "  param %i: align: %u, misalign: %u\n",
4573                 i, al.align, al.misalign);
4574      }
4575   }
4576 }
4577
4578 /* The IPCP driver.  */
4579
4580 static unsigned int
4581 ipcp_driver (void)
4582 {
4583   struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
4584   struct cgraph_edge_hook_list *edge_removal_hook_holder;
4585   struct ipa_topo_info topo;
4586
4587   ipa_check_create_node_params ();
4588   ipa_check_create_edge_args ();
4589   grow_edge_clone_vectors ();
4590   edge_duplication_hook_holder =
4591     symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
4592   edge_removal_hook_holder =
4593     symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
4594
4595   if (dump_file)
4596     {
4597       fprintf (dump_file, "\nIPA structures before propagation:\n");
4598       if (dump_flags & TDF_DETAILS)
4599         ipa_print_all_params (dump_file);
4600       ipa_print_all_jump_functions (dump_file);
4601     }
4602
4603   /* Topological sort.  */
4604   build_toporder_info (&topo);
4605   /* Do the interprocedural propagation.  */
4606   ipcp_propagate_stage (&topo);
4607   /* Decide what constant propagation and cloning should be performed.  */
4608   ipcp_decision_stage (&topo);
4609   /* Store results of alignment propagation. */
4610   ipcp_store_alignment_results ();
4611
4612   /* Free all IPCP structures.  */
4613   free_toporder_info (&topo);
4614   next_edge_clone.release ();
4615   prev_edge_clone.release ();
4616   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
4617   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
4618   ipa_free_all_structures_after_ipa_cp ();
4619   if (dump_file)
4620     fprintf (dump_file, "\nIPA constant propagation end\n");
4621   return 0;
4622 }
4623
4624 /* Initialization and computation of IPCP data structures.  This is the initial
4625    intraprocedural analysis of functions, which gathers information to be
4626    propagated later on.  */
4627
4628 static void
4629 ipcp_generate_summary (void)
4630 {
4631   struct cgraph_node *node;
4632
4633   if (dump_file)
4634     fprintf (dump_file, "\nIPA constant propagation start:\n");
4635   ipa_register_cgraph_hooks ();
4636
4637   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
4638     ipa_analyze_node (node);
4639 }
4640
4641 /* Write ipcp summary for nodes in SET.  */
4642
4643 static void
4644 ipcp_write_summary (void)
4645 {
4646   ipa_prop_write_jump_functions ();
4647 }
4648
4649 /* Read ipcp summary.  */
4650
4651 static void
4652 ipcp_read_summary (void)
4653 {
4654   ipa_prop_read_jump_functions ();
4655 }
4656
4657 namespace {
4658
4659 const pass_data pass_data_ipa_cp =
4660 {
4661   IPA_PASS, /* type */
4662   "cp", /* name */
4663   OPTGROUP_NONE, /* optinfo_flags */
4664   TV_IPA_CONSTANT_PROP, /* tv_id */
4665   0, /* properties_required */
4666   0, /* properties_provided */
4667   0, /* properties_destroyed */
4668   0, /* todo_flags_start */
4669   ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
4670 };
4671
4672 class pass_ipa_cp : public ipa_opt_pass_d
4673 {
4674 public:
4675   pass_ipa_cp (gcc::context *ctxt)
4676     : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
4677                       ipcp_generate_summary, /* generate_summary */
4678                       ipcp_write_summary, /* write_summary */
4679                       ipcp_read_summary, /* read_summary */
4680                       ipcp_write_transformation_summaries, /*
4681                       write_optimization_summary */
4682                       ipcp_read_transformation_summaries, /*
4683                       read_optimization_summary */
4684                       NULL, /* stmt_fixup */
4685                       0, /* function_transform_todo_flags_start */
4686                       ipcp_transform_function, /* function_transform */
4687                       NULL) /* variable_transform */
4688   {}
4689
4690   /* opt_pass methods: */
4691   virtual bool gate (function *)
4692     {
4693       /* FIXME: We should remove the optimize check after we ensure we never run
4694          IPA passes when not optimizing.  */
4695       return (flag_ipa_cp && optimize) || in_lto_p;
4696     }
4697
4698   virtual unsigned int execute (function *) { return ipcp_driver (); }
4699
4700 }; // class pass_ipa_cp
4701
4702 } // anon namespace
4703
4704 ipa_opt_pass_d *
4705 make_pass_ipa_cp (gcc::context *ctxt)
4706 {
4707   return new pass_ipa_cp (ctxt);
4708 }
4709
4710 /* Reset all state within ipa-cp.c so that we can rerun the compiler
4711    within the same process.  For use by toplev::finalize.  */
4712
4713 void
4714 ipa_cp_c_finalize (void)
4715 {
4716   max_count = 0;
4717   overall_size = 0;
4718   max_new_size = 0;
4719 }