diff options
author | Steven Bosscher <steven@gcc.gnu.org> | 2012-10-09 20:37:11 +0000 |
---|---|---|
committer | Steven Bosscher <steven@gcc.gnu.org> | 2012-10-09 20:37:11 +0000 |
commit | aa4723d7f56dd0c690c514b50c917c827a3d56dd (patch) | |
tree | 784313dcb1809538918556fac30dbf561f9d8332 /gcc/cfghooks.c | |
parent | ca4277584fa6e046279dd3e75fdaa53881d9eaf3 (diff) | |
download | gcc-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.c | 54 |
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); + } +} |