Skip to content

Commit 8122e14

Browse files
committed
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: [email protected] Author: Andreas Karlsson, with significant editorializing by me Reviewed-By: Peter Geoghegan, Oskari Saarenmaa
1 parent 7e9ed62 commit 8122e14

File tree

6 files changed

+109
-0
lines changed

6 files changed

+109
-0
lines changed

config/c-compiler.m4

+37
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,43 @@ undefine([Ac_cachevar])dnl
125125
])# PGAC_TYPE_64BIT_INT
126126

127127

128+
# PGAC_TYPE_128BIT_INT
129+
# ---------------------
130+
# Check if __int128 is a working 128 bit integer type, and if so
131+
# define PG_INT128_TYPE to that typename. This currently only detects
132+
# a GCC/clang extension, but support for different environments may be
133+
# added in the future.
134+
#
135+
# For the moment we only test for support for 128bit math; support for
136+
# 128bit literals and snprintf is not required.
137+
AC_DEFUN([PGAC_TYPE_128BIT_INT],
138+
[AC_CACHE_CHECK([for __int128], [pgac_cv__128bit_int],
139+
[AC_LINK_IFELSE([AC_LANG_PROGRAM([
140+
/*
141+
* These are globals to discourage the compiler from folding all the
142+
* arithmetic tests down to compile-time constants. We do not have
143+
* convenient support for 64bit literals at this point...
144+
*/
145+
__int128 a = 48828125;
146+
__int128 b = 97656255;
147+
],[
148+
__int128 c,d;
149+
a = (a << 12) + 1; /* 200000000001 */
150+
b = (b << 12) + 5; /* 400000000005 */
151+
/* use the most relevant arithmetic ops */
152+
c = a * b;
153+
d = (c + b) / b;
154+
/* return different values, to prevent optimizations */
155+
if (d != a+1)
156+
return 0;
157+
return 1;
158+
])],
159+
[pgac_cv__128bit_int=yes],
160+
[pgac_cv__128bit_int=no])])
161+
if test x"$pgac_cv__128bit_int" = xyes ; then
162+
AC_DEFINE(PG_INT128_TYPE, __int128, [Define to the name of a signed 128-bit integer type.])
163+
fi])# PGAC_TYPE_128BIT_INT
164+
128165

129166
# PGAC_C_FUNCNAME_SUPPORT
130167
# -----------------------

configure

+52
Original file line numberDiff line numberDiff line change
@@ -13803,6 +13803,58 @@ _ACEOF
1380313803
fi
1380413804

1380513805

13806+
# Check for extensions offering the integer scalar type __int128.
13807+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __int128" >&5
13808+
$as_echo_n "checking for __int128... " >&6; }
13809+
if ${pgac_cv__128bit_int+:} false; then :
13810+
$as_echo_n "(cached) " >&6
13811+
else
13812+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
13813+
/* end confdefs.h. */
13814+
13815+
/*
13816+
* These are globals to discourage the compiler from folding all the
13817+
* arithmetic tests down to compile-time constants. We do not have
13818+
* convenient support for 64bit literals at this point...
13819+
*/
13820+
__int128 a = 48828125;
13821+
__int128 b = 97656255;
13822+
13823+
int
13824+
main ()
13825+
{
13826+
13827+
__int128 c,d;
13828+
a = (a << 12) + 1; /* 200000000001 */
13829+
b = (b << 12) + 5; /* 400000000005 */
13830+
/* use the most relevant arithmetic ops */
13831+
c = a * b;
13832+
d = (c + b) / b;
13833+
/* return different values, to prevent optimizations */
13834+
if (d != a+1)
13835+
return 0;
13836+
return 1;
13837+
13838+
;
13839+
return 0;
13840+
}
13841+
_ACEOF
13842+
if ac_fn_c_try_link "$LINENO"; then :
13843+
pgac_cv__128bit_int=yes
13844+
else
13845+
pgac_cv__128bit_int=no
13846+
fi
13847+
rm -f core conftest.err conftest.$ac_objext \
13848+
conftest$ac_exeext conftest.$ac_ext
13849+
fi
13850+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__128bit_int" >&5
13851+
$as_echo "$pgac_cv__128bit_int" >&6; }
13852+
if test x"$pgac_cv__128bit_int" = xyes ; then
13853+
13854+
$as_echo "#define PG_INT128_TYPE __int128" >>confdefs.h
13855+
13856+
fi
13857+
1380613858
# Check for various atomic operations now that we have checked how to declare
1380713859
# 64bit integers.
1380813860
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for builtin __sync char locking functions" >&5

configure.in

+3
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,9 @@ AC_CHECK_TYPES([int8, uint8, int64, uint64], [], [],
17711771
# C, but is missing on some old platforms.
17721772
AC_CHECK_TYPES(sig_atomic_t, [], [], [#include <signal.h>])
17731773

1774+
# Check for extensions offering the integer scalar type __int128.
1775+
PGAC_TYPE_128BIT_INT
1776+
17741777
# Check for various atomic operations now that we have checked how to declare
17751778
# 64bit integers.
17761779
PGAC_HAVE_GCC__SYNC_CHAR_TAS

src/include/c.h

+11
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,17 @@ typedef unsigned long long int uint64;
293293
#define HAVE_INT64_TIMESTAMP
294294
#endif
295295

296+
/*
297+
* 128-bit signed and unsigned integers
298+
* There currently is only a limited support for the type. E.g. 128bit
299+
* literals and snprintf are not supported; but math is.
300+
*/
301+
#if defined(PG_INT128_TYPE)
302+
#define HAVE_INT128
303+
typedef PG_INT128_TYPE int128;
304+
typedef unsigned PG_INT128_TYPE uint128;
305+
#endif
306+
296307
/* sig_atomic_t is required by ANSI C, but may be missing on old platforms */
297308
#ifndef HAVE_SIG_ATOMIC_T
298309
typedef int sig_atomic_t;

src/include/pg_config.h.in

+3
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,9 @@
711711
/* Define to the version of this package. */
712712
#undef PACKAGE_VERSION
713713

714+
/* Define to the name of a signed 128-bit integer type. */
715+
#undef PG_INT128_TYPE
716+
714717
/* Define to the name of a signed 64-bit integer type. */
715718
#undef PG_INT64_TYPE
716719

src/include/pg_config.h.win32

+3
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@
562562
/* Define to the version of this package. */
563563
#define PACKAGE_VERSION "9.5devel"
564564

565+
/* Define to the name of a signed 128-bit integer type. */
566+
#undef PG_INT128_TYPE
567+
565568
/* Define to the name of a signed 64-bit integer type. */
566569
#define PG_INT64_TYPE long long int
567570

0 commit comments

Comments
 (0)