changeset 25844:dd10eea0be97

maint: Merge stable to default.
author John W. Eaton <jwe@octave.org>
date Thu, 30 Aug 2018 10:45:51 -0400
parents e9910742d968 (current diff) 144820478378 (diff)
children aa4e0ca9873b
files configure.ac liboctave/util/oct-inttypes.h m4/acinclude.m4
diffstat 5 files changed, 34 insertions(+), 234 deletions(-) [+]
line wrap: on
line diff
--- a/build-aux/mk-octave-config-h.sh	Wed Aug 29 14:34:24 2018 -0700
+++ b/build-aux/mk-octave-config-h.sh	Thu Aug 30 10:45:51 2018 -0400
@@ -196,7 +196,6 @@
 $SED -n 's/#\(\(undef\|define\) OCTAVE_ENABLE_ATOMIC_REFCOUNT.*$\)/#  \1/p' $config_h_file
 $SED -n 's/#\(\(undef\|define\) OCTAVE_ENABLE_BOUNDS_CHECK.*$\)/#  \1/p' $config_h_file
 $SED -n 's/#\(\(undef\|define\) OCTAVE_ENABLE_OPENMP.*$\)/#  \1/p' $config_h_file
-$SED -n 's/#\(\(undef\|define\) OCTAVE_HAVE_FAST_INT_OPS.*$\)/#  \1/p' $config_h_file
 $SED -n 's/#\(\(undef\|define\) OCTAVE_HAVE_LONG_LONG_INT.*$\)/#  \1/p' $config_h_file
 $SED -n 's/#\(\(undef\|define\) OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT.*$\)/#  \1/p' $config_h_file
 $SED -n 's/#\(\(undef\|define\) OCTAVE_HAVE_OVERLOAD_CHAR_INT8_TYPES.*$\)/#  \1/p' $config_h_file
--- a/configure.ac	Wed Aug 29 14:34:24 2018 -0700
+++ b/configure.ac	Thu Aug 30 10:45:51 2018 -0400
@@ -1120,9 +1120,6 @@
 ## Are there functions to access real/imag parts of numbers via references?
 OCTAVE_CXX_COMPLEX_REFERENCE_ACCESSORS
 
-## Check if fast integer arithmetics based on bit tricks is available.
-OCTAVE_FAST_INT_OPS
-
 ## Does the C compiler handle alloca and const correctly?
 AC_FUNC_ALLOCA
 
