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