Re: Missing _BitScanReverse64()

2015-01-05 Thread Gisle Vanem

Pádraig Brady wrote:


Does the following address the issue for you?
It should drop back to the more generic slow path on 32 bit.


But I do have _BitReverse. That could be an intrinsic.


BTW do we have the same issue with __popcnt64 in count-one-bits.h?


Seems so:
  __MACHINEX64(unsigned __int64 __popcnt64(unsigned __int64))

X86 compilers only.

--
--gv



Re: Missing _BitScanReverse64()

2015-01-05 Thread Paul Eggert

Pádraig Brady wrote:

I noticed that count_one_bits() branches on the popcount_support
variable on each call, which might negate much of the gain from using this 
instruction?



Could be.  As far as I know it's never been benchmarked.  I stole that code from 
Emacs without investigating its performance (requires MS-Windows to test, which 
I don't have).  It'd be nice to simplify the code by removing it if it doesn't 
help performance significantly on MS-Windows.




Re: Missing _BitScanReverse64()

2015-01-05 Thread Pádraig Brady
On 05/01/15 21:32, Gisle Vanem wrote:
 Pádraig Brady wrote:
 
 Does the following address the issue for you?
 It should drop back to the more generic slow path on 32 bit.
 
 But I do have _BitReverse. That could be an intrinsic.

I was assuming we could do the simpler patch and be
slightly slower on the shrinking 32 bit target.
Though I suppose it's only slightly more awkward to use
builtins where available, so I've done that in the attached.

 BTW do we have the same issue with __popcnt64 in count-one-bits.h?
 
 Seems so:
__MACHINEX64(unsigned __int64 __popcnt64(unsigned __int64))
 
 X86 compilers only.

I've included that too, and also count-trailing-zeros is updated.

thanks,
Pádraig.

p.s. I noticed that count_one_bits() branches on the popcount_support
variable on each call, which might negate much of the gain from using this 
instruction?

From 061484434eb09a80f872cab0e173847668b46e4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= p...@draigbrady.com
Date: Tue, 6 Jan 2015 02:27:16 +
Subject: [PATCH] count-leading-zeros: avoid 64-bit intrinsics on 32-bit
 Windows

* lib/count-leading-zeros.h (count_leading_zeros_ll): Use 32 bit
intrinsics in this case.
* lib/count-trailing-zeros.h: Likewise.
* lib/count-one-bits.h: Likewise.
---
 ChangeLog  | 8 
 lib/count-leading-zeros.h  | 5 +
 lib/count-one-bits.h   | 4 
 lib/count-trailing-zeros.h | 5 +
 4 files changed, 22 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 938e031..3b08279 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2015-01-06  Pádraig Brady  p...@draigbrady.com
+
+	count-leading-zeros: avoid 64-bit intrinsics on 32-bit Windows
+	* lib/count-leading-zeros.h (count_leading_zeros_ll): Use 32 bit
+	intrinsics in this case.
+	* lib/count-trailing-zeros.h: Likewise.
+	* lib/count-one-bits.h: Likewise.
+
 2015-01-04  Benno Schulenberg  bensb...@justemail.net
 
 	maint: fix grammar nits in propername (trivial change)
diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h
index 722615f..9e72fff 100644
--- a/lib/count-leading-zeros.h
+++ b/lib/count-leading-zeros.h
@@ -104,8 +104,13 @@ count_leading_zeros_l (unsigned long int x)
 COUNT_LEADING_ZEROS_INLINE int
 count_leading_zeros_ll (unsigned long long int x)
 {
+# if _MSC_VER  ! defined _M_X64
+  int count = count_leading_zeros (x  31  1);
+  return count  32 ? count : 32 + count_leading_zeros (x);
+# else
   COUNT_LEADING_ZEROS (__builtin_clzll, _BitScanReverse64,
unsigned long long int);
+# endif
 }
 #endif
 
diff --git a/lib/count-one-bits.h b/lib/count-one-bits.h
index d54397f..bd79fc5 100644
--- a/lib/count-one-bits.h
+++ b/lib/count-one-bits.h
@@ -127,7 +127,11 @@ count_one_bits_l (unsigned long int x)
 COUNT_ONE_BITS_INLINE int
 count_one_bits_ll (unsigned long long int x)
 {
+# if _MSC_VER  ! defined _M_X64
+  return count_one_bits (x  31  1) + count_one_bits (x);
+# else
   COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int);
+# endif
 }
 #endif
 
