diff options
Diffstat (limited to 'gcc/auto-profile.cc')
-rw-r--r-- | gcc/auto-profile.cc | 46 |
1 files changed, 39 insertions, 7 deletions
diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc index 91cc8db..e12b304 100644 --- a/gcc/auto-profile.cc +++ b/gcc/auto-profile.cc @@ -35,6 +35,8 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic-core.h" #include "profile.h" #include "langhooks.h" +#include "context.h" +#include "pass_manager.h" #include "cfgloop.h" #include "tree-cfg.h" #include "tree-cfgcleanup.h" @@ -573,10 +575,10 @@ void function_instance::merge (function_instance *other) for (callsite_map::const_iterator iter = other->callsites.begin (); iter != other->callsites.end (); ++iter) if (callsites.count (iter->first) == 0) - callsites[iter->first] = iter->second; + callsites[iter->first] = iter->second; - for (position_count_map::const_iterator iter = pos_counts.begin (); - iter != pos_counts.end (); ++iter) + for (position_count_map::const_iterator iter = other->pos_counts.begin (); + iter != other->pos_counts.end (); ++iter) if (pos_counts.count (iter->first) == 0) pos_counts[iter->first] = iter->second; else @@ -858,6 +860,9 @@ autofdo_source_profile::read () /* Read in the function/callsite profile, and store it in local data structure. */ unsigned function_num = gcov_read_unsigned (); + int profile_pass_num + = g->get_passes ()->get_pass_auto_profile ()->static_pass_number; + g->get_dumps ()->dump_start (profile_pass_num, NULL); for (unsigned i = 0; i < function_num; i++) { function_instance::function_instance_stack stack; @@ -870,8 +875,21 @@ autofdo_source_profile::read () if (map_.count (fun_id) == 0) map_[fun_id] = s; else - map_[fun_id]->merge (s); + { + /* Since this is invoked very early, before the pass + manager, we need to set up the dumping explicitly. This is + similar to the handling in finish_optimization_passes. */ + if (dump_enabled_p ()) + { + dump_user_location_t loc + = dump_user_location_t::from_location_t (input_location); + dump_printf_loc (MSG_NOTE, loc, "Merging profile for %s\n", + afdo_string_table->get_name (s->name ())); + } + map_[fun_id]->merge (s); + } } + g->get_dumps ()->dump_finish (profile_pass_num); return true; } @@ -1102,7 +1120,8 @@ update_count_by_afdo_count (profile_count *count, gcov_type c) /* In case we have guessed profile which is already zero, preserve quality info. */ else if (count->nonzero_p () - || count->quality () == GUESSED) + || count->quality () == GUESSED + || count->quality () == GUESSED_LOCAL) *count = profile_count::zero ().afdo (); } @@ -1497,8 +1516,21 @@ afdo_calculate_branch_prob (bb_set *annotated_bb) if (num_unknown_succ == 0 && total_count.nonzero_p ()) { FOR_EACH_EDGE (e, ei, bb->succs) - e->probability - = AFDO_EINFO (e)->get_count ().probability_in (total_count); + { + /* If probability is 1, preserve reliable static prediction + (This is, for example the case of single fallthru edge + or single fallthru plus unlikely EH edge.) */ + if (AFDO_EINFO (e)->get_count () == total_count + && e->probability == profile_probability::always ()) + ; + else if (AFDO_EINFO (e)->get_count ().nonzero_p ()) + e->probability + = AFDO_EINFO (e)->get_count ().probability_in (total_count); + /* If probability is zero, preserve reliable static prediction. */ + else if (e->probability.nonzero_p () + || e->probability.quality () == GUESSED) + e->probability = profile_probability::never ().afdo (); + } } } FOR_ALL_BB_FN (bb, cfun) |