summaryrefslogtreecommitdiff
path: root/gcc/value-prof.c
diff options
context:
space:
mode:
authorspark <spark@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-18 19:02:44 +0000
committerspark <spark@138bc75d-0d04-0410-961f-82ee72b054a4>2008-08-18 19:02:44 +0000
commite0dc6f2bee436056af7d1c49ed2714fa53ee430d (patch)
tree60eb8bcbffe0c58454ecbc0a68eeff80b6a19db3 /gcc/value-prof.c
parent826174ed5baf39165e89813106f5df7bc36021c7 (diff)
downloadgcc-e0dc6f2bee436056af7d1c49ed2714fa53ee430d.tar.gz
2008-08-18 Paul Yuan <yingbo.com@gmail.com>
Vinodha Ramasamy <vinodha@google.com> * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139208 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/value-prof.c')
-rw-r--r--gcc/value-prof.c53
1 files changed, 40 insertions, 13 deletions
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 7f776ccaf89..f3522f6dcb5 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;