diff --git a/lib/count-trailing-zeros.h b/lib/count-trailing-zeros.h
index 83ce2fb..1e71977 100644
--- a/lib/count-trailing-zeros.h
+++ b/lib/count-trailing-zeros.h
@@ -96,8 +96,13 @@ count_trailing_zeros_l (unsigned long int x)
 COUNT_TRAILING_ZEROS_INLINE int
 count_trailing_zeros_ll (unsigned long long int x)
 {
+# if _MSC_VER  ! defined _M_X64
+  int count = count_trailing_zeros (x);
+  return count  32 ? count : 32 + count_trailing_zeros (x  31  1);
+# else
   COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
 unsigned long long int);
+# endif
 }
 #endif
 
-- 
2.1.0



Missing _BitScanReverse64()

2015-01-05 Thread Gisle Vanem

I'm on Win-XP (32bit, MSVC v16) and get a link error on a
missing '__BitScanReverse64()' in test-count-leading-zeros.c:.
Here is the dis-asm:

 _count_leading_zeros_ll:
 pushebp
 mov ebp,esp
 sub esp,0x0008
 X$72:
 mov eax,dword ptr 0xc[ebp]
 pusheax
 mov ecx,dword ptr 0x8[ebp]
 pushecx
 lea edx,-0x4[ebp]
 pushedx
 callj^__BitScanReverse64

According to MSVC's intrin.h, the intrinsic for this function only
exists on 64-bit machines:

/*__MACHINEW64  : WIN64(tm), 64 bit compilers only */
  __MACHINEW64(unsigned char _BitScanForward64(unsigned long* Index,
   unsigned __int64 Mask))

--
--gv



Re: Missing _BitScanReverse64()

2015-01-05 Thread Pádraig Brady
On 05/01/15 20:05, Gisle Vanem wrote:
 I'm on Win-XP (32bit, MSVC v16) and get a link error on a
 missing '__BitScanReverse64()' in test-count-leading-zeros.c:.
 Here is the dis-asm:
 
   _count_leading_zeros_ll:
   pushebp
   mov ebp,esp
   sub esp,0x0008
   X$72:
   mov eax,dword ptr 0xc[ebp]
   pusheax
   mov ecx,dword ptr 0x8[ebp]
   pushecx
   lea edx,-0x4[ebp]
   pushedx
   callj^__BitScanReverse64
 
 According to MSVC's intrin.h, the intrinsic for this function only
 exists on 64-bit machines:
 
 /*__MACHINEW64  : WIN64(tm), 64 bit compilers only */
__MACHINEW64(unsigned char _BitScanForward64(unsigned long* Index,
 unsigned __int64 Mask))

Does the following address the issue for you?
It should drop back to the more generic slow path on 32 bit.
BTW do we have the same issue with __popcnt64 in count-one-bits.h?

thanks,
Pádraig

diff --git a/lib/count-leading-zeros.h b/lib/count-leading-zeros.h
index 722615f..77a72ed 100644
--- a/lib/count-leading-zeros.h
+++ b/lib/count-leading-zeros.h
@@ -37,7 +37,7 @@ _GL_INLINE_HEADER_BEGIN
 #if __GNUC__  3 || (__GNUC__ == 3  __GNUC_MINOR__ = 4)
 # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)\
   return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
-#elif _MSC_VER
+#elif _MSC_VER  defined _M_X64
 # pragma intrinsic _BitReverse
 # pragma intrinsic _BitReverse64
 # define COUNT_LEADING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE)\