aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2012-10-09 20:37:11 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2012-10-09 20:37:11 +0000
commitaa4723d7f56dd0c690c514b50c917c827a3d56dd (patch)
tree784313dcb1809538918556fac30dbf561f9d8332 /gcc/cfghooks.c
parentca4277584fa6e046279dd3e75fdaa53881d9eaf3 (diff)
downloadgcc-aa4723d7f56dd0c690c514b50c917c827a3d56dd.zip
gcc-aa4723d7f56dd0c690c514b50c917c827a3d56dd.tar.gz
gcc-aa4723d7f56dd0c690c514b50c917c827a3d56dd.tar.bz2
* basic-block. (profile_record): New struct, moved from passes.c.
* cfghooks.h (struct cfg_hooks) <account_profile_record>: New hook. (account_profile_record): New prototype. * cfghooks.c (account_profile_record): New function. * tree-cfg.c (gimple_account_profile_record): New function (gimple_cfg_hooks): Add it. * cfgrtl.c (rtl_account_profile_record): New function (rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Add it. * passes.c (check_profile_consistency): Simplify. Move IR-dependent code around using cfghooks machinery. From-SVN: r192271
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index acd1f7a..d54dd46 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -1324,3 +1324,57 @@ split_block_before_cond_jump (basic_block bb)
return cfg_hooks->split_block_before_cond_jump (bb);
}
+/* Work-horse for passes.c:check_profile_consistency.
+ Do book-keeping of the CFG for the profile consistency checker.
+ If AFTER_PASS is 0, do pre-pass accounting, or if AFTER_PASS is 1
+ then do post-pass accounting. Store the counting in RECORD. */
+
+void
+account_profile_record (struct profile_record *record, int after_pass)
+{
+ basic_block bb;
+ edge_iterator ei;
+ edge e;
+ int sum;
+ gcov_type lsum;
+
+ FOR_ALL_BB (bb)
+ {
+ if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (cfun)
+ && profile_status != PROFILE_ABSENT)
+ {
+ sum = 0;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ sum += e->probability;
+ if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
+ record->num_mismatched_freq_out[after_pass]++;
+ lsum = 0;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ lsum += e->count;
+ if (EDGE_COUNT (bb->succs)
+ && (lsum - bb->count > 100 || lsum - bb->count < -100))
+ record->num_mismatched_count_out[after_pass]++;
+ }
+ if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)
+ && profile_status != PROFILE_ABSENT)
+ {
+ sum = 0;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ sum += EDGE_FREQUENCY (e);
+ if (abs (sum - bb->frequency) > 100
+ || (MAX (sum, bb->frequency) > 10
+ && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10))
+ record->num_mismatched_freq_in[after_pass]++;
+ lsum = 0;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ lsum += e->count;
+ if (lsum - bb->count > 100 || lsum - bb->count < -100)
+ record->num_mismatched_count_in[after_pass]++;
+ }
+ if (bb == ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)
+ || bb == EXIT_BLOCK_PTR_FOR_FUNCTION (cfun))
+ continue;
+ gcc_assert (cfg_hooks->account_profile_record);
+ cfg_hooks->account_profile_record(bb, after_pass, record);
+ }
+}