From: Martin Liska Date: Wed, 10 Dec 2014 14:10:21 +0000 (+0100) Subject: New sreal implementation which uses int64_t as m_sig. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d1704358924217b920bb60e0197282154fa02a4b;p=gcc.git New sreal implementation which uses int64_t as m_sig. * sreal.c (sreal::shift_right): New implementation for int64_t as m_sig. (sreal::normalize): Likewise. (sreal::to_int): Likewise. (sreal::operator+): Likewise. (sreal::operator-): Likewise. (sreal::operator*): Likewise. (sreal::operator/): Likewise. (sreal::signedless_minus): Removed. (sreal::signedless_plus): Removed. (sreal::debug): const keyword is added. * sreal.h (sreal::operator<): New implementation for int64_t as m_sig. * ipa-inline.c (recursive_inlining): LONG_MIN is replaced with sreal::min (). From-SVN: r218579 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8d502586f7f..c74adfae2bc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ +2014-12-10 Martin Liska + + * sreal.c (sreal::shift_right): New implementation + for int64_t as m_sig. + (sreal::normalize): Likewise. + (sreal::to_int): Likewise. + (sreal::operator+): Likewise. + (sreal::operator-): Likewise. + (sreal::operator*): Likewise. + (sreal::operator/): Likewise. + (sreal::signedless_minus): Removed. + (sreal::signedless_plus): Removed. + (sreal::debug): const keyword is added. + * sreal.h (sreal::operator<): New implementation + for int64_t as m_sig. + * ipa-inline.c (recursive_inlining): LONG_MIN is replaced + with sreal::min (). + 2014-12-10 Martin Liska * gimple-iterator.h (gsi_start_bb_nondebug): New function. diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f62760fd39c..9f600b092c2 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1311,7 +1311,7 @@ recursive_inlining (struct cgraph_edge *edge, vec *new_edges) { int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO); - edge_heap_t heap (LONG_MIN); + edge_heap_t heap (sreal::min ()); struct cgraph_node *node; struct cgraph_edge *e; struct cgraph_node *master_clone = NULL, *next; diff --git a/gcc/sreal.c b/gcc/sreal.c index 2b5e3ae82be..bc3af2309db 100644 --- a/gcc/sreal.c +++ b/gcc/sreal.c @@ -61,13 +61,13 @@ sreal::dump (FILE *file) const } DEBUG_FUNCTION void -debug (sreal &ref) +debug (const sreal &ref) { ref.dump (stderr); } DEBUG_FUNCTION void -debug (sreal *ptr) +debug (const sreal *ptr) { if (ptr) debug (*ptr); @@ -91,7 +91,7 @@ sreal::shift_right (int s) m_exp += s; - m_sig += (uint64_t) 1 << (s - 1); + m_sig += (int64_t) 1 << (s - 1); m_sig >>= s; } @@ -100,43 +100,45 @@ sreal::shift_right (int s) void sreal::normalize () { - if (m_sig == 0) + int64_t s = m_sig < 0 ? -1 : 1; + unsigned HOST_WIDE_INT sig = absu_hwi (m_sig); + + if (sig == 0) { - m_negative = 0; m_exp = -SREAL_MAX_EXP; } - else if (m_sig < SREAL_MIN_SIG) + else if (sig < SREAL_MIN_SIG) { do { - m_sig <<= 1; + sig <<= 1; m_exp--; } - while (m_sig < SREAL_MIN_SIG); + while (sig < SREAL_MIN_SIG); /* Check underflow. */ if (m_exp < -SREAL_MAX_EXP) { m_exp = -SREAL_MAX_EXP; - m_sig = 0; + sig = 0; } } - else if (m_sig > SREAL_MAX_SIG) + else if (sig > SREAL_MAX_SIG) { int last_bit; do { - last_bit = m_sig & 1; - m_sig >>= 1; + last_bit = sig & 1; + sig >>= 1; m_exp++; } - while (m_sig > SREAL_MAX_SIG); + while (sig > SREAL_MAX_SIG); /* Round the number. */ - m_sig += last_bit; - if (m_sig > SREAL_MAX_SIG) + sig += last_bit; + if (sig > SREAL_MAX_SIG) { - m_sig >>= 1; + sig >>= 1; m_exp++; } @@ -144,9 +146,11 @@ sreal::normalize () if (m_exp > SREAL_MAX_EXP) { m_exp = SREAL_MAX_EXP; - m_sig = SREAL_MAX_SIG; + sig = SREAL_MAX_SIG; } } + + m_sig = s * sig; } /* Return integer value of *this. */ @@ -154,17 +158,17 @@ sreal::normalize () int64_t sreal::to_int () const { - int64_t sign = m_negative ? -1 : 1; + int64_t sign = m_sig < 0 ? -1 : 1; if (m_exp <= -SREAL_BITS) return 0; if (m_exp >= SREAL_PART_BITS) return sign * INTTYPE_MAXIMUM (int64_t); if (m_exp > 0) - return sign * (m_sig << m_exp); + return m_sig << m_exp; if (m_exp < 0) - return sign * (m_sig >> -m_exp); - return sign * m_sig; + return m_sig >> -m_exp; + return m_sig; } /* Return *this + other. */ @@ -172,36 +176,10 @@ sreal::to_int () const sreal sreal::operator+ (const sreal &other) const { - const sreal *a_p = this, *b_p = &other; - - if (a_p->m_negative && !b_p->m_negative) - std::swap (a_p, b_p); - - /* a + -b => a - b. */ - if (!a_p->m_negative && b_p->m_negative) - { - sreal tmp = -(*b_p); - if (*a_p < tmp) - return signedless_minus (tmp, *a_p, true); - else - return signedless_minus (*a_p, tmp, false); - } - - gcc_checking_assert (a_p->m_negative == b_p->m_negative); - - sreal r = signedless_plus (*a_p, *b_p, a_p->m_negative); - - return r; -} - -sreal -sreal::signedless_plus (const sreal &a, const sreal &b, bool negative) -{ - const sreal *bb; - sreal r, tmp; int dexp; - const sreal *a_p = &a; - const sreal *b_p = &b; + sreal tmp, r; + + const sreal *a_p = this, *b_p = &other, *bb; if (a_p->m_exp < b_p->m_exp) std::swap (a_p, b_p); @@ -211,7 +189,6 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative) if (dexp > SREAL_BITS) { r.m_sig = a_p->m_sig; - r.m_negative = negative; return r; } @@ -226,56 +203,32 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative) r.m_sig = a_p->m_sig + bb->m_sig; r.normalize (); - - r.m_negative = negative; return r; } + /* Return *this - other. */ sreal sreal::operator- (const sreal &other) const -{ - /* -a - b => -a + (-b). */ - if (m_negative && !other.m_negative) - return signedless_plus (*this, -other, true); - - /* a - (-b) => a + b. */ - if (!m_negative && other.m_negative) - return signedless_plus (*this, -other, false); - - gcc_checking_assert (m_negative == other.m_negative); - - /* We want to substract a smaller number from bigger - for nonegative numbers. */ - if (!m_negative && *this < other) - return signedless_minus (other, *this, true); - - /* Example: -2 - (-3) => 3 - 2 */ - if (m_negative && *this > other) - return signedless_minus (-other, -(*this), false); - - sreal r = signedless_minus (*this, other, m_negative); - - return r; -} - -sreal -sreal::signedless_minus (const sreal &a, const sreal &b, bool negative) { int dexp; sreal tmp, r; const sreal *bb; - const sreal *a_p = &a; - const sreal *b_p = &b; + const sreal *a_p = this, *b_p = &other; - dexp = a_p->m_exp - b_p->m_exp; + int64_t sign = 1; + if (a_p->m_exp < b_p->m_exp) + { + sign = -1; + std::swap (a_p, b_p); + } + dexp = a_p->m_exp - b_p->m_exp; r.m_exp = a_p->m_exp; if (dexp > SREAL_BITS) { - r.m_sig = a_p->m_sig; - r.m_negative = negative; + r.m_sig = sign * a_p->m_sig; return r; } if (dexp == 0) @@ -287,10 +240,8 @@ sreal::signedless_minus (const sreal &a, const sreal &b, bool negative) bb = &tmp; } - r.m_sig = a_p->m_sig - bb->m_sig; + r.m_sig = sign * (a_p->m_sig - bb->m_sig); r.normalize (); - - r.m_negative = negative; return r; } @@ -300,7 +251,7 @@ sreal sreal::operator* (const sreal &other) const { sreal r; - if (m_sig < SREAL_MIN_SIG || other.m_sig < SREAL_MIN_SIG) + if (std::abs (m_sig) < SREAL_MIN_SIG || std::abs (other.m_sig) < SREAL_MIN_SIG) { r.m_sig = 0; r.m_exp = -SREAL_MAX_EXP; @@ -312,7 +263,6 @@ sreal::operator* (const sreal &other) const r.normalize (); } - r.m_negative = m_negative ^ other.m_negative; return r; } @@ -325,7 +275,6 @@ sreal::operator/ (const sreal &other) const sreal r; r.m_sig = (m_sig << SREAL_PART_BITS) / other.m_sig; r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS; - r.m_negative = m_negative ^ other.m_negative; r.normalize (); return r; } diff --git a/gcc/sreal.h b/gcc/sreal.h index 3938c6ef12a..730f49c4d89 100644 --- a/gcc/sreal.h +++ b/gcc/sreal.h @@ -25,8 +25,8 @@ along with GCC; see the file COPYING3. If not see #define UINT64_BITS 64 -#define SREAL_MIN_SIG ((uint64_t) 1 << (SREAL_PART_BITS - 1)) -#define SREAL_MAX_SIG (((uint64_t) 1 << SREAL_PART_BITS) - 1) +#define SREAL_MIN_SIG ((int64_t) 1 << (SREAL_PART_BITS - 2)) +#define SREAL_MAX_SIG (((int64_t) 1 << (SREAL_PART_BITS - 1)) - 1) #define SREAL_MAX_EXP (INT_MAX / 4) #define SREAL_BITS SREAL_PART_BITS @@ -36,18 +36,11 @@ class sreal { public: /* Construct an uninitialized sreal. */ - sreal () : m_sig (-1), m_exp (-1), m_negative (0) {} + sreal () : m_sig (-1), m_exp (-1) {} /* Construct a sreal. */ - sreal (int64_t sig, int exp = 0) : m_exp (exp) + sreal (int64_t sig, int exp = 0) : m_sig (sig), m_exp (exp) { - m_negative = sig < 0; - - if (sig < 0) - sig = -sig; - - m_sig = (uint64_t) sig; - normalize (); } @@ -60,33 +53,30 @@ public: bool operator< (const sreal &other) const { - /* We negate result in case of negative numbers and - it would return true for equal negative numbers. */ - if (*this == other) - return false; - - if (m_negative != other.m_negative) - return m_negative > other.m_negative; - - bool r = m_exp < other.m_exp - || (m_exp == other.m_exp && m_sig < other.m_sig); - - return m_negative ? !r : r; + if (m_exp == other.m_exp) + return m_sig < other.m_sig; + else + { + bool negative = m_sig < 0; + bool other_negative = other.m_sig < 0; + + if (negative != other_negative) + return negative > other_negative; + + bool r = m_exp < other.m_exp; + return negative ? !r : r; + } } bool operator== (const sreal &other) const { - return m_exp == other.m_exp && m_sig == other.m_sig - && m_negative == other.m_negative; + return m_exp == other.m_exp && m_sig == other.m_sig; } sreal operator- () const { - if (m_sig == 0) - return *this; - sreal tmp = *this; - tmp.m_negative = !tmp.m_negative; + tmp.m_sig *= -1; return tmp; } @@ -125,17 +115,15 @@ public: private: void normalize (); void shift_right (int amount); - static sreal signedless_plus (const sreal &a, const sreal &b, bool negative); static sreal signedless_minus (const sreal &a, const sreal &b, bool negative); - uint64_t m_sig; /* Significant. */ + int64_t m_sig; /* Significant. */ signed int m_exp; /* Exponent. */ - bool m_negative; /* Negative sign. */ }; -extern void debug (sreal &ref); -extern void debug (sreal *ptr); +extern void debug (const sreal &ref); +extern void debug (const sreal *ptr); inline sreal &operator+= (sreal &a, const sreal &b) {