diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2019-11-28 15:44:08 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2019-11-28 14:44:08 +0000 |
commit | b49d29d73ac1e25e1ec7c5279d7493f9be6961bb (patch) | |
tree | 226f1a5e36253ed76580b40f21d20e56fd1212ea /gcc/profile-count.c | |
parent | eb081fd0e2cb852c3cf0ef09da497ed3fee77029 (diff) | |
download | gcc-b49d29d73ac1e25e1ec7c5279d7493f9be6961bb.zip gcc-b49d29d73ac1e25e1ec7c5279d7493f9be6961bb.tar.gz gcc-b49d29d73ac1e25e1ec7c5279d7493f9be6961bb.tar.bz2 |
Fix profile adjusments while cloning
This patch fixes profile updates while cloning. When new clone is produced
its global profile is subtracted from the original function. If the original
function profile drops to 0 we want to switch from global profiles to global0
profiles which is implemented by combine_with_ipa_count_within.
However this is done on all edges independnetly and it may happen that we end
up combining global and globa0 profiles in one functions which is not a good
idea.
This implements profile_count::combine_with_ipa_count_within which is able
to take into account that the counter is inside function with a given count.
* profile-count.h (profile_count::combine_with_ipa_count_within):
Declare.
* profile-count.c (profile_count::combine_with_ipa_count_within):
New.
* cgraphclones.c (cgraph_edge::clone, cgraph_node::create_clone): Use
it.
From-SVN: r278810
Diffstat (limited to 'gcc/profile-count.c')
-rw-r--r-- | gcc/profile-count.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/gcc/profile-count.c b/gcc/profile-count.c index e8602a0..d0800b2 100644 --- a/gcc/profile-count.c +++ b/gcc/profile-count.c @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "wide-int.h" #include "sreal.h" +#include "selftest.h" /* Names from profile_quality enum values. */ @@ -291,6 +292,7 @@ profile_count::to_cgraph_frequency (profile_count entry_bb_count) const return 0; gcc_checking_assert (entry_bb_count.initialized_p ()); uint64_t scale; + gcc_checking_assert (compatible_p (entry_bb_count)); if (!safe_scale_64bit (!entry_bb_count.m_val ? m_val + 1 : m_val, CGRAPH_FREQ_BASE, MAX (1, entry_bb_count.m_val), &scale)) return CGRAPH_FREQ_MAX; @@ -328,6 +330,7 @@ profile_count::to_sreal_scale (profile_count in, bool *known) const return 0; if (m_val == in.m_val) return 1; + gcc_checking_assert (compatible_p (in)); if (!in.m_val) { @@ -373,6 +376,8 @@ profile_count::adjust_for_ipa_scaling (profile_count *num, profile_count profile_count::combine_with_ipa_count (profile_count ipa) { + if (!initialized_p ()) + return *this; ipa = ipa.ipa (); if (ipa.nonzero_p ()) return ipa; @@ -383,6 +388,23 @@ profile_count::combine_with_ipa_count (profile_count ipa) return this->global0adjusted (); } +/* Sae as profile_count::combine_with_ipa_count but within function with count + IPA2. */ +profile_count +profile_count::combine_with_ipa_count_within (profile_count ipa, + profile_count ipa2) +{ + profile_count ret; + if (!initialized_p ()) + return *this; + if (ipa2.ipa () == ipa2 && ipa.initialized_p ()) + ret = ipa; + else + ret = combine_with_ipa_count (ipa); + gcc_checking_assert (ret.compatible_p (ipa2)); + return ret; +} + /* The profiling runtime uses gcov_type, which is usually 64bit integer. Conversions back and forth are used to read the coverage and get it into internal representation. */ @@ -425,3 +447,65 @@ profile_probability::combine_with_count (profile_count count1, else return *this * even () + other * even (); } + +#if CHECKING_P +namespace selftest { + +/* Verify non-trivial type conversions for IPA scaling. This happens often + during inlining. */ + +static void +profile_count_verify_ipa_scaling (void) +{ + profile_count cnt1 = profile_count::from_gcov_type (4).global0 (); + profile_count cnt2 = profile_count::from_gcov_type (2); + profile_count cnt3 = profile_count::from_gcov_type (8); + profile_count cnt4 = cnt3.apply_scale (cnt1, cnt2); + + /* Result should be 16 with GUESSED_GLOBAL0. */ + ASSERT_EQ (cnt4.ipa (), profile_count::zero ()); + ASSERT_EQ (cnt4.to_gcov_type (), 16); + + cnt1 = profile_count::from_gcov_type (4).global0adjusted (); + cnt4 = cnt3.apply_scale (cnt1, cnt2); + /* Result should be 16 with GUESSED_GLOBAL0_ADJUSTED. */ + ASSERT_EQ (cnt4.ipa (), profile_count::adjusted_zero ()); + ASSERT_EQ (cnt4.to_gcov_type (), 16); +} + +/* Verify non-trivial cases of sreal scale calculations. */ + +static void +profile_count_verify_to_sreal_scale (void) +{ + profile_count cnt1 = profile_count::from_gcov_type (4).global0 (); + profile_count cnt2 = profile_count::from_gcov_type (8); + + /* If count is globally 0 it should have 0 scale in non-zero global count. */ + ASSERT_EQ (cnt1.to_sreal_scale (cnt2), 0); +} + +/* Verify non-trivial cases of probability_in calculations. */ + +static void +profile_count_verify_probability_in (void) +{ + /*profile_count cnt1 = profile_count::from_gcov_type (4).global0 (); + profile_count cnt2 = profile_count::from_gcov_type (8);*/ + + /* If count is globally 0 it should have 0 probability in non-zero global + count. */ + /*ASSERT_EQ (cnt1.probability_in (cnt2), profile_probability::never ());*/ +} + +/* Run all of the selftests within this file. */ + +void profile_count_c_tests (void) +{ + profile_count_verify_ipa_scaling (); + profile_count_verify_to_sreal_scale (); + profile_count_verify_probability_in (); +} + +} +#endif |