summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-12-17 22:11:46 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2014-12-17 21:11:46 +0000
commit6c0c245e30e159720d62954a978ec2eb4d526d88 (patch)
tree78d1b62334419d5a244d634c647dc1fd0ac08abb
parent12d9ce19034428072b3779eff017c5e129ee4c0e (diff)
downloadgcc-6c0c245e30e159720d62954a978ec2eb4d526d88.tar.gz
sreal.h (sreal::normalize): Implement inline.
* sreal.h (sreal::normalize): Implement inline. (sreal::normalize_up): New function. (sreal::normalize_down): New function. * sreal.c (sreal::normalize): Remove. From-SVN: r218833
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/sreal.c58
-rw-r--r--gcc/sreal.h85
3 files changed, 91 insertions, 59 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 882be014256..eb016cdbc96 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-12-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * sreal.h (sreal::normalize): Implement inline.
+ (sreal::normalize_up): New function.
+ (sreal::normalize_down): New function.
+ * sreal.c (sreal::normalize): Remove.
+
2014-12-17 James Greenhalgh <james.greenhalgh@arm.com>
* config/aarch64/aarch64.md (generic_sched): Delete it.
diff --git a/gcc/sreal.c b/gcc/sreal.c
index 85253793650..cf6b738cf48 100644
--- a/gcc/sreal.c
+++ b/gcc/sreal.c
@@ -96,64 +96,6 @@ sreal::shift_right (int s)
m_sig >>= s;
}
-/* Normalize *this. */
-
-void
-sreal::normalize ()
-{
- int64_t s = m_sig < 0 ? -1 : 1;
- unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
-
- if (sig == 0)
- {
- m_exp = -SREAL_MAX_EXP;
- }
- else if (sig < SREAL_MIN_SIG)
- {
- do
- {
- sig <<= 1;
- m_exp--;
- }
- while (sig < SREAL_MIN_SIG);
-
- /* Check underflow. */
- if (m_exp < -SREAL_MAX_EXP)
- {
- m_exp = -SREAL_MAX_EXP;
- sig = 0;
- }
- }
- else if (sig > SREAL_MAX_SIG)
- {
- int last_bit;
- do
- {
- last_bit = sig & 1;
- sig >>= 1;
- m_exp++;
- }
- while (sig > SREAL_MAX_SIG);
-
- /* Round the number. */
- sig += last_bit;
- if (sig > SREAL_MAX_SIG)
- {
- sig >>= 1;
- m_exp++;
- }
-
- /* Check overflow. */
- if (m_exp > SREAL_MAX_EXP)
- {
- m_exp = SREAL_MAX_EXP;
- sig = SREAL_MAX_SIG;
- }
- }
-
- m_sig = s * sig;
-}
-
/* Return integer value of *this. */
int64_t
diff --git a/gcc/sreal.h b/gcc/sreal.h
index 6314cea0fc4..2bee542a68c 100644
--- a/gcc/sreal.h
+++ b/gcc/sreal.h
@@ -116,7 +116,9 @@ public:
}
private:
- void normalize ();
+ inline void normalize ();
+ inline void normalize_up ();
+ inline void normalize_down ();
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);
@@ -178,4 +180,85 @@ inline sreal operator>> (const sreal &a, int exp)
return a.shift (-exp);
}
+/* Make significant to be >= SREAL_MIN_SIG.
+
+ Make this separate method so inliner can handle hot path better. */
+
+inline void
+sreal::normalize_up ()
+{
+ int64_t s = m_sig < 0 ? -1 : 1;
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+ int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);
+
+ gcc_checking_assert (shift > 0);
+ sig <<= shift;
+ m_exp -= shift;
+ gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
+
+ /* Check underflow. */
+ if (m_exp < -SREAL_MAX_EXP)
+ {
+ m_exp = -SREAL_MAX_EXP;
+ sig = 0;
+ }
+ if (s == -1)
+ m_sig = -sig;
+ else
+ m_sig = sig;
+}
+
+/* Make significant to be <= SREAL_MAX_SIG.
+
+ Make this separate method so inliner can handle hot path better. */
+
+inline void
+sreal::normalize_down ()
+{
+ int64_t s = m_sig < 0 ? -1 : 1;
+ int last_bit;
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+ int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;
+
+ gcc_checking_assert (shift > 0);
+ last_bit = (sig >> (shift-1)) & 1;
+ sig >>= shift;
+ m_exp += shift;
+ gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
+
+ /* Round the number. */
+ sig += last_bit;
+ if (sig > SREAL_MAX_SIG)
+ {
+ sig >>= 1;
+ m_exp++;
+ }
+
+ /* Check overflow. */
+ if (m_exp > SREAL_MAX_EXP)
+ {
+ m_exp = SREAL_MAX_EXP;
+ sig = SREAL_MAX_SIG;
+ }
+ if (s == -1)
+ m_sig = -sig;
+ else
+ m_sig = sig;
+}
+
+/* Normalize *this; the hot path. */
+
+inline void
+sreal::normalize ()
+{
+ unsigned HOST_WIDE_INT sig = absu_hwi (m_sig);
+
+ if (sig == 0)
+ m_exp = -SREAL_MAX_EXP;
+ else if (sig > SREAL_MAX_SIG)
+ normalize_down ();
+ else if (sig < SREAL_MIN_SIG)
+ normalize_up ();
+}
+
#endif