--- a/liboctave/util/oct-inttypes.cc	Wed Aug 29 14:34:24 2018 -0700
+++ b/liboctave/util/oct-inttypes.cc	Thu Aug 30 10:45:51 2018 -0400
@@ -363,12 +363,12 @@
 int64_t
 octave_int_arith_base<int64_t, true>::mul_internal (int64_t x, int64_t y)
 {
-  // The signed case is far worse.  The problem is that even if neither integer
-  // fits into signed 32-bit range, the result may still be OK.  Uh oh.
+  // The signed case is far worse.  The problem is that even if neither
+  // integer fits into signed 32-bit range, the result may still be OK.
+  // Uh oh.
 
   // Essentially, what we do is compute sign, multiply absolute values
   // (as above) and impose the sign.
-  // FIXME: can we do something faster if we OCTAVE_HAVE_FAST_INT_OPS?
 
   uint64_t usx = octave_int_abs (x);
   uint64_t usy = octave_int_abs (y);
--- a/liboctave/util/oct-inttypes.h	Wed Aug 29 14:34:24 2018 -0700
+++ b/liboctave/util/oct-inttypes.h	Thu Aug 30 10:45:51 2018 -0400
@@ -497,32 +497,6 @@
 
 #endif
 
-// Signed integer arithmetic.
-//
-// Rationale: If OCTAVE_HAVE_FAST_INT_OPS is defined, the following
-// conditions should hold:
-//
-//   1. Signed numbers are represented by twos complement (see
-//      <http://en.wikipedia.org/wiki/Two%27s_complement>)
-//
-//   2. static_cast to unsigned int counterpart works like
-//      interpreting the signed bit pattern as unsigned (and is thus
-//      zero-cost).
-//
-//   3. Signed addition and subtraction yield the same bit results as
-//      unsigned.  (We use casts to prevent optimization interference,
-//      so there is no need for things like -ftrapv).
-//
-//   4. Bit operations on signed integers work like on unsigned
-//      integers, except for the shifts.  Shifts are arithmetic.
-//
-// The above conditions are satisfied by most modern platforms.  If
-// OCTAVE_HAVE_FAST_INT_OPS is defined, bit tricks and wraparound
-// arithmetics are used to avoid conditional jumps as much as
-// possible, thus being friendly to modern pipeline processor
-// architectures.  Otherwise, we fall back to a bullet-proof code that
-// only uses assumptions guaranteed by the standard.
-
 template <typename T>
 class octave_int_arith_base<T, true> : octave_int_base<T>
 {
@@ -540,32 +514,16 @@
   static T
   abs (T x)
   {
-#if defined (OCTAVE_HAVE_FAST_INT_OPS)
-    // This is close to how GCC does std::abs, but we can't just use std::abs,
-    // because its behavior for INT_MIN is undefined and the compiler could
-    // discard the following test.
-    T m = x >> std::numeric_limits<T>::digits;
-    T y = (x ^ m) - m;
-    if (y < 0)
-      {
-        y = octave_int_base<T>::max_val ();
-      }
-    return y;
-#else
-    // -INT_MAX is safe because C++ actually allows only three implementations
-    // of integers: sign & magnitude, ones complement and twos complement.
-    // The first test will, with modest optimizations, evaluate at compile
-    // time, and maybe eliminate the branch completely.
-    T y;
-    if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
-        && x == octave_int_base<T>::min_val ())
-      {
-        y = octave_int_base<T>::max_val ();
-      }
-    else
-      y = (x < 0) ? -x : x;
-    return y;
-#endif
+    // -INT_MAX is safe because C++ actually allows only three
+    // implementations of integers: sign & magnitude, ones complement
+    // and twos complement.  The first test will, with modest
+    // optimizations, evaluate at compile time, and maybe eliminate
+    // the branch completely.
+
+    return ((octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
+             && x == octave_int_base<T>::min_val ())
+            ? octave_int_base<T>::max_val ()
+            : ((x < 0) ? -x : x));
   }
 
   static T
@@ -586,114 +544,42 @@
   lshift (T x, int n) { return x << n; }
 
   // Minus has problems similar to abs.
+
   static T
   minus (T x)
   {
-#if defined (OCTAVE_HAVE_FAST_INT_OPS)
-    T y = -x;
-    if (y == octave_int_base<T>::min_val ())
-      {
-        --y;
-      }
-    return y;
-#else
-    T y;
-    if (octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
-        && x == octave_int_base<T>::min_val ())
-      {
-        y = octave_int_base<T>::max_val ();
-      }
-    else
-      y = -x;
-    return y;
-#endif
+    return ((octave_int_base<T>::min_val () < -octave_int_base<T>::max_val ()
+             && x == octave_int_base<T>::min_val ())
+            ? octave_int_base<T>::max_val ()
+            : -x);
   }
 
   static T
   add (T x, T y)
   {
-#if defined (OCTAVE_HAVE_FAST_INT_OPS)
-
-    // The typecasts do nothing, but they are here to prevent an optimizing
-    // compiler from interfering.  Also, the signed operations on small types
-    // actually return int.
-    T u = static_cast<UT> (x) + static_cast<UT> (y);
-    T ux = u ^ x;
-    T uy = u ^ y;
-
-    return ((ux & uy) < 0
-            ? (u < 0
-               ? octave_int_base<T>::max_val ()
-               : octave_int_base<T>::min_val ())
-            : u);
-
-#else
+    // Avoid anything that may overflow.
 
-    // We shall carefully avoid anything that may overflow.
-    T u;
-
-    if (y < 0)
-      {
-        if (x < octave_int_base<T>::min_val () - y)
-          u = octave_int_base<T>::min_val ();
-        else
-          u = x + y;
-      }
-    else
-      {
-        if (x > octave_int_base<T>::max_val () - y)
-          u = octave_int_base<T>::max_val ();
-        else
-          u = x + y;
-      }
-
-    return u;
-
-#endif
+    return (y < 0
+            ? (x < octave_int_base<T>::min_val () - y
+               ? octave_int_base<T>::min_val ()
+               : x + y)
+            : (x > octave_int_base<T>::max_val () - y
+               ? octave_int_base<T>::max_val ()
+               : x + y));
   }
 
-  // This is very similar to addition.
   static T
   sub (T x, T y)
   {
-#if defined (OCTAVE_HAVE_FAST_INT_OPS)
-    // The typecasts do nothing, but they are here to prevent an optimizing
-    // compiler from interfering.  Also, the signed operations on small types
-    // actually return int.
-    T u = static_cast<UT> (x) - static_cast<UT> (y);
-    T ux = u ^ x;
-    T uy = u ^ ~y;
-    if ((ux & uy) < 0)
-      {
-        u = (__signbit (~u)
-             ? octave_int_base<T>::min_val ()
-             : octave_int_base<T>::max_val ());
-      }
-    return u;
-#else
-    // We shall carefully avoid anything that may overflow.
-    T u;
-    if (y < 0)
-      {
-        if (x > octave_int_base<T>::max_val () + y)
-          {
-            u = octave_int_base<T>::max_val ();
-          }
-        else
-          u = x - y;
-      }
-    else
-      {
-        if (x < octave_int_base<T>::min_val () + y)
-          {
-            u = octave_int_base<T>::min_val ();
-          }
-        else
-          u = x - y;
-      }
+    // Avoid anything that may overflow.
 
-    return u;
-#endif
+    return (y < 0
+            ? (x > octave_int_base<T>::max_val () + y
+               ? octave_int_base<T>::max_val ()
+               : x - y)
+            : (x < octave_int_base<T>::min_val () + y
+                ? octave_int_base<T>::min_val ()
+               : x - y));
   }
 
   // Multiplication is done using promotion to wider integer type.  If there is
@@ -793,9 +679,6 @@
 
   long double p = static_cast<long double> (x) * static_cast<long double> (y);
 
-  // NOTE: We could maybe do it with a single branch if
-  // OCTAVE_HAVE_FAST_INT_OPS, but it would require one more runtime
-  // conversion, so the question is whether it would really be faster.
   if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ()))
     retval = octave_int_base<int64_t>::max_val ();
   else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ()))
