Commit d1704358 by Martin Liska Committed by Martin Liska

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
parent 42c0b54d
2014-12-10 Martin Liska <mliska@suse.cz> 2014-12-10 Martin Liska <mliska@suse.cz>
* 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 <mliska@suse.cz>
* gimple-iterator.h (gsi_start_bb_nondebug): New function. * gimple-iterator.h (gsi_start_bb_nondebug): New function.
* ipa-icf-gimple.c (func_checker::compare_bb): Correct iteration * ipa-icf-gimple.c (func_checker::compare_bb): Correct iteration
replaces loop based on precomputed number of non-debug statements. replaces loop based on precomputed number of non-debug statements.
...@@ -1311,7 +1311,7 @@ recursive_inlining (struct cgraph_edge *edge, ...@@ -1311,7 +1311,7 @@ recursive_inlining (struct cgraph_edge *edge,
vec<cgraph_edge *> *new_edges) vec<cgraph_edge *> *new_edges)
{ {
int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO); 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_node *node;
struct cgraph_edge *e; struct cgraph_edge *e;
struct cgraph_node *master_clone = NULL, *next; struct cgraph_node *master_clone = NULL, *next;
......
...@@ -61,13 +61,13 @@ sreal::dump (FILE *file) const ...@@ -61,13 +61,13 @@ sreal::dump (FILE *file) const
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug (sreal &ref) debug (const sreal &ref)
{ {
ref.dump (stderr); ref.dump (stderr);
} }
DEBUG_FUNCTION void DEBUG_FUNCTION void
debug (sreal *ptr) debug (const sreal *ptr)
{ {
if (ptr) if (ptr)
debug (*ptr); debug (*ptr);
...@@ -91,7 +91,7 @@ sreal::shift_right (int s) ...@@ -91,7 +91,7 @@ sreal::shift_right (int s)
m_exp += s; m_exp += s;
m_sig += (uint64_t) 1 << (s - 1); m_sig += (int64_t) 1 << (s - 1);
m_sig >>= s; m_sig >>= s;
} }
...@@ -100,43 +100,45 @@ sreal::shift_right (int s) ...@@ -100,43 +100,45 @@ sreal::shift_right (int s)
void void
sreal::normalize () 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; m_exp = -SREAL_MAX_EXP;
} }
else if (m_sig < SREAL_MIN_SIG) else if (sig < SREAL_MIN_SIG)
{ {
do do
{ {
m_sig <<= 1; sig <<= 1;
m_exp--; m_exp--;
} }
while (m_sig < SREAL_MIN_SIG); while (sig < SREAL_MIN_SIG);
/* Check underflow. */ /* Check underflow. */
if (m_exp < -SREAL_MAX_EXP) if (m_exp < -SREAL_MAX_EXP)
{ {
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; int last_bit;
do do
{ {
last_bit = m_sig & 1; last_bit = sig & 1;
m_sig >>= 1; sig >>= 1;
m_exp++; m_exp++;
} }
while (m_sig > SREAL_MAX_SIG); while (sig > SREAL_MAX_SIG);
/* Round the number. */ /* Round the number. */
m_sig += last_bit; sig += last_bit;
if (m_sig > SREAL_MAX_SIG) if (sig > SREAL_MAX_SIG)
{ {
m_sig >>= 1; sig >>= 1;
m_exp++; m_exp++;
} }
...@@ -144,9 +146,11 @@ sreal::normalize () ...@@ -144,9 +146,11 @@ sreal::normalize ()
if (m_exp > SREAL_MAX_EXP) if (m_exp > SREAL_MAX_EXP)
{ {
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. */ /* Return integer value of *this. */
...@@ -154,17 +158,17 @@ sreal::normalize () ...@@ -154,17 +158,17 @@ sreal::normalize ()
int64_t int64_t
sreal::to_int () const sreal::to_int () const
{ {
int64_t sign = m_negative ? -1 : 1; int64_t sign = m_sig < 0 ? -1 : 1;
if (m_exp <= -SREAL_BITS) if (m_exp <= -SREAL_BITS)
return 0; return 0;
if (m_exp >= SREAL_PART_BITS) if (m_exp >= SREAL_PART_BITS)
return sign * INTTYPE_MAXIMUM (int64_t); return sign * INTTYPE_MAXIMUM (int64_t);
if (m_exp > 0) if (m_exp > 0)
return sign * (m_sig << m_exp); return m_sig << m_exp;
if (m_exp < 0) if (m_exp < 0)
return sign * (m_sig >> -m_exp); return m_sig >> -m_exp;
return sign * m_sig; return m_sig;
} }
/* Return *this + other. */ /* Return *this + other. */
...@@ -172,36 +176,10 @@ sreal::to_int () const ...@@ -172,36 +176,10 @@ sreal::to_int () const
sreal sreal
sreal::operator+ (const sreal &other) const 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; int dexp;
const sreal *a_p = &a; sreal tmp, r;
const sreal *b_p = &b;
const sreal *a_p = this, *b_p = &other, *bb;
if (a_p->m_exp < b_p->m_exp) if (a_p->m_exp < b_p->m_exp)
std::swap (a_p, b_p); std::swap (a_p, b_p);
...@@ -211,7 +189,6 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative) ...@@ -211,7 +189,6 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative)
if (dexp > SREAL_BITS) if (dexp > SREAL_BITS)
{ {
r.m_sig = a_p->m_sig; r.m_sig = a_p->m_sig;
r.m_negative = negative;
return r; return r;
} }
...@@ -226,56 +203,32 @@ sreal::signedless_plus (const sreal &a, const sreal &b, bool negative) ...@@ -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.m_sig = a_p->m_sig + bb->m_sig;
r.normalize (); r.normalize ();
r.m_negative = negative;
return r; return r;
} }
/* Return *this - other. */ /* Return *this - other. */
sreal sreal
sreal::operator- (const sreal &other) const 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; int dexp;
sreal tmp, r; sreal tmp, r;
const sreal *bb; const sreal *bb;
const sreal *a_p = &a; const sreal *a_p = this, *b_p = &other;
const sreal *b_p = &b;
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; r.m_exp = a_p->m_exp;
if (dexp > SREAL_BITS) if (dexp > SREAL_BITS)
{ {
r.m_sig = a_p->m_sig; r.m_sig = sign * a_p->m_sig;
r.m_negative = negative;
return r; return r;
} }
if (dexp == 0) if (dexp == 0)
...@@ -287,10 +240,8 @@ sreal::signedless_minus (const sreal &a, const sreal &b, bool negative) ...@@ -287,10 +240,8 @@ sreal::signedless_minus (const sreal &a, const sreal &b, bool negative)
bb = &tmp; 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.normalize ();
r.m_negative = negative;
return r; return r;
} }
...@@ -300,7 +251,7 @@ sreal ...@@ -300,7 +251,7 @@ sreal
sreal::operator* (const sreal &other) const sreal::operator* (const sreal &other) const
{ {
sreal r; 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_sig = 0;
r.m_exp = -SREAL_MAX_EXP; r.m_exp = -SREAL_MAX_EXP;
...@@ -312,7 +263,6 @@ sreal::operator* (const sreal &other) const ...@@ -312,7 +263,6 @@ sreal::operator* (const sreal &other) const
r.normalize (); r.normalize ();
} }
r.m_negative = m_negative ^ other.m_negative;
return r; return r;
} }
...@@ -325,7 +275,6 @@ sreal::operator/ (const sreal &other) const ...@@ -325,7 +275,6 @@ sreal::operator/ (const sreal &other) const
sreal r; sreal r;
r.m_sig = (m_sig << SREAL_PART_BITS) / other.m_sig; r.m_sig = (m_sig << SREAL_PART_BITS) / other.m_sig;
r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS; r.m_exp = m_exp - other.m_exp - SREAL_PART_BITS;
r.m_negative = m_negative ^ other.m_negative;
r.normalize (); r.normalize ();
return r; return r;
} }
...@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3. If not see
#define UINT64_BITS 64 #define UINT64_BITS 64
#define SREAL_MIN_SIG ((uint64_t) 1 << (SREAL_PART_BITS - 1)) #define SREAL_MIN_SIG ((int64_t) 1 << (SREAL_PART_BITS - 2))
#define SREAL_MAX_SIG (((uint64_t) 1 << SREAL_PART_BITS) - 1) #define SREAL_MAX_SIG (((int64_t) 1 << (SREAL_PART_BITS - 1)) - 1)
#define SREAL_MAX_EXP (INT_MAX / 4) #define SREAL_MAX_EXP (INT_MAX / 4)
#define SREAL_BITS SREAL_PART_BITS #define SREAL_BITS SREAL_PART_BITS
...@@ -36,18 +36,11 @@ class sreal ...@@ -36,18 +36,11 @@ class sreal
{ {
public: public:
/* Construct an uninitialized sreal. */ /* Construct an uninitialized sreal. */
sreal () : m_sig (-1), m_exp (-1), m_negative (0) {} sreal () : m_sig (-1), m_exp (-1) {}
/* Construct a sreal. */ /* 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 (); normalize ();
} }
...@@ -60,33 +53,30 @@ public: ...@@ -60,33 +53,30 @@ public:
bool operator< (const sreal &other) const bool operator< (const sreal &other) const
{ {
/* We negate result in case of negative numbers and if (m_exp == other.m_exp)
it would return true for equal negative numbers. */ return m_sig < other.m_sig;
if (*this == other) else
return false; {
bool negative = m_sig < 0;
if (m_negative != other.m_negative) bool other_negative = other.m_sig < 0;
return m_negative > other.m_negative;
if (negative != other_negative)
bool r = m_exp < other.m_exp return negative > other_negative;
|| (m_exp == other.m_exp && m_sig < other.m_sig);
bool r = m_exp < other.m_exp;
return m_negative ? !r : r; return negative ? !r : r;
}
} }
bool operator== (const sreal &other) const bool operator== (const sreal &other) const
{ {
return m_exp == other.m_exp && m_sig == other.m_sig return m_exp == other.m_exp && m_sig == other.m_sig;
&& m_negative == other.m_negative;
} }
sreal operator- () const sreal operator- () const
{ {
if (m_sig == 0)
return *this;
sreal tmp = *this; sreal tmp = *this;
tmp.m_negative = !tmp.m_negative; tmp.m_sig *= -1;
return tmp; return tmp;
} }
...@@ -125,17 +115,15 @@ public: ...@@ -125,17 +115,15 @@ public:
private: private:
void normalize (); void normalize ();
void shift_right (int amount); void shift_right (int amount);
static sreal signedless_plus (const sreal &a, const sreal &b, bool negative); static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
static sreal signedless_minus (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. */ signed int m_exp; /* Exponent. */
bool m_negative; /* Negative sign. */
}; };
extern void debug (sreal &ref); extern void debug (const sreal &ref);
extern void debug (sreal *ptr); extern void debug (const sreal *ptr);
inline sreal &operator+= (sreal &a, const sreal &b) inline sreal &operator+= (sreal &a, const sreal &b)
{ {
......
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