| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/js-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compilation-dependencies.h" | 8 #include "src/compilation-dependencies.h" |
| 9 #include "src/compiler/access-builder.h" | 9 #include "src/compiler/access-builder.h" |
| 10 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 bool GetCompareNumberOperationHint(NumberOperationHint* hint) { | 56 bool GetCompareNumberOperationHint(NumberOperationHint* hint) { |
| 57 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { | 57 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { |
| 58 DCHECK_NE(0, node_->op()->ControlOutputCount()); | 58 DCHECK_NE(0, node_->op()->ControlOutputCount()); |
| 59 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 59 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
| 60 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); | 60 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); |
| 61 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); | 61 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); |
| 62 switch (hints.combined()) { | 62 switch (hints.combined()) { |
| 63 case CompareOperationHints::kSignedSmall: | 63 case CompareOperationHints::kSignedSmall: |
| 64 *hint = NumberOperationHint::kSignedSmall; | 64 *hint = NumberOperationHint::kSignedSmall; |
| 65 return true; | 65 return true; |
| 66 case CompareOperationHints::kNumber: |
| 67 *hint = NumberOperationHint::kNumber; |
| 68 return true; |
| 66 case CompareOperationHints::kNumberOrOddball: | 69 case CompareOperationHints::kNumberOrOddball: |
| 67 *hint = NumberOperationHint::kNumberOrOddball; | 70 *hint = NumberOperationHint::kNumberOrOddball; |
| 68 return true; | 71 return true; |
| 69 case CompareOperationHints::kAny: | 72 case CompareOperationHints::kAny: |
| 70 case CompareOperationHints::kNone: | 73 case CompareOperationHints::kNone: |
| 71 case CompareOperationHints::kString: | 74 case CompareOperationHints::kString: |
| 72 case CompareOperationHints::kBoolean: | 75 case CompareOperationHints::kBoolean: |
| 73 case CompareOperationHints::kUniqueName: | 76 case CompareOperationHints::kUniqueName: |
| 74 case CompareOperationHints::kInternalizedString: | 77 case CompareOperationHints::kInternalizedString: |
| 75 case CompareOperationHints::kReceiver: | 78 case CompareOperationHints::kReceiver: |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 // Insert an boolean not to invert the value. | 155 // Insert an boolean not to invert the value. |
| 153 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); | 156 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); |
| 154 node_->ReplaceUses(value); | 157 node_->ReplaceUses(value); |
| 155 // Note: ReplaceUses() smashes all uses, so smash it back here. | 158 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 156 value->ReplaceInput(0, node_); | 159 value->ReplaceInput(0, node_); |
| 157 return lowering_->Replace(value); | 160 return lowering_->Replace(value); |
| 158 } | 161 } |
| 159 return lowering_->Changed(node_); | 162 return lowering_->Changed(node_); |
| 160 } | 163 } |
| 161 | 164 |
| 162 Reduction ChangeToSpeculativeOperator(const Operator* op, Type* upper_bound) { | 165 Reduction ChangeToSpeculativeOperator(const Operator* op, bool invert, |
| 166 Type* upper_bound) { |
| 163 DCHECK_EQ(1, op->EffectInputCount()); | 167 DCHECK_EQ(1, op->EffectInputCount()); |
| 164 DCHECK_EQ(1, op->EffectOutputCount()); | 168 DCHECK_EQ(1, op->EffectOutputCount()); |
| 165 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); | 169 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); |
| 166 DCHECK_EQ(1, op->ControlInputCount()); | 170 DCHECK_EQ(1, op->ControlInputCount()); |
| 167 DCHECK_EQ(0, op->ControlOutputCount()); | 171 DCHECK_EQ(0, op->ControlOutputCount()); |
| 168 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); | 172 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); |
| 169 DCHECK_EQ(2, op->ValueInputCount()); | 173 DCHECK_EQ(2, op->ValueInputCount()); |
| 170 | 174 |
| 171 DCHECK_EQ(1, node_->op()->EffectInputCount()); | 175 DCHECK_EQ(1, node_->op()->EffectInputCount()); |
| 172 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 176 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 195 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); | 199 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); |
| 196 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); | 200 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); |
| 197 | 201 |
| 198 NodeProperties::ChangeOp(node_, op); | 202 NodeProperties::ChangeOp(node_, op); |
| 199 | 203 |
| 200 // Update the type to number. | 204 // Update the type to number. |
| 201 Type* node_type = NodeProperties::GetType(node_); | 205 Type* node_type = NodeProperties::GetType(node_); |
| 202 NodeProperties::SetType(node_, | 206 NodeProperties::SetType(node_, |
| 203 Type::Intersect(node_type, upper_bound, zone())); | 207 Type::Intersect(node_type, upper_bound, zone())); |
| 204 | 208 |
| 209 if (invert) { |
| 210 // Insert an boolean not to invert the value. |
| 211 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); |
| 212 node_->ReplaceUses(value); |
| 213 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 214 value->ReplaceInput(0, node_); |
| 215 return lowering_->Replace(value); |
| 216 } |
| 205 return lowering_->Changed(node_); | 217 return lowering_->Changed(node_); |
| 206 } | 218 } |
| 207 | 219 |
| 208 Reduction ChangeToPureOperator(const Operator* op, Type* type) { | 220 Reduction ChangeToPureOperator(const Operator* op, Type* type) { |
| 209 return ChangeToPureOperator(op, false, type); | 221 return ChangeToPureOperator(op, false, type); |
| 210 } | 222 } |
| 211 | 223 |
| 224 Reduction ChangeToSpeculativeOperator(const Operator* op, Type* type) { |
| 225 return ChangeToSpeculativeOperator(op, false, type); |
| 226 } |
| 227 |
| 212 bool LeftInputIs(Type* t) { return left_type()->Is(t); } | 228 bool LeftInputIs(Type* t) { return left_type()->Is(t); } |
| 213 | 229 |
| 214 bool RightInputIs(Type* t) { return right_type()->Is(t); } | 230 bool RightInputIs(Type* t) { return right_type()->Is(t); } |
| 215 | 231 |
| 216 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } | 232 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } |
| 217 | 233 |
| 218 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } | 234 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } |
| 219 | 235 |
| 220 bool OneInputCannotBe(Type* t) { | 236 bool OneInputCannotBe(Type* t) { |
| 221 return !left_type()->Maybe(t) || !right_type()->Maybe(t); | 237 return !left_type()->Maybe(t) || !right_type()->Maybe(t); |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 | 701 |
| 686 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { | 702 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { |
| 687 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); | 703 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); |
| 688 if (reduction.Changed()) { | 704 if (reduction.Changed()) { |
| 689 ReplaceWithValue(node, reduction.replacement()); | 705 ReplaceWithValue(node, reduction.replacement()); |
| 690 return reduction; | 706 return reduction; |
| 691 } | 707 } |
| 692 | 708 |
| 693 JSBinopReduction r(this, node); | 709 JSBinopReduction r(this, node); |
| 694 | 710 |
| 695 if (r.BothInputsAre(Type::Number())) { | |
| 696 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | |
| 697 } | |
| 698 if (r.BothInputsAre(Type::String())) { | 711 if (r.BothInputsAre(Type::String())) { |
| 699 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); | 712 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
| 700 } | 713 } |
| 701 if (r.BothInputsAre(Type::Boolean())) { | 714 if (r.BothInputsAre(Type::Boolean())) { |
| 702 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), | 715 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), |
| 703 invert); | 716 invert); |
| 704 } | 717 } |
| 705 if (r.BothInputsAre(Type::Receiver())) { | 718 if (r.BothInputsAre(Type::Receiver())) { |
| 706 return r.ChangeToPureOperator( | 719 return r.ChangeToPureOperator( |
| 707 simplified()->ReferenceEqual(Type::Receiver()), invert); | 720 simplified()->ReferenceEqual(Type::Receiver()), invert); |
| 708 } | 721 } |
| 709 if (r.OneInputIs(Type::Undetectable())) { | 722 if (r.OneInputIs(Type::Undetectable())) { |
| 710 RelaxEffectsAndControls(node); | 723 RelaxEffectsAndControls(node); |
| 711 node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); | 724 node->RemoveInput(r.LeftInputIs(Type::Undetectable()) ? 0 : 1); |
| 712 node->TrimInputCount(1); | 725 node->TrimInputCount(1); |
| 713 NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); | 726 NodeProperties::ChangeOp(node, simplified()->ObjectIsUndetectable()); |
| 714 if (invert) { | 727 if (invert) { |
| 715 // Insert an boolean not to invert the value. | 728 // Insert an boolean not to invert the value. |
| 716 Node* value = graph()->NewNode(simplified()->BooleanNot(), node); | 729 Node* value = graph()->NewNode(simplified()->BooleanNot(), node); |
| 717 node->ReplaceUses(value); | 730 node->ReplaceUses(value); |
| 718 // Note: ReplaceUses() smashes all uses, so smash it back here. | 731 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 719 value->ReplaceInput(0, node); | 732 value->ReplaceInput(0, node); |
| 720 return Replace(value); | 733 return Replace(value); |
| 721 } | 734 } |
| 722 return Changed(node); | 735 return Changed(node); |
| 723 } | 736 } |
| 737 |
| 738 NumberOperationHint hint; |
| 739 if (r.BothInputsAre(Type::Signed32()) || |
| 740 r.BothInputsAre(Type::Unsigned32())) { |
| 741 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
| 742 } else if (r.GetCompareNumberOperationHint(&hint)) { |
| 743 return r.ChangeToSpeculativeOperator( |
| 744 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); |
| 745 } else if (r.BothInputsAre(Type::Number())) { |
| 746 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
| 747 } |
| 724 return NoChange(); | 748 return NoChange(); |
| 725 } | 749 } |
| 726 | 750 |
| 727 | 751 |
| 728 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 752 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { |
| 729 JSBinopReduction r(this, node); | 753 JSBinopReduction r(this, node); |
| 730 if (r.left() == r.right()) { | 754 if (r.left() == r.right()) { |
| 731 // x === x is always true if x != NaN | 755 // x === x is always true if x != NaN |
| 732 if (!r.left_type()->Maybe(Type::NaN())) { | 756 if (!r.left_type()->Maybe(Type::NaN())) { |
| 733 Node* replacement = jsgraph()->BooleanConstant(!invert); | 757 Node* replacement = jsgraph()->BooleanConstant(!invert); |
| (...skipping 1365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2099 } | 2123 } |
| 2100 | 2124 |
| 2101 | 2125 |
| 2102 CompilationDependencies* JSTypedLowering::dependencies() const { | 2126 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2103 return dependencies_; | 2127 return dependencies_; |
| 2104 } | 2128 } |
| 2105 | 2129 |
| 2106 } // namespace compiler | 2130 } // namespace compiler |
| 2107 } // namespace internal | 2131 } // namespace internal |
| 2108 } // namespace v8 | 2132 } // namespace v8 |
| OLD | NEW |