From 52c76998c7109adca55106b881b9945fea860015 Mon Sep 17 00:00:00 2001 From: Paul Yuan Date: Mon, 18 Aug 2008 19:02:44 +0000 Subject: cgraph.c (cgraph_edge): Handle inconsistent counts when setting count_scale. 2008-08-18 Paul Yuan Vinodha Ramasamy * cgraph.c (cgraph_edge): Handle inconsistent counts when setting count_scale. * value-prof.c (check_counter): Fix the counter if flag_profile_correction is true. (tree_divmod_fixed_value_transform, tree_mod_pow2_value_transform, tree_mod_subtract_transform): Follow check_counter parameter change. * common.opt (fprofile-correction): New option. * mcf.c: New file. * profile.c (edge_info, EDGE_INFO): Moved to new file profile.h. (sum_edge_counts, is_edge_inconsistent, correct_negative_edge_counts, is_inconsistent, set_bb_counts, read_profile_edge_counts): New functions. (compute_branch_probabilities): Refactored. Invokes mcf_smooth_cfg if flag_profile_correction is set. Co-Authored-By: Vinodha Ramasamy From-SVN: r139208 --- gcc/value-prof.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'gcc/value-prof.c') diff --git a/gcc/value-prof.c b/gcc/value-prof.c index 7f776cc..f3522f6 100644 --- a/gcc/value-prof.c +++ b/gcc/value-prof.c @@ -453,18 +453,32 @@ free_histograms (void) somehow. */ static bool -check_counter (gimple stmt, const char *name, gcov_type all, gcov_type bb_count) +check_counter (gimple stmt, const char * name, + gcov_type *count, gcov_type *all, gcov_type bb_count) { - if (all != bb_count) + if (*all != bb_count || *count > *all) { location_t locus; locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - error ("%HCorrupted value profile: %s profiler overall count (%d) " - "does not match BB count (%d)", &locus, name, (int)all, - (int)bb_count); - return true; + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + if (flag_profile_correction) + { + inform ("%HCorrecting inconsistent value profile: " + "%s profiler overall count (%d) does not match BB count " + "(%d)", &locus, name, (int)all, (int)bb_count); + *all = bb_count; + if (*count > *all) + *count = *all; + return false; + } + else + { + error ("%HCorrupted value profile: %s profiler overall count (%d) " + "does not match BB count (%d)", &locus, name, (int)all, + (int)bb_count); + return true; + } } return false; @@ -658,7 +672,7 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si) || !maybe_hot_bb_p (gimple_bb (stmt))) return false; - if (check_counter (stmt, "value", all, gimple_bb (stmt)->count)) + if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) return false; /* Compute probability of taking the optimal path. */ @@ -818,7 +832,7 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si) /* Compute probability of taking the optimal path. */ all = count + wrong_values; - if (check_counter (stmt, "pow2", all, gimple_bb (stmt)->count)) + if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count)) return false; if (all > 0) @@ -982,12 +996,17 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si) count2 = histogram->hvalue.counters[1]; /* Compute probability of taking the optimal path. */ - if (check_counter (stmt, "interval", all, gimple_bb (stmt)->count)) + if (check_counter (stmt, "interval", &count1, &all, gimple_bb (stmt)->count)) { gimple_remove_histogram_value (cfun, stmt, histogram); return false; } + if (flag_profile_correction && count1 + count2 > all) + all = count1 + count2; + + gcc_assert (count1 + count2 <= all); + /* We require that we use just subtractions in at least 50% of all evaluations. */ count = 0; @@ -1160,7 +1179,7 @@ static bool gimple_ic_transform (gimple stmt) { histogram_value histogram; - gcov_type val, count, all; + gcov_type val, count, all, bb_all; gcov_type prob; tree callee; gimple modify; @@ -1186,6 +1205,14 @@ gimple_ic_transform (gimple stmt) if (4 * count <= 3 * all) return false; + bb_all = gimple_bb (stmt)->count; + /* The order of CHECK_COUNTER calls is important - + since check_counter can correct the third parameter + and we want to make count <= all <= bb_all. */ + if ( check_counter (stmt, "ic", &all, &bb_all, bb_all) + || check_counter (stmt, "ic", &count, &all, all)) + return false; + if (all > 0) prob = (count * REG_BR_PROB_BASE + all / 2) / all; else @@ -1372,7 +1399,7 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi) at least 80% of time. */ if ((6 * count / 5) < all || !maybe_hot_bb_p (gimple_bb (stmt))) return false; - if (check_counter (stmt, "value", all, gimple_bb (stmt)->count)) + if (check_counter (stmt, "value", &count, &all, gimple_bb (stmt)->count)) return false; if (all > 0) prob = (count * REG_BR_PROB_BASE + all / 2) / all; -- cgit v1.1