sreal.h (sreal::normalize): Implement inline.
authorJan Hubicka <hubicka@ucw.cz>
Wed, 17 Dec 2014 21:11:46 +0000 (22:11 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 17 Dec 2014 21:11:46 +0000 (21:11 +0000)
* sreal.h (sreal::normalize): Implement inline.
(sreal::normalize_up): New function.
(sreal::normalize_down): New function.
* sreal.c (sreal::normalize): Remove.

From-SVN: r218833

gcc/ChangeLog
gcc/sreal.c
gcc/sreal.h

index 882be01..eb016cd 100644 (file)
@@ -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.
index 8525379..cf6b738 100644 (file)
@@ -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
index 6314cea..2bee542 100644 (file)
@@ -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