OSDN Git Service

Revert "ART: DCHECK zero case for CLZ/CTZ"
authorAndreas Gampe <agampe@google.com>
Fri, 14 Aug 2015 18:39:30 +0000 (18:39 +0000)
committerAndreas Gampe <agampe@google.com>
Fri, 14 Aug 2015 18:39:30 +0000 (18:39 +0000)
This reverts commit 51db2c217052fd6881b81f3ac5162fe88c36dbf0.

Still breaks for arm32. :(

Change-Id: I5fe6fc0cc410cc1c5b6bd68028ce9bf835cb94d5

runtime/base/bit_utils.h
runtime/leb128.h

index 332012b..6f45dc8 100644 (file)
@@ -29,28 +29,21 @@ namespace art {
 template<typename T>
 static constexpr int CLZ(T x) {
   static_assert(std::is_integral<T>::value, "T must be integral");
-  static_assert(std::is_unsigned<T>::value, "T must be unsigned");
+  // TODO: assert unsigned. There is currently many uses with signed values.
   static_assert(sizeof(T) <= sizeof(long long),  // NOLINT [runtime/int] [4]
                 "T too large, must be smaller than long long");
-  return
-      DCHECK_CONSTEXPR(x != 0, "x must not be zero", T(0))
-      (sizeof(T) == sizeof(uint32_t))
-          ? __builtin_clz(x)
-          : __builtin_clzll(x);
+  return (sizeof(T) == sizeof(uint32_t))
+      ? __builtin_clz(x)  // TODO: __builtin_clz[ll] has undefined behavior for x=0
+      : __builtin_clzll(x);
 }
 
 template<typename T>
 static constexpr int CTZ(T x) {
   static_assert(std::is_integral<T>::value, "T must be integral");
-  // A similar check to the above does not make sense. It isn't as non-intuitive to ask for
-  // trailing zeros in a negative number, and the quick backends do this for immediate encodings.
-  static_assert(sizeof(T) <= sizeof(long long),  // NOLINT [runtime/int] [4]
-                "T too large, must be smaller than long long");
-  return
-      DCHECK_CONSTEXPR(x != 0, "x must not be zero", T(0))
-      (sizeof(T) == sizeof(uint32_t))
-          ? __builtin_ctz(x)
-          : __builtin_ctzll(x);
+  // TODO: assert unsigned. There is currently many uses with signed values.
+  return (sizeof(T) == sizeof(uint32_t))
+      ? __builtin_ctz(x)
+      : __builtin_ctzll(x);
 }
 
 template<typename T>
index 976936d..14683d4 100644 (file)
@@ -101,7 +101,7 @@ static inline int32_t DecodeSignedLeb128(const uint8_t** data) {
 static inline uint32_t UnsignedLeb128Size(uint32_t data) {
   // bits_to_encode = (data != 0) ? 32 - CLZ(x) : 1  // 32 - CLZ(data | 1)
   // bytes = ceil(bits_to_encode / 7.0);             // (6 + bits_to_encode) / 7
-  uint32_t x = 6 + 32 - CLZ(data | 1U);
+  uint32_t x = 6 + 32 - CLZ(data | 1);
   // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
   // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
   return (x * 37) >> 8;
@@ -111,7 +111,7 @@ static inline uint32_t UnsignedLeb128Size(uint32_t data) {
 static inline uint32_t SignedLeb128Size(int32_t data) {
   // Like UnsignedLeb128Size(), but we need one bit beyond the highest bit that differs from sign.
   data = data ^ (data >> 31);
-  uint32_t x = 1 /* we need to encode the sign bit */ + 6 + 32 - CLZ(data | 1U);
+  uint32_t x = 1 /* we need to encode the sign bit */ + 6 + 32 - CLZ(data | 1);
   return (x * 37) >> 8;
 }