In new code, I'm making intensive use of the functions ffs and ffsll, for searching in a bitset. So, these functions should better be well optimized, even for MSVC.
And while at it, also the integer_length* functions. 2020-08-03 Bruno Haible <br...@clisp.org> integer_length_ll: Optimize for MSVC in 64-bit mode. * lib/integer_length_l.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. (FUNC): On MSVC, use MSVC_BUILTIN if defined. 2020-08-03 Bruno Haible <br...@clisp.org> integer_length_ll: Optimize for MSVC in 32-bit mode. * lib/integer_length_l.c: Include <intrin.h>. (integer_length): Define as inline function, like in lib/integer_length.c. 2020-08-03 Bruno Haible <br...@clisp.org> integer_length: Optimize for MSVC. * lib/integer_length.c: Include <intrin.h>. (integer_length): With MSVC, use the _BitScanReverse built-in. 2020-08-03 Bruno Haible <br...@clisp.org> ffsll: Optimize for MSVC in 64-bit mode. * lib/ffsl.h (FUNC): On MSVC, use MSVC_BUILTIN if defined. * lib/ffsll.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. * lib/ffsl.c (MSVC_BUILTIN): Define for MSVC. 2020-08-03 Bruno Haible <br...@clisp.org> ffsll: Optimize for MSVC in 32-bit mode. * lib/ffsl.h: Include <intrin.h>. (ffs): Define as inline function, like in lib/ffs.c. 2020-08-03 Bruno Haible <br...@clisp.org> ffs: Optimize for MSVC. * lib/ffs.c: Include <intrin.h>. (ffs): With MSVC, use the _BitScanForward built-in.
>From 353cc7c6906f650fa228d295dad270637f9441c7 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 00:05:05 +0200 Subject: [PATCH 1/6] ffs: Optimize for MSVC. * lib/ffs.c: Include <intrin.h>. (ffs): With MSVC, use the _BitScanForward built-in. --- ChangeLog | 6 ++++++ lib/ffs.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index 526747e..773a9f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + ffs: Optimize for MSVC. + * lib/ffs.c: Include <intrin.h>. + (ffs): With MSVC, use the _BitScanForward built-in. + +2020-08-03 Bruno Haible <br...@clisp.org> + sigprocmask: Try to avoid breakage for people who use an Autoconf cache. * m4/signalblocking.m4 (gl_SIGNALBLOCKING): Change the name of the cache variable. diff --git a/lib/ffs.c b/lib/ffs.c index ba4915e..d8a65ca 100644 --- a/lib/ffs.c +++ b/lib/ffs.c @@ -23,11 +23,23 @@ #include <limits.h> +#if defined _MSC_VER +# include <intrin.h> +#endif + int ffs (int i) { #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) return __builtin_ffs (i); +#elif defined _MSC_VER + /* _BitScanForward + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */ + unsigned long bit; + if (_BitScanForward (&bit, i)) + return bit + 1; + else + return 0; #else /* <https://github.com/gibsjose/BitHacks> gives this deBruijn constant for a branch-less computation, although -- 2.7.4
>From c728189201864850c562862fa7fc54d925c472e0 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 00:11:02 +0200 Subject: [PATCH 2/6] ffsll: Optimize for MSVC in 32-bit mode. * lib/ffsl.h: Include <intrin.h>. (ffs): Define as inline function, like in lib/ffs.c. --- ChangeLog | 6 ++++++ lib/ffsl.h | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/ChangeLog b/ChangeLog index 773a9f5..0a336bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + ffsll: Optimize for MSVC in 32-bit mode. + * lib/ffsl.h: Include <intrin.h>. + (ffs): Define as inline function, like in lib/ffs.c. + +2020-08-03 Bruno Haible <br...@clisp.org> + ffs: Optimize for MSVC. * lib/ffs.c: Include <intrin.h>. (ffs): With MSVC, use the _BitScanForward built-in. diff --git a/lib/ffsl.h b/lib/ffsl.h index cea4386..d5c5a97 100644 --- a/lib/ffsl.h +++ b/lib/ffsl.h @@ -27,6 +27,22 @@ #include <limits.h> #include <strings.h> +#if defined _MSC_VER +# include <intrin.h> +/* Copied from ffs.c. */ +static inline int +ffs (int i) +{ + /* _BitScanForward + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */ + unsigned long bit; + if (_BitScanForward (&bit, i)) + return bit + 1; + else + return 0; +} +#endif + #if !defined FUNC || !defined TYPE # error #endif -- 2.7.4
>From 1552de7c513ffbedf675de10b77a6d5c264ee3b2 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 00:13:46 +0200 Subject: [PATCH 3/6] ffsll: Optimize for MSVC in 64-bit mode. * lib/ffsl.h (FUNC): On MSVC, use MSVC_BUILTIN if defined. * lib/ffsll.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. * lib/ffsl.c (MSVC_BUILTIN): Define for MSVC. --- ChangeLog | 7 +++++++ lib/ffsl.c | 1 + lib/ffsl.h | 8 ++++++++ lib/ffsll.c | 3 +++ 4 files changed, 19 insertions(+) diff --git a/ChangeLog b/ChangeLog index 0a336bf..51b2be7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + ffsll: Optimize for MSVC in 64-bit mode. + * lib/ffsl.h (FUNC): On MSVC, use MSVC_BUILTIN if defined. + * lib/ffsll.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. + * lib/ffsl.c (MSVC_BUILTIN): Define for MSVC. + +2020-08-03 Bruno Haible <br...@clisp.org> + ffsll: Optimize for MSVC in 32-bit mode. * lib/ffsl.h: Include <intrin.h>. (ffs): Define as inline function, like in lib/ffs.c. diff --git a/lib/ffsl.c b/lib/ffsl.c index ee99ba7..198cacb 100644 --- a/lib/ffsl.c +++ b/lib/ffsl.c @@ -1,4 +1,5 @@ #define FUNC ffsl #define TYPE long int #define GCC_BUILTIN __builtin_ffsl +#define MSVC_BUILTIN _BitScanForward #include "ffsl.h" diff --git a/lib/ffsl.h b/lib/ffsl.h index d5c5a97..fa5c093 100644 --- a/lib/ffsl.h +++ b/lib/ffsl.h @@ -52,6 +52,14 @@ FUNC (TYPE i) { #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) && defined GCC_BUILTIN return GCC_BUILTIN (i); +#elif defined _MSC_VER && defined MSVC_BUILTIN + /* _BitScanForward, _BitScanForward64 + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanforward-bitscanforward64> */ + unsigned long bit; + if (MSVC_BUILTIN (&bit, i)) + return bit + 1; + else + return 0; #else unsigned TYPE j = i; /* Split j into chunks, and look at one chunk after the other. */ diff --git a/lib/ffsll.c b/lib/ffsll.c index f0e9425..80a273c 100644 --- a/lib/ffsll.c +++ b/lib/ffsll.c @@ -1,4 +1,7 @@ #define FUNC ffsll #define TYPE long long int #define GCC_BUILTIN __builtin_ffsll +#ifdef _WIN64 +# define MSVC_BUILTIN _BitScanForward64 +#endif #include "ffsl.h" -- 2.7.4
>From 8c7b90680b73580b5c257baa3c9c22239ab0c3d1 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 00:40:24 +0200 Subject: [PATCH 4/6] integer_length: Optimize for MSVC. * lib/integer_length.c: Include <intrin.h>. (integer_length): With MSVC, use the _BitScanReverse built-in. --- ChangeLog | 6 ++++++ lib/integer_length.c | 14 ++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 51b2be7..b2169e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + integer_length: Optimize for MSVC. + * lib/integer_length.c: Include <intrin.h>. + (integer_length): With MSVC, use the _BitScanReverse built-in. + +2020-08-03 Bruno Haible <br...@clisp.org> + ffsll: Optimize for MSVC in 64-bit mode. * lib/ffsl.h (FUNC): On MSVC, use MSVC_BUILTIN if defined. * lib/ffsll.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. diff --git a/lib/integer_length.c b/lib/integer_length.c index edad54b..43d8f49 100644 --- a/lib/integer_length.c +++ b/lib/integer_length.c @@ -25,10 +25,8 @@ #include "float+.h" -/* MSVC with option -fp:strict refuses to compile constant initializers that - contain floating-point operations. Pacify this compiler. */ -#ifdef _MSC_VER -# pragma fenv_access (off) +#if defined _MSC_VER +# include <intrin.h> #endif #define NBITS (sizeof (unsigned int) * CHAR_BIT) @@ -41,6 +39,14 @@ integer_length (unsigned int x) return 0; else return NBITS - __builtin_clz (x); +#elif defined _MSC_VER + /* _BitScanReverse + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64> */ + unsigned long bit; + if (_BitScanReverse (&bit, x)) + return bit + 1; + else + return 0; #else # if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT if (NBITS <= DBL_MANT_BIT) -- 2.7.4
>From dc87bda7182bf9ad9034ca739f46b3dbb9dc4632 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 01:10:23 +0200 Subject: [PATCH 5/6] integer_length_ll: Optimize for MSVC in 32-bit mode. * lib/integer_length_l.c: Include <intrin.h>. (integer_length): Define as inline function, like in lib/integer_length.c. --- ChangeLog | 7 +++++++ lib/integer_length_l.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/ChangeLog b/ChangeLog index b2169e3..bfd2ade 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + integer_length_ll: Optimize for MSVC in 32-bit mode. + * lib/integer_length_l.c: Include <intrin.h>. + (integer_length): Define as inline function, like in + lib/integer_length.c. + +2020-08-03 Bruno Haible <br...@clisp.org> + integer_length: Optimize for MSVC. * lib/integer_length.c: Include <intrin.h>. (integer_length): With MSVC, use the _BitScanReverse built-in. diff --git a/lib/integer_length_l.c b/lib/integer_length_l.c index 7a60357..ea52ac3 100644 --- a/lib/integer_length_l.c +++ b/lib/integer_length_l.c @@ -37,6 +37,22 @@ # define GCC_BUILTIN __builtin_clzl #endif +#if defined _MSC_VER +# include <intrin.h> +/* Copied from integer_length.c. */ +static inline int +integer_length (unsigned int x) +{ + /* _BitScanReverse + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64> */ + unsigned long bit; + if (_BitScanReverse (&bit, x)) + return bit + 1; + else + return 0; +} +#endif + #define NBITS (sizeof (TYPE) * CHAR_BIT) /* Modify shift count to be in bounds, even in dead code, otherwise GCC -- 2.7.4
>From eb7f785f5ad4fd6a9d9e8e74e42838a27d1dff86 Mon Sep 17 00:00:00 2001 From: Bruno Haible <br...@clisp.org> Date: Tue, 4 Aug 2020 01:17:36 +0200 Subject: [PATCH 6/6] integer_length_ll: Optimize for MSVC in 64-bit mode. * lib/integer_length_l.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. (FUNC): On MSVC, use MSVC_BUILTIN if defined. --- ChangeLog | 6 ++++++ lib/integer_length_l.c | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ChangeLog b/ChangeLog index bfd2ade..9919a40 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2020-08-03 Bruno Haible <br...@clisp.org> + integer_length_ll: Optimize for MSVC in 64-bit mode. + * lib/integer_length_l.c (MSVC_BUILTIN): Define for MSVC in 64-bit mode. + (FUNC): On MSVC, use MSVC_BUILTIN if defined. + +2020-08-03 Bruno Haible <br...@clisp.org> + integer_length_ll: Optimize for MSVC in 32-bit mode. * lib/integer_length_l.c: Include <intrin.h>. (integer_length): Define as inline function, like in diff --git a/lib/integer_length_l.c b/lib/integer_length_l.c index ea52ac3..161f1af 100644 --- a/lib/integer_length_l.c +++ b/lib/integer_length_l.c @@ -31,10 +31,14 @@ # define FUNC integer_length_ll # define TYPE unsigned long long # define GCC_BUILTIN __builtin_clzll +# ifdef _WIN64 +# define MSVC_BUILTIN _BitScanReverse64 +# endif #else # define FUNC integer_length_l # define TYPE unsigned long # define GCC_BUILTIN __builtin_clzl +# define MSVC_BUILTIN _BitScanReverse #endif #if defined _MSC_VER @@ -67,6 +71,14 @@ FUNC (TYPE x) return 0; else return NBITS - GCC_BUILTIN (x); +#elif defined _MSC_VER && defined MSVC_BUILTIN + /* _BitScanReverse, _BitScanReverse64 + <https://docs.microsoft.com/en-us/cpp/intrinsics/bitscanreverse-bitscanreverse64> */ + unsigned long bit; + if (MSVC_BUILTIN (&bit, x)) + return bit + 1; + else + return 0; #else /* Split x into chunks, and look at one chunk after the other. */ if (sizeof (TYPE) > 2 * sizeof (unsigned int)) -- 2.7.4