| Index: runtime/vm/intermediate_language.cc
|
| diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
|
| index db190ac6b704eb8c6fcd343bc0af6e16e417591e..6cdb0542bb492d5870fb4b9e286e4bc770a35f7c 100644
|
| --- a/runtime/vm/intermediate_language.cc
|
| +++ b/runtime/vm/intermediate_language.cc
|
| @@ -1757,14 +1757,30 @@ Definition* CheckedSmiOpInstr::Canonicalize(FlowGraph* flow_graph) {
|
| default:
|
| break;
|
| }
|
| - if (Token::IsRelationalOperator(op_kind())) {
|
| - replacement = new RelationalOpInstr(token_pos(), op_kind(),
|
| + }
|
| + return this;
|
| +}
|
| +
|
| +
|
| +ComparisonInstr* CheckedSmiComparisonInstr::CopyWithNewOperands(
|
| + Value* left, Value* right) {
|
| + UNREACHABLE();
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +Definition* CheckedSmiComparisonInstr::Canonicalize(FlowGraph* flow_graph) {
|
| + if ((left()->Type()->ToCid() == kSmiCid) &&
|
| + (right()->Type()->ToCid() == kSmiCid)) {
|
| + Definition* replacement = NULL;
|
| + if (Token::IsRelationalOperator(kind())) {
|
| + replacement = new RelationalOpInstr(token_pos(), kind(),
|
| new Value(left()->definition()),
|
| new Value(right()->definition()),
|
| kSmiCid,
|
| Thread::kNoDeoptId);
|
| - } else if (Token::IsEqualityOperator(op_kind())) {
|
| - replacement = new EqualityCompareInstr(token_pos(), op_kind(),
|
| + } else if (Token::IsEqualityOperator(kind())) {
|
| + replacement = new EqualityCompareInstr(token_pos(), kind(),
|
| new Value(left()->definition()),
|
| new Value(right()->definition()),
|
| kSmiCid,
|
| @@ -2356,9 +2372,9 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
|
|
|
| Definition* BooleanNegateInstr::Canonicalize(FlowGraph* flow_graph) {
|
| Definition* defn = value()->definition();
|
| - if (defn->IsComparison() && defn->HasOnlyUse(value())) {
|
| - // Comparisons always have a bool result.
|
| - ASSERT(value()->definition()->Type()->ToCid() == kBoolCid);
|
| + if (defn->IsComparison() &&
|
| + defn->HasOnlyUse(value()) &&
|
| + defn->Type()->ToCid() == kBoolCid) {
|
| defn->AsComparison()->NegateComparison();
|
| return defn;
|
| }
|
| @@ -2387,7 +2403,8 @@ static bool MaybeNumber(CompileType* type) {
|
| // Returns a replacement for a strict comparison and signals if the result has
|
| // to be negated.
|
| static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
|
| - bool* negated) {
|
| + bool* negated,
|
| + bool is_branch) {
|
| // Use propagated cid and type information to eliminate number checks.
|
| // If one of the inputs is not a boxable number (Mint, Double, Bigint), or
|
| // is not a subtype of num, no need for number checks.
|
| @@ -2400,7 +2417,6 @@ static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
|
| compare->set_needs_number_check(false);
|
| }
|
| }
|
| -
|
| *negated = false;
|
| PassiveObject& constant = PassiveObject::Handle();
|
| Value* other = NULL;
|
| @@ -2414,25 +2430,26 @@ static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
|
| return compare;
|
| }
|
|
|
| + const bool can_merge = is_branch || (other->Type()->ToCid() == kBoolCid);
|
| Definition* other_defn = other->definition();
|
| Token::Kind kind = compare->kind();
|
| // Handle e === true.
|
| if ((kind == Token::kEQ_STRICT) &&
|
| (constant.raw() == Bool::True().raw()) &&
|
| - (other->Type()->ToCid() == kBoolCid)) {
|
| + can_merge) {
|
| return other_defn;
|
| }
|
| // Handle e !== false.
|
| if ((kind == Token::kNE_STRICT) &&
|
| (constant.raw() == Bool::False().raw()) &&
|
| - (other->Type()->ToCid() == kBoolCid)) {
|
| + can_merge) {
|
| return other_defn;
|
| }
|
| // Handle e !== true.
|
| if ((kind == Token::kNE_STRICT) &&
|
| (constant.raw() == Bool::True().raw()) &&
|
| other_defn->IsComparison() &&
|
| - (other->Type()->ToCid() == kBoolCid) &&
|
| + can_merge &&
|
| other_defn->HasOnlyUse(other)) {
|
| *negated = true;
|
| return other_defn;
|
| @@ -2441,7 +2458,7 @@ static Definition* CanonicalizeStrictCompare(StrictCompareInstr* compare,
|
| if ((kind == Token::kEQ_STRICT) &&
|
| (constant.raw() == Bool::False().raw()) &&
|
| other_defn->IsComparison() &&
|
| - (other->Type()->ToCid() == kBoolCid) &&
|
| + can_merge &&
|
| other_defn->HasOnlyUse(other)) {
|
| *negated = true;
|
| return other_defn;
|
| @@ -2501,7 +2518,8 @@ Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) {
|
| if (comparison()->IsStrictCompare()) {
|
| bool negated = false;
|
| Definition* replacement =
|
| - CanonicalizeStrictCompare(comparison()->AsStrictCompare(), &negated);
|
| + CanonicalizeStrictCompare(comparison()->AsStrictCompare(),
|
| + &negated, /* is_branch = */ true);
|
| if (replacement == comparison()) {
|
| return this;
|
| }
|
| @@ -2573,7 +2591,8 @@ Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) {
|
| Definition* StrictCompareInstr::Canonicalize(FlowGraph* flow_graph) {
|
| if (!HasUses()) return NULL;
|
| bool negated = false;
|
| - Definition* replacement = CanonicalizeStrictCompare(this, &negated);
|
| + Definition* replacement = CanonicalizeStrictCompare(this, &negated,
|
| + /* is_branch = */ false);
|
| if (negated && replacement->IsComparison()) {
|
| ASSERT(replacement != this);
|
| replacement->AsComparison()->NegateComparison();
|
|
|