Commit 83d502cf by Jan Hubicka Committed by Jan Hubicka

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
parent 8b48488f
2017-10-12 Jan Hubicka <hubicka@ucw.cz>
* 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 <law@redhat.com> 2017-10-12 Jeff Law <law@redhat.com>
* tree-ssa-dse.c (valid_ao_ref_for_dse): Reject ao_refs with * tree-ssa-dse.c (valid_ao_ref_for_dse): Reject ao_refs with
...@@ -147,12 +147,12 @@ profile_probability::differs_from_p (profile_probability other) const ...@@ -147,12 +147,12 @@ profile_probability::differs_from_p (profile_probability other) const
{ {
if (!initialized_p () || !other.initialized_p ()) if (!initialized_p () || !other.initialized_p ())
return false; return false;
if ((uint64_t)m_val - (uint64_t)other.m_val < 10 if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
|| (uint64_t)other.m_val - (uint64_t)m_val < 10) || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
return false; return false;
if (!other.m_val) if (!other.m_val)
return true; 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; return ratio < 99 || ratio > 101;
} }
......
...@@ -67,7 +67,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res) ...@@ -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) if (a < ((uint64_t)1 << 31)
&& b < ((uint64_t)1 << 31) && b < ((uint64_t)1 << 31)
&& c < ((uint64_t)1 << 31)) && c < ((uint64_t)1 << 31))
return (a * b + (c / 2)) / c; {
*res = (a * b + (c / 2)) / c;
return true;
}
#endif #endif
return slow_safe_scale_64bit (a, b, c, res); 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) ...@@ -111,11 +114,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
class GTY((user)) profile_probability 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 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 static const uint32_t uninitialized_probability
= ((uint32_t) 1 << (n_bits - 1)) - 1; = ((uint32_t) 1 << (n_bits - 1)) - 1;
...@@ -210,14 +212,14 @@ public: ...@@ -210,14 +212,14 @@ public:
{ {
profile_probability ret; profile_probability ret;
gcc_checking_assert (v >= 0 && v <= REG_BR_PROB_BASE); 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; ret.m_quality = profile_guessed;
return ret; return ret;
} }
int to_reg_br_prob_base () const int to_reg_br_prob_base () const
{ {
gcc_checking_assert (initialized_p ()); 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. */ /* Conversion to and from RTL representation of profile probabilities. */
...@@ -246,7 +248,12 @@ public: ...@@ -246,7 +248,12 @@ public:
if (val1 > val2) if (val1 > val2)
ret.m_val = max_probability; ret.m_val = max_probability;
else 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; ret.m_quality = profile_precise;
return ret; return ret;
} }
...@@ -443,8 +450,9 @@ public: ...@@ -443,8 +450,9 @@ public:
if (!initialized_p ()) if (!initialized_p ())
return profile_probability::uninitialized (); return profile_probability::uninitialized ();
profile_probability ret; profile_probability ret;
ret.m_val = MIN (RDIV (m_val * num, den), uint64_t tmp;
max_probability); safe_scale_64bit (m_val, num, den, &tmp);
ret.m_val = MIN (tmp, max_probability);
ret.m_quality = MIN (m_quality, profile_adjusted); ret.m_quality = MIN (m_quality, profile_adjusted);
return ret; return ret;
} }
...@@ -482,7 +490,7 @@ public: ...@@ -482,7 +490,7 @@ public:
if (m_val == uninitialized_probability) if (m_val == uninitialized_probability)
return m_quality == profile_guessed; return m_quality == profile_guessed;
else else
return m_val <= REG_BR_PROB_BASE; return m_val <= max_probability;
} }
/* Comparsions are three-state and conservative. False is returned if /* Comparsions are three-state and conservative. False is returned if
...@@ -781,8 +789,10 @@ public: ...@@ -781,8 +789,10 @@ public:
if (!initialized_p ()) if (!initialized_p ())
return profile_count::uninitialized (); return profile_count::uninitialized ();
profile_count ret; profile_count ret;
ret.m_val = RDIV (m_val * prob.m_val, uint64_t tmp;
profile_probability::max_probability); 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); ret.m_quality = MIN (m_quality, prob.m_quality);
return ret; return ret;
} }
...@@ -794,11 +804,11 @@ public: ...@@ -794,11 +804,11 @@ public:
if (!initialized_p ()) if (!initialized_p ())
return profile_count::uninitialized (); return profile_count::uninitialized ();
profile_count ret; profile_count ret;
uint64_t tmp;
gcc_checking_assert (num >= 0 && den > 0); gcc_checking_assert (num >= 0 && den > 0);
/* FIXME: shrink wrapping violates this sanity check. */ safe_scale_64bit (m_val, num, den, &tmp);
gcc_checking_assert ((num <= REG_BR_PROB_BASE ret.m_val = MIN (tmp, max_count);
|| den <= REG_BR_PROB_BASE) || 1);
ret.m_val = RDIV (m_val * num, den);
ret.m_quality = MIN (m_quality, profile_adjusted); ret.m_quality = MIN (m_quality, profile_adjusted);
return ret; return ret;
} }
......
2017-10-12 Jan Hubicka <hubicka@ucw.cz>
* gcc.dg/predict-13.c: Update template for probaility change.
* gcc.dg/predict-8.c: Likewise.
2017-10-12 David Malcolm <dmalcolm@redhat.com> 2017-10-12 David Malcolm <dmalcolm@redhat.com>
* c-c++-common/cilk-plus/AN/parser_errors.c: Update expected * c-c++-common/cilk-plus/AN/parser_errors.c: Update expected
......
...@@ -35,5 +35,5 @@ test (int i) ...@@ -35,5 +35,5 @@ test (int i)
lookup (9 * i); lookup (9 * i);
} }
/* { dg-final { scan-ipa-dump "Wrapper penalty" "inline" } } */ /* { 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-not "Inlined lookup_slow into lookup" "inline" } } */
/* { dg-final { scan-ipa-dump "Inlining lookup to test" "inline" } } */ /* { dg-final { scan-ipa-dump "Inlined lookup into test" "inline" } } */
...@@ -21,4 +21,4 @@ int main(int argc, char **argv) ...@@ -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\[^:\]*: 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"} } */
/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ /* { 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) { int foo(float a, float b) {
if (a == b) if (a == b)
...@@ -8,4 +8,4 @@ int foo(float a, float b) { ...@@ -8,4 +8,4 @@ int foo(float a, float b) {
return 2; 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"} } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment