From 83d502cf40077b7115c8e6342218186223a42474 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Thu, 12 Oct 2017 20:48:59 +0200 Subject: [PATCH] profile-count.c (safe_scale_64bit): Fix GCC4.x path. * profile-count.c (safe_scale_64bit): Fix GCC4.x path. (profile_probability): Set max_probability to (uint32_t) 1 << (n_bits - 2) and update accessors to avoid overlfows in temporaries. * profile-count.c (profile_probability::differs_from_p): Do not rely on max_probaiblity == 10000 * gcc.dg/predict-13.c: Update template for probaility change. * gcc.dg/predict-8.c: Likewise. From-SVN: r253692 --- gcc/ChangeLog | 9 +++++ gcc/profile-count.c | 6 ++-- gcc/profile-count.h | 44 +++++++++++++++---------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/ipa/inlinehint-4.c | 4 +-- gcc/testsuite/gcc.dg/predict-13.c | 2 +- gcc/testsuite/gcc.dg/predict-8.c | 4 +-- 7 files changed, 49 insertions(+), 25 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5ee088e77f..92cdc5f0c9a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-10-12 Jan Hubicka + + * profile-count.h (safe_scale_64bit): Fix GCC4.x path. + (profile_probability): Set max_probability + to (uint32_t) 1 << (n_bits - 2) and update accessors to avoid overlfows + in temporaries. + * profile-count.c (profile_probability::differs_from_p): Do not + rely on max_probaiblity == 10000 + 2017-10-12 Jeff Law * tree-ssa-dse.c (valid_ao_ref_for_dse): Reject ao_refs with diff --git a/gcc/profile-count.c b/gcc/profile-count.c index 02c9ec241d4..44ceaed2d66 100644 --- a/gcc/profile-count.c +++ b/gcc/profile-count.c @@ -147,12 +147,12 @@ profile_probability::differs_from_p (profile_probability other) const { if (!initialized_p () || !other.initialized_p ()) return false; - if ((uint64_t)m_val - (uint64_t)other.m_val < 10 - || (uint64_t)other.m_val - (uint64_t)m_val < 10) + if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000 + || (uint64_t)other.m_val - (uint64_t)max_probability < 1000) return false; if (!other.m_val) return true; - int64_t ratio = m_val * 100 / other.m_val; + int64_t ratio = (int64_t)m_val * 100 / other.m_val; return ratio < 99 || ratio > 101; } diff --git a/gcc/profile-count.h b/gcc/profile-count.h index cb1aa365c95..4546e199f24 100644 --- a/gcc/profile-count.h +++ b/gcc/profile-count.h @@ -67,7 +67,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res) if (a < ((uint64_t)1 << 31) && b < ((uint64_t)1 << 31) && c < ((uint64_t)1 << 31)) - return (a * b + (c / 2)) / c; + { + *res = (a * b + (c / 2)) / c; + return true; + } #endif return slow_safe_scale_64bit (a, b, c, res); } @@ -111,11 +114,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res) class GTY((user)) profile_probability { - /* For now use values in range 0...REG_BR_PROB_BASE. Later we can use full - precision of 30 bits available. */ - static const int n_bits = 30; - static const uint32_t max_probability = REG_BR_PROB_BASE; + /* We can technically use ((uint32_t) 1 << (n_bits - 1)) - 2 but that + will lead to harder multiplication sequences. */ + static const uint32_t max_probability = (uint32_t) 1 << (n_bits - 2); static const uint32_t uninitialized_probability = ((uint32_t) 1 << (n_bits - 1)) - 1; @@ -210,14 +212,14 @@ public: { profile_probability ret; gcc_checking_assert (v >= 0 && v <= REG_BR_PROB_BASE); - ret.m_val = RDIV (v * max_probability, REG_BR_PROB_BASE); + ret.m_val = RDIV (v * (uint64_t) max_probability, REG_BR_PROB_BASE); ret.m_quality = profile_guessed; return ret; } int to_reg_br_prob_base () const { gcc_checking_assert (initialized_p ()); - return RDIV (m_val * REG_BR_PROB_BASE, max_probability); + return RDIV (m_val * (uint64_t) REG_BR_PROB_BASE, max_probability); } /* Conversion to and from RTL representation of profile probabilities. */ @@ -246,7 +248,12 @@ public: if (val1 > val2) ret.m_val = max_probability; else - ret.m_val = RDIV (val1 * max_probability, val2); + { + uint64_t tmp; + safe_scale_64bit (val1, max_probability, val2, &tmp); + gcc_checking_assert (tmp <= max_probability); + ret.m_val = tmp; + } ret.m_quality = profile_precise; return ret; } @@ -443,8 +450,9 @@ public: if (!initialized_p ()) return profile_probability::uninitialized (); profile_probability ret; - ret.m_val = MIN (RDIV (m_val * num, den), - max_probability); + uint64_t tmp; + safe_scale_64bit (m_val, num, den, &tmp); + ret.m_val = MIN (tmp, max_probability); ret.m_quality = MIN (m_quality, profile_adjusted); return ret; } @@ -482,7 +490,7 @@ public: if (m_val == uninitialized_probability) return m_quality == profile_guessed; else - return m_val <= REG_BR_PROB_BASE; + return m_val <= max_probability; } /* Comparsions are three-state and conservative. False is returned if @@ -781,8 +789,10 @@ public: if (!initialized_p ()) return profile_count::uninitialized (); profile_count ret; - ret.m_val = RDIV (m_val * prob.m_val, - profile_probability::max_probability); + uint64_t tmp; + safe_scale_64bit (m_val, prob.m_val, profile_probability::max_probability, + &tmp); + ret.m_val = tmp; ret.m_quality = MIN (m_quality, prob.m_quality); return ret; } @@ -794,11 +804,11 @@ public: if (!initialized_p ()) return profile_count::uninitialized (); profile_count ret; + uint64_t tmp; + gcc_checking_assert (num >= 0 && den > 0); - /* FIXME: shrink wrapping violates this sanity check. */ - gcc_checking_assert ((num <= REG_BR_PROB_BASE - || den <= REG_BR_PROB_BASE) || 1); - ret.m_val = RDIV (m_val * num, den); + safe_scale_64bit (m_val, num, den, &tmp); + ret.m_val = MIN (tmp, max_count); ret.m_quality = MIN (m_quality, profile_adjusted); return ret; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 79642b88d82..c8043641a4b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-10-12 Jan Hubicka + + * gcc.dg/predict-13.c: Update template for probaility change. + * gcc.dg/predict-8.c: Likewise. + 2017-10-12 David Malcolm * c-c++-common/cilk-plus/AN/parser_errors.c: Update expected diff --git a/gcc/testsuite/gcc.dg/ipa/inlinehint-4.c b/gcc/testsuite/gcc.dg/ipa/inlinehint-4.c index 441a0c70855..71b16f80be2 100644 --- a/gcc/testsuite/gcc.dg/ipa/inlinehint-4.c +++ b/gcc/testsuite/gcc.dg/ipa/inlinehint-4.c @@ -35,5 +35,5 @@ test (int i) lookup (9 * i); } /* { dg-final { scan-ipa-dump "Wrapper penalty" "inline" } } */ -/* { dg-final { scan-ipa-dump-not "Inlining lookup_slow to lookup" "inline" } } */ -/* { dg-final { scan-ipa-dump "Inlining lookup to test" "inline" } } */ +/* { dg-final { scan-ipa-dump-not "Inlined lookup_slow into lookup" "inline" } } */ +/* { dg-final { scan-ipa-dump "Inlined lookup into test" "inline" } } */ diff --git a/gcc/testsuite/gcc.dg/predict-13.c b/gcc/testsuite/gcc.dg/predict-13.c index 7fe714a0d72..385be9e1389 100644 --- a/gcc/testsuite/gcc.dg/predict-13.c +++ b/gcc/testsuite/gcc.dg/predict-13.c @@ -21,4 +21,4 @@ int main(int argc, char **argv) } /* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.3%" 3 "profile_estimate"} } */ -/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.0%" 2 "profile_estimate"} } */ +/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.1%" 2 "profile_estimate"} } */ diff --git a/gcc/testsuite/gcc.dg/predict-8.c b/gcc/testsuite/gcc.dg/predict-8.c index e13cc006f3a..fa975b3d95f 100644 --- a/gcc/testsuite/gcc.dg/predict-8.c +++ b/gcc/testsuite/gcc.dg/predict-8.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ -/* { dg-options "-O2 -fdump-rtl-expand" } */ +/* { dg-options "-O2 -fdump-rtl-expand-details-blocks" } */ int foo(float a, float b) { if (a == b) @@ -8,4 +8,4 @@ int foo(float a, float b) { return 2; } -/* { dg-final { scan-rtl-dump-times "REG_BR_PROB 400 " 1 "expand"} } */ +/* { dg-final { scan-rtl-dump-times "99.0. .guessed" 2 "expand"} } */ -- 2.30.2