Chromium Code Reviews| Index: runtime/vm/intermediate_language.cc |
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc |
| index cd82381ad10efc47540cb02b80b763f66616d707..b62c460bfb09ef43c1679ce075d82a7cb745624e 100644 |
| --- a/runtime/vm/intermediate_language.cc |
| +++ b/runtime/vm/intermediate_language.cc |
| @@ -1380,6 +1380,129 @@ intptr_t BinaryDoubleOpInstr::ResultCid() const { |
| } |
| +static bool ToIntegerConstant(Value* value, intptr_t* result) { |
| + if (!value->BindsToConstant()) { |
| + return false; |
| + } |
| + |
| + const Object& constant = value->BoundConstant(); |
| + if (constant.IsDouble()) { |
| + const Double& double_constant = Double::Cast(constant); |
| + *result = static_cast<intptr_t>(double_constant.value()); |
| + return (static_cast<double>(*result) == double_constant.value()); |
| + } else if (constant.IsSmi()) { |
| + *result = Smi::Cast(constant).Value(); |
| + return true; |
| + } |
| + |
| + return false; |
| +} |
| + |
| + |
| +static Definition* CanonicalizeCommutativeArithmetic(Token::Kind op, |
| + intptr_t cid, |
| + Value* left, |
| + Value* right) { |
| + ASSERT((cid == kSmiCid) || (cid == kDoubleCid)); |
| + |
| + intptr_t value; |
|
Florian Schneider
2013/01/08 12:15:47
For better readability I'd rename this to left_val
|
| + if (!ToIntegerConstant(left, &value)) { |
| + return NULL; |
| + } |
| + |
| + switch (op) { |
| + case Token::kMUL: |
| + if (value == 1) { |
| + return right->definition(); |
| + } else if (value == 0) { |
| + return left->definition(); |
| + } |
| + break; |
| + case Token::kADD: |
| + if ((value == 0) && (cid == kSmiCid)) { |
| + // Can't apply this equivalence to double operations because |
| + // 0.0 + (-0.0) is 0.0 not -0.0. |
| + return right->definition(); |
| + } |
| + break; |
| + case Token::kBIT_AND: |
| + ASSERT(cid == kSmiCid); |
| + if (value == 0) { |
| + return left->definition(); |
| + } else if (value == -1) { |
| + return right->definition(); |
| + } |
| + break; |
| + case Token::kBIT_OR: |
| + ASSERT(cid == kSmiCid); |
| + if (value == 0) { |
| + return right->definition(); |
| + } else if (value == -1) { |
| + return left->definition(); |
| + } |
| + break; |
| + case Token::kBIT_XOR: |
| + ASSERT(cid == kSmiCid); |
| + if (value == 0) { |
| + return right->definition(); |
| + } |
| + break; |
| + default: |
| + break; |
| + } |
| + |
| + return NULL; |
| +} |
| + |
| + |
| +Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| + Definition* result = NULL; |
| + |
|
Florian Schneider
2013/01/08 12:15:47
Remove extra \n.
|
| + |
| + result = CanonicalizeCommutativeArithmetic(op_kind(), |
| + kDoubleCid, |
| + left(), |
| + right()); |
| + if (result != NULL) { |
| + return result; |
| + } |
| + |
| + result = CanonicalizeCommutativeArithmetic(op_kind(), |
| + kDoubleCid, |
| + right(), |
| + left()); |
| + if (result != NULL) { |
| + return result; |
| + } |
| + |
| + return this; |
| +} |
| + |
| + |
| +Definition* BinarySmiOpInstr::Canonicalize(FlowGraphOptimizer* optimizer) { |
| + Definition* result = NULL; |
| + |
|
Florian Schneider
2013/01/08 12:15:47
Remove extra \n.
|
| + |
| + result = CanonicalizeCommutativeArithmetic(op_kind(), |
| + kSmiCid, |
| + left(), |
| + right()); |
| + if (result != NULL) { |
| + return result; |
| + } |
| + |
| + result = CanonicalizeCommutativeArithmetic(op_kind(), |
| + kSmiCid, |
| + right(), |
| + left()); |
| + if (result != NULL) { |
| + return result; |
| + } |
| + |
| + return this; |
| +} |
| + |
| + |
| RawAbstractType* MathSqrtInstr::CompileType() const { |
| return Type::Double(); |
| } |