Mercurial > hg > CbC > CbC_gcc
diff gcc/ipa-profile.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/ipa-profile.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/ipa-profile.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* Basic IPA optimizations based on profile. - Copyright (C) 2003-2017 Free Software Foundation, Inc. + Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of GCC. @@ -25,13 +25,6 @@ from profile feedback. This histogram is complete only with LTO, otherwise it contains information only about the current unit. - Similar histogram is also estimated by coverage runtime. This histogram - is not dependent on LTO, but it suffers from various defects; first - gcov runtime is not weighting individual basic block by estimated execution - time and second the merging of multiple runs makes assumption that the - histogram distribution did not change. Consequentely histogram constructed - here may be more precise. - The information is used to set hot/cold thresholds. - Next speculative indirect call resolution is performed: the local profile pass assigns profile-id to each function and provide us with a @@ -179,53 +172,54 @@ hash_table<histogram_hash> hashtable (10); FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) - FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) - { - int time = 0; - int size = 0; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple *stmt = gsi_stmt (gsi); - if (gimple_code (stmt) == GIMPLE_CALL - && !gimple_call_fndecl (stmt)) - { - histogram_value h; - h = gimple_histogram_value_of_type - (DECL_STRUCT_FUNCTION (node->decl), - stmt, HIST_TYPE_INDIR_CALL); - /* No need to do sanity check: gimple_ic_transform already - takes away bad histograms. */ - if (h) - { - /* counter 0 is target, counter 1 is number of execution we called target, - counter 2 is total number of executions. */ - if (h->hvalue.counters[2]) - { - struct cgraph_edge * e = node->get_edge (stmt); - if (e && !e->indirect_unknown_callee) - continue; - e->indirect_info->common_target_id - = h->hvalue.counters [0]; - e->indirect_info->common_target_probability - = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]); - if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE) - { - if (dump_file) - fprintf (dump_file, "Probability capped to 1\n"); - e->indirect_info->common_target_probability = REG_BR_PROB_BASE; - } - } - gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->decl), - stmt, h); - } - } - time += estimate_num_insns (stmt, &eni_time_weights); - size += estimate_num_insns (stmt, &eni_size_weights); - } - if (bb->count.initialized_p ()) - account_time_size (&hashtable, histogram, bb->count.to_gcov_type (), - time, size); - } + if (ENTRY_BLOCK_PTR_FOR_FN (DECL_STRUCT_FUNCTION (node->decl))->count.ipa_p ()) + FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl)) + { + int time = 0; + int size = 0; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple *stmt = gsi_stmt (gsi); + if (gimple_code (stmt) == GIMPLE_CALL + && !gimple_call_fndecl (stmt)) + { + histogram_value h; + h = gimple_histogram_value_of_type + (DECL_STRUCT_FUNCTION (node->decl), + stmt, HIST_TYPE_INDIR_CALL); + /* No need to do sanity check: gimple_ic_transform already + takes away bad histograms. */ + if (h) + { + /* counter 0 is target, counter 1 is number of execution we called target, + counter 2 is total number of executions. */ + if (h->hvalue.counters[2]) + { + struct cgraph_edge * e = node->get_edge (stmt); + if (e && !e->indirect_unknown_callee) + continue; + e->indirect_info->common_target_id + = h->hvalue.counters [0]; + e->indirect_info->common_target_probability + = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]); + if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE) + { + if (dump_file) + fprintf (dump_file, "Probability capped to 1\n"); + e->indirect_info->common_target_probability = REG_BR_PROB_BASE; + } + } + gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->decl), + stmt, h); + } + } + time += estimate_num_insns (stmt, &eni_time_weights); + size += estimate_num_insns (stmt, &eni_size_weights); + } + if (bb->count.ipa_p () && bb->count.initialized_p ()) + account_time_size (&hashtable, histogram, bb->count.ipa ().to_gcov_type (), + time, size); + } histogram.qsort (cmp_counts); } @@ -330,33 +324,34 @@ it is executed by the train run. Transfer the function only if all callers are unlikely executed. */ if (profile_info - && edge->callee->count.initialized_p () - /* Thunks are not profiled. This is more or less implementation - bug. */ - && !d->function_symbol->thunk.thunk_p + && !(edge->callee->count.ipa () == profile_count::zero ()) && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED || (edge->caller->global.inlined_to && edge->caller->global.inlined_to->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED))) d->maybe_unlikely_executed = false; - if (!edge->frequency) + if (edge->count.ipa ().initialized_p () + && !edge->count.ipa ().nonzero_p ()) continue; switch (edge->caller->frequency) { case NODE_FREQUENCY_UNLIKELY_EXECUTED: break; case NODE_FREQUENCY_EXECUTED_ONCE: - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Called by %s that is executed once\n", - edge->caller->name ()); - d->maybe_unlikely_executed = false; - if (ipa_call_summaries->get (edge)->loop_depth) - { - d->maybe_executed_once = false; - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " Called in loop\n"); - } - break; + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Called by %s that is executed once\n", + edge->caller->name ()); + d->maybe_unlikely_executed = false; + ipa_call_summary *s = ipa_call_summaries->get (edge); + if (s != NULL && s->loop_depth) + { + d->maybe_executed_once = false; + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " Called in loop\n"); + } + break; + } case NODE_FREQUENCY_HOT: case NODE_FREQUENCY_NORMAL: if (dump_file && (dump_flags & TDF_DETAILS)) @@ -430,11 +425,11 @@ } /* With profile we can decide on hot/normal based on count. */ - if (node->count.initialized_p ()) + if (node->count. ipa().initialized_p ()) { bool hot = false; - if (!(node->count == profile_count::zero ()) - && node->count >= get_hot_bb_threshold ()) + if (!(node->count. ipa() == profile_count::zero ()) + && node->count. ipa() >= get_hot_bb_threshold ()) hot = true; if (!hot) hot |= contains_hot_call_p (node); @@ -510,25 +505,7 @@ gcov_type threshold; gcc_assert (overall_size); - if (dump_file) - { - gcov_type min, cumulated_time = 0, cumulated_size = 0; - fprintf (dump_file, "Overall time: %" PRId64"\n", - (int64_t)overall_time); - min = get_hot_bb_threshold (); - for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min; - i++) - { - cumulated_time += histogram[i]->count * histogram[i]->time; - cumulated_size += histogram[i]->size; - } - fprintf (dump_file, "GCOV min count: %" PRId64 - " Time:%3.2f%% Size:%3.2f%%\n", - (int64_t)min, - cumulated_time * 100.0 / overall_time, - cumulated_size * 100.0 / overall_size); - } cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000; threshold = 0; for (i = 0; cumulated < cutoff; i++) @@ -555,6 +532,7 @@ cumulated_time * 100.0 / overall_time, cumulated_size * 100.0 / overall_size); } + if (threshold > get_hot_bb_threshold () || in_lto_p) { @@ -666,9 +644,7 @@ e->make_speculative (n2, e->count.apply_probability - (e->indirect_info->common_target_probability), - apply_scale (e->frequency, - e->indirect_info->common_target_probability)); + (e->indirect_info->common_target_probability)); update = true; } }