Commit 5f8c0b84 authored by U-THEFACEBOOK\smarlow's avatar U-THEFACEBOOK\smarlow Committed by Simon Marlow

Revert "Revert "Use __builtin_clz() to implement log_1()""

This reverts commit 546f24e4.

And adds a fix for Windows: we need to use __builtin_clzll() rather than
__builtin_clzl(), because StgWord is unsigned long long on Windows.
parent 36d29f7c
......@@ -199,31 +199,47 @@ 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.
#if SIZEOF_VOID_P == SIZEOF_LONG
#define CLZW(n) (__builtin_clzl(n))
#else
#define CLZW(n) (__builtin_clzll(n))
#endif
// 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 CLZW(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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment