]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-profile.c
PR tree-optimization/92412 - excessive errno aliasing assumption defeats optimization
[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
479/* Simple ipa profile pass propagating frequencies across the callgraph. */
480
481static unsigned int
482ipa_profile (void)
483{
484 struct cgraph_node **order;
485 struct cgraph_edge *e;
486 int order_pos;
487 bool something_changed = false;
488 int i;
489 gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
490 struct cgraph_node *n,*n2;
491 int nindirect = 0, ncommon = 0, nunknown = 0, nuseless = 0, nconverted = 0;
95d81ba5 492 int nmismatch = 0, nimpossible = 0;
08f835dc
JH
493 bool node_map_initialized = false;
494
495 if (dump_file)
496 dump_histogram (dump_file, histogram);
497 for (i = 0; i < (int)histogram.length (); i++)
498 {
499 overall_time += histogram[i]->count * histogram[i]->time;
500 overall_size += histogram[i]->size;
501 }
502 if (overall_time)
503 {
504 gcov_type threshold;
505
506 gcc_assert (overall_size);
08f835dc 507
028d4092 508 cutoff = (overall_time * param_hot_bb_count_ws_permille + 500) / 1000;
08f835dc
JH
509 threshold = 0;
510 for (i = 0; cumulated < cutoff; i++)
511 {
512 cumulated += histogram[i]->count * histogram[i]->time;
513 threshold = histogram[i]->count;
514 }
515 if (!threshold)
516 threshold = 1;
517 if (dump_file)
518 {
519 gcov_type cumulated_time = 0, cumulated_size = 0;
520
521 for (i = 0;
522 i < (int)histogram.length () && histogram[i]->count >= threshold;
523 i++)
524 {
525 cumulated_time += histogram[i]->count * histogram[i]->time;
526 cumulated_size += histogram[i]->size;
527 }
16998094 528 fprintf (dump_file, "Determined min count: %" PRId64
08f835dc 529 " Time:%3.2f%% Size:%3.2f%%\n",
a9243bfc 530 (int64_t)threshold,
08f835dc
JH
531 cumulated_time * 100.0 / overall_time,
532 cumulated_size * 100.0 / overall_size);
533 }
512cc015 534
e53f77c6 535 if (in_lto_p)
08f835dc
JH
536 {
537 if (dump_file)
e53f77c6 538 fprintf (dump_file, "Setting hotness threshold in LTO mode.\n");
08f835dc
JH
539 set_hot_bb_threshold (threshold);
540 }
541 }
c3284718 542 histogram.release ();
d7809518 543 histogram_pool.release ();
08f835dc
JH
544
545 /* Produce speculative calls: we saved common traget from porfiling into
546 e->common_target_id. Now, at link time, we can look up corresponding
547 function node and produce speculative call. */
548
549 FOR_EACH_DEFINED_FUNCTION (n)
550 {
551 bool update = false;
552
1ede94c5
JH
553 if (!opt_for_fn (n->decl, flag_ipa_profile))
554 continue;
555
08f835dc
JH
556 for (e = n->indirect_calls; e; e = e->next_callee)
557 {
3995f3a2 558 if (n->count.initialized_p ())
08f835dc
JH
559 nindirect++;
560 if (e->indirect_info->common_target_id)
561 {
562 if (!node_map_initialized)
563 init_node_map (false);
564 node_map_initialized = true;
565 ncommon++;
566 n2 = find_func_by_profile_id (e->indirect_info->common_target_id);
567 if (n2)
568 {
569 if (dump_file)
570 {
571 fprintf (dump_file, "Indirect call -> direct call from"
464d0118
ML
572 " other module %s => %s, prob %3.2f\n",
573 n->dump_name (),
574 n2->dump_name (),
08f835dc
JH
575 e->indirect_info->common_target_probability
576 / (float)REG_BR_PROB_BASE);
577 }
578 if (e->indirect_info->common_target_probability
579 < REG_BR_PROB_BASE / 2)
580 {
581 nuseless++;
582 if (dump_file)
583 fprintf (dump_file,
584 "Not speculating: probability is too low.\n");
585 }
3dafb85c 586 else if (!e->maybe_hot_p ())
08f835dc
JH
587 {
588 nuseless++;
589 if (dump_file)
590 fprintf (dump_file,
591 "Not speculating: call is cold.\n");
592 }
d52f5295
ML
593 else if (n2->get_availability () <= AVAIL_INTERPOSABLE
594 && n2->can_be_discarded_p ())
08f835dc
JH
595 {
596 nuseless++;
597 if (dump_file)
598 fprintf (dump_file,
599 "Not speculating: target is overwritable "
600 "and can be discarded.\n");
601 }
6fe906a3 602 else if (ipa_node_params_sum && ipa_edge_args_sum
f65f1ae3
MJ
603 && (!vec_safe_is_empty
604 (IPA_NODE_REF (n2)->descriptors))
95d81ba5
JH
605 && ipa_get_param_count (IPA_NODE_REF (n2))
606 != ipa_get_cs_argument_count (IPA_EDGE_REF (e))
607 && (ipa_get_param_count (IPA_NODE_REF (n2))
608 >= ipa_get_cs_argument_count (IPA_EDGE_REF (e))
609 || !stdarg_p (TREE_TYPE (n2->decl))))
610 {
611 nmismatch++;
612 if (dump_file)
613 fprintf (dump_file,
614 "Not speculating: "
4e8e460b 615 "parameter count mismatch\n");
95d81ba5
JH
616 }
617 else if (e->indirect_info->polymorphic
618 && !opt_for_fn (n->decl, flag_devirtualize)
619 && !possible_polymorphic_call_target_p (e, n2))
620 {
621 nimpossible++;
622 if (dump_file)
623 fprintf (dump_file,
624 "Not speculating: "
625 "function is not in the polymorphic "
626 "call target list\n");
627 }
08f835dc
JH
628 else
629 {
630 /* Target may be overwritable, but profile says that
631 control flow goes to this particular implementation
632 of N2. Speculate on the local alias to allow inlining.
633 */
d52f5295 634 if (!n2->can_be_discarded_p ())
5b79657a
JH
635 {
636 cgraph_node *alias;
d52f5295 637 alias = dyn_cast<cgraph_node *> (n2->noninterposable_alias ());
5b79657a
JH
638 if (alias)
639 n2 = alias;
640 }
08f835dc 641 nconverted++;
3dafb85c
ML
642 e->make_speculative
643 (n2,
3995f3a2 644 e->count.apply_probability
1bad9c18 645 (e->indirect_info->common_target_probability));
08f835dc
JH
646 update = true;
647 }
648 }
649 else
650 {
651 if (dump_file)
652 fprintf (dump_file, "Function with profile-id %i not found.\n",
653 e->indirect_info->common_target_id);
654 nunknown++;
655 }
656 }
657 }
658 if (update)
0bceb671 659 ipa_update_overall_fn_summary (n);
08f835dc
JH
660 }
661 if (node_map_initialized)
662 del_node_map ();
663 if (dump_file && nindirect)
664 fprintf (dump_file,
665 "%i indirect calls trained.\n"
666 "%i (%3.2f%%) have common target.\n"
667 "%i (%3.2f%%) targets was not found.\n"
95d81ba5
JH
668 "%i (%3.2f%%) targets had parameter count mismatch.\n"
669 "%i (%3.2f%%) targets was not in polymorphic call target list.\n"
08f835dc
JH
670 "%i (%3.2f%%) speculations seems useless.\n"
671 "%i (%3.2f%%) speculations produced.\n",
672 nindirect,
673 ncommon, ncommon * 100.0 / nindirect,
674 nunknown, nunknown * 100.0 / nindirect,
95d81ba5
JH
675 nmismatch, nmismatch * 100.0 / nindirect,
676 nimpossible, nimpossible * 100.0 / nindirect,
08f835dc
JH
677 nuseless, nuseless * 100.0 / nindirect,
678 nconverted, nconverted * 100.0 / nindirect);
679
3dafb85c 680 order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
08f835dc
JH
681 order_pos = ipa_reverse_postorder (order);
682 for (i = order_pos - 1; i >= 0; i--)
683 {
87f94429 684 if (order[i]->local
1ede94c5
JH
685 && opt_for_fn (order[i]->decl, flag_ipa_profile)
686 && ipa_propagate_frequency (order[i]))
08f835dc
JH
687 {
688 for (e = order[i]->callees; e; e = e->next_callee)
87f94429 689 if (e->callee->local && !e->callee->aux)
08f835dc
JH
690 {
691 something_changed = true;
67348ccc 692 e->callee->aux = (void *)1;
08f835dc
JH
693 }
694 }
67348ccc 695 order[i]->aux = NULL;
08f835dc
JH
696 }
697
698 while (something_changed)
699 {
700 something_changed = false;
701 for (i = order_pos - 1; i >= 0; i--)
702 {
1ede94c5
JH
703 if (order[i]->aux
704 && opt_for_fn (order[i]->decl, flag_ipa_profile)
705 && ipa_propagate_frequency (order[i]))
08f835dc
JH
706 {
707 for (e = order[i]->callees; e; e = e->next_callee)
87f94429 708 if (e->callee->local && !e->callee->aux)
08f835dc
JH
709 {
710 something_changed = true;
67348ccc 711 e->callee->aux = (void *)1;
08f835dc
JH
712 }
713 }
67348ccc 714 order[i]->aux = NULL;
08f835dc
JH
715 }
716 }
717 free (order);
718 return 0;
719}
720
08f835dc
JH
721namespace {
722
723const pass_data pass_data_ipa_profile =
724{
725 IPA_PASS, /* type */
726 "profile_estimate", /* name */
727 OPTGROUP_NONE, /* optinfo_flags */
08f835dc
JH
728 TV_IPA_PROFILE, /* tv_id */
729 0, /* properties_required */
730 0, /* properties_provided */
731 0, /* properties_destroyed */
732 0, /* todo_flags_start */
733 0, /* todo_flags_finish */
734};
735
736class pass_ipa_profile : public ipa_opt_pass_d
737{
738public:
c3284718
RS
739 pass_ipa_profile (gcc::context *ctxt)
740 : ipa_opt_pass_d (pass_data_ipa_profile, ctxt,
741 ipa_profile_generate_summary, /* generate_summary */
742 ipa_profile_write_summary, /* write_summary */
743 ipa_profile_read_summary, /* read_summary */
744 NULL, /* write_optimization_summary */
745 NULL, /* read_optimization_summary */
746 NULL, /* stmt_fixup */
747 0, /* function_transform_todo_flags_start */
748 NULL, /* function_transform */
749 NULL) /* variable_transform */
08f835dc
JH
750 {}
751
752 /* opt_pass methods: */
2bf86c84 753 virtual bool gate (function *) { return flag_ipa_profile || in_lto_p; }
be55bfe6 754 virtual unsigned int execute (function *) { return ipa_profile (); }
08f835dc
JH
755
756}; // class pass_ipa_profile
757
758} // anon namespace
759
760ipa_opt_pass_d *
761make_pass_ipa_profile (gcc::context *ctxt)
762{
763 return new pass_ipa_profile (ctxt);
764}