| Index: src/hydrogen-instructions.cc
|
| diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
|
| index 28511f714208f6fcc9eb84a4d1812723f09ba01b..997b7c2fda9b29455d03faac59c5a49a60d18d5c 100644
|
| --- a/src/hydrogen-instructions.cc
|
| +++ b/src/hydrogen-instructions.cc
|
| @@ -1155,6 +1155,29 @@ void HLoadFieldByIndex::PrintDataTo(StringStream* stream) {
|
| }
|
|
|
|
|
| +static bool MatchLeftIsOnes(HValue* l, HValue* r, HValue** negated) {
|
| + if (!l->EqualsInteger32Constant(~0)) return false;
|
| + *negated = r;
|
| + return true;
|
| +}
|
| +
|
| +
|
| +static bool MatchNegationViaXor(HValue* instr, HValue** negated) {
|
| + if (!instr->IsBitwise()) return false;
|
| + HBitwise* b = HBitwise::cast(instr);
|
| + return (b->op() == Token::BIT_XOR) &&
|
| + (MatchLeftIsOnes(b->left(), b->right(), negated) ||
|
| + MatchLeftIsOnes(b->right(), b->left(), negated));
|
| +}
|
| +
|
| +
|
| +static bool MatchDoubleNegation(HValue* instr, HValue** arg) {
|
| + HValue* negated;
|
| + return MatchNegationViaXor(instr, &negated) &&
|
| + MatchNegationViaXor(negated, arg);
|
| +}
|
| +
|
| +
|
| HValue* HBitwise::Canonicalize() {
|
| if (!representation().IsSmiOrInteger32()) return this;
|
| // If x is an int32, then x & -1 == x, x | 0 == x and x ^ 0 == x.
|
| @@ -1167,18 +1190,10 @@ HValue* HBitwise::Canonicalize() {
|
| !left()->CheckFlag(kUint32)) {
|
| return left();
|
| }
|
| - return this;
|
| -}
|
| -
|
| -
|
| -HValue* HBitNot::Canonicalize() {
|
| - // Optimize ~~x, a common pattern used for ToInt32(x).
|
| - if (value()->IsBitNot()) {
|
| - HValue* result = HBitNot::cast(value())->value();
|
| - ASSERT(result->representation().IsInteger32());
|
| - if (!result->CheckFlag(kUint32)) {
|
| - return result;
|
| - }
|
| + // Optimize double negation, a common pattern used for ToInt32(x).
|
| + HValue* arg;
|
| + if (MatchDoubleNegation(this, &arg) && !arg->CheckFlag(kUint32)) {
|
| + return arg;
|
| }
|
| return this;
|
| }
|
|
|