gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / gcc / ipa-profile.c
1 /* Basic IPA optimizations based on profile.
2    Copyright (C) 2003-2015 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 /* ipa-profile pass implements the following analysis propagating profille
21    inter-procedurally.
22
23    - Count histogram construction.  This is a histogram analyzing how much
24      time is spent executing statements with a given execution count read
25      from profile feedback. This histogram is complete only with LTO,
26      otherwise it contains information only about the current unit.
27
28      Similar histogram is also estimated by coverage runtime.  This histogram
29      is not dependent on LTO, but it suffers from various defects; first
30      gcov runtime is not weighting individual basic block by estimated execution
31      time and second the merging of multiple runs makes assumption that the
32      histogram distribution did not change.  Consequentely histogram constructed
33      here may be more precise.
34
35      The information is used to set hot/cold thresholds.
36    - Next speculative indirect call resolution is performed:  the local
37      profile pass assigns profile-id to each function and provide us with a
38      histogram specifying the most common target.  We look up the callgraph
39      node corresponding to the target and produce a speculative call.
40
41      This call may or may not survive through IPA optimization based on decision
42      of inliner. 
43    - Finally we propagate the following flags: unlikely executed, executed
44      once, executed at startup and executed at exit.  These flags are used to
45      control code size/performance threshold and and code placement (by producing
46      .text.unlikely/.text.hot/.text.startup/.text.exit subsections).  */
47 #include "config.h"
48 #include "system.h"
49 #include "coretypes.h"
50 #include "tm.h"
51 #include "hash-set.h"
52 #include "machmode.h"
53 #include "vec.h"
54 #include "double-int.h"
55 #include "input.h"
56 #include "alias.h"
57 #include "symtab.h"
58 #include "wide-int.h"
59 #include "inchash.h"
60 #include "tree.h"
61 #include "fold-const.h"
62 #include "predict.h"
63 #include "dominance.h"
64 #include "cfg.h"
65 #include "basic-block.h"
66 #include "hash-map.h"
67 #include "is-a.h"
68 #include "plugin-api.h"
69 #include "hard-reg-set.h"
70 #include "input.h"
71 #include "function.h"
72 #include "ipa-ref.h"
73 #include "cgraph.h"
74 #include "tree-pass.h"
75 #include "tree-ssa-alias.h"
76 #include "internal-fn.h"
77 #include "gimple-expr.h"
78 #include "gimple.h"
79 #include "gimple-iterator.h"
80 #include "flags.h"
81 #include "target.h"
82 #include "tree-iterator.h"
83 #include "ipa-utils.h"
84 #include "profile.h"
85 #include "params.h"
86 #include "value-prof.h"
87 #include "alloc-pool.h"
88 #include "tree-inline.h"
89 #include "lto-streamer.h"
90 #include "data-streamer.h"
91 #include "symbol-summary.h"
92 #include "ipa-prop.h"
93 #include "ipa-inline.h"
94
95 /* Entry in the histogram.  */
96
97 struct histogram_entry
98 {
99   gcov_type count;
100   int time;
101   int size;
102 };
103
104 /* Histogram of profile values.
105    The histogram is represented as an ordered vector of entries allocated via
106    histogram_pool. During construction a separate hashtable is kept to lookup
107    duplicate entries.  */
108
109 vec<histogram_entry *> histogram;
110 static alloc_pool histogram_pool;
111
112 /* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR.  */
113
114 struct histogram_hash : typed_noop_remove <histogram_entry>
115 {
116   typedef histogram_entry value_type;
117   typedef histogram_entry compare_type;
118   static inline hashval_t hash (const value_type *);
119   static inline int equal (const value_type *, const compare_type *);
120 };
121
122 inline hashval_t
123 histogram_hash::hash (const histogram_entry *val)
124 {
125   return val->count;
126 }
127
128 inline int
129 histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
130 {
131   return val->count == val2->count;
132 }
133
134 /* Account TIME and SIZE executed COUNT times into HISTOGRAM.
135    HASHTABLE is the on-side hash kept to avoid duplicates.  */
136
137 static void
138 account_time_size (hash_table<histogram_hash> *hashtable,
139                    vec<histogram_entry *> &histogram,
140                    gcov_type count, int time, int size)
141 {
142   histogram_entry key = {count, 0, 0};
143   histogram_entry **val = hashtable->find_slot (&key, INSERT);
144
145   if (!*val)
146     {
147       *val = (histogram_entry *) pool_alloc (histogram_pool);
148       **val = key;
149       histogram.safe_push (*val);
150     }
151   (*val)->time += time;
152   (*val)->size += size;
153 }
154
155 int
156 cmp_counts (const void *v1, const void *v2)
157 {
158   const histogram_entry *h1 = *(const histogram_entry * const *)v1;
159   const histogram_entry *h2 = *(const histogram_entry * const *)v2;
160   if (h1->count < h2->count)
161     return 1;
162   if (h1->count > h2->count)
163     return -1;
164   return 0;
165 }
166
167 /* Dump HISTOGRAM to FILE.  */
168
169 static void
170 dump_histogram (FILE *file, vec<histogram_entry *> histogram)
171 {
172   unsigned int i;
173   gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
174   
175   fprintf (dump_file, "Histogram:\n");
176   for (i = 0; i < histogram.length (); i++)
177     {
178       overall_time += histogram[i]->count * histogram[i]->time;
179       overall_size += histogram[i]->size;
180     }
181   if (!overall_time)
182     overall_time = 1;
183   if (!overall_size)
184     overall_size = 1;
185   for (i = 0; i < histogram.length (); i++)
186     {
187       cumulated_time += histogram[i]->count * histogram[i]->time;
188       cumulated_size += histogram[i]->size;
189       fprintf (file, "  %" PRId64": time:%i (%2.2f) size:%i (%2.2f)\n",
190                (int64_t) histogram[i]->count,
191                histogram[i]->time,
192                cumulated_time * 100.0 / overall_time,
193                histogram[i]->size,
194                cumulated_size * 100.0 / overall_size);
195    }
196 }
197
198 /* Collect histogram from CFG profiles.  */
199
200 static void
201 ipa_profile_generate_summary (void)
202 {
203   struct cgraph_node *node;
204   gimple_stmt_iterator gsi;
205   basic_block bb;
206
207   hash_table<histogram_hash> hashtable (10);
208   histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
209                                       10);
210   
211   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
212     FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
213       {
214         int time = 0;
215         int size = 0;
216         for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
217           {
218             gimple stmt = gsi_stmt (gsi);
219             if (gimple_code (stmt) == GIMPLE_CALL
220                 && !gimple_call_fndecl (stmt))
221               {
222                 histogram_value h;
223                 h = gimple_histogram_value_of_type
224                       (DECL_STRUCT_FUNCTION (node->decl),
225                        stmt, HIST_TYPE_INDIR_CALL);
226                 /* No need to do sanity check: gimple_ic_transform already
227                    takes away bad histograms.  */
228                 if (h)
229                   {
230                     /* counter 0 is target, counter 1 is number of execution we called target,
231                        counter 2 is total number of executions.  */
232                     if (h->hvalue.counters[2])
233                       {
234                         struct cgraph_edge * e = node->get_edge (stmt);
235                         if (e && !e->indirect_unknown_callee)
236                           continue;
237                         e->indirect_info->common_target_id
238                           = h->hvalue.counters [0];
239                         e->indirect_info->common_target_probability
240                           = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]);
241                         if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE)
242                           {
243                             if (dump_file)
244                               fprintf (dump_file, "Probability capped to 1\n");
245                             e->indirect_info->common_target_probability = REG_BR_PROB_BASE;
246                           }
247                       }
248                     gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->decl),
249                                                     stmt, h);
250                   }
251               }
252             time += estimate_num_insns (stmt, &eni_time_weights);
253             size += estimate_num_insns (stmt, &eni_size_weights);
254           }
255         account_time_size (&hashtable, histogram, bb->count, time, size);
256       }
257   histogram.qsort (cmp_counts);
258 }
259
260 /* Serialize the ipa info for lto.  */
261
262 static void
263 ipa_profile_write_summary (void)
264 {
265   struct lto_simple_output_block *ob
266     = lto_create_simple_output_block (LTO_section_ipa_profile);
267   unsigned int i;
268
269   streamer_write_uhwi_stream (ob->main_stream, histogram.length ());
270   for (i = 0; i < histogram.length (); i++)
271     {
272       streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
273       streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
274       streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
275     }
276   lto_destroy_simple_output_block (ob);
277 }
278
279 /* Deserialize the ipa info for lto.  */
280
281 static void
282 ipa_profile_read_summary (void)
283 {
284   struct lto_file_decl_data ** file_data_vec
285     = lto_get_file_decl_data ();
286   struct lto_file_decl_data * file_data;
287   int j = 0;
288
289   hash_table<histogram_hash> hashtable (10);
290   histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
291                                       10);
292
293   while ((file_data = file_data_vec[j++]))
294     {
295       const char *data;
296       size_t len;
297       struct lto_input_block *ib
298         = lto_create_simple_input_block (file_data,
299                                          LTO_section_ipa_profile,
300                                          &data, &len);
301       if (ib)
302         {
303           unsigned int num = streamer_read_uhwi (ib);
304           unsigned int n;
305           for (n = 0; n < num; n++)
306             {
307               gcov_type count = streamer_read_gcov_count (ib);
308               int time = streamer_read_uhwi (ib);
309               int size = streamer_read_uhwi (ib);
310               account_time_size (&hashtable, histogram,
311                                  count, time, size);
312             }
313           lto_destroy_simple_input_block (file_data,
314                                           LTO_section_ipa_profile,
315                                           ib, data, len);
316         }
317     }
318   histogram.qsort (cmp_counts);
319 }
320
321 /* Data used by ipa_propagate_frequency.  */
322
323 struct ipa_propagate_frequency_data
324 {
325   cgraph_node *function_symbol;
326   bool maybe_unlikely_executed;
327   bool maybe_executed_once;
328   bool only_called_at_startup;
329   bool only_called_at_exit;
330 };
331
332 /* Worker for ipa_propagate_frequency_1.  */
333
334 static bool
335 ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
336 {
337   struct ipa_propagate_frequency_data *d;
338   struct cgraph_edge *edge;
339
340   d = (struct ipa_propagate_frequency_data *)data;
341   for (edge = node->callers;
342        edge && (d->maybe_unlikely_executed || d->maybe_executed_once
343                 || d->only_called_at_startup || d->only_called_at_exit);
344        edge = edge->next_caller)
345     {
346       if (edge->caller != d->function_symbol)
347         {
348           d->only_called_at_startup &= edge->caller->only_called_at_startup;
349           /* It makes sense to put main() together with the static constructors.
350              It will be executed for sure, but rest of functions called from
351              main are definitely not at startup only.  */
352           if (MAIN_NAME_P (DECL_NAME (edge->caller->decl)))
353             d->only_called_at_startup = 0;
354           d->only_called_at_exit &= edge->caller->only_called_at_exit;
355         }
356
357       /* When profile feedback is available, do not try to propagate too hard;
358          counts are already good guide on function frequencies and roundoff
359          errors can make us to push function into unlikely section even when
360          it is executed by the train run.  Transfer the function only if all
361          callers are unlikely executed.  */
362       if (profile_info
363           && opt_for_fn (d->function_symbol->decl, flag_branch_probabilities)
364           /* Thunks are not profiled.  This is more or less implementation
365              bug.  */
366           && !d->function_symbol->thunk.thunk_p
367           && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED
368               || (edge->caller->global.inlined_to
369                   && edge->caller->global.inlined_to->frequency
370                      != NODE_FREQUENCY_UNLIKELY_EXECUTED)))
371           d->maybe_unlikely_executed = false;
372       if (!edge->frequency)
373         continue;
374       switch (edge->caller->frequency)
375         {
376         case NODE_FREQUENCY_UNLIKELY_EXECUTED:
377           break;
378         case NODE_FREQUENCY_EXECUTED_ONCE:
379           if (dump_file && (dump_flags & TDF_DETAILS))
380             fprintf (dump_file, "  Called by %s that is executed once\n",
381                      edge->caller->name ());
382           d->maybe_unlikely_executed = false;
383           if (inline_edge_summary (edge)->loop_depth)
384             {
385               d->maybe_executed_once = false;
386               if (dump_file && (dump_flags & TDF_DETAILS))
387                 fprintf (dump_file, "  Called in loop\n");
388             }
389           break;
390         case NODE_FREQUENCY_HOT:
391         case NODE_FREQUENCY_NORMAL:
392           if (dump_file && (dump_flags & TDF_DETAILS))
393             fprintf (dump_file, "  Called by %s that is normal or hot\n",
394                      edge->caller->name ());
395           d->maybe_unlikely_executed = false;
396           d->maybe_executed_once = false;
397           break;
398         }
399     }
400   return edge != NULL;
401 }
402
403 /* Return ture if NODE contains hot calls.  */
404
405 bool
406 contains_hot_call_p (struct cgraph_node *node)
407 {
408   struct cgraph_edge *e;
409   for (e = node->callees; e; e = e->next_callee)
410     if (e->maybe_hot_p ())
411       return true;
412     else if (!e->inline_failed
413              && contains_hot_call_p (e->callee))
414       return true;
415   for (e = node->indirect_calls; e; e = e->next_callee)
416     if (e->maybe_hot_p ())
417       return true;
418   return false;
419 }
420
421 /* See if the frequency of NODE can be updated based on frequencies of its
422    callers.  */
423 bool
424 ipa_propagate_frequency (struct cgraph_node *node)
425 {
426   struct ipa_propagate_frequency_data d = {node, true, true, true, true};
427   bool changed = false;
428
429   /* We can not propagate anything useful about externally visible functions
430      nor about virtuals.  */
431   if (!node->local.local
432       || node->alias
433       || (opt_for_fn (node->decl, flag_devirtualize)
434           && DECL_VIRTUAL_P (node->decl)))
435     return false;
436   gcc_assert (node->analyzed);
437   if (dump_file && (dump_flags & TDF_DETAILS))
438     fprintf (dump_file, "Processing frequency %s\n", node->name ());
439
440   node->call_for_symbol_and_aliases (ipa_propagate_frequency_1, &d,
441                                      true);
442
443   if ((d.only_called_at_startup && !d.only_called_at_exit)
444       && !node->only_called_at_startup)
445     {
446        node->only_called_at_startup = true;
447        if (dump_file)
448          fprintf (dump_file, "Node %s promoted to only called at startup.\n",
449                   node->name ());
450        changed = true;
451     }
452   if ((d.only_called_at_exit && !d.only_called_at_startup)
453       && !node->only_called_at_exit)
454     {
455        node->only_called_at_exit = true;
456        if (dump_file)
457          fprintf (dump_file, "Node %s promoted to only called at exit.\n",
458                   node->name ());
459        changed = true;
460     }
461
462   /* With profile we can decide on hot/normal based on count.  */
463   if (node->count)
464     {
465       bool hot = false;
466       if (node->count >= get_hot_bb_threshold ())
467         hot = true;
468       if (!hot)
469         hot |= contains_hot_call_p (node);
470       if (hot)
471         {
472           if (node->frequency != NODE_FREQUENCY_HOT)
473             {
474               if (dump_file)
475                 fprintf (dump_file, "Node %s promoted to hot.\n",
476                          node->name ());
477               node->frequency = NODE_FREQUENCY_HOT;
478               return true;
479             }
480           return false;
481         }
482       else if (node->frequency == NODE_FREQUENCY_HOT)
483         {
484           if (dump_file)
485             fprintf (dump_file, "Node %s reduced to normal.\n",
486                      node->name ());
487           node->frequency = NODE_FREQUENCY_NORMAL;
488           changed = true;
489         }
490     }
491   /* These come either from profile or user hints; never update them.  */
492   if (node->frequency == NODE_FREQUENCY_HOT
493       || node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
494     return changed;
495   if (d.maybe_unlikely_executed)
496     {
497       node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
498       if (dump_file)
499         fprintf (dump_file, "Node %s promoted to unlikely executed.\n",
500                  node->name ());
501       changed = true;
502     }
503   else if (d.maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
504     {
505       node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
506       if (dump_file)
507         fprintf (dump_file, "Node %s promoted to executed once.\n",
508                  node->name ());
509       changed = true;
510     }
511   return changed;
512 }
513
514 /* Simple ipa profile pass propagating frequencies across the callgraph.  */
515
516 static unsigned int
517 ipa_profile (void)
518 {
519   struct cgraph_node **order;
520   struct cgraph_edge *e;
521   int order_pos;
522   bool something_changed = false;
523   int i;
524   gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
525   struct cgraph_node *n,*n2;
526   int nindirect = 0, ncommon = 0, nunknown = 0, nuseless = 0, nconverted = 0;
527   bool node_map_initialized = false;
528
529   if (dump_file)
530     dump_histogram (dump_file, histogram);
531   for (i = 0; i < (int)histogram.length (); i++)
532     {
533       overall_time += histogram[i]->count * histogram[i]->time;
534       overall_size += histogram[i]->size;
535     }
536   if (overall_time)
537     {
538       gcov_type threshold;
539
540       gcc_assert (overall_size);
541       if (dump_file)
542         {
543           gcov_type min, cumulated_time = 0, cumulated_size = 0;
544
545           fprintf (dump_file, "Overall time: %" PRId64"\n",
546                    (int64_t)overall_time);
547           min = get_hot_bb_threshold ();
548           for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
549                i++)
550             {
551               cumulated_time += histogram[i]->count * histogram[i]->time;
552               cumulated_size += histogram[i]->size;
553             }
554           fprintf (dump_file, "GCOV min count: %" PRId64
555                    " Time:%3.2f%% Size:%3.2f%%\n", 
556                    (int64_t)min,
557                    cumulated_time * 100.0 / overall_time,
558                    cumulated_size * 100.0 / overall_size);
559         }
560       cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
561       threshold = 0;
562       for (i = 0; cumulated < cutoff; i++)
563         {
564           cumulated += histogram[i]->count * histogram[i]->time;
565           threshold = histogram[i]->count;
566         }
567       if (!threshold)
568         threshold = 1;
569       if (dump_file)
570         {
571           gcov_type cumulated_time = 0, cumulated_size = 0;
572
573           for (i = 0;
574                i < (int)histogram.length () && histogram[i]->count >= threshold;
575                i++)
576             {
577               cumulated_time += histogram[i]->count * histogram[i]->time;
578               cumulated_size += histogram[i]->size;
579             }
580           fprintf (dump_file, "Determined min count: %" PRId64
581                    " Time:%3.2f%% Size:%3.2f%%\n", 
582                    (int64_t)threshold,
583                    cumulated_time * 100.0 / overall_time,
584                    cumulated_size * 100.0 / overall_size);
585         }
586       if (threshold > get_hot_bb_threshold ()
587           || in_lto_p)
588         {
589           if (dump_file)
590             fprintf (dump_file, "Threshold updated.\n");
591           set_hot_bb_threshold (threshold);
592         }
593     }
594   histogram.release ();
595   free_alloc_pool (histogram_pool);
596
597   /* Produce speculative calls: we saved common traget from porfiling into
598      e->common_target_id.  Now, at link time, we can look up corresponding
599      function node and produce speculative call.  */
600
601   FOR_EACH_DEFINED_FUNCTION (n)
602     {
603       bool update = false;
604
605       if (!opt_for_fn (n->decl, flag_ipa_profile))
606         continue;
607
608       for (e = n->indirect_calls; e; e = e->next_callee)
609         {
610           if (n->count)
611             nindirect++;
612           if (e->indirect_info->common_target_id)
613             {
614               if (!node_map_initialized)
615                 init_node_map (false);
616               node_map_initialized = true;
617               ncommon++;
618               n2 = find_func_by_profile_id (e->indirect_info->common_target_id);
619               if (n2)
620                 {
621                   if (dump_file)
622                     {
623                       fprintf (dump_file, "Indirect call -> direct call from"
624                                " other module %s/%i => %s/%i, prob %3.2f\n",
625                                xstrdup_for_dump (n->name ()), n->order,
626                                xstrdup_for_dump (n2->name ()), n2->order,
627                                e->indirect_info->common_target_probability
628                                / (float)REG_BR_PROB_BASE);
629                     }
630                   if (e->indirect_info->common_target_probability
631                       < REG_BR_PROB_BASE / 2)
632                     {
633                       nuseless++;
634                       if (dump_file)
635                         fprintf (dump_file,
636                                  "Not speculating: probability is too low.\n");
637                     }
638                   else if (!e->maybe_hot_p ())
639                     {
640                       nuseless++;
641                       if (dump_file)
642                         fprintf (dump_file,
643                                  "Not speculating: call is cold.\n");
644                     }
645                   else if (n2->get_availability () <= AVAIL_INTERPOSABLE
646                            && n2->can_be_discarded_p ())
647                     {
648                       nuseless++;
649                       if (dump_file)
650                         fprintf (dump_file,
651                                  "Not speculating: target is overwritable "
652                                  "and can be discarded.\n");
653                     }
654                   else
655                     {
656                       /* Target may be overwritable, but profile says that
657                          control flow goes to this particular implementation
658                          of N2.  Speculate on the local alias to allow inlining.
659                        */
660                       if (!n2->can_be_discarded_p ())
661                         {
662                           cgraph_node *alias;
663                           alias = dyn_cast<cgraph_node *> (n2->noninterposable_alias ());
664                           if (alias)
665                             n2 = alias;
666                         }
667                       nconverted++;
668                       e->make_speculative
669                         (n2,
670                          apply_scale (e->count,
671                                       e->indirect_info->common_target_probability),
672                          apply_scale (e->frequency,
673                                       e->indirect_info->common_target_probability));
674                       update = true;
675                     }
676                 }
677               else
678                 {
679                   if (dump_file)
680                     fprintf (dump_file, "Function with profile-id %i not found.\n",
681                              e->indirect_info->common_target_id);
682                   nunknown++;
683                 }
684             }
685          }
686        if (update)
687          inline_update_overall_summary (n);
688      }
689   if (node_map_initialized)
690     del_node_map ();
691   if (dump_file && nindirect)
692     fprintf (dump_file,
693              "%i indirect calls trained.\n"
694              "%i (%3.2f%%) have common target.\n"
695              "%i (%3.2f%%) targets was not found.\n"
696              "%i (%3.2f%%) speculations seems useless.\n"
697              "%i (%3.2f%%) speculations produced.\n",
698              nindirect,
699              ncommon, ncommon * 100.0 / nindirect,
700              nunknown, nunknown * 100.0 / nindirect,
701              nuseless, nuseless * 100.0 / nindirect,
702              nconverted, nconverted * 100.0 / nindirect);
703
704   order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
705   order_pos = ipa_reverse_postorder (order);
706   for (i = order_pos - 1; i >= 0; i--)
707     {
708       if (order[i]->local.local
709           && opt_for_fn (order[i]->decl, flag_ipa_profile)
710           && ipa_propagate_frequency (order[i]))
711         {
712           for (e = order[i]->callees; e; e = e->next_callee)
713             if (e->callee->local.local && !e->callee->aux)
714               {
715                 something_changed = true;
716                 e->callee->aux = (void *)1;
717               }
718         }
719       order[i]->aux = NULL;
720     }
721
722   while (something_changed)
723     {
724       something_changed = false;
725       for (i = order_pos - 1; i >= 0; i--)
726         {
727           if (order[i]->aux
728               && opt_for_fn (order[i]->decl, flag_ipa_profile)
729               && ipa_propagate_frequency (order[i]))
730             {
731               for (e = order[i]->callees; e; e = e->next_callee)
732                 if (e->callee->local.local && !e->callee->aux)
733                   {
734                     something_changed = true;
735                     e->callee->aux = (void *)1;
736                   }
737             }
738           order[i]->aux = NULL;
739         }
740     }
741   free (order);
742   return 0;
743 }
744
745 namespace {
746
747 const pass_data pass_data_ipa_profile =
748 {
749   IPA_PASS, /* type */
750   "profile_estimate", /* name */
751   OPTGROUP_NONE, /* optinfo_flags */
752   TV_IPA_PROFILE, /* tv_id */
753   0, /* properties_required */
754   0, /* properties_provided */
755   0, /* properties_destroyed */
756   0, /* todo_flags_start */
757   0, /* todo_flags_finish */
758 };
759
760 class pass_ipa_profile : public ipa_opt_pass_d
761 {
762 public:
763   pass_ipa_profile (gcc::context *ctxt)
764     : ipa_opt_pass_d (pass_data_ipa_profile, ctxt,
765                       ipa_profile_generate_summary, /* generate_summary */
766                       ipa_profile_write_summary, /* write_summary */
767                       ipa_profile_read_summary, /* read_summary */
768                       NULL, /* write_optimization_summary */
769                       NULL, /* read_optimization_summary */
770                       NULL, /* stmt_fixup */
771                       0, /* function_transform_todo_flags_start */
772                       NULL, /* function_transform */
773                       NULL) /* variable_transform */
774   {}
775
776   /* opt_pass methods: */
777   virtual bool gate (function *) { return flag_ipa_profile || in_lto_p; }
778   virtual unsigned int execute (function *) { return ipa_profile (); }
779
780 }; // class pass_ipa_profile
781
782 } // anon namespace
783
784 ipa_opt_pass_d *
785 make_pass_ipa_profile (gcc::context *ctxt)
786 {
787   return new pass_ipa_profile (ctxt);
788 }