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

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

Issue 2531183003: Revert of [turbofan] Utilize String comparison feedback. (Closed)
Patch Set: Created 4 years 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 | « no previous file | no next file » | 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/ast/modules.h" 7 #include "src/ast/modules.h"
8 #include "src/builtins/builtins-utils.h" 8 #include "src/builtins/builtins-utils.h"
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/compilation-dependencies.h" 10 #include "src/compilation-dependencies.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 *hint = NumberOperationHint::kNumberOrOddball; 68 *hint = NumberOperationHint::kNumberOrOddball;
69 return true; 69 return true;
70 case CompareOperationHint::kAny: 70 case CompareOperationHint::kAny:
71 case CompareOperationHint::kNone: 71 case CompareOperationHint::kNone:
72 case CompareOperationHint::kString: 72 case CompareOperationHint::kString:
73 break; 73 break;
74 } 74 }
75 } 75 }
76 return false; 76 return false;
77 } 77 }
78
79 bool IsStringCompareOperation() {
80 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
81 DCHECK_EQ(1, node_->op()->EffectOutputCount());
82 return (CompareOperationHintOf(node_->op()) ==
83 CompareOperationHint::kString) &&
84 BothInputsMaybe(Type::String());
85 }
86 return false;
87 }
88 78
89 // Check if a string addition will definitely result in creating a ConsString, 79 // Check if a string addition will definitely result in creating a ConsString,
90 // i.e. if the combined length of the resulting string exceeds the ConsString 80 // i.e. if the combined length of the resulting string exceeds the ConsString
91 // minimum length. 81 // minimum length.
92 bool ShouldCreateConsString() { 82 bool ShouldCreateConsString() {
93 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); 83 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
94 if (BothInputsAre(Type::String()) || 84 if (BothInputsAre(Type::String()) ||
95 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && 85 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
96 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { 86 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
97 HeapObjectBinopMatcher m(node_); 87 HeapObjectBinopMatcher m(node_);
98 if (m.right().HasValue() && m.right().Value()->IsString()) { 88 if (m.right().HasValue() && m.right().Value()->IsString()) {
99 Handle<String> right_string = Handle<String>::cast(m.right().Value()); 89 Handle<String> right_string = Handle<String>::cast(m.right().Value());
100 if (right_string->length() >= ConsString::kMinLength) return true; 90 if (right_string->length() >= ConsString::kMinLength) return true;
101 } 91 }
102 if (m.left().HasValue() && m.left().Value()->IsString()) { 92 if (m.left().HasValue() && m.left().Value()->IsString()) {
103 Handle<String> left_string = Handle<String>::cast(m.left().Value()); 93 Handle<String> left_string = Handle<String>::cast(m.left().Value());
104 if (left_string->length() >= ConsString::kMinLength) { 94 if (left_string->length() >= ConsString::kMinLength) {
105 // The invariant for ConsString requires the left hand side to be 95 // The invariant for ConsString requires the left hand side to be
106 // a sequential or external string if the right hand side is the 96 // a sequential or external string if the right hand side is the
107 // empty string. Since we don't know anything about the right hand 97 // empty string. Since we don't know anything about the right hand
108 // side here, we must ensure that the left hand side satisfy the 98 // side here, we must ensure that the left hand side satisfy the
109 // constraints independent of the right hand side. 99 // constraints independent of the right hand side.
110 return left_string->IsSeqString() || left_string->IsExternalString(); 100 return left_string->IsSeqString() || left_string->IsExternalString();
111 } 101 }
112 } 102 }
113 } 103 }
114 return false; 104 return false;
115 } 105 }
116 106
117 // Checks that both inputs are String, and if we don't know statically that
118 // one side is already a String, insert a CheckString node.
119 void CheckInputsToString() {
120 if (!left_type()->Is(Type::String())) {
121 Node* left_input = graph()->NewNode(simplified()->CheckString(), left(),
122 effect(), control());
123 node_->ReplaceInput(0, left_input);
124 update_effect(left_input);
125 }
126 if (!right_type()->Is(Type::String())) {
127 Node* right_input = graph()->NewNode(simplified()->CheckString(), right(),
128 effect(), control());
129 node_->ReplaceInput(1, right_input);
130 update_effect(right_input);
131 }
132 }
133
134 void ConvertInputsToNumber() { 107 void ConvertInputsToNumber() {
135 // To convert the inputs to numbers, we have to provide frame states 108 // To convert the inputs to numbers, we have to provide frame states
136 // for lazy bailouts in the ToNumber conversions. 109 // for lazy bailouts in the ToNumber conversions.
137 // We use a little hack here: we take the frame state before the binary 110 // We use a little hack here: we take the frame state before the binary
138 // operation and use it to construct the frame states for the conversion 111 // operation and use it to construct the frame states for the conversion
139 // so that after the deoptimization, the binary operation IC gets 112 // so that after the deoptimization, the binary operation IC gets
140 // already converted values from full code. This way we are sure that we 113 // already converted values from full code. This way we are sure that we
141 // will not re-do any of the side effects. 114 // will not re-do any of the side effects.
142 115
143 Node* left_input = nullptr; 116 Node* left_input = nullptr;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 } 310 }
338 311
339 bool LeftInputIs(Type* t) { return left_type()->Is(t); } 312 bool LeftInputIs(Type* t) { return left_type()->Is(t); }
340 313
341 bool RightInputIs(Type* t) { return right_type()->Is(t); } 314 bool RightInputIs(Type* t) { return right_type()->Is(t); }
342 315
343 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } 316 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); }
344 317
345 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); } 318 bool BothInputsAre(Type* t) { return LeftInputIs(t) && RightInputIs(t); }
346 319
347 bool BothInputsMaybe(Type* t) {
348 return left_type()->Maybe(t) && right_type()->Maybe(t);
349 }
350
351 bool OneInputCannotBe(Type* t) { 320 bool OneInputCannotBe(Type* t) {
352 return !left_type()->Maybe(t) || !right_type()->Maybe(t); 321 return !left_type()->Maybe(t) || !right_type()->Maybe(t);
353 } 322 }
354 323
355 bool NeitherInputCanBe(Type* t) { 324 bool NeitherInputCanBe(Type* t) {
356 return !left_type()->Maybe(t) && !right_type()->Maybe(t); 325 return !left_type()->Maybe(t) && !right_type()->Maybe(t);
357 } 326 }
358 327
359 Node* effect() { return NodeProperties::GetEffectInput(node_); } 328 Node* effect() { return NodeProperties::GetEffectInput(node_); }
360 Node* control() { return NodeProperties::GetControlInput(node_); } 329 Node* control() { return NodeProperties::GetControlInput(node_); }
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 less_than_or_equal = simplified()->NumberLessThanOrEqual(); 740 less_than_or_equal = simplified()->NumberLessThanOrEqual();
772 } else if (r.GetCompareNumberOperationHint(&hint)) { 741 } else if (r.GetCompareNumberOperationHint(&hint)) {
773 less_than = simplified()->SpeculativeNumberLessThan(hint); 742 less_than = simplified()->SpeculativeNumberLessThan(hint);
774 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); 743 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
775 } else if (r.OneInputCannotBe(Type::StringOrReceiver()) && 744 } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
776 (r.BothInputsAre(Type::PlainPrimitive()) || 745 (r.BothInputsAre(Type::PlainPrimitive()) ||
777 !(flags() & kDeoptimizationEnabled))) { 746 !(flags() & kDeoptimizationEnabled))) {
778 r.ConvertInputsToNumber(); 747 r.ConvertInputsToNumber();
779 less_than = simplified()->NumberLessThan(); 748 less_than = simplified()->NumberLessThan();
780 less_than_or_equal = simplified()->NumberLessThanOrEqual(); 749 less_than_or_equal = simplified()->NumberLessThanOrEqual();
781 } else if (r.IsStringCompareOperation()) {
782 r.CheckInputsToString();
783 less_than = simplified()->StringLessThan();
784 less_than_or_equal = simplified()->StringLessThanOrEqual();
785 } else { 750 } else {
786 return NoChange(); 751 return NoChange();
787 } 752 }
788 const Operator* comparison; 753 const Operator* comparison;
789 switch (node->opcode()) { 754 switch (node->opcode()) {
790 case IrOpcode::kJSLessThan: 755 case IrOpcode::kJSLessThan:
791 comparison = less_than; 756 comparison = less_than;
792 break; 757 break;
793 case IrOpcode::kJSGreaterThan: 758 case IrOpcode::kJSGreaterThan:
794 comparison = less_than; 759 comparison = less_than;
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 878
914 NumberOperationHint hint; 879 NumberOperationHint hint;
915 if (r.BothInputsAre(Type::Signed32()) || 880 if (r.BothInputsAre(Type::Signed32()) ||
916 r.BothInputsAre(Type::Unsigned32())) { 881 r.BothInputsAre(Type::Unsigned32())) {
917 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 882 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
918 } else if (r.GetCompareNumberOperationHint(&hint)) { 883 } else if (r.GetCompareNumberOperationHint(&hint)) {
919 return r.ChangeToSpeculativeOperator( 884 return r.ChangeToSpeculativeOperator(
920 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 885 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
921 } else if (r.BothInputsAre(Type::Number())) { 886 } else if (r.BothInputsAre(Type::Number())) {
922 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 887 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
923 } else if (r.IsStringCompareOperation()) {
924 r.CheckInputsToString();
925 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
926 } 888 }
927 return NoChange(); 889 return NoChange();
928 } 890 }
929 891
930 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { 892 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
931 JSBinopReduction r(this, node); 893 JSBinopReduction r(this, node);
932 if (r.left() == r.right()) { 894 if (r.left() == r.right()) {
933 // x === x is always true if x != NaN 895 // x === x is always true if x != NaN
934 if (!r.left_type()->Maybe(Type::NaN())) { 896 if (!r.left_type()->Maybe(Type::NaN())) {
935 Node* replacement = jsgraph()->BooleanConstant(!invert); 897 Node* replacement = jsgraph()->BooleanConstant(!invert);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 940
979 NumberOperationHint hint; 941 NumberOperationHint hint;
980 if (r.BothInputsAre(Type::Signed32()) || 942 if (r.BothInputsAre(Type::Signed32()) ||
981 r.BothInputsAre(Type::Unsigned32())) { 943 r.BothInputsAre(Type::Unsigned32())) {
982 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 944 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
983 } else if (r.GetCompareNumberOperationHint(&hint)) { 945 } else if (r.GetCompareNumberOperationHint(&hint)) {
984 return r.ChangeToSpeculativeOperator( 946 return r.ChangeToSpeculativeOperator(
985 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 947 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
986 } else if (r.BothInputsAre(Type::Number())) { 948 } else if (r.BothInputsAre(Type::Number())) {
987 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 949 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
988 } else if (r.IsStringCompareOperation()) {
989 r.CheckInputsToString();
990 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
991 } 950 }
992 return NoChange(); 951 return NoChange();
993 } 952 }
994 953
995 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { 954 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
996 Node* const input = node->InputAt(0); 955 Node* const input = node->InputAt(0);
997 Type* const input_type = NodeProperties::GetType(input); 956 Type* const input_type = NodeProperties::GetType(input);
998 if (input_type->Is(Type::Boolean())) { 957 if (input_type->Is(Type::Boolean())) {
999 // JSToBoolean(x:boolean) => x 958 // JSToBoolean(x:boolean) => x
1000 return Replace(input); 959 return Replace(input);
(...skipping 1312 matching lines...) Expand 10 before | Expand all | Expand 10 after
2313 } 2272 }
2314 2273
2315 2274
2316 CompilationDependencies* JSTypedLowering::dependencies() const { 2275 CompilationDependencies* JSTypedLowering::dependencies() const {
2317 return dependencies_; 2276 return dependencies_;
2318 } 2277 }
2319 2278
2320 } // namespace compiler 2279 } // namespace compiler
2321 } // namespace internal 2280 } // namespace internal
2322 } // namespace v8 2281 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698