diff options
author | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-07-31 14:11:33 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2017-08-01 10:10:36 -0700 |
commit | 04418d5617f6ab7015c5cf7b905b4775a5219f4b (patch) | |
tree | 3b6b75b982702f7cabc777ae7fcc3f1a8dec2392 | |
parent | 5a07a930ad51003411b2bc827ea9bf08728ecc5a (diff) | |
download | binaryen-04418d5617f6ab7015c5cf7b905b4775a5219f4b.tar.gz binaryen-04418d5617f6ab7015c5cf7b905b4775a5219f4b.tar.bz2 binaryen-04418d5617f6ab7015c5cf7b905b4775a5219f4b.zip |
use effective shifts in more places in optimize-instructions
-rw-r--r-- | src/ast/bits.h | 3 | ||||
-rw-r--r-- | src/ast/properties.h | 8 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 4 | ||||
-rw-r--r-- | test/passes/optimize-instructions.txt | 15 | ||||
-rw-r--r-- | test/passes/optimize-instructions.wast | 30 |
5 files changed, 53 insertions, 7 deletions
diff --git a/src/ast/bits.h b/src/ast/bits.h index 11cf7b06d..0aee50ffe 100644 --- a/src/ast/bits.h +++ b/src/ast/bits.h @@ -51,7 +51,8 @@ struct Bits { WASM_UNREACHABLE(); } - static Index getEffectiveShifts(Const* amount) { + static Index getEffectiveShifts(Expression* expr) { + auto* amount = expr->cast<Const>(); if (amount->type == i32) { return getEffectiveShifts(amount->value.geti32(), i32); } else if (amount->type == i64) { diff --git a/src/ast/properties.h b/src/ast/properties.h index 097f7a8f0..8c8655c07 100644 --- a/src/ast/properties.h +++ b/src/ast/properties.h @@ -79,7 +79,7 @@ struct Properties { // gets the size of the sign-extended value static Index getSignExtBits(Expression* curr) { - return 32 - curr->cast<Binary>()->right->cast<Const>()->value.geti32(); + return 32 - Bits::getEffectiveShifts(curr->cast<Binary>()->right); } // Check if an expression is almost a sign-extend: perhaps the inner shift @@ -93,7 +93,7 @@ struct Properties { if (auto* inner = outer->left->dynCast<Binary>()) { if (inner->op == ShlInt32) { if (auto* innerConst = inner->right->dynCast<Const>()) { - if (outerConst->value.leU(innerConst->value).geti32()) { + if (Bits::getEffectiveShifts(outerConst) <= Bits::getEffectiveShifts(innerConst)) { return inner->left; } } @@ -109,8 +109,8 @@ struct Properties { // gets the size of the almost sign-extended value, as well as the // extra shifts, if any static Index getAlmostSignExtBits(Expression* curr, Index& extraShifts) { - extraShifts = curr->cast<Binary>()->left->cast<Binary>()->right->cast<Const>()->value.geti32() - - curr->cast<Binary>()->right->cast<Const>()->value.geti32(); + extraShifts = Bits::getEffectiveShifts(curr->cast<Binary>()->left->cast<Binary>()->right) - + Bits::getEffectiveShifts(curr->cast<Binary>()->right); return getSignExtBits(curr); } diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 4fd7cbe8d..578a01f11 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -779,7 +779,7 @@ private: return; } else if (binary->op == ShlInt32) { if (auto* c = binary->right->dynCast<Const>()) { - seek(binary->left, mul * Pow2(c->value.geti32())); + seek(binary->left, mul * Pow2(Bits::getEffectiveShifts(c))); return; } } else if (binary->op == MulInt32) { @@ -836,7 +836,7 @@ private: } } else if (curr->op == ShlInt32) { // shifting a 0 is a 0, unless the shift has side effects - if (left && left->value.geti32() == 0 && !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) { + if (left && Bits::getEffectiveShifts(left) == 0 && !EffectAnalyzer(passOptions, curr->right).hasSideEffects()) { replaceCurrent(left); return; } diff --git a/test/passes/optimize-instructions.txt b/test/passes/optimize-instructions.txt index a399a9096..2e46379fb 100644 --- a/test/passes/optimize-instructions.txt +++ b/test/passes/optimize-instructions.txt @@ -2061,4 +2061,19 @@ (i32.const 9) ) ) + (func $mix-shifts (type $2) (result i32) + (i32.shr_s + (i32.shl + (i32.const 23) + (i32.const -61) + ) + (i32.const 168) + ) + ) + (func $actually-no-shifts (type $2) (result i32) + (i32.const 33) + ) + (func $less-shifts-than-it-seems (type $3) (param $x i32) (result i32) + (i32.const 4800) + ) ) diff --git a/test/passes/optimize-instructions.wast b/test/passes/optimize-instructions.wast index 8362453e9..517c74ea6 100644 --- a/test/passes/optimize-instructions.wast +++ b/test/passes/optimize-instructions.wast @@ -2496,4 +2496,34 @@ (i32.const 4098) ;; 2 bits effectively ) ) + (func $mix-shifts (result i32) + (i32.shr_s + (i32.shl + (i32.const 23) + (i32.const -61) + ) + (i32.const 168) + ) + ) + (func $actually-no-shifts (result i32) + (i32.add + (i32.shl + (i32.const 23) + (i32.const 32) ;; really 0 + ) + (i32.const 10) + ) + ) + (func $less-shifts-than-it-seems (param $x i32) (result i32) + (i32.add + (i32.shl + (i32.const 200) + (i32.const 36) ;; really 4 + ) + (i32.shl + (i32.const 100) + (i32.const 4) + ) + ) + ) ) |