[commit: ghc] master: Use __builtin_clz() to implement log_2() (24864ba)
git at git.haskell.org
git at git.haskell.org
Tue Apr 26 14:58:05 UTC 2016
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/24864ba5587c1a0447beabae90529e8bb4fa117a/ghc
>---------------------------------------------------------------
commit 24864ba5587c1a0447beabae90529e8bb4fa117a
Author: Simon Marlow <marlowsd at gmail.com>
Date: Sat Apr 23 22:14:43 2016 +0100
Use __builtin_clz() to implement log_2()
A microoptimisation in the block allocator.
>---------------------------------------------------------------
24864ba5587c1a0447beabae90529e8bb4fa117a
rts/sm/BlockAlloc.c | 32 +++++++++++++++++++++-----------
1 file changed, 21 insertions(+), 11 deletions(-)
diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c
index a633726..1c83de9 100644
--- a/rts/sm/BlockAlloc.c
+++ b/rts/sm/BlockAlloc.c
@@ -199,31 +199,41 @@ initGroup(bdescr *head)
}
}
-// There are quicker non-loopy ways to do log_2, but we expect n to be
-// usually small, and MAX_FREE_LIST is also small, so the loop version
-// might well be the best choice here.
+// log base 2 (floor), needs to support up to 2^MAX_FREE_LIST
STATIC_INLINE nat
-log_2_ceil(W_ n)
+log_2(W_ n)
{
+#if defined(__GNUC__)
+ return __builtin_clzl(n) ^ (sizeof(StgWord)*8 - 1);
+ // generates good code on x86. __builtin_clz() compiles to bsr+xor, but
+ // we want just bsr, so the xor here cancels out gcc's xor.
+#else
W_ i, x;
- x = 1;
+ x = n;
for (i=0; i < MAX_FREE_LIST; i++) {
- if (x >= n) return i;
- x = x << 1;
+ x = x >> 1;
+ if (x == 0) return i;
}
return MAX_FREE_LIST;
+#endif
}
+// log base 2 (ceiling), needs to support up to 2^MAX_FREE_LIST
STATIC_INLINE nat
-log_2(W_ n)
+log_2_ceil(W_ n)
{
+#if defined(__GNUC__)
+ nat r = log_2(n);
+ return (n & (n-1)) ? r+1 : r;
+#else
W_ i, x;
- x = n;
+ x = 1;
for (i=0; i < MAX_FREE_LIST; i++) {
- x = x >> 1;
- if (x == 0) return i;
+ if (x >= n) return i;
+ x = x << 1;
}
return MAX_FREE_LIST;
+#endif
}
STATIC_INLINE void
More information about the ghc-commits
mailing list