diff options
author | Alon Zakai <azakai@google.com> | 2022-09-13 09:32:51 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-13 16:32:51 +0000 |
commit | 6a4fafe4fe9468acb6ee959804b5753fa1d63d7c (patch) | |
tree | 7bcb6215646ac91b87075c2fcfce51df08062e35 | |
parent | 59fbd50fdee6fd10886163ee4a02008cea61311f (diff) | |
download | binaryen-6a4fafe4fe9468acb6ee959804b5753fa1d63d7c.tar.gz binaryen-6a4fafe4fe9468acb6ee959804b5753fa1d63d7c.tar.bz2 binaryen-6a4fafe4fe9468acb6ee959804b5753fa1d63d7c.zip |
Move relational-optimizing code to optimizeRelational [NFC] (#5036)
This just moves the code from #5025 to the right function, which I did not
realize existed. optimizeRelational is where we optimize binary operations
that do comparisons, and it's nice to put all that code together. Avoids repeated
checks of isRelational() in separate places.
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index 9b207d6e7..286bfd2b6 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -3570,36 +3570,6 @@ private: return left; } } - // x + C1 > C2 ==> x > (C2-C1) if no overflowing, C2 >= C1 - // x + C1 > C2 ==> x + (C1-C2) > 0 if no overflowing, C2 < C1 - // And similarly for other relational operations on integers. - if (curr->isRelational()) { - Binary* add; - Const* c1; - Const* c2; - if ((matches(curr, - binary(binary(&add, Add, any(), ival(&c1)), ival(&c2))) || - matches(curr, - binary(binary(&add, Add, any(), ival(&c1)), ival(&c2)))) && - !canOverflow(add)) { - if (c2->value.geU(c1->value).getInteger()) { - // This is the first line above, we turn into x > (C2-C1) - c2->value = c2->value.sub(c1->value); - curr->left = add->left; - return curr; - } - // This is the second line above, we turn into x + (C1-C2) > 0. Other - // optimizations can often kick in later. However, we must rule out the - // case where C2 is already 0 (as then we would not actually change - // anything, and we could infinite loop). - auto zero = Literal::makeZero(c2->type); - if (c2->value != zero) { - c1->value = c1->value.sub(c2->value); - c2->value = zero; - return curr; - } - } - } { // x != NaN ==> 1 // x <=> NaN ==> 0 @@ -3902,6 +3872,9 @@ private: // TODO: templatize on type? Expression* optimizeRelational(Binary* curr) { + using namespace Abstract; + using namespace Match; + auto type = curr->right->type; if (curr->left->type.isInteger()) { if (curr->op == Abstract::getBinary(type, Abstract::Eq) || @@ -3935,9 +3908,6 @@ private: // unsigned(x - y) > 0 => x != y // unsigned(x - y) <= 0 => x == y { - using namespace Abstract; - using namespace Match; - Binary* inner; // unsigned(x - y) > 0 => x != y if (matches(curr, @@ -3969,6 +3939,38 @@ private: } } + // x + C1 > C2 ==> x > (C2-C1) if no overflowing, C2 >= C1 + // x + C1 > C2 ==> x + (C1-C2) > 0 if no overflowing, C2 < C1 + // And similarly for other relational operations on integers with a "+" + // on the left. + { + Binary* add; + Const* c1; + Const* c2; + if ((matches(curr, + binary(binary(&add, Add, any(), ival(&c1)), ival(&c2))) || + matches(curr, + binary(binary(&add, Add, any(), ival(&c1)), ival(&c2)))) && + !canOverflow(add)) { + if (c2->value.geU(c1->value).getInteger()) { + // This is the first line above, we turn into x > (C2-C1) + c2->value = c2->value.sub(c1->value); + curr->left = add->left; + return curr; + } + // This is the second line above, we turn into x + (C1-C2) > 0. Other + // optimizations can often kick in later. However, we must rule out + // the case where C2 is already 0 (as then we would not actually + // change anything, and we could infinite loop). + auto zero = Literal::makeZero(c2->type); + if (c2->value != zero) { + c1->value = c1->value.sub(c2->value); + c2->value = zero; + return curr; + } + } + } + // Comparisons can sometimes be simplified depending on the number of // bits, e.g. (unsigned)x > y must be true if x has strictly more bits. // A common case is a constant on the right, e.g. (x & 255) < 256 must be |