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