From 9ebdf047578f0da7e6578d0c51c32f55e84ac157 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 7 Nov 2019 15:52:44 +0100 Subject: [PATCH] build: CRC32C build system integration --- configure.ac | 78 ++++++++++++++++++++++++++++++++++-- src/Makefile.am | 1 + src/Makefile.crc32c.include | 75 ++++++++++++++++++++++++++++++++++ src/Makefile.leveldb.include | 5 ++- 4 files changed, 153 insertions(+), 6 deletions(-) create mode 100644 src/Makefile.crc32c.include diff --git a/configure.ac b/configure.ac index 6fe5abfa06..cd9167e14c 100644 --- a/configure.ac +++ b/configure.ac @@ -355,7 +355,7 @@ if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]]) fi -enable_hwcrc32=no +enable_sse42=no enable_sse41=no enable_avx2=no enable_shani=no @@ -365,6 +365,8 @@ if test "x$use_asm" = "xyes"; then dnl Check for optional instruction set support. Enabling these does _not_ imply that all code will dnl be compiled with them, rather that specific objects/libs may use them after checking for runtime dnl compatibility. + +dnl x86 AX_CHECK_COMPILE_FLAG([-msse4.2],[[SSE42_CXXFLAGS="-msse4.2"]],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-msse4.1],[[SSE41_CXXFLAGS="-msse4.1"]],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-mavx -mavx2],[[AVX2_CXXFLAGS="-mavx -mavx2"]],,[[$CXXFLAG_WERROR]]) @@ -372,7 +374,7 @@ AX_CHECK_COMPILE_FLAG([-msse4 -msha],[[SHANI_CXXFLAGS="-msse4 -msha"]],,[[$CXXFL TEMP_CXXFLAGS="$CXXFLAGS" CXXFLAGS="$CXXFLAGS $SSE42_CXXFLAGS" -AC_MSG_CHECKING(for assembler crc32 support) +AC_MSG_CHECKING(for SSE4.2 intrinsics) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #if defined(_MSC_VER) @@ -387,7 +389,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ l = _mm_crc32_u64(l, 0); return l; ]])], - [ AC_MSG_RESULT(yes); enable_hwcrc32=yes], + [ AC_MSG_RESULT(yes); enable_sse42=yes], [ AC_MSG_RESULT(no)] ) CXXFLAGS="$TEMP_CXXFLAGS" @@ -439,6 +441,24 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ) CXXFLAGS="$TEMP_CXXFLAGS" +# ARM +AX_CHECK_COMPILE_FLAG([-march=armv8-a+crc+crypto],[[ARM_CRC_CXXFLAGS="-march=armv8-a+crc+crypto"]],,[[$CXXFLAG_WERROR]]) + +TEMP_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $ARM_CRC_CXXFLAGS" +AC_MSG_CHECKING(for ARM CRC32 intrinsics) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + ]],[[ + __crc32cb(0, 0); __crc32ch(0, 0); __crc32cw(0, 0); __crc32cd(0, 0); + vmull_p64(0, 0); + ]])], + [ AC_MSG_RESULT(yes); enable_arm_crc=yes; ], + [ AC_MSG_RESULT(no)] +) +CXXFLAGS="$TEMP_CXXFLAGS" + fi CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS" @@ -956,6 +976,50 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no); HAVE_O_CLOEXEC=0 ] ) +dnl crc32c platform checks +AC_MSG_CHECKING(for __builtin_prefetch) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[ + char data = 0; + const char* address = &data; + __builtin_prefetch(address, 0, 0); + ]])], + [ AC_MSG_RESULT(yes); HAVE_BUILTIN_PREFETCH=1 ], + [ AC_MSG_RESULT(no); HAVE_BUILTIN_PREFETCH=0 ] +) + +AC_MSG_CHECKING(for _mm_prefetch) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + char data = 0; + const char* address = &data; + _mm_prefetch(address, _MM_HINT_NTA); + ]])], + [ AC_MSG_RESULT(yes); HAVE_MM_PREFETCH=1 ], + [ AC_MSG_RESULT(no); HAVE_MM_PREFETCH=0 ] +) + +AC_MSG_CHECKING(for strong getauxval support in the system headers) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + #include + #include + #include + ]], [[ + getauxval(AT_HWCAP); + ]])], + [ AC_MSG_RESULT(yes); HAVE_STRONG_GETAUXVAL=1 ], + [ AC_MSG_RESULT(no); HAVE_STRONG_GETAUXVAL=0 ] +) + +AC_MSG_CHECKING(for weak getauxval support in the compiler) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ + unsigned long getauxval(unsigned long type) __attribute__((weak)); + #define AT_HWCAP 16 + ]], [[ + getauxval(AT_HWCAP); + ]])], + [ AC_MSG_RESULT(yes); HAVE_WEAK_GETAUXVAL=1 ], + [ AC_MSG_RESULT(no); HAVE_WEAK_GETAUXVAL=0 ] +) + dnl Check for reduced exports if test x$use_reduce_exports = xyes; then AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"], @@ -1511,10 +1575,11 @@ AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes]) AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes]) AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes]) AM_CONDITIONAL([HARDEN],[test x$use_hardening = xyes]) -AM_CONDITIONAL([ENABLE_HWCRC32],[test x$enable_hwcrc32 = xyes]) +AM_CONDITIONAL([ENABLE_SSE42],[test x$enable_sse42 = xyes]) AM_CONDITIONAL([ENABLE_SSE41],[test x$enable_sse41 = xyes]) AM_CONDITIONAL([ENABLE_AVX2],[test x$enable_avx2 = xyes]) AM_CONDITIONAL([ENABLE_SHANI],[test x$enable_shani = xyes]) +AM_CONDITIONAL([ENABLE_ARM_CRC],[test x$enable_arm_crc = xyes]) AM_CONDITIONAL([USE_ASM],[test x$use_asm = xyes]) AM_CONDITIONAL([WORDS_BIGENDIAN],[test x$ac_cv_c_bigendian = xyes]) @@ -1563,6 +1628,7 @@ AC_SUBST(SSE42_CXXFLAGS) AC_SUBST(SSE41_CXXFLAGS) AC_SUBST(AVX2_CXXFLAGS) AC_SUBST(SHANI_CXXFLAGS) +AC_SUBST(ARM_CRC_CXXFLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) @@ -1577,6 +1643,10 @@ AC_SUBST(QR_LIBS) AC_SUBST(HAVE_FDATASYNC) AC_SUBST(HAVE_FULLFSYNC) AC_SUBST(HAVE_O_CLOEXEC) +AC_SUBST(HAVE_BUILTIN_PREFETCH) +AC_SUBST(HAVE_MM_PREFETCH) +AC_SUBST(HAVE_STRONG_GETAUXVAL) +AC_SUBST(HAVE_WEAK_GETAUXVAL) AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/config.ini]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) diff --git a/src/Makefile.am b/src/Makefile.am index 821553579a..367e006d73 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -716,6 +716,7 @@ if HARDEN endif if EMBEDDED_LEVELDB +include Makefile.crc32c.include include Makefile.leveldb.include endif diff --git a/src/Makefile.crc32c.include b/src/Makefile.crc32c.include new file mode 100644 index 0000000000..802b3a2e4b --- /dev/null +++ b/src/Makefile.crc32c.include @@ -0,0 +1,75 @@ +# Copyright (c) 2019 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +LIBCRC32C_INT = crc32c/libcrc32c.a +LIBLEVELDB_SSE42_INT = leveldb/libleveldb_sse42.a + +EXTRA_LIBRARIES += $(LIBCRC32C_INT) + +LIBCRC32C = $(LIBCRC32C_INT) + +CRC32C_CPPFLAGS_INT = +CRC32C_CPPFLAGS_INT += -I$(srcdir)/crc32c/include +CRC32C_CPPFLAGS_INT += -DHAVE_BUILTIN_PREFETCH=@HAVE_BUILTIN_PREFETCH@ +CRC32C_CPPFLAGS_INT += -DHAVE_MM_PREFETCH=@HAVE_MM_PREFETCH@ +CRC32C_CPPFLAGS_INT += -DHAVE_STRONG_GETAUXVAL=@HAVE_STRONG_GETAUXVAL@ +CRC32C_CPPFLAGS_INT += -DHAVE_WEAK_GETAUXVAL=@HAVE_WEAK_GETAUXVAL@ +CRC32C_CPPFLAGS_INT += -DCRC32C_TESTS_BUILT_WITH_GLOG=0 + +if ENABLE_SSE42 +CRC32C_CPPFLAGS_INT += -DHAVE_SSE42=1 +else +CRC32C_CPPFLAGS_INT += -DHAVE_SSE42=0 +endif + +if ENABLE_ARM_CRC +CRC32C_CPPFLAGS_INT += -DHAVE_ARM64_CRC32C=1 +else +CRC32C_CPPFLAGS_INT += -DHAVE_ARM64_CRC32C=0 +endif + +if WORDS_BIGENDIAN +CRC32C_CPPFLAGS_INT += -DBYTE_ORDER_BIG_ENDIAN=1 +else +CRC32C_CPPFLAGS_INT += -DBYTE_ORDER_BIG_ENDIAN=0 +endif + +crc32c_libcrc32c_a_CPPFLAGS = $(AM_CPPFLAGS) $(CRC32C_CPPFLAGS_INT) $(CRC32C_CPPFLAGS) +crc32c_libcrc32c_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) + +crc32c_libcrc32c_a_SOURCES = +crc32c_libcrc32c_a_SOURCES += crc32c/include/crc32c/crc32c.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_arm64.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_arm64_linux_check.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_internal.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_prefetch.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_read_le.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_round_up.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_sse42_check.h +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_sse42.h + +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c.cc +crc32c_libcrc32c_a_SOURCES += crc32c/src/crc32c_portable.cc + +if ENABLE_SSE42 +LIBCRC32C_SSE42_INT = crc32c/libcrc32c_sse42.a +EXTRA_LIBRARIES += $(LIBCRC32C_SSE42_INT) +LIBCRC32C += $(LIBCRC32C_SSE42_INT) + +crc32c_libcrc32c_sse42_a_CPPFLAGS = $(crc32c_libcrc32c_a_CPPFLAGS) +crc32c_libcrc32c_sse42_a_CXXFLAGS = $(crc32c_libcrc32c_a_CXXFLAGS) $(SSE42_CXXFLAGS) + +crc32c_libcrc32c_sse42_a_SOURCES = crc32c/src/crc32c_sse42.cc +endif + +if ENABLE_ARM_CRC +LIBCRC32C_ARM_CRC_INT = crc32c/libcrc32c_arm_crc.a +EXTRA_LIBRARIES += $(LIBCRC32C_ARM_CRC_INT) +LIBCRC32C += $(LIBCRC32C_ARM_CRC_INT) + +crc32c_libcrc32c_arm_crc_a_CPPFLAGS = $(crc32c_libcrc32c_a_CPPFLAGS) +crc32c_libcrc32c_arm_crc_a_CXXFLAGS = $(crc32c_libcrc32c_a_CXXFLAGS) $(ARM_CRC_CXXFLAGS) + +crc32c_libcrc32c_arm_crc_a_SOURCES = crc32c/src/crc32c_arm64.cc +endif diff --git a/src/Makefile.leveldb.include b/src/Makefile.leveldb.include index 72bcb00e85..04b53471e4 100644 --- a/src/Makefile.leveldb.include +++ b/src/Makefile.leveldb.include @@ -8,7 +8,7 @@ LIBMEMENV_INT = leveldb/libmemenv.a EXTRA_LIBRARIES += $(LIBLEVELDB_INT) EXTRA_LIBRARIES += $(LIBMEMENV_INT) -LIBLEVELDB += $(LIBLEVELDB_INT) +LIBLEVELDB += $(LIBLEVELDB_INT) $(LIBCRC32C) LIBMEMENV += $(LIBMEMENV_INT) LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/include @@ -16,8 +16,9 @@ LEVELDB_CPPFLAGS += -I$(srcdir)/leveldb/helpers/memenv LEVELDB_CPPFLAGS_INT = LEVELDB_CPPFLAGS_INT += -I$(srcdir)/leveldb +LEVELDB_CPPFLAGS_INT += -I$(srcdir)/crc32c/include LEVELDB_CPPFLAGS_INT += -D__STDC_LIMIT_MACROS -LEVELDB_CPPFLAGS_INT += -DHAVE_SNAPPY=0 -DHAVE_CRC32C=0 +LEVELDB_CPPFLAGS_INT += -DHAVE_SNAPPY=0 -DHAVE_CRC32C=1 LEVELDB_CPPFLAGS_INT += -DHAVE_FDATASYNC=@HAVE_FDATASYNC@ LEVELDB_CPPFLAGS_INT += -DHAVE_FULLFSYNC=@HAVE_FULLFSYNC@ LEVELDB_CPPFLAGS_INT += -DHAVE_O_CLOEXEC=@HAVE_O_CLOEXEC@