summaryrefslogtreecommitdiffstats
path: root/runtime/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/utils.h')
-rw-r--r--runtime/utils.h67
1 files changed, 33 insertions, 34 deletions
diff --git a/runtime/utils.h b/runtime/utils.h
index 4b2f23063b..14a532ebef 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -47,7 +47,7 @@ enum TimeUnit {
};
template<typename T>
-static inline bool IsPowerOfTwo(T x) {
+static constexpr bool IsPowerOfTwo(T x) {
return (x & (x - 1)) == 0;
}
@@ -115,39 +115,46 @@ static inline uint32_t High32Bits(uint64_t value) {
}
// A static if which determines whether to return type A or B based on the condition boolean.
-template <const bool condition, typename A, typename B>
+template <bool condition, typename A, typename B>
struct TypeStaticIf {
- typedef A value;
+ typedef A type;
};
// Specialization to handle the false case.
template <typename A, typename B>
struct TypeStaticIf<false, A, B> {
- typedef B value;
+ typedef B type;
+};
+
+// Type identity.
+template <typename T>
+struct TypeIdentity {
+ typedef T type;
};
// For rounding integers.
template<typename T>
-static inline T RoundDown(T x, int n) {
- DCHECK(IsPowerOfTwo(n));
- return (x & -n);
+static constexpr T RoundDown(T x, typename TypeIdentity<T>::type n) {
+ return
+ // DCHECK(IsPowerOfTwo(n)) in a form acceptable in a constexpr function:
+ (kIsDebugBuild && !IsPowerOfTwo(n)) ? (LOG(FATAL) << n << " isn't a power of 2", T(0))
+ : (x & -n);
}
template<typename T>
-static inline T RoundUp(T x, int n) {
+static constexpr T RoundUp(T x, typename TypeIdentity<T>::type n) {
return RoundDown(x + n - 1, n);
}
// For aligning pointers.
template<typename T>
-static inline T* AlignDown(T* x, int n) {
- CHECK(IsPowerOfTwo(n));
- return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(x) & -static_cast<uintptr_t>(n));
+static inline T* AlignDown(T* x, uintptr_t n) {
+ return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uintptr_t>(x), n));
}
template<typename T>
-static inline T* AlignUp(T* x, int n) {
- return AlignDown(reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(x) + static_cast<uintptr_t>(n - 1)), n);
+static inline T* AlignUp(T* x, uintptr_t n) {
+ return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uintptr_t>(x), n));
}
// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
@@ -162,33 +169,25 @@ static inline uint32_t RoundUpToPowerOfTwo(uint32_t x) {
return x + 1;
}
-// Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.,
-// figure 5-2, page 66, where the function is called pop.
-static inline int CountOneBits(uint32_t x) {
- x = x - ((x >> 1) & 0x55555555);
- x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
- x = (x + (x >> 4)) & 0x0F0F0F0F;
- x = x + (x >> 8);
- x = x + (x >> 16);
- return static_cast<int>(x & 0x0000003F);
+template<typename T>
+static constexpr int CLZ(T x) {
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_clz(x)
+ : __builtin_clzll(x);
}
template<typename T>
-static inline int CLZ(T x) {
- if (sizeof(T) == sizeof(uint32_t)) {
- return __builtin_clz(x);
- } else {
- return __builtin_clzll(x);
- }
+static constexpr int CTZ(T x) {
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_ctz(x)
+ : __builtin_ctzll(x);
}
template<typename T>
-static inline int CTZ(T x) {
- if (sizeof(T) == sizeof(uint32_t)) {
- return __builtin_ctz(x);
- } else {
- return __builtin_ctzll(x);
- }
+static constexpr int POPCOUNT(T x) {
+ return (sizeof(T) == sizeof(uint32_t))
+ ? __builtin_popcount(x)
+ : __builtin_popcountll(x);
}
static inline uint32_t PointerToLowMemUInt32(const void* p) {