summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2020-09-30 16:08:00 -0700
committerGitHub <noreply@github.com>2020-09-30 16:08:00 -0700
commit2f6939a2cecc37691a1e474ff15a7801f9509cfb (patch)
treed994f14cb68e95d675d0ac3943c8087c77129b3e /src
parentb91603f65c45139ad49dfa257749d100117b763d (diff)
downloadbinaryen-2f6939a2cecc37691a1e474ff15a7801f9509cfb.tar.gz
binaryen-2f6939a2cecc37691a1e474ff15a7801f9509cfb.tar.bz2
binaryen-2f6939a2cecc37691a1e474ff15a7801f9509cfb.zip
Clean up support/bits.h (#3177)
Use overloads instead of templates where applicable and change function names from PascalCase to camelCase. Also puts the functions in the Bits namespace to avoid naming conflicts.
Diffstat (limited to 'src')
-rw-r--r--src/ir/bits.h10
-rw-r--r--src/passes/OptimizeInstructions.cpp18
-rw-r--r--src/support/bits.cpp47
-rw-r--r--src/support/bits.h82
-rw-r--r--src/support/utilities.h2
-rw-r--r--src/wasm/literal.cpp20
-rw-r--r--src/wasm/wasm-binary.cpp2
-rw-r--r--src/wasm/wasm-stack.cpp2
8 files changed, 93 insertions, 90 deletions
diff --git a/src/ir/bits.h b/src/ir/bits.h
index 40bd8e545..95481eeab 100644
--- a/src/ir/bits.h
+++ b/src/ir/bits.h
@@ -51,7 +51,7 @@ inline uint32_t getMaskedBits(uint32_t mask) {
return 0;
}
// this is indeed a mask
- return 32 - CountLeadingZeroes(mask);
+ return 32 - countLeadingZeroes(mask);
}
// gets the number of effective shifts a shift operation does. In
@@ -180,7 +180,7 @@ Index getMaxBits(Expression* curr,
if (maxBitsLeft == 32) {
return 32;
}
- auto bitsRight = Index(CeilLog2(c->value.geti32()));
+ auto bitsRight = Index(ceilLog2(c->value.geti32()));
return std::min(maxBitsLeft, bitsRight);
}
return 32;
@@ -188,7 +188,7 @@ Index getMaxBits(Expression* curr,
case RemUInt32: {
if (auto* c = binary->right->dynCast<Const>()) {
auto maxBitsLeft = getMaxBits(binary->left, localInfoProvider);
- auto bitsRight = Index(CeilLog2(c->value.geti32()));
+ auto bitsRight = Index(ceilLog2(c->value.geti32()));
return std::min(maxBitsLeft, bitsRight);
}
return 32;
@@ -275,7 +275,7 @@ Index getMaxBits(Expression* curr,
if (maxBitsLeft == 64) {
return 64;
}
- auto bitsRight = Index(CeilLog2(c->value.geti64()));
+ auto bitsRight = Index(ceilLog2(c->value.geti64()));
return std::min(maxBitsLeft, bitsRight);
}
return 64;
@@ -283,7 +283,7 @@ Index getMaxBits(Expression* curr,
case RemUInt64: {
if (auto* c = binary->right->dynCast<Const>()) {
auto maxBitsLeft = getMaxBits(binary->left, localInfoProvider);
- auto bitsRight = Index(CeilLog2(c->value.geti64()));
+ auto bitsRight = Index(ceilLog2(c->value.geti64()));
return std::min(maxBitsLeft, bitsRight);
}
return 64;
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp
index 55af9a34d..dc38933a6 100644
--- a/src/passes/OptimizeInstructions.cpp
+++ b/src/passes/OptimizeInstructions.cpp
@@ -304,7 +304,7 @@ struct OptimizeInstructions
if (matches(curr,
unary(Abstract::EqZ,
binary(&inner, Abstract::RemS, any(), ival(&c)))) &&
- IsPowerOf2((uint64_t)c->value.getInteger())) {
+ Bits::isPowerOf2((uint64_t)c->value.getInteger())) {
inner->op = Abstract::getBinary(c->type, Abstract::And);
c->value = c->value.sub(Literal::makeFromInt32(1, c->type));
return curr;
@@ -407,7 +407,7 @@ struct OptimizeInstructions
// forcing them to zero like we do in the zero-extend.
int32_t constValue = c->value.geti32();
auto upperConstValue = constValue & ~Bits::lowBitMask(bits);
- uint32_t count = PopCount(upperConstValue);
+ uint32_t count = Bits::popCount(upperConstValue);
auto constSignBit = constValue & (1 << (bits - 1));
if ((count > 0 && count < 32 - bits) ||
(constSignBit && count == 0)) {
@@ -529,7 +529,7 @@ struct OptimizeInstructions
Bits::getMaxBits(binary->left, this) <= 31) {
binary->op = op;
}
- if (IsPowerOf2((uint32_t)c)) {
+ if (Bits::isPowerOf2((uint32_t)c)) {
switch (binary->op) {
case MulInt32:
return optimizePowerOf2Mul(binary, (uint32_t)c);
@@ -550,7 +550,7 @@ struct OptimizeInstructions
Bits::getMaxBits(binary->left, this) <= 63) {
binary->op = op;
}
- if (IsPowerOf2((uint64_t)c)) {
+ if (Bits::isPowerOf2((uint64_t)c)) {
switch (binary->op) {
case MulInt64:
return optimizePowerOf2Mul(binary, (uint64_t)c);
@@ -976,8 +976,8 @@ private:
continue;
} else if (binary->op == ShlInt32) {
if (auto* c = binary->right->dynCast<Const>()) {
- seekStack.emplace_back(binary->left,
- mul * Pow2(Bits::getEffectiveShifts(c)));
+ seekStack.emplace_back(
+ binary->left, mul * Bits::pow2(Bits::getEffectiveShifts(c)));
continue;
}
} else if (binary->op == MulInt32) {
@@ -1206,7 +1206,7 @@ private:
static_assert(std::is_same<T, uint32_t>::value ||
std::is_same<T, uint64_t>::value,
"type mismatch");
- auto shifts = CountTrailingZeroes<T>(c);
+ auto shifts = Bits::countTrailingZeroes(c);
binary->op = std::is_same<T, uint32_t>::value ? ShlInt32 : ShlInt64;
binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));
return binary;
@@ -1221,7 +1221,7 @@ private:
static_assert(std::is_same<T, uint32_t>::value ||
std::is_same<T, uint64_t>::value,
"type mismatch");
- auto shifts = CountTrailingZeroes<T>(c);
+ auto shifts = Bits::countTrailingZeroes(c);
binary->op = std::is_same<T, uint32_t>::value ? ShrUInt32 : ShrUInt64;
binary->right->cast<Const>()->value = Literal(static_cast<T>(shifts));
return binary;
@@ -1310,7 +1310,7 @@ private:
binary(Abstract::Ne,
binary(&inner, Abstract::RemS, any(), ival(&c)),
ival(0))) &&
- IsPowerOf2((uint64_t)c->value.getInteger())) {
+ Bits::isPowerOf2((uint64_t)c->value.getInteger())) {
inner->op = Abstract::getBinary(c->type, Abstract::And);
c->value = c->value.sub(Literal::makeFromInt32(1, c->type));
return curr;
diff --git a/src/support/bits.cpp b/src/support/bits.cpp
index e60f2365b..7e22466d8 100644
--- a/src/support/bits.cpp
+++ b/src/support/bits.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#define wasm_support_bits_definitions
#include "support/bits.h"
#include "../compiler-support.h"
#include "support/utilities.h"
@@ -25,7 +24,9 @@
namespace wasm {
-template<> int PopCount<uint8_t>(uint8_t v) {
+namespace Bits {
+
+int popCount(uint8_t v) {
// Small table lookup.
static const uint8_t tbl[32] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2,
3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
@@ -33,15 +34,15 @@ template<> int PopCount<uint8_t>(uint8_t v) {
return tbl[v & 0xf] + tbl[v >> 4];
}
-template<> int PopCount<uint16_t>(uint16_t v) {
+int popCount(uint16_t v) {
#if __has_builtin(__builtin_popcount) || defined(__GNUC__)
return __builtin_popcount(v);
#else
- return PopCount((uint8_t)(v & 0xFF)) + PopCount((uint8_t)(v >> 8));
+ return popCount((uint8_t)(v & 0xFF)) + popCount((uint8_t)(v >> 8));
#endif
}
-template<> int PopCount<uint32_t>(uint32_t v) {
+int popCount(uint32_t v) {
#if __has_builtin(__builtin_popcount) || defined(__GNUC__)
return __builtin_popcount(v);
#else
@@ -53,15 +54,15 @@ template<> int PopCount<uint32_t>(uint32_t v) {
#endif
}
-template<> int PopCount<uint64_t>(uint64_t v) {
+int popCount(uint64_t v) {
#if __has_builtin(__builtin_popcount) || defined(__GNUC__)
return __builtin_popcountll(v);
#else
- return PopCount((uint32_t)v) + PopCount((uint32_t)(v >> 32));
+ return popCount((uint32_t)v) + popCount((uint32_t)(v >> 32));
#endif
}
-template<> uint32_t BitReverse<uint32_t>(uint32_t v) {
+uint32_t bitReverse(uint32_t v) {
// See Hacker's Delight, first edition, figure 7-1.
v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555);
v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333);
@@ -70,7 +71,7 @@ template<> uint32_t BitReverse<uint32_t>(uint32_t v) {
return v;
}
-template<> int CountTrailingZeroes<uint32_t>(uint32_t v) {
+int countTrailingZeroes(uint32_t v) {
if (v == 0) {
return 32;
}
@@ -91,7 +92,7 @@ template<> int CountTrailingZeroes<uint32_t>(uint32_t v) {
#endif
}
-template<> int CountTrailingZeroes<uint64_t>(uint64_t v) {
+int countTrailingZeroes(uint64_t v) {
if (v == 0) {
return 64;
}
@@ -102,12 +103,12 @@ template<> int CountTrailingZeroes<uint64_t>(uint64_t v) {
_BitScanForward64(&count, v);
return (int)count;
#else
- return (uint32_t)v ? CountTrailingZeroes((uint32_t)v)
- : 32 + CountTrailingZeroes((uint32_t)(v >> 32));
+ return (uint32_t)v ? countTrailingZeroes((uint32_t)v)
+ : 32 + countTrailingZeroes((uint32_t)(v >> 32));
#endif
}
-template<> int CountLeadingZeroes<uint32_t>(uint32_t v) {
+int countLeadingZeroes(uint32_t v) {
if (v == 0) {
return 32;
}
@@ -136,7 +137,7 @@ template<> int CountLeadingZeroes<uint32_t>(uint32_t v) {
#endif
}
-template<> int CountLeadingZeroes<uint64_t>(uint64_t v) {
+int countLeadingZeroes(uint64_t v) {
if (v == 0) {
return 64;
}
@@ -147,20 +148,16 @@ template<> int CountLeadingZeroes<uint64_t>(uint64_t v) {
_BitScanReverse64(&count, v);
return 63 - int(count);
#else
- return v >> 32 ? CountLeadingZeroes((uint32_t)(v >> 32))
- : 32 + CountLeadingZeroes((uint32_t)v);
+ return v >> 32 ? countLeadingZeroes((uint32_t)(v >> 32))
+ : 32 + countLeadingZeroes((uint32_t)v);
#endif
}
-template<> int CeilLog2<uint32_t>(uint32_t v) {
- return 32 - CountLeadingZeroes(v - 1);
-}
+int ceilLog2(uint32_t v) { return 32 - countLeadingZeroes(v - 1); }
-template<> int CeilLog2<uint64_t>(uint64_t v) {
- return 64 - CountLeadingZeroes(v - 1);
-}
+int ceilLog2(uint64_t v) { return 64 - countLeadingZeroes(v - 1); }
-uint32_t Log2(uint32_t v) {
+uint32_t log2(uint32_t v) {
switch (v) {
default:
WASM_UNREACHABLE("invalid value");
@@ -179,6 +176,8 @@ uint32_t Log2(uint32_t v) {
}
}
-uint32_t Pow2(uint32_t v) { return 1 << v; }
+uint32_t pow2(uint32_t v) { return 1 << v; }
+
+} // namespace Bits
} // namespace wasm
diff --git a/src/support/bits.h b/src/support/bits.h
index a927a2832..3231e1c96 100644
--- a/src/support/bits.h
+++ b/src/support/bits.h
@@ -29,67 +29,71 @@
*
* We instead use portable and reasonably-fast implementations, while
* avoiding implementations with large lookup tables.
- *
- * TODO: The convention here should be changed PopCount => popCount,
- * initial lowercase, to match the rest of the codebase.
*/
namespace wasm {
-template<typename T> int PopCount(T);
-template<typename T> uint32_t BitReverse(T);
-template<typename T> int CountTrailingZeroes(T);
-template<typename T> int CountLeadingZeroes(T);
-template<typename T> int CeilLog2(T);
-
-#ifndef wasm_support_bits_definitions
-// The template specializations are provided elsewhere.
-extern template int PopCount(uint8_t);
-extern template int PopCount(uint16_t);
-extern template int PopCount(uint32_t);
-extern template int PopCount(uint64_t);
-extern template uint32_t BitReverse(uint32_t);
-extern template int CountTrailingZeroes(uint32_t);
-extern template int CountTrailingZeroes(uint64_t);
-extern template int CountLeadingZeroes(uint32_t);
-extern template int CountLeadingZeroes(uint64_t);
-extern template int CeilLog2(uint32_t);
-extern template int CeilLog2(uint64_t);
-#endif
-
-// Convenience signed -> unsigned. It usually doesn't make much sense to use bit
-// functions on signed types.
-template<typename T> int PopCount(T v) {
- return PopCount(typename std::make_unsigned<T>::type(v));
+namespace Bits {
+
+int popCount(uint8_t);
+int popCount(uint16_t);
+int popCount(uint32_t);
+int popCount(uint64_t);
+
+inline int popCount(int8_t v) { return popCount(uint8_t(v)); }
+inline int popCount(int16_t v) { return popCount(uint16_t(v)); }
+inline int popCount(int32_t v) { return popCount(uint32_t(v)); }
+inline int popCount(int64_t v) { return popCount(uint64_t(v)); }
+
+uint32_t bitReverse(uint32_t);
+
+int countTrailingZeroes(uint32_t);
+int countTrailingZeroes(uint64_t);
+
+inline int countTrailingZeroes(int32_t v) {
+ return countTrailingZeroes(uint32_t(v));
}
-template<typename T> int CountTrailingZeroes(T v) {
- return CountTrailingZeroes(typename std::make_unsigned<T>::type(v));
+inline int countTrailingZeroes(int64_t v) {
+ return countTrailingZeroes(uint64_t(v));
}
-template<typename T> int CountLeadingZeroes(T v) {
- return CountLeadingZeroes(typename std::make_unsigned<T>::type(v));
+
+int countLeadingZeroes(uint32_t);
+int countLeadingZeroes(uint64_t);
+
+inline int countLeadingZeroes(int32_t v) {
+ return countLeadingZeroes(uint32_t(v));
}
-template<typename T> int CeilLog2(T v) {
- return CeilLog2(typename std::make_unsigned<T>::type(v));
+inline int countLeadingZeroes(int64_t v) {
+ return countLeadingZeroes(uint64_t(v));
}
-template<typename T> bool IsPowerOf2(T v) {
+
+int ceilLog2(uint32_t);
+int ceilLog2(uint64_t);
+
+inline int ceilLog2(int32_t v) { return ceilLog2(uint32_t(v)); }
+inline int ceilLog2(int64_t v) { return ceilLog2(uint64_t(v)); }
+
+template<typename T> bool isPowerOf2(T v) {
return v != 0 && (v & (v - 1)) == 0;
}
-template<typename T, typename U> inline static T RotateLeft(T val, U count) {
+template<typename T, typename U> inline static T rotateLeft(T val, U count) {
auto value = typename std::make_unsigned<T>::type(val);
U mask = sizeof(T) * CHAR_BIT - 1;
count &= mask;
return (value << count) | (value >> (-count & mask));
}
-template<typename T, typename U> inline static T RotateRight(T val, U count) {
+template<typename T, typename U> inline static T rotateRight(T val, U count) {
auto value = typename std::make_unsigned<T>::type(val);
U mask = sizeof(T) * CHAR_BIT - 1;
count &= mask;
return (value >> count) | (value << (-count & mask));
}
-extern uint32_t Log2(uint32_t v);
-extern uint32_t Pow2(uint32_t v);
+uint32_t log2(uint32_t v);
+uint32_t pow2(uint32_t v);
+
+} // namespace Bits
} // namespace wasm
diff --git a/src/support/utilities.h b/src/support/utilities.h
index 5280fcb3b..38fe6fd73 100644
--- a/src/support/utilities.h
+++ b/src/support/utilities.h
@@ -44,7 +44,7 @@ inline Destination bit_cast(const Source& source) {
}
inline size_t alignAddr(size_t address, size_t alignment) {
- assert(alignment && IsPowerOf2((uint32_t)alignment) &&
+ assert(alignment && Bits::isPowerOf2((uint32_t)alignment) &&
"Alignment is not a power of two!");
assert(address + alignment - 1 >= address);
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index 54453b356..f42727aeb 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -472,30 +472,30 @@ std::ostream& operator<<(std::ostream& o, const ExceptionPackage& exn) {
Literal Literal::countLeadingZeroes() const {
if (type == Type::i32) {
- return Literal((int32_t)CountLeadingZeroes(i32));
+ return Literal((int32_t)Bits::countLeadingZeroes(i32));
}
if (type == Type::i64) {
- return Literal((int64_t)CountLeadingZeroes(i64));
+ return Literal((int64_t)Bits::countLeadingZeroes(i64));
}
WASM_UNREACHABLE("invalid type");
}
Literal Literal::countTrailingZeroes() const {
if (type == Type::i32) {
- return Literal((int32_t)CountTrailingZeroes(i32));
+ return Literal((int32_t)Bits::countTrailingZeroes(i32));
}
if (type == Type::i64) {
- return Literal((int64_t)CountTrailingZeroes(i64));
+ return Literal((int64_t)Bits::countTrailingZeroes(i64));
}
WASM_UNREACHABLE("invalid type");
}
Literal Literal::popCount() const {
if (type == Type::i32) {
- return Literal((int32_t)PopCount(i32));
+ return Literal((int32_t)Bits::popCount(i32));
}
if (type == Type::i64) {
- return Literal((int64_t)PopCount(i64));
+ return Literal((int64_t)Bits::popCount(i64));
}
WASM_UNREACHABLE("invalid type");
}
@@ -1149,9 +1149,9 @@ Literal Literal::shrU(const Literal& other) const {
Literal Literal::rotL(const Literal& other) const {
switch (type.getBasic()) {
case Type::i32:
- return Literal(RotateLeft(uint32_t(i32), uint32_t(other.i32)));
+ return Literal(Bits::rotateLeft(uint32_t(i32), uint32_t(other.i32)));
case Type::i64:
- return Literal(RotateLeft(uint64_t(i64), uint64_t(other.i64)));
+ return Literal(Bits::rotateLeft(uint64_t(i64), uint64_t(other.i64)));
default:
WASM_UNREACHABLE("unexpected type");
}
@@ -1160,9 +1160,9 @@ Literal Literal::rotL(const Literal& other) const {
Literal Literal::rotR(const Literal& other) const {
switch (type.getBasic()) {
case Type::i32:
- return Literal(RotateRight(uint32_t(i32), uint32_t(other.i32)));
+ return Literal(Bits::rotateRight(uint32_t(i32), uint32_t(other.i32)));
case Type::i64:
- return Literal(RotateRight(uint64_t(i64), uint64_t(other.i64)));
+ return Literal(Bits::rotateRight(uint64_t(i64), uint64_t(other.i64)));
default:
WASM_UNREACHABLE("unexpected type");
}
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 38a85bd1b..8ebddc8e8 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -3145,7 +3145,7 @@ void WasmBinaryBuilder::readMemoryAccess(Address& alignment, Address& offset) {
if (rawAlignment > 4) {
throwError("Alignment must be of a reasonable size");
}
- alignment = Pow2(rawAlignment);
+ alignment = Bits::pow2(rawAlignment);
offset = getU32LEB();
}
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 1ca8869c7..fcf9e4b8a 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1935,7 +1935,7 @@ void BinaryInstWriter::setScratchLocals() {
void BinaryInstWriter::emitMemoryAccess(size_t alignment,
size_t bytes,
uint32_t offset) {
- o << U32LEB(Log2(alignment ? alignment : bytes));
+ o << U32LEB(Bits::log2(alignment ? alignment : bytes));
o << U32LEB(offset);
}