aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2015-03-20 10:26:17 +0100
committerAndres Freund <andres@anarazel.de>2015-03-20 10:26:17 +0100
commit8122e1437e332e156d971a0274879b0ee76e488a (patch)
tree4049661023618ba959e645969698c7829ce19ed1
parent7e9ed623d9988fcb1497a2a8ca7f676a5bfa136f (diff)
downloadpostgresql-8122e1437e332e156d971a0274879b0ee76e488a.tar.gz
postgresql-8122e1437e332e156d971a0274879b0ee76e488a.zip
Add, optional, support for 128bit integers.
We will, for the foreseeable future, not expose 128 bit datatypes to SQL. But being able to use 128bit math will allow us, in a later patch, to use 128bit accumulators for some aggregates; leading to noticeable speedups over using numeric. So far we only detect a gcc/clang extension that supports 128bit math, but no 128bit literals, and no *printf support. We might want to expand this in the future to further compilers; if there are any that that provide similar support. Discussion: 544BB5F1.50709@proxel.se Author: Andreas Karlsson, with significant editorializing by me Reviewed-By: Peter Geoghegan, Oskari Saarenmaa
-rw-r--r--config/c-compiler.m437
-rwxr-xr-xconfigure52
-rw-r--r--configure.in3
-rw-r--r--src/include/c.h11
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/include/pg_config.h.win323
6 files changed, 109 insertions, 0 deletions
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 509f96139ff..38aab11bc65 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -125,6 +125,43 @@ undefine([Ac_cachevar])dnl
])# PGAC_TYPE_64BIT_INT
+# PGAC_TYPE_128BIT_INT
+# ---------------------
+# Check if __int128 is a working 128 bit integer type, and if so
+# define PG_INT128_TYPE to that typename. This currently only detects
+# a GCC/clang extension, but support for different environments may be
+# added in the future.
+#
+# For the moment we only test for support for 128bit math; support for
+# 128bit literals and snprintf is not required.
+AC_DEFUN([PGAC_TYPE_128BIT_INT],
+[AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int],
+[AC_LINK_IFELSE([AC_LANG_PROGRAM([
+/*
+ * These are globals to discourage the compiler from folding all the
+ * arithmetic tests down to compile-time constants. We do not have
+ * convenient support for 64bit literals at this point...
+ */
+__int128 a = 48828125;
+__int128 b = 97656255;
+],[
+__int128 c,d;
+a = (a << 12) + 1; /* 200000000001 */
+b = (b << 12) + 5; /* 400000000005 */
+/* use the most relevant arithmetic ops */
+c = a * b;
+d = (c + b) / b;
+/* return different values, to prevent optimizations */
+if (d != a+1)
+ return 0;
+return 1;
+])],
+[pgac_cv__128bit_int=yes],
+[pgac_cv__128bit_int=no])])
+if test x"$pgac_cv__128bit_int" = xyes ; then
+ AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
+fi])# PGAC_TYPE_128BIT_INT
+
# PGAC_C_FUNCNAME_SUPPORT
# -----------------------
diff --git a/configure b/configure
index 379dab16ab9..2c9b3a7c710 100755
--- a/configure
+++ b/configure
@@ -13803,6 +13803,58 @@ _ACEOF
fi
+# Check for extensions offering the integer scalar type __int128.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
+$as_echo_n "checking for __int128... " >&6; }
+if ${pgac_cv__128bit_int+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/*
+ * These are globals to discourage the compiler from folding all the
+ * arithmetic tests down to compile-time constants. We do not have
+ * convenient support for 64bit literals at this point...
+ */
+__int128 a = 48828125;
+__int128 b = 97656255;
+
+int
+main ()
+{
+
+__int128 c,d;
+a = (a << 12) + 1; /* 200000000001 */
+b = (b << 12) + 5; /* 400000000005 */
+/* use the most relevant arithmetic ops */
+c = a * b;
+d = (c + b) / b;
+/* return different values, to prevent optimizations */
+if (d != a+1)
+ return 0;
+return 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ pgac_cv__128bit_int=yes
+else
+ pgac_cv__128bit_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int" >&5
+$as_echo "$pgac_cv__128bit_int" >&6; }
+if test x"$pgac_cv__128bit_int" = xyes ; then
+
+$as_echo "#define PG_INT128_TYPE __int128" >>confdefs.h
+
+fi
+
# Check for various atomic operations now that we have checked how to declare
# 64bit integers.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for builtin __sync char locking functions" >&5
diff --git a/configure.in b/configure.in
index ca29e93eee1..b2c1ce71d23 100644
--- a/configure.in
+++ b/configure.in
@@ -1771,6 +1771,9 @@ AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
# C, but is missing on some old platforms.
AC_CHECK_TYPES(sig_atomic_t, [], [], [#include <signal.h>])
+# Check for extensions offering the integer scalar type __int128.
+PGAC_TYPE_128BIT_INT
+
# Check for various atomic operations now that we have checked how to declare
# 64bit integers.
PGAC_HAVE_GCC__SYNC_CHAR_TAS
diff --git a/src/include/c.h b/src/include/c.h
index a2d4a2c5c5d..744721860c5 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -293,6 +293,17 @@ typedef unsigned long long int uint64;
#define HAVE_INT64_TIMESTAMP
#endif
+/*
+ * 128-bit signed and unsigned integers
+ * There currently is only a limited support for the type. E.g. 128bit
+ * literals and snprintf are not supported; but math is.
+ */
+#if defined(PG_INT128_TYPE)
+#define HAVE_INT128
+typedef PG_INT128_TYPE int128;
+typedef unsigned PG_INT128_TYPE uint128;
+#endif
+
/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
#ifndef HAVE_SIG_ATOMIC_T
typedef int sig_atomic_t;
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ece57c81ccf..202c51a34a5 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -711,6 +711,9 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
+/* Define to the name of a signed 128-bit integer type. */
+#undef PG_INT128_TYPE
+
/* Define to the name of a signed 64-bit integer type. */
#undef PG_INT64_TYPE
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 3f858c658b9..1baf64f0056 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -562,6 +562,9 @@
/* Define to the version of this package. */
#define PACKAGE_VERSION "9.5devel"
+/* Define to the name of a signed 128-bit integer type. */
+#undef PG_INT128_TYPE
+
/* Define to the name of a signed 64-bit integer type. */
#define PG_INT64_TYPE long long int