Merge branch 'vendor/GCC50'
[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 /* Propagate constants from the caller to the callee of CS.  INFO describes the
1791    caller.  */
1792
1793 static bool
1794 propagate_constants_accross_call (struct cgraph_edge *cs)
1795 {
1796   struct ipa_node_params *callee_info;
1797   enum availability availability;
1798   struct cgraph_node *callee, *alias_or_thunk;
1799   struct ipa_edge_args *args;
1800   bool ret = false;
1801   int i, args_count, parms_count;
1802
1803   callee = cs->callee->function_symbol (&availability);
1804   if (!callee->definition)
1805     return false;
1806   gcc_checking_assert (callee->has_gimple_body_p ());
1807   callee_info = IPA_NODE_REF (callee);
1808
1809   args = IPA_EDGE_REF (cs);
1810   args_count = ipa_get_cs_argument_count (args);
1811   parms_count = ipa_get_param_count (callee_info);
1812   if (parms_count == 0)
1813     return false;
1814
1815   /* No propagation through instrumentation thunks is available yet.
1816      It should be possible with proper mapping of call args and
1817      instrumented callee params in the propagation loop below.  But
1818      this case mostly occurs when legacy code calls instrumented code
1819      and it is not a primary target for optimizations.
1820      We detect instrumentation thunks in aliases and thunks chain by
1821      checking instrumentation_clone flag for chain source and target.
1822      Going through instrumentation thunks we always have it changed
1823      from 0 to 1 and all other nodes do not change it.  */
1824   if (!cs->callee->instrumentation_clone
1825       && callee->instrumentation_clone)
1826     {
1827       for (i = 0; i < parms_count; i++)
1828         ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1829                                                                  i));
1830       return ret;
1831     }
1832
1833   /* If this call goes through a thunk we must not propagate to the first (0th)
1834      parameter.  However, we might need to uncover a thunk from below a series
1835      of aliases first.  */
1836   alias_or_thunk = cs->callee;
1837   while (alias_or_thunk->alias)
1838     alias_or_thunk = alias_or_thunk->get_alias_target ();
1839   if (alias_or_thunk->thunk.thunk_p)
1840     {
1841       ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
1842                                                                0));
1843       i = 1;
1844     }
1845   else
1846     i = 0;
1847
1848   for (; (i < args_count) && (i < parms_count); i++)
1849     {
1850       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
1851       struct ipcp_param_lattices *dest_plats;
1852
1853       dest_plats = ipa_get_parm_lattices (callee_info, i);
1854       if (availability == AVAIL_INTERPOSABLE)
1855         ret |= set_all_contains_variable (dest_plats);
1856       else
1857         {
1858           ret |= propagate_scalar_accross_jump_function (cs, jump_func,
1859                                                          &dest_plats->itself);
1860           ret |= propagate_context_accross_jump_function (cs, jump_func, i,
1861                                                           &dest_plats->ctxlat);
1862           ret |= propagate_alignment_accross_jump_function (cs, jump_func,
1863                                                             dest_plats);
1864           ret |= propagate_aggs_accross_jump_function (cs, jump_func,
1865                                                        dest_plats);
1866         }
1867     }
1868   for (; i < parms_count; i++)
1869     ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
1870
1871   return ret;
1872 }
1873
1874 /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
1875    KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination.  The latter
1876    three can be NULL.  If AGG_REPS is not NULL, KNOWN_AGGS is ignored.  */
1877
1878 static tree
1879 ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
1880                                 vec<tree> known_csts,
1881                                 vec<ipa_polymorphic_call_context> known_contexts,
1882                                 vec<ipa_agg_jump_function_p> known_aggs,
1883                                 struct ipa_agg_replacement_value *agg_reps,
1884                                 bool *speculative)
1885 {
1886   int param_index = ie->indirect_info->param_index;
1887   HOST_WIDE_INT anc_offset;
1888   tree t;
1889   tree target = NULL;
1890
1891   *speculative = false;
1892
1893   if (param_index == -1
1894       || known_csts.length () <= (unsigned int) param_index)
1895     return NULL_TREE;
1896
1897   if (!ie->indirect_info->polymorphic)
1898     {
1899       tree t;
1900
1901       if (ie->indirect_info->agg_contents)
1902         {
1903           if (agg_reps)
1904             {
1905               t = NULL;
1906               while (agg_reps)
1907                 {
1908                   if (agg_reps->index == param_index
1909                       && agg_reps->offset == ie->indirect_info->offset
1910                       && agg_reps->by_ref == ie->indirect_info->by_ref)
1911                     {
1912                       t = agg_reps->value;
1913                       break;
1914                     }
1915                   agg_reps = agg_reps->next;
1916                 }
1917             }
1918           else if (known_aggs.length () > (unsigned int) param_index)
1919             {
1920               struct ipa_agg_jump_function *agg;
1921               agg = known_aggs[param_index];
1922               t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
1923                                               ie->indirect_info->by_ref);
1924             }
1925           else
1926             t = NULL;
1927         }
1928       else
1929         t = known_csts[param_index];
1930
1931       if (t &&
1932           TREE_CODE (t) == ADDR_EXPR
1933           && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
1934         return TREE_OPERAND (t, 0);
1935       else
1936         return NULL_TREE;
1937     }
1938
1939   if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
1940     return NULL_TREE;
1941
1942   gcc_assert (!ie->indirect_info->agg_contents);
1943   anc_offset = ie->indirect_info->offset;
1944
1945   t = NULL;
1946
1947   /* Try to work out value of virtual table pointer value in replacemnets.  */
1948   if (!t && agg_reps && !ie->indirect_info->by_ref)
1949     {
1950       while (agg_reps)
1951         {
1952           if (agg_reps->index == param_index
1953               && agg_reps->offset == ie->indirect_info->offset
1954               && agg_reps->by_ref)
1955             {
1956               t = agg_reps->value;
1957               break;
1958             }
1959           agg_reps = agg_reps->next;
1960         }
1961     }
1962
1963   /* Try to work out value of virtual table pointer value in known
1964      aggregate values.  */
1965   if (!t && known_aggs.length () > (unsigned int) param_index
1966       && !ie->indirect_info->by_ref)
1967     {
1968        struct ipa_agg_jump_function *agg;
1969        agg = known_aggs[param_index];
1970        t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
1971                                        true);
1972     }
1973
1974   /* If we found the virtual table pointer, lookup the target.  */
1975   if (t)
1976     {
1977       tree vtable;
1978       unsigned HOST_WIDE_INT offset;
1979       if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
1980         {
1981           target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
1982                                                       vtable, offset);
1983           if (target)
1984             {
1985               if ((TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE
1986                    && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
1987                   || !possible_polymorphic_call_target_p
1988                        (ie, cgraph_node::get (target)))
1989                 target = ipa_impossible_devirt_target (ie, target);
1990               *speculative = ie->indirect_info->vptr_changed;
1991               if (!*speculative)
1992                 return target;
1993             }
1994         }
1995     }
1996
1997   /* Do we know the constant value of pointer?  */
1998   if (!t)
1999     t = known_csts[param_index];
2000
2001   gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
2002
2003   ipa_polymorphic_call_context context;
2004   if (known_contexts.length () > (unsigned int) param_index)
2005     {
2006       context = known_contexts[param_index];
2007       context.offset_by (anc_offset);
2008       if (ie->indirect_info->vptr_changed)
2009         context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2010                                               ie->indirect_info->otr_type);
2011       if (t)
2012         {
2013           ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
2014             (t, ie->indirect_info->otr_type, anc_offset);
2015           if (!ctx2.useless_p ())
2016             context.combine_with (ctx2, ie->indirect_info->otr_type);
2017         }
2018     }
2019   else if (t)
2020     {
2021       context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
2022                                               anc_offset);
2023       if (ie->indirect_info->vptr_changed)
2024         context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
2025                                               ie->indirect_info->otr_type);
2026     }
2027   else
2028     return NULL_TREE;
2029
2030   vec <cgraph_node *>targets;
2031   bool final;
2032
2033   targets = possible_polymorphic_call_targets
2034     (ie->indirect_info->otr_type,
2035      ie->indirect_info->otr_token,
2036      context, &final);
2037   if (!final || targets.length () > 1)
2038     {
2039       struct cgraph_node *node;
2040       if (*speculative)
2041         return target;
2042       if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
2043           || ie->speculative || !ie->maybe_hot_p ())
2044         return NULL;
2045       node = try_speculative_devirtualization (ie->indirect_info->otr_type,
2046                                                ie->indirect_info->otr_token,
2047                                                context);
2048       if (node)
2049         {
2050           *speculative = true;
2051           target = node->decl;
2052         }
2053       else
2054         return NULL;
2055     }
2056   else
2057     {
2058       *speculative = false;
2059       if (targets.length () == 1)
2060         target = targets[0]->decl;
2061       else
2062         target = ipa_impossible_devirt_target (ie, NULL_TREE);
2063     }
2064
2065   if (target && !possible_polymorphic_call_target_p (ie,
2066                                                      cgraph_node::get (target)))
2067     target = ipa_impossible_devirt_target (ie, target);
2068
2069   return target;
2070 }
2071
2072
2073 /* If an indirect edge IE can be turned into a direct one based on KNOWN_CSTS,
2074    KNOWN_CONTEXTS (which can be vNULL) or KNOWN_AGGS (which also can be vNULL)
2075    return the destination.  */
2076
2077 tree
2078 ipa_get_indirect_edge_target (struct cgraph_edge *ie,
2079                               vec<tree> known_csts,
2080                               vec<ipa_polymorphic_call_context> known_contexts,
2081                               vec<ipa_agg_jump_function_p> known_aggs,
2082                               bool *speculative)
2083 {
2084   return ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2085                                          known_aggs, NULL, speculative);
2086 }
2087
2088 /* Calculate devirtualization time bonus for NODE, assuming we know KNOWN_CSTS
2089    and KNOWN_CONTEXTS.  */
2090
2091 static int
2092 devirtualization_time_bonus (struct cgraph_node *node,
2093                              vec<tree> known_csts,
2094                              vec<ipa_polymorphic_call_context> known_contexts,
2095                              vec<ipa_agg_jump_function_p> known_aggs)
2096 {
2097   struct cgraph_edge *ie;
2098   int res = 0;
2099
2100   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
2101     {
2102       struct cgraph_node *callee;
2103       struct inline_summary *isummary;
2104       enum availability avail;
2105       tree target;
2106       bool speculative;
2107
2108       target = ipa_get_indirect_edge_target (ie, known_csts, known_contexts,
2109                                              known_aggs, &speculative);
2110       if (!target)
2111         continue;
2112
2113       /* Only bare minimum benefit for clearly un-inlineable targets.  */
2114       res += 1;
2115       callee = cgraph_node::get (target);
2116       if (!callee || !callee->definition)
2117         continue;
2118       callee = callee->function_symbol (&avail);
2119       if (avail < AVAIL_AVAILABLE)
2120         continue;
2121       isummary = inline_summaries->get (callee);
2122       if (!isummary->inlinable)
2123         continue;
2124
2125       /* FIXME: The values below need re-considering and perhaps also
2126          integrating into the cost metrics, at lest in some very basic way.  */
2127       if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
2128         res += 31 / ((int)speculative + 1);
2129       else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
2130         res += 15 / ((int)speculative + 1);
2131       else if (isummary->size <= MAX_INLINE_INSNS_AUTO
2132                || DECL_DECLARED_INLINE_P (callee->decl))
2133         res += 7 / ((int)speculative + 1);
2134     }
2135
2136   return res;
2137 }
2138
2139 /* Return time bonus incurred because of HINTS.  */
2140
2141 static int
2142 hint_time_bonus (inline_hints hints)
2143 {
2144   int result = 0;
2145   if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
2146     result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);
2147   if (hints & INLINE_HINT_array_index)
2148     result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
2149   return result;
2150 }
2151
2152 /* If there is a reason to penalize the function described by INFO in the
2153    cloning goodness evaluation, do so.  */
2154
2155 static inline int64_t
2156 incorporate_penalties (ipa_node_params *info, int64_t evaluation)
2157 {
2158   if (info->node_within_scc)
2159     evaluation = (evaluation
2160                   * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;
2161
2162   if (info->node_calling_single_call)
2163     evaluation = (evaluation
2164                   * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))
2165       / 100;
2166
2167   return evaluation;
2168 }
2169
2170 /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
2171    and SIZE_COST and with the sum of frequencies of incoming edges to the
2172    potential new clone in FREQUENCIES.  */
2173
2174 static bool
2175 good_cloning_opportunity_p (struct cgraph_node *node, int time_benefit,
2176                             int freq_sum, gcov_type count_sum, int size_cost)
2177 {
2178   if (time_benefit == 0
2179       || !opt_for_fn (node->decl, flag_ipa_cp_clone)
2180       || !optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
2181     return false;
2182
2183   gcc_assert (size_cost > 0);
2184
2185   struct ipa_node_params *info = IPA_NODE_REF (node);
2186   if (max_count)
2187     {
2188       int factor = (count_sum * 1000) / max_count;
2189       int64_t evaluation = (((int64_t) time_benefit * factor)
2190                                     / size_cost);
2191       evaluation = incorporate_penalties (info, evaluation);
2192
2193       if (dump_file && (dump_flags & TDF_DETAILS))
2194         fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
2195                  "size: %i, count_sum: " HOST_WIDE_INT_PRINT_DEC
2196                  "%s%s) -> evaluation: " "%"PRId64
2197                  ", threshold: %i\n",
2198                  time_benefit, size_cost, (HOST_WIDE_INT) count_sum,
2199                  info->node_within_scc ? ", scc" : "",
2200                  info->node_calling_single_call ? ", single_call" : "",
2201                  evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
2202
2203       return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
2204     }
2205   else
2206     {
2207       int64_t evaluation = (((int64_t) time_benefit * freq_sum)
2208                                     / size_cost);
2209       evaluation = incorporate_penalties (info, evaluation);
2210
2211       if (dump_file && (dump_flags & TDF_DETAILS))
2212         fprintf (dump_file, "     good_cloning_opportunity_p (time: %i, "
2213                  "size: %i, freq_sum: %i%s%s) -> evaluation: "
2214                  "%"PRId64 ", threshold: %i\n",
2215                  time_benefit, size_cost, freq_sum,
2216                  info->node_within_scc ? ", scc" : "",
2217                  info->node_calling_single_call ? ", single_call" : "",
2218                  evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
2219
2220       return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
2221     }
2222 }
2223
2224 /* Return all context independent values from aggregate lattices in PLATS in a
2225    vector.  Return NULL if there are none.  */
2226
2227 static vec<ipa_agg_jf_item, va_gc> *
2228 context_independent_aggregate_values (struct ipcp_param_lattices *plats)
2229 {
2230   vec<ipa_agg_jf_item, va_gc> *res = NULL;
2231
2232   if (plats->aggs_bottom
2233       || plats->aggs_contain_variable
2234       || plats->aggs_count == 0)
2235     return NULL;
2236
2237   for (struct ipcp_agg_lattice *aglat = plats->aggs;
2238        aglat;
2239        aglat = aglat->next)
2240     if (aglat->is_single_const ())
2241       {
2242         struct ipa_agg_jf_item item;
2243         item.offset = aglat->offset;
2244         item.value = aglat->values->value;
2245         vec_safe_push (res, item);
2246       }
2247   return res;
2248 }
2249
2250 /* Allocate KNOWN_CSTS, KNOWN_CONTEXTS and, if non-NULL, KNOWN_AGGS and
2251    populate them with values of parameters that are known independent of the
2252    context.  INFO describes the function.  If REMOVABLE_PARAMS_COST is
2253    non-NULL, the movement cost of all removable parameters will be stored in
2254    it.  */
2255
2256 static bool
2257 gather_context_independent_values (struct ipa_node_params *info,
2258                                    vec<tree> *known_csts,
2259                                    vec<ipa_polymorphic_call_context>
2260                                    *known_contexts,
2261                                    vec<ipa_agg_jump_function> *known_aggs,
2262                                    int *removable_params_cost)
2263 {
2264   int i, count = ipa_get_param_count (info);
2265   bool ret = false;
2266
2267   known_csts->create (0);
2268   known_contexts->create (0);
2269   known_csts->safe_grow_cleared (count);
2270   known_contexts->safe_grow_cleared (count);
2271   if (known_aggs)
2272     {
2273       known_aggs->create (0);
2274       known_aggs->safe_grow_cleared (count);
2275     }
2276
2277   if (removable_params_cost)
2278     *removable_params_cost = 0;
2279
2280   for (i = 0; i < count ; i++)
2281     {
2282       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2283       ipcp_lattice<tree> *lat = &plats->itself;
2284
2285       if (lat->is_single_const ())
2286         {
2287           ipcp_value<tree> *val = lat->values;
2288           gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
2289           (*known_csts)[i] = val->value;
2290           if (removable_params_cost)
2291             *removable_params_cost
2292               += estimate_move_cost (TREE_TYPE (val->value), false);
2293           ret = true;
2294         }
2295       else if (removable_params_cost
2296                && !ipa_is_param_used (info, i))
2297         *removable_params_cost
2298           += ipa_get_param_move_cost (info, i);
2299
2300       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2301       if (ctxlat->is_single_const ())
2302         {
2303           (*known_contexts)[i] = ctxlat->values->value;
2304           ret = true;
2305         }
2306
2307       if (known_aggs)
2308         {
2309           vec<ipa_agg_jf_item, va_gc> *agg_items;
2310           struct ipa_agg_jump_function *ajf;
2311
2312           agg_items = context_independent_aggregate_values (plats);
2313           ajf = &(*known_aggs)[i];
2314           ajf->items = agg_items;
2315           ajf->by_ref = plats->aggs_by_ref;
2316           ret |= agg_items != NULL;
2317         }
2318     }
2319
2320   return ret;
2321 }
2322
2323 /* The current interface in ipa-inline-analysis requires a pointer vector.
2324    Create it.
2325
2326    FIXME: That interface should be re-worked, this is slightly silly.  Still,
2327    I'd like to discuss how to change it first and this demonstrates the
2328    issue.  */
2329
2330 static vec<ipa_agg_jump_function_p>
2331 agg_jmp_p_vec_for_t_vec (vec<ipa_agg_jump_function> known_aggs)
2332 {
2333   vec<ipa_agg_jump_function_p> ret;
2334   struct ipa_agg_jump_function *ajf;
2335   int i;
2336
2337   ret.create (known_aggs.length ());
2338   FOR_EACH_VEC_ELT (known_aggs, i, ajf)
2339     ret.quick_push (ajf);
2340   return ret;
2341 }
2342
2343 /* Perform time and size measurement of NODE with the context given in
2344    KNOWN_CSTS, KNOWN_CONTEXTS and KNOWN_AGGS, calculate the benefit and cost
2345    given BASE_TIME of the node without specialization, REMOVABLE_PARAMS_COST of
2346    all context-independent removable parameters and EST_MOVE_COST of estimated
2347    movement of the considered parameter and store it into VAL.  */
2348
2349 static void
2350 perform_estimation_of_a_value (cgraph_node *node, vec<tree> known_csts,
2351                                vec<ipa_polymorphic_call_context> known_contexts,
2352                                vec<ipa_agg_jump_function_p> known_aggs_ptrs,
2353                                int base_time, int removable_params_cost,
2354                                int est_move_cost, ipcp_value_base *val)
2355 {
2356   int time, size, time_benefit;
2357   inline_hints hints;
2358
2359   estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2360                                      known_aggs_ptrs, &size, &time,
2361                                      &hints);
2362   time_benefit = base_time - time
2363     + devirtualization_time_bonus (node, known_csts, known_contexts,
2364                                    known_aggs_ptrs)
2365     + hint_time_bonus (hints)
2366     + removable_params_cost + est_move_cost;
2367
2368   gcc_checking_assert (size >=0);
2369   /* The inliner-heuristics based estimates may think that in certain
2370      contexts some functions do not have any size at all but we want
2371      all specializations to have at least a tiny cost, not least not to
2372      divide by zero.  */
2373   if (size == 0)
2374     size = 1;
2375
2376   val->local_time_benefit = time_benefit;
2377   val->local_size_cost = size;
2378 }
2379
2380 /* Iterate over known values of parameters of NODE and estimate the local
2381    effects in terms of time and size they have.  */
2382
2383 static void
2384 estimate_local_effects (struct cgraph_node *node)
2385 {
2386   struct ipa_node_params *info = IPA_NODE_REF (node);
2387   int i, count = ipa_get_param_count (info);
2388   vec<tree> known_csts;
2389   vec<ipa_polymorphic_call_context> known_contexts;
2390   vec<ipa_agg_jump_function> known_aggs;
2391   vec<ipa_agg_jump_function_p> known_aggs_ptrs;
2392   bool always_const;
2393   int base_time = inline_summaries->get (node)->time;
2394   int removable_params_cost;
2395
2396   if (!count || !ipcp_versionable_function_p (node))
2397     return;
2398
2399   if (dump_file && (dump_flags & TDF_DETAILS))
2400     fprintf (dump_file, "\nEstimating effects for %s/%i, base_time: %i.\n",
2401              node->name (), node->order, base_time);
2402
2403   always_const = gather_context_independent_values (info, &known_csts,
2404                                                     &known_contexts, &known_aggs,
2405                                                     &removable_params_cost);
2406   known_aggs_ptrs = agg_jmp_p_vec_for_t_vec (known_aggs);
2407   if (always_const)
2408     {
2409       struct caller_statistics stats;
2410       inline_hints hints;
2411       int time, size;
2412
2413       init_caller_stats (&stats);
2414       node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
2415                                               false);
2416       estimate_ipcp_clone_size_and_time (node, known_csts, known_contexts,
2417                                          known_aggs_ptrs, &size, &time, &hints);
2418       time -= devirtualization_time_bonus (node, known_csts, known_contexts,
2419                                            known_aggs_ptrs);
2420       time -= hint_time_bonus (hints);
2421       time -= removable_params_cost;
2422       size -= stats.n_calls * removable_params_cost;
2423
2424       if (dump_file)
2425         fprintf (dump_file, " - context independent values, size: %i, "
2426                  "time_benefit: %i\n", size, base_time - time);
2427
2428       if (size <= 0
2429           || node->will_be_removed_from_program_if_no_direct_calls_p ())
2430         {
2431           info->do_clone_for_all_contexts = true;
2432           base_time = time;
2433
2434           if (dump_file)
2435             fprintf (dump_file, "     Decided to specialize for all "
2436                      "known contexts, code not going to grow.\n");
2437         }
2438       else if (good_cloning_opportunity_p (node, base_time - time,
2439                                            stats.freq_sum, stats.count_sum,
2440                                            size))
2441         {
2442           if (size + overall_size <= max_new_size)
2443             {
2444               info->do_clone_for_all_contexts = true;
2445               base_time = time;
2446               overall_size += size;
2447
2448               if (dump_file)
2449                 fprintf (dump_file, "     Decided to specialize for all "
2450                          "known contexts, growth deemed beneficial.\n");
2451             }
2452           else if (dump_file && (dump_flags & TDF_DETAILS))
2453             fprintf (dump_file, "   Not cloning for all contexts because "
2454                      "max_new_size would be reached with %li.\n",
2455                      size + overall_size);
2456         }
2457     }
2458
2459   for (i = 0; i < count ; i++)
2460     {
2461       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2462       ipcp_lattice<tree> *lat = &plats->itself;
2463       ipcp_value<tree> *val;
2464
2465       if (lat->bottom
2466           || !lat->values
2467           || known_csts[i])
2468         continue;
2469
2470       for (val = lat->values; val; val = val->next)
2471         {
2472           gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
2473           known_csts[i] = val->value;
2474
2475           int emc = estimate_move_cost (TREE_TYPE (val->value), true);
2476           perform_estimation_of_a_value (node, known_csts, known_contexts,
2477                                          known_aggs_ptrs, base_time,
2478                                          removable_params_cost, emc, val);
2479
2480           if (dump_file && (dump_flags & TDF_DETAILS))
2481             {
2482               fprintf (dump_file, " - estimates for value ");
2483               print_ipcp_constant_value (dump_file, val->value);
2484               fprintf (dump_file, " for ");
2485               ipa_dump_param (dump_file, info, i);
2486               fprintf (dump_file, ": time_benefit: %i, size: %i\n",
2487                        val->local_time_benefit, val->local_size_cost);
2488             }
2489         }
2490       known_csts[i] = NULL_TREE;
2491     }
2492
2493   for (i = 0; i < count; i++)
2494     {
2495       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2496
2497       if (!plats->virt_call)
2498         continue;
2499
2500       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2501       ipcp_value<ipa_polymorphic_call_context> *val;
2502
2503       if (ctxlat->bottom
2504           || !ctxlat->values
2505           || !known_contexts[i].useless_p ())
2506         continue;
2507
2508       for (val = ctxlat->values; val; val = val->next)
2509         {
2510           known_contexts[i] = val->value;
2511           perform_estimation_of_a_value (node, known_csts, known_contexts,
2512                                          known_aggs_ptrs, base_time,
2513                                          removable_params_cost, 0, val);
2514
2515           if (dump_file && (dump_flags & TDF_DETAILS))
2516             {
2517               fprintf (dump_file, " - estimates for polymorphic context ");
2518               print_ipcp_constant_value (dump_file, val->value);
2519               fprintf (dump_file, " for ");
2520               ipa_dump_param (dump_file, info, i);
2521               fprintf (dump_file, ": time_benefit: %i, size: %i\n",
2522                        val->local_time_benefit, val->local_size_cost);
2523             }
2524         }
2525       known_contexts[i] = ipa_polymorphic_call_context ();
2526     }
2527
2528   for (i = 0; i < count ; i++)
2529     {
2530       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2531       struct ipa_agg_jump_function *ajf;
2532       struct ipcp_agg_lattice *aglat;
2533
2534       if (plats->aggs_bottom || !plats->aggs)
2535         continue;
2536
2537       ajf = &known_aggs[i];
2538       for (aglat = plats->aggs; aglat; aglat = aglat->next)
2539         {
2540           ipcp_value<tree> *val;
2541           if (aglat->bottom || !aglat->values
2542               /* If the following is true, the one value is in known_aggs.  */
2543               || (!plats->aggs_contain_variable
2544                   && aglat->is_single_const ()))
2545             continue;
2546
2547           for (val = aglat->values; val; val = val->next)
2548             {
2549               struct ipa_agg_jf_item item;
2550
2551               item.offset = aglat->offset;
2552               item.value = val->value;
2553               vec_safe_push (ajf->items, item);
2554
2555               perform_estimation_of_a_value (node, known_csts, known_contexts,
2556                                              known_aggs_ptrs, base_time,
2557                                              removable_params_cost, 0, val);
2558
2559               if (dump_file && (dump_flags & TDF_DETAILS))
2560                 {
2561                   fprintf (dump_file, " - estimates for value ");
2562                   print_ipcp_constant_value (dump_file, val->value);
2563                   fprintf (dump_file, " for ");
2564                   ipa_dump_param (dump_file, info, i);
2565                   fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
2566                            "]: time_benefit: %i, size: %i\n",
2567                            plats->aggs_by_ref ? "ref " : "",
2568                            aglat->offset,
2569                            val->local_time_benefit, val->local_size_cost);
2570                 }
2571
2572               ajf->items->pop ();
2573             }
2574         }
2575     }
2576
2577   for (i = 0; i < count ; i++)
2578     vec_free (known_aggs[i].items);
2579
2580   known_csts.release ();
2581   known_contexts.release ();
2582   known_aggs.release ();
2583   known_aggs_ptrs.release ();
2584 }
2585
2586
2587 /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
2588    topological sort of values.  */
2589
2590 template <typename valtype>
2591 void
2592 value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
2593 {
2594   ipcp_value_source<valtype> *src;
2595
2596   if (cur_val->dfs)
2597     return;
2598
2599   dfs_counter++;
2600   cur_val->dfs = dfs_counter;
2601   cur_val->low_link = dfs_counter;
2602
2603   cur_val->topo_next = stack;
2604   stack = cur_val;
2605   cur_val->on_stack = true;
2606
2607   for (src = cur_val->sources; src; src = src->next)
2608     if (src->val)
2609       {
2610         if (src->val->dfs == 0)
2611           {
2612             add_val (src->val);
2613             if (src->val->low_link < cur_val->low_link)
2614               cur_val->low_link = src->val->low_link;
2615           }
2616         else if (src->val->on_stack
2617                  && src->val->dfs < cur_val->low_link)
2618           cur_val->low_link = src->val->dfs;
2619       }
2620
2621   if (cur_val->dfs == cur_val->low_link)
2622     {
2623       ipcp_value<valtype> *v, *scc_list = NULL;
2624
2625       do
2626         {
2627           v = stack;
2628           stack = v->topo_next;
2629           v->on_stack = false;
2630
2631           v->scc_next = scc_list;
2632           scc_list = v;
2633         }
2634       while (v != cur_val);
2635
2636       cur_val->topo_next = values_topo;
2637       values_topo = cur_val;
2638     }
2639 }
2640
2641 /* Add all values in lattices associated with NODE to the topological sort if
2642    they are not there yet.  */
2643
2644 static void
2645 add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
2646 {
2647   struct ipa_node_params *info = IPA_NODE_REF (node);
2648   int i, count = ipa_get_param_count (info);
2649
2650   for (i = 0; i < count ; i++)
2651     {
2652       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
2653       ipcp_lattice<tree> *lat = &plats->itself;
2654       struct ipcp_agg_lattice *aglat;
2655
2656       if (!lat->bottom)
2657         {
2658           ipcp_value<tree> *val;
2659           for (val = lat->values; val; val = val->next)
2660             topo->constants.add_val (val);
2661         }
2662
2663       if (!plats->aggs_bottom)
2664         for (aglat = plats->aggs; aglat; aglat = aglat->next)
2665           if (!aglat->bottom)
2666             {
2667               ipcp_value<tree> *val;
2668               for (val = aglat->values; val; val = val->next)
2669                 topo->constants.add_val (val);
2670             }
2671
2672       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
2673       if (!ctxlat->bottom)
2674         {
2675           ipcp_value<ipa_polymorphic_call_context> *ctxval;
2676           for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
2677             topo->contexts.add_val (ctxval);
2678         }
2679     }
2680 }
2681
2682 /* One pass of constants propagation along the call graph edges, from callers
2683    to callees (requires topological ordering in TOPO), iterate over strongly
2684    connected components.  */
2685
2686 static void
2687 propagate_constants_topo (struct ipa_topo_info *topo)
2688 {
2689   int i;
2690
2691   for (i = topo->nnodes - 1; i >= 0; i--)
2692     {
2693       unsigned j;
2694       struct cgraph_node *v, *node = topo->order[i];
2695       vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
2696
2697       /* First, iteratively propagate within the strongly connected component
2698          until all lattices stabilize.  */
2699       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
2700         if (v->has_gimple_body_p ())
2701           push_node_to_stack (topo, v);
2702
2703       v = pop_node_from_stack (topo);
2704       while (v)
2705         {
2706           struct cgraph_edge *cs;
2707
2708           for (cs = v->callees; cs; cs = cs->next_callee)
2709             if (ipa_edge_within_scc (cs))
2710               {
2711                 IPA_NODE_REF (v)->node_within_scc = true;
2712                 if (propagate_constants_accross_call (cs))
2713                   push_node_to_stack (topo, cs->callee->function_symbol ());
2714               }
2715           v = pop_node_from_stack (topo);
2716         }
2717
2718       /* Afterwards, propagate along edges leading out of the SCC, calculates
2719          the local effects of the discovered constants and all valid values to
2720          their topological sort.  */
2721       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
2722         if (v->has_gimple_body_p ())
2723           {
2724             struct cgraph_edge *cs;
2725
2726             estimate_local_effects (v);
2727             add_all_node_vals_to_toposort (v, topo);
2728             for (cs = v->callees; cs; cs = cs->next_callee)
2729               if (!ipa_edge_within_scc (cs))
2730                 propagate_constants_accross_call (cs);
2731           }
2732       cycle_nodes.release ();
2733     }
2734 }
2735
2736
2737 /* Return the sum of A and B if none of them is bigger than INT_MAX/2, return
2738    the bigger one if otherwise.  */
2739
2740 static int
2741 safe_add (int a, int b)
2742 {
2743   if (a > INT_MAX/2 || b > INT_MAX/2)
2744     return a > b ? a : b;
2745   else
2746     return a + b;
2747 }
2748
2749
2750 /* Propagate the estimated effects of individual values along the topological
2751    from the dependent values to those they depend on.  */
2752
2753 template <typename valtype>
2754 void
2755 value_topo_info<valtype>::propagate_effects ()
2756 {
2757   ipcp_value<valtype> *base;
2758
2759   for (base = values_topo; base; base = base->topo_next)
2760     {
2761       ipcp_value_source<valtype> *src;
2762       ipcp_value<valtype> *val;
2763       int time = 0, size = 0;
2764
2765       for (val = base; val; val = val->scc_next)
2766         {
2767           time = safe_add (time,
2768                            val->local_time_benefit + val->prop_time_benefit);
2769           size = safe_add (size, val->local_size_cost + val->prop_size_cost);
2770         }
2771
2772       for (val = base; val; val = val->scc_next)
2773         for (src = val->sources; src; src = src->next)
2774           if (src->val
2775               && src->cs->maybe_hot_p ())
2776             {
2777               src->val->prop_time_benefit = safe_add (time,
2778                                                 src->val->prop_time_benefit);
2779               src->val->prop_size_cost = safe_add (size,
2780                                                    src->val->prop_size_cost);
2781             }
2782     }
2783 }
2784
2785
2786 /* Propagate constants, polymorphic contexts and their effects from the
2787    summaries interprocedurally.  */
2788
2789 static void
2790 ipcp_propagate_stage (struct ipa_topo_info *topo)
2791 {
2792   struct cgraph_node *node;
2793
2794   if (dump_file)
2795     fprintf (dump_file, "\n Propagating constants:\n\n");
2796
2797   if (in_lto_p)
2798     ipa_update_after_lto_read ();
2799
2800
2801   FOR_EACH_DEFINED_FUNCTION (node)
2802   {
2803     struct ipa_node_params *info = IPA_NODE_REF (node);
2804
2805     determine_versionability (node);
2806     if (node->has_gimple_body_p ())
2807       {
2808         info->lattices = XCNEWVEC (struct ipcp_param_lattices,
2809                                    ipa_get_param_count (info));
2810         initialize_node_lattices (node);
2811       }
2812     if (node->definition && !node->alias)
2813       overall_size += inline_summaries->get (node)->self_size;
2814     if (node->count > max_count)
2815       max_count = node->count;
2816   }
2817
2818   max_new_size = overall_size;
2819   if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
2820     max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
2821   max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
2822
2823   if (dump_file)
2824     fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
2825              overall_size, max_new_size);
2826
2827   propagate_constants_topo (topo);
2828 #ifdef ENABLE_CHECKING
2829   ipcp_verify_propagated_values ();
2830 #endif
2831   topo->constants.propagate_effects ();
2832   topo->contexts.propagate_effects ();
2833
2834   if (dump_file)
2835     {
2836       fprintf (dump_file, "\nIPA lattices after all propagation:\n");
2837       print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
2838     }
2839 }
2840
2841 /* Discover newly direct outgoing edges from NODE which is a new clone with
2842    known KNOWN_CSTS and make them direct.  */
2843
2844 static void
2845 ipcp_discover_new_direct_edges (struct cgraph_node *node,
2846                                 vec<tree> known_csts,
2847                                 vec<ipa_polymorphic_call_context>
2848                                 known_contexts,
2849                                 struct ipa_agg_replacement_value *aggvals)
2850 {
2851   struct cgraph_edge *ie, *next_ie;
2852   bool found = false;
2853
2854   for (ie = node->indirect_calls; ie; ie = next_ie)
2855     {
2856       tree target;
2857       bool speculative;
2858
2859       next_ie = ie->next_callee;
2860       target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
2861                                                vNULL, aggvals, &speculative);
2862       if (target)
2863         {
2864           bool agg_contents = ie->indirect_info->agg_contents;
2865           bool polymorphic = ie->indirect_info->polymorphic;
2866           int param_index = ie->indirect_info->param_index;
2867           struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
2868                                                                    speculative);
2869           found = true;
2870
2871           if (cs && !agg_contents && !polymorphic)
2872             {
2873               struct ipa_node_params *info = IPA_NODE_REF (node);
2874               int c = ipa_get_controlled_uses (info, param_index);
2875               if (c != IPA_UNDESCRIBED_USE)
2876                 {
2877                   struct ipa_ref *to_del;
2878
2879                   c--;
2880                   ipa_set_controlled_uses (info, param_index, c);
2881                   if (dump_file && (dump_flags & TDF_DETAILS))
2882                     fprintf (dump_file, "     controlled uses count of param "
2883                              "%i bumped down to %i\n", param_index, c);
2884                   if (c == 0
2885                       && (to_del = node->find_reference (cs->callee, NULL, 0)))
2886                     {
2887                       if (dump_file && (dump_flags & TDF_DETAILS))
2888                         fprintf (dump_file, "       and even removing its "
2889                                  "cloning-created reference\n");
2890                       to_del->remove_reference ();
2891                     }
2892                 }
2893             }
2894         }
2895     }
2896   /* Turning calls to direct calls will improve overall summary.  */
2897   if (found)
2898     inline_update_overall_summary (node);
2899 }
2900
2901 /* Vector of pointers which for linked lists of clones of an original crgaph
2902    edge. */
2903
2904 static vec<cgraph_edge *> next_edge_clone;
2905 static vec<cgraph_edge *> prev_edge_clone;
2906
2907 static inline void
2908 grow_edge_clone_vectors (void)
2909 {
2910   if (next_edge_clone.length ()
2911       <=  (unsigned) symtab->edges_max_uid)
2912     next_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
2913   if (prev_edge_clone.length ()
2914       <=  (unsigned) symtab->edges_max_uid)
2915     prev_edge_clone.safe_grow_cleared (symtab->edges_max_uid + 1);
2916 }
2917
2918 /* Edge duplication hook to grow the appropriate linked list in
2919    next_edge_clone. */
2920
2921 static void
2922 ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
2923                             void *)
2924 {
2925   grow_edge_clone_vectors ();
2926
2927   struct cgraph_edge *old_next = next_edge_clone[src->uid];
2928   if (old_next)
2929     prev_edge_clone[old_next->uid] = dst;
2930   prev_edge_clone[dst->uid] = src;
2931
2932   next_edge_clone[dst->uid] = old_next;
2933   next_edge_clone[src->uid] = dst;
2934 }
2935
2936 /* Hook that is called by cgraph.c when an edge is removed.  */
2937
2938 static void
2939 ipcp_edge_removal_hook (struct cgraph_edge *cs, void *)
2940 {
2941   grow_edge_clone_vectors ();
2942
2943   struct cgraph_edge *prev = prev_edge_clone[cs->uid];
2944   struct cgraph_edge *next = next_edge_clone[cs->uid];
2945   if (prev)
2946     next_edge_clone[prev->uid] = next;
2947   if (next)
2948     prev_edge_clone[next->uid] = prev;
2949 }
2950
2951 /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
2952    parameter with the given INDEX.  */
2953
2954 static tree
2955 get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
2956                      int index)
2957 {
2958   struct ipa_agg_replacement_value *aggval;
2959
2960   aggval = ipa_get_agg_replacements_for_node (node);
2961   while (aggval)
2962     {
2963       if (aggval->offset == offset
2964           && aggval->index == index)
2965         return aggval->value;
2966       aggval = aggval->next;
2967     }
2968   return NULL_TREE;
2969 }
2970
2971 /* Return true is NODE is DEST or its clone for all contexts.  */
2972
2973 static bool
2974 same_node_or_its_all_contexts_clone_p (cgraph_node *node, cgraph_node *dest)
2975 {
2976   if (node == dest)
2977     return true;
2978
2979   struct ipa_node_params *info = IPA_NODE_REF (node);
2980   return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
2981 }
2982
2983 /* Return true if edge CS does bring about the value described by SRC to node
2984    DEST or its clone for all contexts.  */
2985
2986 static bool
2987 cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
2988                             cgraph_node *dest)
2989 {
2990   struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
2991   enum availability availability;
2992   cgraph_node *real_dest = cs->callee->function_symbol (&availability);
2993
2994   if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
2995       || availability <= AVAIL_INTERPOSABLE
2996       || caller_info->node_dead)
2997     return false;
2998   if (!src->val)
2999     return true;
3000
3001   if (caller_info->ipcp_orig_node)
3002     {
3003       tree t;
3004       if (src->offset == -1)
3005         t = caller_info->known_csts[src->index];
3006       else
3007         t = get_clone_agg_value (cs->caller, src->offset, src->index);
3008       return (t != NULL_TREE
3009               && values_equal_for_ipcp_p (src->val->value, t));
3010     }
3011   else
3012     {
3013       struct ipcp_agg_lattice *aglat;
3014       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3015                                                                  src->index);
3016       if (src->offset == -1)
3017         return (plats->itself.is_single_const ()
3018                 && values_equal_for_ipcp_p (src->val->value,
3019                                             plats->itself.values->value));
3020       else
3021         {
3022           if (plats->aggs_bottom || plats->aggs_contain_variable)
3023             return false;
3024           for (aglat = plats->aggs; aglat; aglat = aglat->next)
3025             if (aglat->offset == src->offset)
3026               return  (aglat->is_single_const ()
3027                        && values_equal_for_ipcp_p (src->val->value,
3028                                                    aglat->values->value));
3029         }
3030       return false;
3031     }
3032 }
3033
3034 /* Return true if edge CS does bring about the value described by SRC to node
3035    DEST or its clone for all contexts.  */
3036
3037 static bool
3038 cgraph_edge_brings_value_p (cgraph_edge *cs,
3039                             ipcp_value_source<ipa_polymorphic_call_context> *src,
3040                             cgraph_node *dest)
3041 {
3042   struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3043   cgraph_node *real_dest = cs->callee->function_symbol ();
3044
3045   if (!same_node_or_its_all_contexts_clone_p (real_dest, dest)
3046       || caller_info->node_dead)
3047     return false;
3048   if (!src->val)
3049     return true;
3050
3051   if (caller_info->ipcp_orig_node)
3052     return (caller_info->known_contexts.length () > (unsigned) src->index)
3053       && values_equal_for_ipcp_p (src->val->value,
3054                                   caller_info->known_contexts[src->index]);
3055
3056   struct ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
3057                                                              src->index);
3058   return plats->ctxlat.is_single_const ()
3059     && values_equal_for_ipcp_p (src->val->value,
3060                                 plats->ctxlat.values->value);
3061 }
3062
3063 /* Get the next clone in the linked list of clones of an edge.  */
3064
3065 static inline struct cgraph_edge *
3066 get_next_cgraph_edge_clone (struct cgraph_edge *cs)
3067 {
3068   return next_edge_clone[cs->uid];
3069 }
3070
3071 /* Given VAL that is intended for DEST, iterate over all its sources and if
3072    they still hold, add their edge frequency and their number into *FREQUENCY
3073    and *CALLER_COUNT respectively.  */
3074
3075 template <typename valtype>
3076 static bool
3077 get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
3078                                 int *freq_sum,
3079                                 gcov_type *count_sum, int *caller_count)
3080 {
3081   ipcp_value_source<valtype> *src;
3082   int freq = 0, count = 0;
3083   gcov_type cnt = 0;
3084   bool hot = false;
3085
3086   for (src = val->sources; src; src = src->next)
3087     {
3088       struct cgraph_edge *cs = src->cs;
3089       while (cs)
3090         {
3091           if (cgraph_edge_brings_value_p (cs, src, dest))
3092             {
3093               count++;
3094               freq += cs->frequency;
3095               cnt += cs->count;
3096               hot |= cs->maybe_hot_p ();
3097             }
3098           cs = get_next_cgraph_edge_clone (cs);
3099         }
3100     }
3101
3102   *freq_sum = freq;
3103   *count_sum = cnt;
3104   *caller_count = count;
3105   return hot;
3106 }
3107
3108 /* Return a vector of incoming edges that do bring value VAL to node DEST.  It
3109    is assumed their number is known and equal to CALLER_COUNT.  */
3110
3111 template <typename valtype>
3112 static vec<cgraph_edge *>
3113 gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
3114                         int caller_count)
3115 {
3116   ipcp_value_source<valtype> *src;
3117   vec<cgraph_edge *> ret;
3118
3119   ret.create (caller_count);
3120   for (src = val->sources; src; src = src->next)
3121     {
3122       struct cgraph_edge *cs = src->cs;
3123       while (cs)
3124         {
3125           if (cgraph_edge_brings_value_p (cs, src, dest))
3126             ret.quick_push (cs);
3127           cs = get_next_cgraph_edge_clone (cs);
3128         }
3129     }
3130
3131   return ret;
3132 }
3133
3134 /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
3135    Return it or NULL if for some reason it cannot be created.  */
3136
3137 static struct ipa_replace_map *
3138 get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
3139 {
3140   struct ipa_replace_map *replace_map;
3141
3142
3143   replace_map = ggc_alloc<ipa_replace_map> ();
3144   if (dump_file)
3145     {
3146       fprintf (dump_file, "    replacing ");
3147       ipa_dump_param (dump_file, info, parm_num);
3148   
3149       fprintf (dump_file, " with const ");
3150       print_generic_expr (dump_file, value, 0);
3151       fprintf (dump_file, "\n");
3152     }
3153   replace_map->old_tree = NULL;
3154   replace_map->parm_num = parm_num;
3155   replace_map->new_tree = value;
3156   replace_map->replace_p = true;
3157   replace_map->ref_p = false;
3158
3159   return replace_map;
3160 }
3161
3162 /* Dump new profiling counts */
3163
3164 static void
3165 dump_profile_updates (struct cgraph_node *orig_node,
3166                       struct cgraph_node *new_node)
3167 {
3168   struct cgraph_edge *cs;
3169
3170   fprintf (dump_file, "    setting count of the specialized node to "
3171            HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) new_node->count);
3172   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3173     fprintf (dump_file, "      edge to %s has count "
3174              HOST_WIDE_INT_PRINT_DEC "\n",
3175              cs->callee->name (), (HOST_WIDE_INT) cs->count);
3176
3177   fprintf (dump_file, "    setting count of the original node to "
3178            HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) orig_node->count);
3179   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3180     fprintf (dump_file, "      edge to %s is left with "
3181              HOST_WIDE_INT_PRINT_DEC "\n",
3182              cs->callee->name (), (HOST_WIDE_INT) cs->count);
3183 }
3184
3185 /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
3186    their profile information to reflect this.  */
3187
3188 static void
3189 update_profiling_info (struct cgraph_node *orig_node,
3190                        struct cgraph_node *new_node)
3191 {
3192   struct cgraph_edge *cs;
3193   struct caller_statistics stats;
3194   gcov_type new_sum, orig_sum;
3195   gcov_type remainder, orig_node_count = orig_node->count;
3196
3197   if (orig_node_count == 0)
3198     return;
3199
3200   init_caller_stats (&stats);
3201   orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3202                                                false);
3203   orig_sum = stats.count_sum;
3204   init_caller_stats (&stats);
3205   new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
3206                                               false);
3207   new_sum = stats.count_sum;
3208
3209   if (orig_node_count < orig_sum + new_sum)
3210     {
3211       if (dump_file)
3212         fprintf (dump_file, "    Problem: node %s/%i has too low count "
3213                  HOST_WIDE_INT_PRINT_DEC " while the sum of incoming "
3214                  "counts is " HOST_WIDE_INT_PRINT_DEC "\n",
3215                  orig_node->name (), orig_node->order,
3216                  (HOST_WIDE_INT) orig_node_count,
3217                  (HOST_WIDE_INT) (orig_sum + new_sum));
3218
3219       orig_node_count = (orig_sum + new_sum) * 12 / 10;
3220       if (dump_file)
3221         fprintf (dump_file, "      proceeding by pretending it was "
3222                  HOST_WIDE_INT_PRINT_DEC "\n",
3223                  (HOST_WIDE_INT) orig_node_count);
3224     }
3225
3226   new_node->count = new_sum;
3227   remainder = orig_node_count - new_sum;
3228   orig_node->count = remainder;
3229
3230   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3231     if (cs->frequency)
3232       cs->count = apply_probability (cs->count,
3233                                      GCOV_COMPUTE_SCALE (new_sum,
3234                                                          orig_node_count));
3235     else
3236       cs->count = 0;
3237
3238   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3239     cs->count = apply_probability (cs->count,
3240                                    GCOV_COMPUTE_SCALE (remainder,
3241                                                        orig_node_count));
3242
3243   if (dump_file)
3244     dump_profile_updates (orig_node, new_node);
3245 }
3246
3247 /* Update the respective profile of specialized NEW_NODE and the original
3248    ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
3249    have been redirected to the specialized version.  */
3250
3251 static void
3252 update_specialized_profile (struct cgraph_node *new_node,
3253                             struct cgraph_node *orig_node,
3254                             gcov_type redirected_sum)
3255 {
3256   struct cgraph_edge *cs;
3257   gcov_type new_node_count, orig_node_count = orig_node->count;
3258
3259   if (dump_file)
3260     fprintf (dump_file, "    the sum of counts of redirected  edges is "
3261              HOST_WIDE_INT_PRINT_DEC "\n", (HOST_WIDE_INT) redirected_sum);
3262   if (orig_node_count == 0)
3263     return;
3264
3265   gcc_assert (orig_node_count >= redirected_sum);
3266
3267   new_node_count = new_node->count;
3268   new_node->count += redirected_sum;
3269   orig_node->count -= redirected_sum;
3270
3271   for (cs = new_node->callees; cs ; cs = cs->next_callee)
3272     if (cs->frequency)
3273       cs->count += apply_probability (cs->count,
3274                                       GCOV_COMPUTE_SCALE (redirected_sum,
3275                                                           new_node_count));
3276     else
3277       cs->count = 0;
3278
3279   for (cs = orig_node->callees; cs ; cs = cs->next_callee)
3280     {
3281       gcov_type dec = apply_probability (cs->count,
3282                                          GCOV_COMPUTE_SCALE (redirected_sum,
3283                                                              orig_node_count));
3284       if (dec < cs->count)
3285         cs->count -= dec;
3286       else
3287         cs->count = 0;
3288     }
3289
3290   if (dump_file)
3291     dump_profile_updates (orig_node, new_node);
3292 }
3293
3294 /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
3295    known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
3296    redirect all edges in CALLERS to it.  */
3297
3298 static struct cgraph_node *
3299 create_specialized_node (struct cgraph_node *node,
3300                          vec<tree> known_csts,
3301                          vec<ipa_polymorphic_call_context> known_contexts,
3302                          struct ipa_agg_replacement_value *aggvals,
3303                          vec<cgraph_edge *> callers)
3304 {
3305   struct ipa_node_params *new_info, *info = IPA_NODE_REF (node);
3306   vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
3307   struct ipa_agg_replacement_value *av;
3308   struct cgraph_node *new_node;
3309   int i, count = ipa_get_param_count (info);
3310   bitmap args_to_skip;
3311
3312   gcc_assert (!info->ipcp_orig_node);
3313
3314   if (node->local.can_change_signature)
3315     {
3316       args_to_skip = BITMAP_GGC_ALLOC ();
3317       for (i = 0; i < count; i++)
3318         {
3319           tree t = known_csts[i];
3320
3321           if (t || !ipa_is_param_used (info, i))
3322             bitmap_set_bit (args_to_skip, i);
3323         }
3324     }
3325   else
3326     {
3327       args_to_skip = NULL;
3328       if (dump_file && (dump_flags & TDF_DETAILS))
3329         fprintf (dump_file, "      cannot change function signature\n");
3330     }
3331
3332   for (i = 0; i < count ; i++)
3333     {
3334       tree t = known_csts[i];
3335       if (t)
3336         {
3337           struct ipa_replace_map *replace_map;
3338
3339           gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
3340           replace_map = get_replacement_map (info, t, i);
3341           if (replace_map)
3342             vec_safe_push (replace_trees, replace_map);
3343         }
3344     }
3345
3346   new_node = node->create_virtual_clone (callers, replace_trees,
3347                                          args_to_skip, "constprop");
3348   ipa_set_node_agg_value_chain (new_node, aggvals);
3349   for (av = aggvals; av; av = av->next)
3350     new_node->maybe_create_reference (av->value, IPA_REF_ADDR, NULL);
3351
3352   if (dump_file && (dump_flags & TDF_DETAILS))
3353     {
3354       fprintf (dump_file, "     the new node is %s/%i.\n",
3355                new_node->name (), new_node->order);
3356       if (known_contexts.exists ())
3357         {
3358           for (i = 0; i < count ; i++)
3359             if (!known_contexts[i].useless_p ())
3360               {
3361                 fprintf (dump_file, "     known ctx %i is ", i);
3362                 known_contexts[i].dump (dump_file);
3363               }
3364         }
3365       if (aggvals)
3366         ipa_dump_agg_replacement_values (dump_file, aggvals);
3367     }
3368   ipa_check_create_node_params ();
3369   update_profiling_info (node, new_node);
3370   new_info = IPA_NODE_REF (new_node);
3371   new_info->ipcp_orig_node = node;
3372   new_info->known_csts = known_csts;
3373   new_info->known_contexts = known_contexts;
3374
3375   ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
3376
3377   callers.release ();
3378   return new_node;
3379 }
3380
3381 /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
3382    KNOWN_CSTS with constants that are also known for all of the CALLERS.  */
3383
3384 static void
3385 find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
3386                                             vec<tree> known_csts,
3387                                             vec<cgraph_edge *> callers)
3388 {
3389   struct ipa_node_params *info = IPA_NODE_REF (node);
3390   int i, count = ipa_get_param_count (info);
3391
3392   for (i = 0; i < count ; i++)
3393     {
3394       struct cgraph_edge *cs;
3395       tree newval = NULL_TREE;
3396       int j;
3397       bool first = true;
3398
3399       if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
3400         continue;
3401
3402       FOR_EACH_VEC_ELT (callers, j, cs)
3403         {
3404           struct ipa_jump_func *jump_func;
3405           tree t;
3406
3407           if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
3408             {
3409               newval = NULL_TREE;
3410               break;
3411             }
3412           jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
3413           t = ipa_value_from_jfunc (IPA_NODE_REF (cs->caller), jump_func);
3414           if (!t
3415               || (newval
3416                   && !values_equal_for_ipcp_p (t, newval))
3417               || (!first && !newval))
3418             {
3419               newval = NULL_TREE;
3420               break;
3421             }
3422           else
3423             newval = t;
3424           first = false;
3425         }
3426
3427       if (newval)
3428         {
3429           if (dump_file && (dump_flags & TDF_DETAILS))
3430             {
3431               fprintf (dump_file, "    adding an extra known scalar value ");
3432               print_ipcp_constant_value (dump_file, newval);
3433               fprintf (dump_file, " for ");
3434               ipa_dump_param (dump_file, info, i);
3435               fprintf (dump_file, "\n");
3436             }
3437
3438           known_csts[i] = newval;
3439         }
3440     }
3441 }
3442
3443 /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
3444    KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
3445    CALLERS.  */
3446
3447 static void
3448 find_more_contexts_for_caller_subset (cgraph_node *node,
3449                                       vec<ipa_polymorphic_call_context>
3450                                       *known_contexts,
3451                                       vec<cgraph_edge *> callers)
3452 {
3453   ipa_node_params *info = IPA_NODE_REF (node);
3454   int i, count = ipa_get_param_count (info);
3455
3456   for (i = 0; i < count ; i++)
3457     {
3458       cgraph_edge *cs;
3459
3460       if (ipa_get_poly_ctx_lat (info, i)->bottom
3461           || (known_contexts->exists ()
3462               && !(*known_contexts)[i].useless_p ()))
3463         continue;
3464
3465       ipa_polymorphic_call_context newval;
3466       bool first = true;
3467       int j;
3468
3469       FOR_EACH_VEC_ELT (callers, j, cs)
3470         {
3471           if (i >= ipa_get_cs_argument_count (IPA_EDGE_REF (cs)))
3472             return;
3473           ipa_jump_func *jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs),
3474                                                             i);
3475           ipa_polymorphic_call_context ctx;
3476           ctx = ipa_context_from_jfunc (IPA_NODE_REF (cs->caller), cs, i,
3477                                         jfunc);
3478           if (first)
3479             {
3480               newval = ctx;
3481               first = false;
3482             }
3483           else
3484             newval.meet_with (ctx);
3485           if (newval.useless_p ())
3486             break;
3487         }
3488
3489       if (!newval.useless_p ())
3490         {
3491           if (dump_file && (dump_flags & TDF_DETAILS))
3492             {
3493               fprintf (dump_file, "    adding an extra known polymorphic "
3494                        "context ");
3495               print_ipcp_constant_value (dump_file, newval);
3496               fprintf (dump_file, " for ");
3497               ipa_dump_param (dump_file, info, i);
3498               fprintf (dump_file, "\n");
3499             }
3500
3501           if (!known_contexts->exists ())
3502             known_contexts->safe_grow_cleared (ipa_get_param_count (info));
3503           (*known_contexts)[i] = newval;
3504         }
3505
3506     }
3507 }
3508
3509 /* Go through PLATS and create a vector of values consisting of values and
3510    offsets (minus OFFSET) of lattices that contain only a single value.  */
3511
3512 static vec<ipa_agg_jf_item>
3513 copy_plats_to_inter (struct ipcp_param_lattices *plats, HOST_WIDE_INT offset)
3514 {
3515   vec<ipa_agg_jf_item> res = vNULL;
3516
3517   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
3518     return vNULL;
3519
3520   for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
3521     if (aglat->is_single_const ())
3522       {
3523         struct ipa_agg_jf_item ti;
3524         ti.offset = aglat->offset - offset;
3525         ti.value = aglat->values->value;
3526         res.safe_push (ti);
3527       }
3528   return res;
3529 }
3530
3531 /* Intersect all values in INTER with single value lattices in PLATS (while
3532    subtracting OFFSET).  */
3533
3534 static void
3535 intersect_with_plats (struct ipcp_param_lattices *plats,
3536                       vec<ipa_agg_jf_item> *inter,
3537                       HOST_WIDE_INT offset)
3538 {
3539   struct ipcp_agg_lattice *aglat;
3540   struct ipa_agg_jf_item *item;
3541   int k;
3542
3543   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
3544     {
3545       inter->release ();
3546       return;
3547     }
3548
3549   aglat = plats->aggs;
3550   FOR_EACH_VEC_ELT (*inter, k, item)
3551     {
3552       bool found = false;
3553       if (!item->value)
3554         continue;
3555       while (aglat)
3556         {
3557           if (aglat->offset - offset > item->offset)
3558             break;
3559           if (aglat->offset - offset == item->offset)
3560             {
3561               gcc_checking_assert (item->value);
3562               if (values_equal_for_ipcp_p (item->value, aglat->values->value))
3563                 found = true;
3564               break;
3565             }
3566           aglat = aglat->next;
3567         }
3568       if (!found)
3569         item->value = NULL_TREE;
3570     }
3571 }
3572
3573 /* Copy agggregate replacement values of NODE (which is an IPA-CP clone) to the
3574    vector result while subtracting OFFSET from the individual value offsets.  */
3575
3576 static vec<ipa_agg_jf_item>
3577 agg_replacements_to_vector (struct cgraph_node *node, int index,
3578                             HOST_WIDE_INT offset)
3579 {
3580   struct ipa_agg_replacement_value *av;
3581   vec<ipa_agg_jf_item> res = vNULL;
3582
3583   for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
3584     if (av->index == index
3585         && (av->offset - offset) >= 0)
3586     {
3587       struct ipa_agg_jf_item item;
3588       gcc_checking_assert (av->value);
3589       item.offset = av->offset - offset;
3590       item.value = av->value;
3591       res.safe_push (item);
3592     }
3593
3594   return res;
3595 }
3596
3597 /* Intersect all values in INTER with those that we have already scheduled to
3598    be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
3599    (while subtracting OFFSET).  */
3600
3601 static void
3602 intersect_with_agg_replacements (struct cgraph_node *node, int index,
3603                                  vec<ipa_agg_jf_item> *inter,
3604                                  HOST_WIDE_INT offset)
3605 {
3606   struct ipa_agg_replacement_value *srcvals;
3607   struct ipa_agg_jf_item *item;
3608   int i;
3609
3610   srcvals = ipa_get_agg_replacements_for_node (node);
3611   if (!srcvals)
3612     {
3613       inter->release ();
3614       return;
3615     }
3616
3617   FOR_EACH_VEC_ELT (*inter, i, item)
3618     {
3619       struct ipa_agg_replacement_value *av;
3620       bool found = false;
3621       if (!item->value)
3622         continue;
3623       for (av = srcvals; av; av = av->next)
3624         {
3625           gcc_checking_assert (av->value);
3626           if (av->index == index
3627               && av->offset - offset == item->offset)
3628             {
3629               if (values_equal_for_ipcp_p (item->value, av->value))
3630                 found = true;
3631               break;
3632             }
3633         }
3634       if (!found)
3635         item->value = NULL_TREE;
3636     }
3637 }
3638
3639 /* Intersect values in INTER with aggregate values that come along edge CS to
3640    parameter number INDEX and return it.  If INTER does not actually exist yet,
3641    copy all incoming values to it.  If we determine we ended up with no values
3642    whatsoever, return a released vector.  */
3643
3644 static vec<ipa_agg_jf_item>
3645 intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
3646                                 vec<ipa_agg_jf_item> inter)
3647 {
3648   struct ipa_jump_func *jfunc;
3649   jfunc = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), index);
3650   if (jfunc->type == IPA_JF_PASS_THROUGH
3651       && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
3652     {
3653       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3654       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
3655
3656       if (caller_info->ipcp_orig_node)
3657         {
3658           struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
3659           struct ipcp_param_lattices *orig_plats;
3660           orig_plats = ipa_get_parm_lattices (IPA_NODE_REF (orig_node),
3661                                               src_idx);
3662           if (agg_pass_through_permissible_p (orig_plats, jfunc))
3663             {
3664               if (!inter.exists ())
3665                 inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
3666               else
3667                 intersect_with_agg_replacements (cs->caller, src_idx,
3668                                                  &inter, 0);
3669             }
3670           else
3671             {
3672               inter.release ();
3673               return vNULL;
3674             }
3675         }
3676       else
3677         {
3678           struct ipcp_param_lattices *src_plats;
3679           src_plats = ipa_get_parm_lattices (caller_info, src_idx);
3680           if (agg_pass_through_permissible_p (src_plats, jfunc))
3681             {
3682               /* Currently we do not produce clobber aggregate jump
3683                  functions, adjust when we do.  */
3684               gcc_checking_assert (!jfunc->agg.items);
3685               if (!inter.exists ())
3686                 inter = copy_plats_to_inter (src_plats, 0);
3687               else
3688                 intersect_with_plats (src_plats, &inter, 0);
3689             }
3690           else
3691             {
3692               inter.release ();
3693               return vNULL;
3694             }
3695         }
3696     }
3697   else if (jfunc->type == IPA_JF_ANCESTOR
3698            && ipa_get_jf_ancestor_agg_preserved (jfunc))
3699     {
3700       struct ipa_node_params *caller_info = IPA_NODE_REF (cs->caller);
3701       int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
3702       struct ipcp_param_lattices *src_plats;
3703       HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
3704
3705       if (caller_info->ipcp_orig_node)
3706         {
3707           if (!inter.exists ())
3708             inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
3709           else
3710             intersect_with_agg_replacements (cs->caller, src_idx, &inter,
3711                                              delta);
3712         }
3713       else
3714         {
3715           src_plats = ipa_get_parm_lattices (caller_info, src_idx);;
3716           /* Currently we do not produce clobber aggregate jump
3717              functions, adjust when we do.  */
3718           gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
3719           if (!inter.exists ())
3720             inter = copy_plats_to_inter (src_plats, delta);
3721           else
3722             intersect_with_plats (src_plats, &inter, delta);
3723         }
3724     }
3725   else if (jfunc->agg.items)
3726     {
3727       struct ipa_agg_jf_item *item;
3728       int k;
3729
3730       if (!inter.exists ())
3731         for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
3732           inter.safe_push ((*jfunc->agg.items)[i]);
3733       else
3734         FOR_EACH_VEC_ELT (inter, k, item)
3735           {
3736             int l = 0;
3737             bool found = false;;
3738
3739             if (!item->value)
3740               continue;
3741
3742             while ((unsigned) l < jfunc->agg.items->length ())
3743               {
3744                 struct ipa_agg_jf_item *ti;
3745                 ti = &(*jfunc->agg.items)[l];
3746                 if (ti->offset > item->offset)
3747                   break;
3748                 if (ti->offset == item->offset)
3749                   {
3750                     gcc_checking_assert (ti->value);
3751                     if (values_equal_for_ipcp_p (item->value,
3752                                                  ti->value))
3753                       found = true;
3754                     break;
3755                   }
3756                 l++;
3757               }
3758             if (!found)
3759               item->value = NULL;
3760           }
3761     }
3762   else
3763     {
3764       inter.release ();
3765       return vec<ipa_agg_jf_item>();
3766     }
3767   return inter;
3768 }
3769
3770 /* Look at edges in CALLERS and collect all known aggregate values that arrive
3771    from all of them.  */
3772
3773 static struct ipa_agg_replacement_value *
3774 find_aggregate_values_for_callers_subset (struct cgraph_node *node,
3775                                           vec<cgraph_edge *> callers)
3776 {
3777   struct ipa_node_params *dest_info = IPA_NODE_REF (node);
3778   struct ipa_agg_replacement_value *res;
3779   struct ipa_agg_replacement_value **tail = &res;
3780   struct cgraph_edge *cs;
3781   int i, j, count = ipa_get_param_count (dest_info);
3782
3783   FOR_EACH_VEC_ELT (callers, j, cs)
3784     {
3785       int c = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
3786       if (c < count)
3787         count = c;
3788     }
3789
3790   for (i = 0; i < count ; i++)
3791     {
3792       struct cgraph_edge *cs;
3793       vec<ipa_agg_jf_item> inter = vNULL;
3794       struct ipa_agg_jf_item *item;
3795       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
3796       int j;
3797
3798       /* Among other things, the following check should deal with all by_ref
3799          mismatches.  */
3800       if (plats->aggs_bottom)
3801         continue;
3802
3803       FOR_EACH_VEC_ELT (callers, j, cs)
3804         {
3805           inter = intersect_aggregates_with_edge (cs, i, inter);
3806
3807           if (!inter.exists ())
3808             goto next_param;
3809         }
3810
3811       FOR_EACH_VEC_ELT (inter, j, item)
3812         {
3813           struct ipa_agg_replacement_value *v;
3814
3815           if (!item->value)
3816             continue;
3817
3818           v = ggc_alloc<ipa_agg_replacement_value> ();
3819           v->index = i;
3820           v->offset = item->offset;
3821           v->value = item->value;
3822           v->by_ref = plats->aggs_by_ref;
3823           *tail = v;
3824           tail = &v->next;
3825         }
3826
3827     next_param:
3828       if (inter.exists ())
3829         inter.release ();
3830     }
3831   *tail = NULL;
3832   return res;
3833 }
3834
3835 /* Turn KNOWN_AGGS into a list of aggreate replacement values.  */
3836
3837 static struct ipa_agg_replacement_value *
3838 known_aggs_to_agg_replacement_list (vec<ipa_agg_jump_function> known_aggs)
3839 {
3840   struct ipa_agg_replacement_value *res;
3841   struct ipa_agg_replacement_value **tail = &res;
3842   struct ipa_agg_jump_function *aggjf;
3843   struct ipa_agg_jf_item *item;
3844   int i, j;
3845
3846   FOR_EACH_VEC_ELT (known_aggs, i, aggjf)
3847     FOR_EACH_VEC_SAFE_ELT (aggjf->items, j, item)
3848       {
3849         struct ipa_agg_replacement_value *v;
3850         v = ggc_alloc<ipa_agg_replacement_value> ();
3851         v->index = i;
3852         v->offset = item->offset;
3853         v->value = item->value;
3854         v->by_ref = aggjf->by_ref;
3855         *tail = v;
3856         tail = &v->next;
3857       }
3858   *tail = NULL;
3859   return res;
3860 }
3861
3862 /* Determine whether CS also brings all scalar values that the NODE is
3863    specialized for.  */
3864
3865 static bool
3866 cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
3867                                          struct cgraph_node *node)
3868 {
3869   struct ipa_node_params *dest_info = IPA_NODE_REF (node);
3870   int count = ipa_get_param_count (dest_info);
3871   struct ipa_node_params *caller_info;
3872   struct ipa_edge_args *args;
3873   int i;
3874
3875   caller_info = IPA_NODE_REF (cs->caller);
3876   args = IPA_EDGE_REF (cs);
3877   for (i = 0; i < count; i++)
3878     {
3879       struct ipa_jump_func *jump_func;
3880       tree val, t;
3881
3882       val = dest_info->known_csts[i];
3883       if (!val)
3884         continue;
3885
3886       if (i >= ipa_get_cs_argument_count (args))
3887         return false;
3888       jump_func = ipa_get_ith_jump_func (args, i);
3889       t = ipa_value_from_jfunc (caller_info, jump_func);
3890       if (!t || !values_equal_for_ipcp_p (val, t))
3891         return false;
3892     }
3893   return true;
3894 }
3895
3896 /* Determine whether CS also brings all aggregate values that NODE is
3897    specialized for.  */
3898 static bool
3899 cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
3900                                           struct cgraph_node *node)
3901 {
3902   struct ipa_node_params *orig_caller_info = IPA_NODE_REF (cs->caller);
3903   struct ipa_node_params *orig_node_info;
3904   struct ipa_agg_replacement_value *aggval;
3905   int i, ec, count;
3906
3907   aggval = ipa_get_agg_replacements_for_node (node);
3908   if (!aggval)
3909     return true;
3910
3911   count = ipa_get_param_count (IPA_NODE_REF (node));
3912   ec = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
3913   if (ec < count)
3914     for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3915       if (aggval->index >= ec)
3916         return false;
3917
3918   orig_node_info = IPA_NODE_REF (IPA_NODE_REF (node)->ipcp_orig_node);
3919   if (orig_caller_info->ipcp_orig_node)
3920     orig_caller_info = IPA_NODE_REF (orig_caller_info->ipcp_orig_node);
3921
3922   for (i = 0; i < count; i++)
3923     {
3924       static vec<ipa_agg_jf_item> values = vec<ipa_agg_jf_item>();
3925       struct ipcp_param_lattices *plats;
3926       bool interesting = false;
3927       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3928         if (aggval->index == i)
3929           {
3930             interesting = true;
3931             break;
3932           }
3933       if (!interesting)
3934         continue;
3935
3936       plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
3937       if (plats->aggs_bottom)
3938         return false;
3939
3940       values = intersect_aggregates_with_edge (cs, i, values);
3941       if (!values.exists ())
3942         return false;
3943
3944       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
3945         if (aggval->index == i)
3946           {
3947             struct ipa_agg_jf_item *item;
3948             int j;
3949             bool found = false;
3950             FOR_EACH_VEC_ELT (values, j, item)
3951               if (item->value
3952                   && item->offset == av->offset
3953                   && values_equal_for_ipcp_p (item->value, av->value))
3954                 {
3955                   found = true;
3956                   break;
3957                 }
3958             if (!found)
3959               {
3960                 values.release ();
3961                 return false;
3962               }
3963           }
3964     }
3965   return true;
3966 }
3967
3968 /* Given an original NODE and a VAL for which we have already created a
3969    specialized clone, look whether there are incoming edges that still lead
3970    into the old node but now also bring the requested value and also conform to
3971    all other criteria such that they can be redirected the the special node.
3972    This function can therefore redirect the final edge in a SCC.  */
3973
3974 template <typename valtype>
3975 static void
3976 perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
3977 {
3978   ipcp_value_source<valtype> *src;
3979   gcov_type redirected_sum = 0;
3980
3981   for (src = val->sources; src; src = src->next)
3982     {
3983       struct cgraph_edge *cs = src->cs;
3984       while (cs)
3985         {
3986           if (cgraph_edge_brings_value_p (cs, src, node)
3987               && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
3988               && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
3989             {
3990               if (dump_file)
3991                 fprintf (dump_file, " - adding an extra caller %s/%i"
3992                          " of %s/%i\n",
3993                          xstrdup_for_dump (cs->caller->name ()),
3994                          cs->caller->order,
3995                          xstrdup_for_dump (val->spec_node->name ()),
3996                          val->spec_node->order);
3997
3998               cs->redirect_callee_duplicating_thunks (val->spec_node);
3999               val->spec_node->expand_all_artificial_thunks ();
4000               redirected_sum += cs->count;
4001             }
4002           cs = get_next_cgraph_edge_clone (cs);
4003         }
4004     }
4005
4006   if (redirected_sum)
4007     update_specialized_profile (val->spec_node, node, redirected_sum);
4008 }
4009
4010 /* Return true if KNOWN_CONTEXTS contain at least one useful context.  */
4011
4012 static bool
4013 known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
4014 {
4015   ipa_polymorphic_call_context *ctx;
4016   int i;
4017
4018   FOR_EACH_VEC_ELT (known_contexts, i, ctx)
4019     if (!ctx->useless_p ())
4020       return true;
4021   return false;
4022 }
4023
4024 /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL.  */
4025
4026 static vec<ipa_polymorphic_call_context>
4027 copy_useful_known_contexts (vec<ipa_polymorphic_call_context> known_contexts)
4028 {
4029   if (known_contexts_useful_p (known_contexts))
4030     return known_contexts.copy ();
4031   else
4032     return vNULL;
4033 }
4034
4035 /* Copy KNOWN_CSTS and modify the copy according to VAL and INDEX.  If
4036    non-empty, replace KNOWN_CONTEXTS with its copy too.  */
4037
4038 static void
4039 modify_known_vectors_with_val (vec<tree> *known_csts,
4040                                vec<ipa_polymorphic_call_context> *known_contexts,
4041                                ipcp_value<tree> *val,
4042                                int index)
4043 {
4044   *known_csts = known_csts->copy ();
4045   *known_contexts = copy_useful_known_contexts (*known_contexts);
4046   (*known_csts)[index] = val->value;
4047 }
4048
4049 /* Replace KNOWN_CSTS with its copy.  Also copy KNOWN_CONTEXTS and modify the
4050    copy according to VAL and INDEX.  */
4051
4052 static void
4053 modify_known_vectors_with_val (vec<tree> *known_csts,
4054                                vec<ipa_polymorphic_call_context> *known_contexts,
4055                                ipcp_value<ipa_polymorphic_call_context> *val,
4056                                int index)
4057 {
4058   *known_csts = known_csts->copy ();
4059   *known_contexts = known_contexts->copy ();
4060   (*known_contexts)[index] = val->value;
4061 }
4062
4063 /* Return true if OFFSET indicates this was not an aggregate value or there is
4064    a replacement equivalent to VALUE, INDEX and OFFSET among those in the
4065    AGGVALS list.  */
4066
4067 DEBUG_FUNCTION bool
4068 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
4069                                int index, HOST_WIDE_INT offset, tree value)
4070 {
4071   if (offset == -1)
4072     return true;
4073
4074   while (aggvals)
4075     {
4076       if (aggvals->index == index
4077           && aggvals->offset == offset
4078           && values_equal_for_ipcp_p (aggvals->value, value))
4079         return true;
4080       aggvals = aggvals->next;
4081     }
4082   return false;
4083 }
4084
4085 /* Return true if offset is minus one because source of a polymorphic contect
4086    cannot be an aggregate value.  */
4087
4088 DEBUG_FUNCTION bool
4089 ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
4090                                int , HOST_WIDE_INT offset,
4091                                ipa_polymorphic_call_context)
4092 {
4093   return offset == -1;
4094 }
4095
4096 /* Decide wheter to create a special version of NODE for value VAL of parameter
4097    at the given INDEX.  If OFFSET is -1, the value is for the parameter itself,
4098    otherwise it is stored at the given OFFSET of the parameter.  KNOWN_CSTS,
4099    KNOWN_CONTEXTS and KNOWN_AGGS describe the other already known values.  */
4100
4101 template <typename valtype>
4102 static bool
4103 decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
4104                     ipcp_value<valtype> *val, vec<tree> known_csts,
4105                     vec<ipa_polymorphic_call_context> known_contexts)
4106 {
4107   struct ipa_agg_replacement_value *aggvals;
4108   int freq_sum, caller_count;
4109   gcov_type count_sum;
4110   vec<cgraph_edge *> callers;
4111
4112   if (val->spec_node)
4113     {
4114       perhaps_add_new_callers (node, val);
4115       return false;
4116     }
4117   else if (val->local_size_cost + overall_size > max_new_size)
4118     {
4119       if (dump_file && (dump_flags & TDF_DETAILS))
4120         fprintf (dump_file, "   Ignoring candidate value because "
4121                  "max_new_size would be reached with %li.\n",
4122                  val->local_size_cost + overall_size);
4123       return false;
4124     }
4125   else if (!get_info_about_necessary_edges (val, node, &freq_sum, &count_sum,
4126                                             &caller_count))
4127     return false;
4128
4129   if (dump_file && (dump_flags & TDF_DETAILS))
4130     {
4131       fprintf (dump_file, " - considering value ");
4132       print_ipcp_constant_value (dump_file, val->value);
4133       fprintf (dump_file, " for ");
4134       ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
4135       if (offset != -1)
4136         fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
4137       fprintf (dump_file, " (caller_count: %i)\n", caller_count);
4138     }
4139
4140   if (!good_cloning_opportunity_p (node, val->local_time_benefit,
4141                                    freq_sum, count_sum,
4142                                    val->local_size_cost)
4143       && !good_cloning_opportunity_p (node,
4144                                       val->local_time_benefit
4145                                       + val->prop_time_benefit,
4146                                       freq_sum, count_sum,
4147                                       val->local_size_cost
4148                                       + val->prop_size_cost))
4149     return false;
4150
4151   if (dump_file)
4152     fprintf (dump_file, "  Creating a specialized node of %s/%i.\n",
4153              node->name (), node->order);
4154
4155   callers = gather_edges_for_value (val, node, caller_count);
4156   if (offset == -1)
4157     modify_known_vectors_with_val (&known_csts, &known_contexts, val, index);
4158   else
4159     {
4160       known_csts = known_csts.copy ();
4161       known_contexts = copy_useful_known_contexts (known_contexts);
4162     }
4163   find_more_scalar_values_for_callers_subset (node, known_csts, callers);
4164   find_more_contexts_for_caller_subset (node, &known_contexts, callers);
4165   aggvals = find_aggregate_values_for_callers_subset (node, callers);
4166   gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
4167                                                       offset, val->value));
4168   val->spec_node = create_specialized_node (node, known_csts, known_contexts,
4169                                             aggvals, callers);
4170   overall_size += val->local_size_cost;
4171
4172   /* TODO: If for some lattice there is only one other known value
4173      left, make a special node for it too. */
4174
4175   return true;
4176 }
4177
4178 /* Decide whether and what specialized clones of NODE should be created.  */
4179
4180 static bool
4181 decide_whether_version_node (struct cgraph_node *node)
4182 {
4183   struct ipa_node_params *info = IPA_NODE_REF (node);
4184   int i, count = ipa_get_param_count (info);
4185   vec<tree> known_csts;
4186   vec<ipa_polymorphic_call_context> known_contexts;
4187   vec<ipa_agg_jump_function> known_aggs = vNULL;
4188   bool ret = false;
4189
4190   if (count == 0)
4191     return false;
4192
4193   if (dump_file && (dump_flags & TDF_DETAILS))
4194     fprintf (dump_file, "\nEvaluating opportunities for %s/%i.\n",
4195              node->name (), node->order);
4196
4197   gather_context_independent_values (info, &known_csts, &known_contexts,
4198                                   info->do_clone_for_all_contexts ? &known_aggs
4199                                   : NULL, NULL);
4200
4201   for (i = 0; i < count ;i++)
4202     {
4203       struct ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4204       ipcp_lattice<tree> *lat = &plats->itself;
4205       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
4206
4207       if (!lat->bottom
4208           && !known_csts[i])
4209         {
4210           ipcp_value<tree> *val;
4211           for (val = lat->values; val; val = val->next)
4212             ret |= decide_about_value (node, i, -1, val, known_csts,
4213                                        known_contexts);
4214         }
4215
4216       if (!plats->aggs_bottom)
4217         {
4218           struct ipcp_agg_lattice *aglat;
4219           ipcp_value<tree> *val;
4220           for (aglat = plats->aggs; aglat; aglat = aglat->next)
4221             if (!aglat->bottom && aglat->values
4222                 /* If the following is false, the one value is in
4223                    known_aggs.  */
4224                 && (plats->aggs_contain_variable
4225                     || !aglat->is_single_const ()))
4226               for (val = aglat->values; val; val = val->next)
4227                 ret |= decide_about_value (node, i, aglat->offset, val,
4228                                            known_csts, known_contexts);
4229         }
4230
4231       if (!ctxlat->bottom
4232           && known_contexts[i].useless_p ())
4233         {
4234           ipcp_value<ipa_polymorphic_call_context> *val;
4235           for (val = ctxlat->values; val; val = val->next)
4236             ret |= decide_about_value (node, i, -1, val, known_csts,
4237                                        known_contexts);
4238         }
4239
4240         info = IPA_NODE_REF (node);
4241     }
4242
4243   if (info->do_clone_for_all_contexts)
4244     {
4245       struct cgraph_node *clone;
4246       vec<cgraph_edge *> callers;
4247
4248       if (dump_file)
4249         fprintf (dump_file, " - Creating a specialized node of %s/%i "
4250                  "for all known contexts.\n", node->name (),
4251                  node->order);
4252
4253       callers = node->collect_callers ();
4254
4255       if (!known_contexts_useful_p (known_contexts))
4256         {
4257           known_contexts.release ();
4258           known_contexts = vNULL;
4259         }
4260       clone = create_specialized_node (node, known_csts, known_contexts,
4261                                known_aggs_to_agg_replacement_list (known_aggs),
4262                                callers);
4263       info = IPA_NODE_REF (node);
4264       info->do_clone_for_all_contexts = false;
4265       IPA_NODE_REF (clone)->is_all_contexts_clone = true;
4266       for (i = 0; i < count ; i++)
4267         vec_free (known_aggs[i].items);
4268       known_aggs.release ();
4269       ret = true;
4270     }
4271   else
4272     {
4273       known_csts.release ();
4274       known_contexts.release ();
4275     }
4276
4277   return ret;
4278 }
4279
4280 /* Transitively mark all callees of NODE within the same SCC as not dead.  */
4281
4282 static void
4283 spread_undeadness (struct cgraph_node *node)
4284 {
4285   struct cgraph_edge *cs;
4286
4287   for (cs = node->callees; cs; cs = cs->next_callee)
4288     if (ipa_edge_within_scc (cs))
4289       {
4290         struct cgraph_node *callee;
4291         struct ipa_node_params *info;
4292
4293         callee = cs->callee->function_symbol (NULL);
4294         info = IPA_NODE_REF (callee);
4295
4296         if (info->node_dead)
4297           {
4298             info->node_dead = 0;
4299             spread_undeadness (callee);
4300           }
4301       }
4302 }
4303
4304 /* Return true if NODE has a caller from outside of its SCC that is not
4305    dead.  Worker callback for cgraph_for_node_and_aliases.  */
4306
4307 static bool
4308 has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
4309                                      void *data ATTRIBUTE_UNUSED)
4310 {
4311   struct cgraph_edge *cs;
4312
4313   for (cs = node->callers; cs; cs = cs->next_caller)
4314     if (cs->caller->thunk.thunk_p
4315         && cs->caller->call_for_symbol_thunks_and_aliases
4316           (has_undead_caller_from_outside_scc_p, NULL, true))
4317       return true;
4318     else if (!ipa_edge_within_scc (cs)
4319              && !IPA_NODE_REF (cs->caller)->node_dead)
4320       return true;
4321   return false;
4322 }
4323
4324
4325 /* Identify nodes within the same SCC as NODE which are no longer needed
4326    because of new clones and will be removed as unreachable.  */
4327
4328 static void
4329 identify_dead_nodes (struct cgraph_node *node)
4330 {
4331   struct cgraph_node *v;
4332   for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4333     if (v->will_be_removed_from_program_if_no_direct_calls_p ()
4334         && !v->call_for_symbol_thunks_and_aliases
4335              (has_undead_caller_from_outside_scc_p, NULL, true))
4336       IPA_NODE_REF (v)->node_dead = 1;
4337
4338   for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4339     if (!IPA_NODE_REF (v)->node_dead)
4340       spread_undeadness (v);
4341
4342   if (dump_file && (dump_flags & TDF_DETAILS))
4343     {
4344       for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4345         if (IPA_NODE_REF (v)->node_dead)
4346           fprintf (dump_file, "  Marking node as dead: %s/%i.\n",
4347                    v->name (), v->order);
4348     }
4349 }
4350
4351 /* The decision stage.  Iterate over the topological order of call graph nodes
4352    TOPO and make specialized clones if deemed beneficial.  */
4353
4354 static void
4355 ipcp_decision_stage (struct ipa_topo_info *topo)
4356 {
4357   int i;
4358
4359   if (dump_file)
4360     fprintf (dump_file, "\nIPA decision stage:\n\n");
4361
4362   for (i = topo->nnodes - 1; i >= 0; i--)
4363     {
4364       struct cgraph_node *node = topo->order[i];
4365       bool change = false, iterate = true;
4366
4367       while (iterate)
4368         {
4369           struct cgraph_node *v;
4370           iterate = false;
4371           for (v = node; v ; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
4372             if (v->has_gimple_body_p ()
4373                 && ipcp_versionable_function_p (v))
4374               iterate |= decide_whether_version_node (v);
4375
4376           change |= iterate;
4377         }
4378       if (change)
4379         identify_dead_nodes (node);
4380     }
4381 }
4382
4383 /* Look up all alignment information that we have discovered and copy it over
4384    to the transformation summary.  */
4385
4386 static void
4387 ipcp_store_alignment_results (void)
4388 {
4389   cgraph_node *node;
4390
4391   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
4392   {
4393     ipa_node_params *info = IPA_NODE_REF (node);
4394     bool dumped_sth = false;
4395     bool found_useful_result = false;
4396
4397     if (!opt_for_fn (node->decl, flag_ipa_cp_alignment))
4398       {
4399         if (dump_file)
4400           fprintf (dump_file, "Not considering %s for alignment discovery "
4401                    "and propagate; -fipa-cp-alignment: disabled.\n",
4402                    node->name ());
4403         continue;
4404       }
4405
4406    if (info->ipcp_orig_node)
4407       info = IPA_NODE_REF (info->ipcp_orig_node);
4408
4409    unsigned count = ipa_get_param_count (info);
4410    for (unsigned i = 0; i < count ; i++)
4411      {
4412        ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4413        if (plats->alignment.known
4414            && plats->alignment.align > 0)
4415          {
4416            found_useful_result = true;
4417            break;
4418          }
4419      }
4420    if (!found_useful_result)
4421      continue;
4422
4423   ipcp_grow_transformations_if_necessary ();
4424    ipcp_transformation_summary *ts = ipcp_get_transformation_summary (node);
4425    vec_safe_reserve_exact (ts->alignments, count);
4426
4427    for (unsigned i = 0; i < count ; i++)
4428      {
4429        ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
4430
4431        if (plats->alignment.align == 0)
4432          plats->alignment.known = false;
4433
4434        ts->alignments->quick_push (plats->alignment);
4435        if (!dump_file || !plats->alignment.known)
4436          continue;
4437        if (!dumped_sth)
4438          {
4439            fprintf (dump_file, "Propagated alignment info for function %s/%i:\n",
4440                     node->name (), node->order);
4441            dumped_sth = true;
4442          }
4443        fprintf (dump_file, "  param %i: align: %u, misalign: %u\n",
4444                 i, plats->alignment.align, plats->alignment.misalign);
4445      }
4446   }
4447 }
4448
4449 /* The IPCP driver.  */
4450
4451 static unsigned int
4452 ipcp_driver (void)
4453 {
4454   struct cgraph_2edge_hook_list *edge_duplication_hook_holder;
4455   struct cgraph_edge_hook_list *edge_removal_hook_holder;
4456   struct ipa_topo_info topo;
4457
4458   ipa_check_create_node_params ();
4459   ipa_check_create_edge_args ();
4460   grow_edge_clone_vectors ();
4461   edge_duplication_hook_holder =
4462     symtab->add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL);
4463   edge_removal_hook_holder =
4464     symtab->add_edge_removal_hook (&ipcp_edge_removal_hook, NULL);
4465
4466   ipcp_cst_values_pool = create_alloc_pool ("IPA-CP constant values",
4467                                             sizeof (ipcp_value<tree>), 32);
4468   ipcp_poly_ctx_values_pool = create_alloc_pool
4469     ("IPA-CP polymorphic contexts",
4470      sizeof (ipcp_value<ipa_polymorphic_call_context>), 32);
4471   ipcp_sources_pool = create_alloc_pool ("IPA-CP value sources",
4472                                          sizeof (ipcp_value_source<tree>), 64);
4473   ipcp_agg_lattice_pool = create_alloc_pool ("IPA_CP aggregate lattices",
4474                                              sizeof (struct ipcp_agg_lattice),
4475                                              32);
4476   if (dump_file)
4477     {
4478       fprintf (dump_file, "\nIPA structures before propagation:\n");
4479       if (dump_flags & TDF_DETAILS)
4480         ipa_print_all_params (dump_file);
4481       ipa_print_all_jump_functions (dump_file);
4482     }
4483
4484   /* Topological sort.  */
4485   build_toporder_info (&topo);
4486   /* Do the interprocedural propagation.  */
4487   ipcp_propagate_stage (&topo);
4488   /* Decide what constant propagation and cloning should be performed.  */
4489   ipcp_decision_stage (&topo);
4490   /* Store results of alignment propagation. */
4491   ipcp_store_alignment_results ();
4492
4493   /* Free all IPCP structures.  */
4494   free_toporder_info (&topo);
4495   next_edge_clone.release ();
4496   symtab->remove_edge_removal_hook (edge_removal_hook_holder);
4497   symtab->remove_edge_duplication_hook (edge_duplication_hook_holder);
4498   ipa_free_all_structures_after_ipa_cp ();
4499   if (dump_file)
4500     fprintf (dump_file, "\nIPA constant propagation end\n");
4501   return 0;
4502 }
4503
4504 /* Initialization and computation of IPCP data structures.  This is the initial
4505    intraprocedural analysis of functions, which gathers information to be
4506    propagated later on.  */
4507
4508 static void
4509 ipcp_generate_summary (void)
4510 {
4511   struct cgraph_node *node;
4512
4513   if (dump_file)
4514     fprintf (dump_file, "\nIPA constant propagation start:\n");
4515   ipa_register_cgraph_hooks ();
4516
4517   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
4518       {
4519         node->local.versionable
4520           = tree_versionable_function_p (node->decl);
4521         ipa_analyze_node (node);
4522       }
4523 }
4524
4525 /* Write ipcp summary for nodes in SET.  */
4526
4527 static void
4528 ipcp_write_summary (void)
4529 {
4530   ipa_prop_write_jump_functions ();
4531 }
4532
4533 /* Read ipcp summary.  */
4534
4535 static void
4536 ipcp_read_summary (void)
4537 {
4538   ipa_prop_read_jump_functions ();
4539 }
4540
4541 namespace {
4542
4543 const pass_data pass_data_ipa_cp =
4544 {
4545   IPA_PASS, /* type */
4546   "cp", /* name */
4547   OPTGROUP_NONE, /* optinfo_flags */
4548   TV_IPA_CONSTANT_PROP, /* tv_id */
4549   0, /* properties_required */
4550   0, /* properties_provided */
4551   0, /* properties_destroyed */
4552   0, /* todo_flags_start */
4553   ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
4554 };
4555
4556 class pass_ipa_cp : public ipa_opt_pass_d
4557 {
4558 public:
4559   pass_ipa_cp (gcc::context *ctxt)
4560     : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
4561                       ipcp_generate_summary, /* generate_summary */
4562                       ipcp_write_summary, /* write_summary */
4563                       ipcp_read_summary, /* read_summary */
4564                       ipcp_write_transformation_summaries, /*
4565                       write_optimization_summary */
4566                       ipcp_read_transformation_summaries, /*
4567                       read_optimization_summary */
4568                       NULL, /* stmt_fixup */
4569                       0, /* function_transform_todo_flags_start */
4570                       ipcp_transform_function, /* function_transform */
4571                       NULL) /* variable_transform */
4572   {}
4573
4574   /* opt_pass methods: */
4575   virtual bool gate (function *)
4576     {
4577       /* FIXME: We should remove the optimize check after we ensure we never run
4578          IPA passes when not optimizing.  */
4579       return (flag_ipa_cp && optimize) || in_lto_p;
4580     }
4581
4582   virtual unsigned int execute (function *) { return ipcp_driver (); }
4583
4584 }; // class pass_ipa_cp
4585
4586 } // anon namespace
4587
4588 ipa_opt_pass_d *
4589 make_pass_ipa_cp (gcc::context *ctxt)
4590 {
4591   return new pass_ipa_cp (ctxt);
4592 }
4593
4594 /* Reset all state within ipa-cp.c so that we can rerun the compiler
4595    within the same process.  For use by toplev::finalize.  */
4596
4597 void
4598 ipa_cp_c_finalize (void)
4599 {
4600   max_count = 0;
4601   overall_size = 0;
4602   max_new_size = 0;
4603 }