--- a/m4/acinclude.m4	Wed Aug 29 14:34:24 2018 -0700
+++ b/m4/acinclude.m4	Thu Aug 30 10:45:51 2018 -0400
@@ -2463,85 +2463,6 @@
   fi
 ])
 dnl
-dnl Check whether fast signed integer arithmetic using bit tricks
-dnl can be used in oct-inttypes.h.
-dnl
-dnl Defines OCTAVE_HAVE_FAST_INT_OPS if the following conditions hold:
-dnl
-dnl   1. Signed numbers are represented by twos complement (see
-dnl      <http://en.wikipedia.org/wiki/Two%27s_complement>)
-dnl
-dnl   2. static_cast to unsigned int counterpart works like
-dnl      interpreting the signed bit pattern as unsigned (and is thus
-dnl      zero-cost).
-dnl
-dnl   3. Signed addition and subtraction yield the same bit results
-dnl      as unsigned.  (We use casts to prevent optimization
-dnl      interference, so there is no need for things like -ftrapv).
-dnl
-dnl   4. Bit operations on signed integers work like on unsigned
-dnl      integers, except for the shifts.  Shifts are arithmetic.
-dnl
-AC_DEFUN([OCTAVE_FAST_INT_OPS], [
-  AC_CACHE_CHECK([whether fast integer arithmetics is usable],
-    [octave_cv_fast_int_ops],
-    [AC_LANG_PUSH(C++)
-    AC_RUN_IFELSE([AC_LANG_PROGRAM([[
-        #include <limits>
-        template<class UT, class ST>
-        static bool
-        do_test (UT, ST)
-        {
-          volatile ST s = std::numeric_limits<ST>::min () / 3;
-          volatile UT u = static_cast<UT> (s);
-          if (*(reinterpret_cast<volatile ST *> (&u)) != s) return true;
-
-          u = 0; u = ~u;
-          if (*(reinterpret_cast<volatile ST *> (&u)) != -1) return true;
-
-          ST sx, sy;
-          sx = std::numeric_limits<ST>::max () / 2 + 1;
-          sy = std::numeric_limits<ST>::max () / 2 + 2;
-          if (static_cast<ST> (static_cast<UT> (sx) + static_cast<UT> (sy))
-              != std::numeric_limits<ST>::min () + 1) return true;
-          if (static_cast<ST> (static_cast<UT> (sx) - static_cast<UT> (sy))
-              != -1) return true;
-
-          if ((sx & sy) != (static_cast<UT> (sx) & static_cast<UT> (sy)))
-            return true;
-          if ((sx | sy) != (static_cast<UT> (sx) | static_cast<UT> (sy)))
-            return true;
-          if ((sx ^ sy) != (static_cast<UT> (sx) ^ static_cast<UT> (sy)))
-            return true;
-          if ((-1 >> 1) != -1) return true;
-          return false;
-        }
-
-        #define DO_TEST(T) \
-          if (do_test (static_cast<unsigned T> (0), static_cast<signed T> (0)))\
-            return sizeof (T);
-
-        ]],[[
-
-        DO_TEST(char)
-        DO_TEST(short)
-        DO_TEST(int)
-        DO_TEST(long)
-        #if (defined(OCTAVE_HAVE_LONG_LONG_INT) && defined(OCTAVE_HAVE_UNSIGNED_LONG_LONG_INT))
-          DO_TEST(long long)
-        #endif
-      ]])],
-      octave_cv_fast_int_ops=yes,
-      octave_cv_fast_int_ops=no,
-      octave_cv_fast_int_ops=yes)
-    AC_LANG_POP(C++)
-  ])
-  if test $octave_cv_fast_int_ops = yes; then
-    AC_DEFINE(OCTAVE_HAVE_FAST_INT_OPS, 1,
-      [Define to 1 if signed integers use two's complement.])
-  fi
-])
-dnl
 dnl Check to see if the compiler and the linker can handle the flags
 dnl "-framework $1" for the given prologue $2 and the given body $3 of
 dnl a source file.  Arguments 2 and 3 optionally can also be empty.