Where possible use compiler builtins for CountBits and FindFirstBit.

This commit is contained in:
Jonathan G Rennison
2016-09-04 18:01:38 +01:00
parent 376a45d9fc
commit 349cd8a6f0
3 changed files with 48 additions and 3 deletions

View File

@@ -185,6 +185,18 @@ static inline T ToggleBit(T &x, const uint8 y)
return x = (T)(x ^ ((T)1U << y));
}
#ifdef WITH_BITMATH_BUILTINS
#define FIND_FIRST_BIT(x) FindFirstBit(x)
inline uint8 FindFirstBit(uint32 x)
{
if (x == 0) return 0;
return __builtin_ctz(x);
}
#else
/** Lookup table to check which bit is set in a 6 bit variable */
extern const uint8 _ffb_64[64];
@@ -201,6 +213,12 @@ extern const uint8 _ffb_64[64];
*/
#define FIND_FIRST_BIT(x) _ffb_64[(x)]
uint8 FindFirstBit(uint32 x);
#endif
uint8 FindLastBit(uint64 x);
/**
* Finds the position of the first non-zero bit in an integer.
*
@@ -224,9 +242,6 @@ static inline uint8 FindFirstBit2x64(const int value)
}
}
uint8 FindFirstBit(uint32 x);
uint8 FindLastBit(uint64 x);
/**
* Clear the first bit in an integer.
*
@@ -252,6 +267,15 @@ static inline T KillFirstBit(T value)
template <typename T>
static inline uint CountBits(T value)
{
#ifdef WITH_BITMATH_BUILTINS
if (sizeof(T) == sizeof(unsigned int)) {
return __builtin_popcount(value);
} else if (sizeof(T) == sizeof(unsigned long)) {
return __builtin_popcountl(value);
} else {
return __builtin_popcountll(value);
}
#else
uint num;
/* This loop is only called once for every bit set by clearing the lowest
@@ -264,6 +288,7 @@ static inline uint CountBits(T value)
}
return num;
#endif
}
/**