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