Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(309)

Side by Side Diff: src/compiler/js-typed-lowering.cc

Issue 2222993003: [turbofan] Consume number type hints for strict equality. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-operator.cc ('k') | test/unittests/compiler/js-typed-lowering-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 case BinaryOperationHints::kNone: 48 case BinaryOperationHints::kNone:
49 case BinaryOperationHints::kString: 49 case BinaryOperationHints::kString:
50 break; 50 break;
51 } 51 }
52 } 52 }
53 return false; 53 return false;
54 } 54 }
55 55
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());
59 DCHECK_EQ(1, node_->op()->EffectOutputCount()); 58 DCHECK_EQ(1, node_->op()->EffectOutputCount());
60 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
61 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); 59 CompareOperationHints hints = CompareOperationHintsOf(node_->op());
62 switch (hints.combined()) { 60 switch (hints.combined()) {
63 case CompareOperationHints::kSignedSmall: 61 case CompareOperationHints::kSignedSmall:
64 *hint = NumberOperationHint::kSignedSmall; 62 *hint = NumberOperationHint::kSignedSmall;
65 return true; 63 return true;
66 case CompareOperationHints::kNumber: 64 case CompareOperationHints::kNumber:
67 *hint = NumberOperationHint::kNumber; 65 *hint = NumberOperationHint::kNumber;
68 return true; 66 return true;
69 case CompareOperationHints::kNumberOrOddball: 67 case CompareOperationHints::kNumberOrOddball:
70 *hint = NumberOperationHint::kNumberOrOddball; 68 *hint = NumberOperationHint::kNumberOrOddball;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 DCHECK_EQ(1, op->EffectOutputCount()); 166 DCHECK_EQ(1, op->EffectOutputCount());
169 DCHECK_EQ(false, OperatorProperties::HasContextInput(op)); 167 DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
170 DCHECK_EQ(1, op->ControlInputCount()); 168 DCHECK_EQ(1, op->ControlInputCount());
171 DCHECK_EQ(0, op->ControlOutputCount()); 169 DCHECK_EQ(0, op->ControlOutputCount());
172 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op)); 170 DCHECK_EQ(0, OperatorProperties::GetFrameStateInputCount(op));
173 DCHECK_EQ(2, op->ValueInputCount()); 171 DCHECK_EQ(2, op->ValueInputCount());
174 172
175 DCHECK_EQ(1, node_->op()->EffectInputCount()); 173 DCHECK_EQ(1, node_->op()->EffectInputCount());
176 DCHECK_EQ(1, node_->op()->EffectOutputCount()); 174 DCHECK_EQ(1, node_->op()->EffectOutputCount());
177 DCHECK_EQ(1, node_->op()->ControlInputCount()); 175 DCHECK_EQ(1, node_->op()->ControlInputCount());
178 DCHECK_LT(1, node_->op()->ControlOutputCount());
179 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op()));
180 DCHECK_EQ(2, node_->op()->ValueInputCount()); 176 DCHECK_EQ(2, node_->op()->ValueInputCount());
181 177
182 // Reconnect the control output to bypass the IfSuccess node and 178 // Reconnect the control output to bypass the IfSuccess node and
183 // possibly disconnect from the IfException node. 179 // possibly disconnect from the IfException node.
184 for (Edge edge : node_->use_edges()) { 180 for (Edge edge : node_->use_edges()) {
185 Node* const user = edge.from(); 181 Node* const user = edge.from();
186 DCHECK(!user->IsDead()); 182 DCHECK(!user->IsDead());
187 if (NodeProperties::IsControlEdge(edge)) { 183 if (NodeProperties::IsControlEdge(edge)) {
188 if (user->opcode() == IrOpcode::kIfSuccess) { 184 if (user->opcode() == IrOpcode::kIfSuccess) {
189 user->ReplaceUses(NodeProperties::GetControlInput(node_)); 185 user->ReplaceUses(NodeProperties::GetControlInput(node_));
190 user->Kill(); 186 user->Kill();
191 } else { 187 } else {
192 DCHECK_EQ(user->opcode(), IrOpcode::kIfException); 188 DCHECK_EQ(user->opcode(), IrOpcode::kIfException);
193 edge.UpdateTo(jsgraph()->Dead()); 189 edge.UpdateTo(jsgraph()->Dead());
194 } 190 }
195 } 191 }
196 } 192 }
197 193
198 // Remove the frame state and the context. 194 // Remove the frame state and the context.
199 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_)); 195 if (OperatorProperties::HasFrameStateInput(node_->op())) {
196 node_->RemoveInput(NodeProperties::FirstFrameStateIndex(node_));
197 }
200 node_->RemoveInput(NodeProperties::FirstContextIndex(node_)); 198 node_->RemoveInput(NodeProperties::FirstContextIndex(node_));
201 199
202 NodeProperties::ChangeOp(node_, op); 200 NodeProperties::ChangeOp(node_, op);
203 201
204 // Update the type to number. 202 // Update the type to number.
205 Type* node_type = NodeProperties::GetType(node_); 203 Type* node_type = NodeProperties::GetType(node_);
206 NodeProperties::SetType(node_, 204 NodeProperties::SetType(node_,
207 Type::Intersect(node_type, upper_bound, zone())); 205 Type::Intersect(node_type, upper_bound, zone()));
208 206
209 if (invert) { 207 if (invert) {
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input, 685 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), input,
688 jsgraph()->NullConstant()), 686 jsgraph()->NullConstant()),
689 jsgraph()->FalseConstant(), 687 jsgraph()->FalseConstant(),
690 graph()->NewNode(simplified()->ObjectIsUndetectable(), input)); 688 graph()->NewNode(simplified()->ObjectIsUndetectable(), input));
691 } else { 689 } else {
692 return NoChange(); 690 return NoChange();
693 } 691 }
694 if (invert) { 692 if (invert) {
695 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement); 693 replacement = graph()->NewNode(simplified()->BooleanNot(), replacement);
696 } 694 }
695 ReplaceWithValue(node, replacement);
697 return Replace(replacement); 696 return Replace(replacement);
698 } 697 }
699 return NoChange(); 698 return NoChange();
700 } 699 }
701 700
702 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { 701 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) {
703 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 702 Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
704 if (reduction.Changed()) { 703 if (reduction.Changed()) return reduction;
705 ReplaceWithValue(node, reduction.replacement());
706 return reduction;
707 }
708 704
709 JSBinopReduction r(this, node); 705 JSBinopReduction r(this, node);
710 706
711 if (r.BothInputsAre(Type::String())) { 707 if (r.BothInputsAre(Type::String())) {
712 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 708 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
713 } 709 }
714 if (r.BothInputsAre(Type::Boolean())) { 710 if (r.BothInputsAre(Type::Boolean())) {
715 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), 711 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()),
716 invert); 712 invert);
717 } 713 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
762 if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) { 758 if (r.OneInputCannotBe(Type::NumberOrSimdOrString())) {
763 // For values with canonical representation (i.e. neither String, nor 759 // For values with canonical representation (i.e. neither String, nor
764 // Simd128Value nor Number) an empty type intersection means the values 760 // Simd128Value nor Number) an empty type intersection means the values
765 // cannot be strictly equal. 761 // cannot be strictly equal.
766 if (!r.left_type()->Maybe(r.right_type())) { 762 if (!r.left_type()->Maybe(r.right_type())) {
767 Node* replacement = jsgraph()->BooleanConstant(invert); 763 Node* replacement = jsgraph()->BooleanConstant(invert);
768 ReplaceWithValue(node, replacement); 764 ReplaceWithValue(node, replacement);
769 return Replace(replacement); 765 return Replace(replacement);
770 } 766 }
771 } 767 }
768
772 Reduction const reduction = ReduceJSEqualTypeOf(node, invert); 769 Reduction const reduction = ReduceJSEqualTypeOf(node, invert);
773 if (reduction.Changed()) { 770 if (reduction.Changed()) return reduction;
774 return reduction; 771
775 }
776 if (r.OneInputIs(the_hole_type_)) { 772 if (r.OneInputIs(the_hole_type_)) {
777 return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_), 773 return r.ChangeToPureOperator(simplified()->ReferenceEqual(the_hole_type_),
778 invert); 774 invert);
779 } 775 }
780 if (r.OneInputIs(Type::Undefined())) { 776 if (r.OneInputIs(Type::Undefined())) {
781 return r.ChangeToPureOperator( 777 return r.ChangeToPureOperator(
782 simplified()->ReferenceEqual(Type::Undefined()), invert); 778 simplified()->ReferenceEqual(Type::Undefined()), invert);
783 } 779 }
784 if (r.OneInputIs(Type::Null())) { 780 if (r.OneInputIs(Type::Null())) {
785 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), 781 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()),
(...skipping 11 matching lines...) Expand all
797 return r.ChangeToPureOperator( 793 return r.ChangeToPureOperator(
798 simplified()->ReferenceEqual(Type::Receiver()), invert); 794 simplified()->ReferenceEqual(Type::Receiver()), invert);
799 } 795 }
800 if (r.BothInputsAre(Type::Unique())) { 796 if (r.BothInputsAre(Type::Unique())) {
801 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), 797 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()),
802 invert); 798 invert);
803 } 799 }
804 if (r.BothInputsAre(Type::String())) { 800 if (r.BothInputsAre(Type::String())) {
805 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); 801 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
806 } 802 }
807 if (r.BothInputsAre(Type::Number())) { 803
804 NumberOperationHint hint;
805 if (r.BothInputsAre(Type::Signed32()) ||
806 r.BothInputsAre(Type::Unsigned32())) {
807 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
808 } else if (r.GetCompareNumberOperationHint(&hint)) {
809 return r.ChangeToSpeculativeOperator(
810 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
811 } else if (r.BothInputsAre(Type::Number())) {
808 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 812 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
809 } 813 }
810 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types)
811 return NoChange(); 814 return NoChange();
812 } 815 }
813 816
814 817
815 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { 818 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
816 Node* const input = node->InputAt(0); 819 Node* const input = node->InputAt(0);
817 Type* const input_type = NodeProperties::GetType(input); 820 Type* const input_type = NodeProperties::GetType(input);
818 if (input_type->Is(Type::Boolean())) { 821 if (input_type->Is(Type::Boolean())) {
819 // JSToBoolean(x:boolean) => x 822 // JSToBoolean(x:boolean) => x
820 return Replace(input); 823 return Replace(input);
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 } 2126 }
2124 2127
2125 2128
2126 CompilationDependencies* JSTypedLowering::dependencies() const { 2129 CompilationDependencies* JSTypedLowering::dependencies() const {
2127 return dependencies_; 2130 return dependencies_;
2128 } 2131 }
2129 2132
2130 } // namespace compiler 2133 } // namespace compiler
2131 } // namespace internal 2134 } // namespace internal
2132 } // namespace v8 2135 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-operator.cc ('k') | test/unittests/compiler/js-typed-lowering-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698