aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfghooks.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2021-11-28 19:25:33 +0100
committerJan Hubicka <jh@suse.cz>2021-11-28 19:25:33 +0100
commitd1471457fcda26cd24e0053b82f8eed35ddb8727 (patch)
treeccb130300fe101af002265cb1efebb51938b17a1 /gcc/cfghooks.c
parent7393fa8b1d21eeeb37e59ff8efaebf178fd891e5 (diff)
downloadgcc-d1471457fcda26cd24e0053b82f8eed35ddb8727.zip
gcc-d1471457fcda26cd24e0053b82f8eed35ddb8727.tar.gz
gcc-d1471457fcda26cd24e0053b82f8eed35ddb8727.tar.bz2
Improve -fprofile-report
Profile-report was never properly updated after switch to new profile representation. This patch fixes the way profile mismatches are calculated: we used to collect separately count and freq mismatches, while now we have only counts & probabilities. So we verify - in count: that total count of incomming edges is close to acutal count of the BB - out prob: that total sum of outgoing edge edge probabilities is close to 1 (except for BB containing noreturn calls or EH). Moreover I added dumping of absolute data which is useful to plot them: with Martin Liska we plan to setup regular testing so we keep optimizers profie updates bit under control. Finally I added both static and dynamic stats about mismatches - static one is simply number of inconsistencies in the cfg while dynamic is scaled by the profile - I think in order to keep eye on optimizers the first number is quite relevant. WHile when tracking why code quality regressed the second number matters more. 2021-11-28 Jan Hubicka <hubicka@ucw.cz> * cfghooks.c: Include sreal.h, profile.h. (profile_record_check_consistency): Fix checking of count counsistency; record also dynamic mismatches. * cfgrtl.c (rtl_account_profile_record): Similarly. * tree-cfg.c (gimple_account_profile_record): Likewise. * cfghooks.h (struct profile_record): Remove num_mismatched_freq_in, num_mismatched_freq_out, turn time to double, add dyn_mismatched_prob_out, dyn_mismatched_count_in, num_mismatched_prob_out; remove num_mismatched_count_out. * passes.c (account_profile_1): New function. (account_profile_in_list): New function. (pass_manager::dump_profile_report): Rewrite. (execute_one_ipa_transform_pass): Check profile consistency after running all passes. (execute_all_ipa_transforms): Remove cfun test; record all transform methods. (execute_one_pass): Fix collecting of profile stats.
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r--gcc/cfghooks.c76
1 files changed, 55 insertions, 21 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c
index fa2dae2..550dc4a 100644
--- a/gcc/cfghooks.c
+++ b/gcc/cfghooks.c
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include "cfganal.h"
#include "tree-ssa.h"
#include "cfgloop.h"
+#include "sreal.h"
+#include "profile.h"
/* Disable warnings about missing quoting in GCC diagnostics. */
#if __GNUC__ >= 10
@@ -1467,41 +1469,73 @@ profile_record_check_consistency (profile_record *record)
FOR_ALL_BB_FN (bb, cfun)
{
if (bb != EXIT_BLOCK_PTR_FOR_FN (cfun)
- && profile_status_for_fn (cfun) != PROFILE_ABSENT)
+ && profile_status_for_fn (cfun) != PROFILE_ABSENT
+ && EDGE_COUNT (bb->succs))
{
- profile_probability sum = profile_probability::never ();
- FOR_EACH_EDGE (e, ei, bb->succs)
- sum += e->probability;
- if (EDGE_COUNT (bb->succs)
- && sum.differs_from_p (profile_probability::always ()))
- record->num_mismatched_freq_out++;
- profile_count lsum = profile_count::zero ();
+ sreal sum = 0;
+ bool found = false;
FOR_EACH_EDGE (e, ei, bb->succs)
- lsum += e->count ();
- if (EDGE_COUNT (bb->succs) && (lsum.differs_from_p (bb->count)))
- record->num_mismatched_count_out++;
+ {
+ if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
+ found = true;
+ if (e->probability.initialized_p ())
+ sum += e->probability.to_sreal ();
+ }
+ double dsum = sum.to_double ();
+ if (found && (dsum < 0.9 || dsum > 1.1)
+ && !(bb->count == profile_count::zero ()))
+ {
+ record->num_mismatched_prob_out++;
+ dsum = dsum > 1 ? dsum - 1 : 1 - dsum;
+ if (profile_info)
+ {
+ if (ENTRY_BLOCK_PTR_FOR_FN
+ (cfun)->count.ipa ().initialized_p ()
+ && ENTRY_BLOCK_PTR_FOR_FN
+ (cfun)->count.ipa ().nonzero_p ()
+ && bb->count.ipa ().initialized_p ())
+ record->dyn_mismatched_prob_out
+ += dsum * bb->count.ipa ().to_gcov_type ();
+ }
+ else if (bb->count.initialized_p ())
+ record->dyn_mismatched_prob_out
+ += dsum * bb->count.to_sreal_scale
+ (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
+ }
}
if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
&& profile_status_for_fn (cfun) != PROFILE_ABSENT)
{
- profile_probability sum = profile_probability::never ();
profile_count lsum = profile_count::zero ();
FOR_EACH_EDGE (e, ei, bb->preds)
+ lsum += e->count ();
+ if (lsum.differs_from_p (bb->count))
{
- sum += e->probability;
- lsum += e->count ();
+ record->num_mismatched_count_in++;
+ profile_count max;
+ if (lsum < bb->count)
+ max = bb->count;
+ else
+ max = lsum;
+ if (profile_info)
+ {
+ if (ENTRY_BLOCK_PTR_FOR_FN
+ (cfun)->count.ipa ().initialized_p ()
+ && ENTRY_BLOCK_PTR_FOR_FN
+ (cfun)->count.ipa ().nonzero_p ()
+ && max.ipa ().initialized_p ())
+ record->dyn_mismatched_count_in
+ += max.ipa ().to_gcov_type ();
+ }
+ else if (bb->count.initialized_p ())
+ record->dyn_mismatched_prob_out
+ += max.to_sreal_scale
+ (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count).to_double ();
}
- if (EDGE_COUNT (bb->preds)
- && sum.differs_from_p (profile_probability::always ()))
- record->num_mismatched_freq_in++;
- if (lsum.differs_from_p (bb->count))
- record->num_mismatched_count_in++;
}
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun)
|| bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
continue;
- gcc_assert (cfg_hooks->account_profile_record);
- cfg_hooks->account_profile_record (bb, record);
}
}