diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-04-11 18:46:48 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-11 18:46:48 -0700 |
commit | a9d59bd033e98d6399a7efab81a57aafcf241be3 (patch) | |
tree | ea52e4acc7439caf5fd49b0ab27018792146d807 /src | |
parent | 61388bbd1fe6ef472e656298483efa2d81cd9ed3 (diff) | |
download | binaryen-a9d59bd033e98d6399a7efab81a57aafcf241be3.tar.gz binaryen-a9d59bd033e98d6399a7efab81a57aafcf241be3.tar.bz2 binaryen-a9d59bd033e98d6399a7efab81a57aafcf241be3.zip |
More math opts (#1507)
`xor` of 0, `and` and `or` of -1
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 3e7c15720..293adcbde 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1120,7 +1120,8 @@ private: if (binary->op == Abstract::getBinary(type, Abstract::Shl) || binary->op == Abstract::getBinary(type, Abstract::ShrU) || binary->op == Abstract::getBinary(type, Abstract::ShrS) || - binary->op == Abstract::getBinary(type, Abstract::Or)) { + binary->op == Abstract::getBinary(type, Abstract::Or) || + binary->op == Abstract::getBinary(type, Abstract::Xor)) { return binary->left; } else if ((binary->op == Abstract::getBinary(type, Abstract::Mul) || binary->op == Abstract::getBinary(type, Abstract::And)) && @@ -1128,9 +1129,23 @@ private: return binary->right; } } + // operations on all 1s + // TODO: shortcut method to create an all-ones? + if (right->value == Literal(int32_t(-1)) || + right->value == Literal(int64_t(-1))) { + if (binary->op == Abstract::getBinary(type, Abstract::And)) { + return binary->left; + } else if (binary->op == Abstract::getBinary(type, Abstract::Or) && + !EffectAnalyzer(getPassOptions(), binary->left).hasSideEffects()) { + return binary->right; + } + } // wasm binary encoding uses signed LEBs, which slightly favor negative - // numbers: -64 is more efficient than +64 etc. we therefore prefer - // x - -64 over x + 64 + // numbers: -64 is more efficient than +64 etc., as well as other powers + // of two 7 bits etc. higher. we therefore prefer x - -64 over x + 64. + // in theory we could just prefer negative numbers over positive, but + // that can have bad effects on gzip compression (as it would mean more + // subtractions than the more common additions). if (binary->op == Abstract::getBinary(type, Abstract::Add) || binary->op == Abstract::getBinary(type, Abstract::Sub)) { auto value = right->value.getInteger(); @@ -1149,6 +1164,7 @@ private: } else { binary->op = Abstract::getBinary(type, Abstract::Add); } + return binary; } } } @@ -1240,6 +1256,7 @@ private: // given a binary expression with equal children and no side effects in either, // we can fold various things + // TODO: trinaries, things like (x & (y & x)) ? Expression* optimizeBinaryWithEqualEffectlessChildren(Binary* binary) { // TODO add: perhaps worth doing 2*x if x is quite large? switch (binary->op) { |