diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2016-04-28 15:20:43 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2016-04-28 17:36:19 +0100 |
commit | 546f24e4f8a7c086b1e5afcdda624176610cbcf8 (patch) | |
tree | e4e1443311b6e83d3b81e11f44976e620ed8a2f8 /rts/sm/BlockAlloc.c | |
parent | c5b1014eb0a477aa32691841dcc2739dbcd2bc85 (diff) | |
download | haskell-546f24e4f8a7c086b1e5afcdda624176610cbcf8.tar.gz |
Revert "Use __builtin_clz() to implement log_2()"
This reverts commit 24864ba5587c1a0447beabae90529e8bb4fa117a.
Diffstat (limited to 'rts/sm/BlockAlloc.c')
-rw-r--r-- | rts/sm/BlockAlloc.c | 32 |
1 files changed, 11 insertions, 21 deletions
diff --git a/rts/sm/BlockAlloc.c b/rts/sm/BlockAlloc.c index 1c83de9ded..a633726935 100644 --- a/rts/sm/BlockAlloc.c +++ b/rts/sm/BlockAlloc.c @@ -199,41 +199,31 @@ initGroup(bdescr *head) } } -// log base 2 (floor), needs to support up to 2^MAX_FREE_LIST +// 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. STATIC_INLINE nat -log_2(W_ n) +log_2_ceil(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 = 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 } -// log base 2 (ceiling), needs to support up to 2^MAX_FREE_LIST STATIC_INLINE nat -log_2_ceil(W_ n) +log_2(W_ n) { -#if defined(__GNUC__) - nat r = log_2(n); - return (n & (n-1)) ? r+1 : r; -#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 } STATIC_INLINE void |