Mercurial > hg > CbC > CbC_gcc
diff gcc/profile-count.c @ 145:1830386684a0
gcc-9.2.0
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 11:34:05 +0900 |
parents | 84e7813d76e9 |
children |
line wrap: on
line diff
--- a/gcc/profile-count.c Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/profile-count.c Thu Feb 13 11:34:05 2020 +0900 @@ -1,5 +1,5 @@ /* Profile counter container type. - Copyright (C) 2017-2018 Free Software Foundation, Inc. + Copyright (C) 2017-2020 Free Software Foundation, Inc. Contributed by Jan Hubicka This file is part of GCC. @@ -33,34 +33,57 @@ #include "wide-int.h" #include "sreal.h" +/* Names from profile_quality enum values. */ + +const char *profile_quality_names[] = +{ + "uninitialized", + "guessed_local", + "guessed_global0", + "guessed_global0adjusted", + "guessed", + "afdo", + "adjusted", + "precise" +}; + /* Get a string describing QUALITY. */ const char * profile_quality_as_string (enum profile_quality quality) { - switch (quality) - { - default: - gcc_unreachable (); - case profile_uninitialized: - return "uninitialized"; - case profile_guessed_local: - return "guessed_local"; - case profile_guessed_global0: - return "guessed_global0"; - case profile_guessed_global0adjusted: - return "guessed_global0adjusted"; - case profile_guessed: - return "guessed"; - case profile_afdo: - return "afdo"; - case profile_adjusted: - return "adjusted"; - case profile_precise: - return "precise"; - } + return profile_quality_names[quality]; } +/* Parse VALUE as profile quality and return true when a valid QUALITY. */ + +bool +parse_profile_quality (const char *value, profile_quality *quality) +{ + for (unsigned i = 0; i < ARRAY_SIZE (profile_quality_names); i++) + if (strcmp (profile_quality_names[i], value) == 0) + { + *quality = (profile_quality)i; + return true; + } + + return false; +} + +/* Display names from profile_quality enum values. */ + +const char *profile_quality_display_names[] = +{ + NULL, + "estimated locally", + "estimated locally, globally 0", + "estimated locally, globally 0 adjusted", + "guessed", + "auto FDO", + "adjusted", + "precise" +}; + /* Dump THIS to F. */ void @@ -69,21 +92,8 @@ if (!initialized_p ()) fprintf (f, "uninitialized"); else - { - fprintf (f, "%" PRId64, m_val); - if (m_quality == profile_guessed_local) - fprintf (f, " (estimated locally)"); - else if (m_quality == profile_guessed_global0) - fprintf (f, " (estimated locally, globally 0)"); - else if (m_quality == profile_guessed_global0adjusted) - fprintf (f, " (estimated locally, globally 0 adjusted)"); - else if (m_quality == profile_adjusted) - fprintf (f, " (adjusted)"); - else if (m_quality == profile_afdo) - fprintf (f, " (auto FDO)"); - else if (m_quality == profile_guessed) - fprintf (f, " (guessed)"); - } + fprintf (f, "%" PRId64 " (%s)", m_val, + profile_quality_display_names[m_quality]); } /* Dump THIS to stderr. */ @@ -95,7 +105,7 @@ fprintf (stderr, "\n"); } -/* Return true if THIS differs from OTHER; tolerate small diferences. */ +/* Return true if THIS differs from OTHER; tolerate small differences. */ bool profile_count::differs_from_p (profile_count other) const @@ -115,7 +125,7 @@ /* Stream THIS from IB. */ profile_count -profile_count::stream_in (struct lto_input_block *ib) +profile_count::stream_in (class lto_input_block *ib) { profile_count ret; ret.m_val = streamer_read_gcov_count (ib); @@ -158,11 +168,11 @@ fprintf (f, "always"); else fprintf (f, "%3.1f%%", (double)m_val * 100 / max_probability); - if (m_quality == profile_adjusted) + if (m_quality == ADJUSTED) fprintf (f, " (adjusted)"); - else if (m_quality == profile_afdo) + else if (m_quality == AFDO) fprintf (f, " (auto FDO)"); - else if (m_quality == profile_guessed) + else if (m_quality == GUESSED) fprintf (f, " (guessed)"); } } @@ -176,7 +186,7 @@ fprintf (stderr, "\n"); } -/* Return true if THIS differs from OTHER; tolerate small diferences. */ +/* Return true if THIS differs from OTHER; tolerate small differences. */ bool profile_probability::differs_from_p (profile_probability other) const @@ -206,7 +216,7 @@ /* Stream THIS from IB. */ profile_probability -profile_probability::stream_in (struct lto_input_block *ib) +profile_probability::stream_in (class lto_input_block *ib) { profile_probability ret; ret.m_val = streamer_read_uhwi (ib); @@ -258,7 +268,7 @@ { if (!initialized_p ()) return BB_FREQ_MAX; - if (*this == profile_count::zero ()) + if (*this == zero ()) return 0; gcc_assert (REG_BR_PROB_BASE == BB_FREQ_MAX && fun->cfg->count_max.initialized_p ()); @@ -277,10 +287,11 @@ { if (!initialized_p () || !entry_bb_count.initialized_p ()) return CGRAPH_FREQ_BASE; - if (*this == profile_count::zero ()) + if (*this == zero ()) 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; @@ -300,8 +311,25 @@ } if (known) *known = true; - if (*this == profile_count::zero ()) + /* Watch for cases where one count is IPA and other is not. */ + if (in.ipa ().initialized_p ()) + { + gcc_checking_assert (ipa ().initialized_p ()); + /* If current count is inter-procedurally 0 and IN is inter-procedurally + non-zero, return 0. */ + if (in.ipa ().nonzero_p () + && !ipa().nonzero_p ()) + return 0; + } + else + /* We can handle correctly 0 IPA count within locally estimated + profile, but otherwise we are lost and this should not happen. */ + gcc_checking_assert (!ipa ().initialized_p () || !ipa ().nonzero_p ()); + if (*this == zero ()) return 0; + if (m_val == in.m_val) + return 1; + gcc_checking_assert (compatible_p (in)); if (!in.m_val) { @@ -327,7 +355,7 @@ if (*num == *den) return; /* Scaling to zero is always zero. */ - if (*num == profile_count::zero ()) + if (*num == zero ()) return; /* If den is non-zero we are safe. */ if (den->force_nonzero () == *den) @@ -343,24 +371,45 @@ if it is nonzero, not changing anything if IPA is uninitialized and if IPA is zero, turning THIS into corresponding local profile with global0. */ + 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; - if (!ipa.initialized_p () || *this == profile_count::zero ()) + if (!ipa.initialized_p () || *this == zero ()) return *this; - if (ipa == profile_count::zero ()) + if (ipa == zero ()) return this->global0 (); 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. */ + profile_count -profile_count::from_gcov_type (gcov_type v) +profile_count::from_gcov_type (gcov_type v, profile_quality quality) { profile_count ret; gcc_checking_assert (v >= 0); @@ -369,13 +418,12 @@ "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n", (int64_t) v, (int64_t) max_count); ret.m_val = MIN (v, (gcov_type)max_count); - ret.m_quality = profile_precise; + ret.m_quality = quality; return ret; } - /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER - happens with COUNT2 probablity. Return probablity that either *THIS or + happens with COUNT2 probability. Return probability that either *THIS or OTHER happens. */ profile_probability @@ -385,7 +433,7 @@ { /* If probabilities are same, we are done. If counts are nonzero we can distribute accordingly. In remaining - cases just avreage the values and hope for the best. */ + cases just average the values and hope for the best. */ if (*this == other || count1 == count2 || (count2 == profile_count::zero () && !(count1 == profile_count::zero ()))) @@ -396,6 +444,14 @@ return *this * count1.probability_in (count1 + count2) + other * count2.probability_in (count1 + count2); else - return *this * profile_probability::even () - + other * profile_probability::even (); + return *this * even () + other * even (); } + +/* Return probability as sreal in range [0, 1]. */ + +sreal +profile_probability::to_sreal () const +{ + gcc_checking_assert (initialized_p ()); + return ((sreal)m_val) >> (n_bits - 2); +}