From db51c2efa3a9c2da064db199792b3bf0de4e850f Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 28 Jul 2017 15:45:27 -0700 Subject: refactor effective shift size computation --- src/ast/bits.h | 11 +++++++++++ src/passes/OptimizeInstructions.cpp | 6 +++--- 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/ast/bits.h b/src/ast/bits.h index d88cb5edb..c7d2ea4f0 100644 --- a/src/ast/bits.h +++ b/src/ast/bits.h @@ -39,6 +39,17 @@ struct Bits { // this is indeed a mask return 32 - CountLeadingZeroes(mask); } + + // gets the number of effective shifts a shift operation does. In + // wasm, only 5 bits matter for 32-bit shifts, and 6 for 64. + static uint32_t getEffectiveShifts(Const* amount) { + if (amount->type == i32) { + return amount->value.geti32() & 31; + } else if (amount->type == i64) { + return amount->value.geti64() & 63; + } + WASM_UNREACHABLE(); + } }; } // namespace wasm diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 2a77b408a..263d4a96d 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -188,14 +188,14 @@ Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) { case OrInt32: case XorInt32: return std::max(getMaxBits(binary->left, localInfoProvider), getMaxBits(binary->right, localInfoProvider)); case ShlInt32: { if (auto* shifts = binary->right->dynCast()) { - return std::min(Index(32), getMaxBits(binary->left, localInfoProvider) + (shifts->value.geti32() & 31)); + return std::min(Index(32), getMaxBits(binary->left, localInfoProvider) + Bits::getEffectiveShifts(shifts)); } return 32; } case ShrUInt32: { if (auto* shift = binary->right->dynCast()) { auto maxBits = getMaxBits(binary->left, localInfoProvider); - auto shifts = std::min(Index(shift->value.geti32() & 31), maxBits); // can ignore more shifts than zero us out + auto shifts = std::min(Index(Bits::getEffectiveShifts(shift)), maxBits); // can ignore more shifts than zero us out return std::max(Index(0), maxBits - shifts); } return 32; @@ -204,7 +204,7 @@ Index getMaxBits(Expression* curr, LocalInfoProvider* localInfoProvider) { if (auto* shift = binary->right->dynCast()) { auto maxBits = getMaxBits(binary->left, localInfoProvider); if (maxBits == 32) return 32; - auto shifts = std::min(Index(shift->value.geti32() & 31), maxBits); // can ignore more shifts than zero us out + auto shifts = std::min(Index(Bits::getEffectiveShifts(shift)), maxBits); // can ignore more shifts than zero us out return std::max(Index(0), maxBits - shifts); } return 32; -- cgit v1.2.3