Commit 9588ea78 by Jan Hubicka Committed by Jan Hubicka

profile-count.h (slow_safe_scale_64bit): New function.

	* profile-count.h (slow_safe_scale_64bit): New function.
	(safe_scale_64bit): New inline.
	(profile_count::max_safe_multiplier): Remove; use safe_scale_64bit.
	* profile-count.c: Include wide-int.h
	(slow_safe_scale_64bit): New.

From-SVN: r253652
parent 278a8434
2017-10-11 Jan Hubicka <hubicka@ucw.cz>
* profile-count.h (slow_safe_scale_64bit): New function.
(safe_scale_64bit): New inline.
(profile_count::max_safe_multiplier): Remove; use safe_scale_64bit.
* profile-count.c: Include wide-int.h
(slow_safe_scale_64bit): New.
2017-10-11 Nathan Sidwell <nathan@acm.org>
* tree.h (DECL_ASSEMBLER_NAME_SET_P): Don't check
......@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "data-streamer.h"
#include "cgraph.h"
#include "wide-int.h"
/* Dump THIS to F. */
......@@ -194,3 +195,21 @@ profile_probability::stream_out (struct lto_output_stream *ob)
streamer_write_uhwi_stream (ob, m_val);
streamer_write_uhwi_stream (ob, m_quality);
}
/* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
bool
slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
{
FIXED_WIDE_INT (128) tmp = a;
bool overflow;
tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
gcc_checking_assert (!overflow);
if (wi::fits_uhwi_p (tmp))
{
*res = tmp.to_uhwi ();
return true;
}
*res = (uint64_t) -1;
return false;
}
......@@ -43,6 +43,35 @@ enum profile_quality {
#define RDIV(X,Y) (((X) + (Y) / 2) / (Y))
bool slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res);
/* Compute RES=(a*b + c/2)/c capping and return false if overflow happened. */
inline bool
safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
{
#if (GCC_VERSION >= 5000)
uint64_t tmp;
if (!__builtin_mul_overflow (a, b, &tmp)
&& !__builtin_add_overflow (tmp, c/2, &tmp))
{
*res = tmp / c;
return true;
}
if (c == 1)
{
*res = (uint64_t) -1;
return false;
}
#else
if (a < ((uint64_t)1 << 31)
&& b < ((uint64_t)1 << 31)
&& c < ((uint64_t)1 << 31))
return (a * b + (c / 2)) / c;
#endif
return slow_safe_scale_64bit (a, b, c, res);
}
/* Data type to hold probabilities. It implements fixed point arithmetics
with capping so probability is always in range [0,1] and scaling requiring
values greater than 1 needs to be represented otherwise.
......@@ -87,7 +116,8 @@ class GTY((user)) profile_probability
static const int n_bits = 30;
static const uint32_t max_probability = REG_BR_PROB_BASE;
static const uint32_t uninitialized_probability = ((uint32_t) 1 << n_bits) - 1;
static const uint32_t uninitialized_probability
= ((uint32_t) 1 << (n_bits - 1)) - 1;
uint32_t m_val : 30;
enum profile_quality m_quality : 2;
......@@ -171,7 +201,7 @@ public:
/* Return true if value can be trusted. */
bool reliable_p () const
{
return initialized_p ();
return m_quality >= profile_adjusted;
}
/* Conversion from and to REG_BR_PROB_BASE integer fixpoint arithmetics.
......@@ -535,11 +565,6 @@ class GTY(()) profile_count
uint64_t m_val : n_bits;
enum profile_quality m_quality : 2;
/* Assume numbers smaller than this to multiply. This is set to make
testsuite pass, in future we may implement precise multiplication in higer
rangers. */
static const uint64_t max_safe_multiplier = 131072;
public:
/* Used for counters which are expected to be never executed. */
......@@ -595,7 +620,7 @@ public:
/* Return true if value can be trusted. */
bool reliable_p () const
{
return initialized_p ();
return m_quality >= profile_adjusted;
}
/* When merging basic blocks, the two different profile counts are unified.
......@@ -790,12 +815,9 @@ public:
return *this;
profile_count ret;
/* Take care for overflows! */
if (num.m_val < max_safe_multiplier || m_val < max_safe_multiplier)
ret.m_val = RDIV (m_val * num.m_val, den.m_val);
else
ret.m_val = RDIV (m_val * RDIV (num.m_val * max_safe_multiplier,
den.m_val), max_safe_multiplier);
uint64_t val;
safe_scale_64bit (m_val, num.m_val, den.m_val, &val);
ret.m_val = MIN (val, max_count);
ret.m_quality = MIN (m_quality, profile_adjusted);
return ret;
}
......
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