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

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

Issue 2523463002: [turbofan] Utilize String comparison feedback. (Closed)
Patch Set: REBASE Created 3 years, 10 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 | « 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 bool IsReceiverCompareOperation() { 91 bool IsReceiverCompareOperation() {
92 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) { 92 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
93 DCHECK_EQ(1, node_->op()->EffectOutputCount()); 93 DCHECK_EQ(1, node_->op()->EffectOutputCount());
94 return (CompareOperationHintOf(node_->op()) == 94 return (CompareOperationHintOf(node_->op()) ==
95 CompareOperationHint::kReceiver) && 95 CompareOperationHint::kReceiver) &&
96 BothInputsMaybe(Type::Receiver()); 96 BothInputsMaybe(Type::Receiver());
97 } 97 }
98 return false; 98 return false;
99 } 99 }
100 100
101 bool IsStringCompareOperation() {
102 if (lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) {
103 DCHECK_EQ(1, node_->op()->EffectOutputCount());
104 return (CompareOperationHintOf(node_->op()) ==
105 CompareOperationHint::kString) &&
106 BothInputsMaybe(Type::String());
107 }
108 return false;
109 }
110
101 // Check if a string addition will definitely result in creating a ConsString, 111 // Check if a string addition will definitely result in creating a ConsString,
102 // i.e. if the combined length of the resulting string exceeds the ConsString 112 // i.e. if the combined length of the resulting string exceeds the ConsString
103 // minimum length. 113 // minimum length.
104 bool ShouldCreateConsString() { 114 bool ShouldCreateConsString() {
105 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode()); 115 DCHECK_EQ(IrOpcode::kJSAdd, node_->opcode());
106 if (BothInputsAre(Type::String()) || 116 if (BothInputsAre(Type::String()) ||
107 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) && 117 ((lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) &&
108 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) { 118 BinaryOperationHintOf(node_->op()) == BinaryOperationHint::kString)) {
109 HeapObjectBinopMatcher m(node_); 119 HeapObjectBinopMatcher m(node_);
110 if (m.right().HasValue() && m.right().Value()->IsString()) { 120 if (m.right().HasValue() && m.right().Value()->IsString()) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 CheckLeftInputToReceiver(); 152 CheckLeftInputToReceiver();
143 } 153 }
144 if (!right_type()->Is(Type::Receiver())) { 154 if (!right_type()->Is(Type::Receiver())) {
145 Node* right_input = graph()->NewNode(simplified()->CheckReceiver(), 155 Node* right_input = graph()->NewNode(simplified()->CheckReceiver(),
146 right(), effect(), control()); 156 right(), effect(), control());
147 node_->ReplaceInput(1, right_input); 157 node_->ReplaceInput(1, right_input);
148 update_effect(right_input); 158 update_effect(right_input);
149 } 159 }
150 } 160 }
151 161
162 // Checks that both inputs are String, and if we don't know
163 // statically that one side is already a String, insert a
164 // CheckString node.
165 void CheckInputsToString() {
166 if (!left_type()->Is(Type::String())) {
167 Node* left_input = graph()->NewNode(simplified()->CheckString(), left(),
168 effect(), control());
169 node_->ReplaceInput(0, left_input);
170 update_effect(left_input);
171 }
172 if (!right_type()->Is(Type::String())) {
173 Node* right_input = graph()->NewNode(simplified()->CheckString(), right(),
174 effect(), control());
175 node_->ReplaceInput(1, right_input);
176 update_effect(right_input);
177 }
178 }
179
152 // Checks that both inputs are InternalizedString, and if we don't know 180 // Checks that both inputs are InternalizedString, and if we don't know
153 // statically that one side is already an InternalizedString, insert a 181 // statically that one side is already an InternalizedString, insert a
154 // CheckInternalizedString node. 182 // CheckInternalizedString node.
155 void CheckInputsToInternalizedString() { 183 void CheckInputsToInternalizedString() {
156 if (!left_type()->Is(Type::UniqueName())) { 184 if (!left_type()->Is(Type::UniqueName())) {
157 Node* left_input = graph()->NewNode( 185 Node* left_input = graph()->NewNode(
158 simplified()->CheckInternalizedString(), left(), effect(), control()); 186 simplified()->CheckInternalizedString(), left(), effect(), control());
159 node_->ReplaceInput(0, left_input); 187 node_->ReplaceInput(0, left_input);
160 update_effect(left_input); 188 update_effect(left_input);
161 } 189 }
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 less_than_or_equal = simplified()->NumberLessThanOrEqual(); 848 less_than_or_equal = simplified()->NumberLessThanOrEqual();
821 } else if (r.GetCompareNumberOperationHint(&hint)) { 849 } else if (r.GetCompareNumberOperationHint(&hint)) {
822 less_than = simplified()->SpeculativeNumberLessThan(hint); 850 less_than = simplified()->SpeculativeNumberLessThan(hint);
823 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint); 851 less_than_or_equal = simplified()->SpeculativeNumberLessThanOrEqual(hint);
824 } else if (r.OneInputCannotBe(Type::StringOrReceiver()) && 852 } else if (r.OneInputCannotBe(Type::StringOrReceiver()) &&
825 (r.BothInputsAre(Type::PlainPrimitive()) || 853 (r.BothInputsAre(Type::PlainPrimitive()) ||
826 !(flags() & kDeoptimizationEnabled))) { 854 !(flags() & kDeoptimizationEnabled))) {
827 r.ConvertInputsToNumber(); 855 r.ConvertInputsToNumber();
828 less_than = simplified()->NumberLessThan(); 856 less_than = simplified()->NumberLessThan();
829 less_than_or_equal = simplified()->NumberLessThanOrEqual(); 857 less_than_or_equal = simplified()->NumberLessThanOrEqual();
858 } else if (r.IsStringCompareOperation()) {
859 r.CheckInputsToString();
860 less_than = simplified()->StringLessThan();
861 less_than_or_equal = simplified()->StringLessThanOrEqual();
830 } else { 862 } else {
831 return NoChange(); 863 return NoChange();
832 } 864 }
833 const Operator* comparison; 865 const Operator* comparison;
834 switch (node->opcode()) { 866 switch (node->opcode()) {
835 case IrOpcode::kJSLessThan: 867 case IrOpcode::kJSLessThan:
836 comparison = less_than; 868 comparison = less_than;
837 break; 869 break;
838 case IrOpcode::kJSGreaterThan: 870 case IrOpcode::kJSGreaterThan:
839 comparison = less_than; 871 comparison = less_than;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 r.BothInputsAre(Type::Unsigned32())) { 1011 r.BothInputsAre(Type::Unsigned32())) {
980 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 1012 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
981 } else if (r.GetCompareNumberOperationHint(&hint)) { 1013 } else if (r.GetCompareNumberOperationHint(&hint)) {
982 return r.ChangeToSpeculativeOperator( 1014 return r.ChangeToSpeculativeOperator(
983 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 1015 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
984 } else if (r.BothInputsAre(Type::Number())) { 1016 } else if (r.BothInputsAre(Type::Number())) {
985 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 1017 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
986 } else if (r.IsReceiverCompareOperation()) { 1018 } else if (r.IsReceiverCompareOperation()) {
987 r.CheckInputsToReceiver(); 1019 r.CheckInputsToReceiver();
988 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 1020 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
1021 } else if (r.IsStringCompareOperation()) {
1022 r.CheckInputsToString();
1023 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
989 } 1024 }
990 return NoChange(); 1025 return NoChange();
991 } 1026 }
992 1027
993 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { 1028 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) {
994 JSBinopReduction r(this, node); 1029 JSBinopReduction r(this, node);
995 if (r.left() == r.right()) { 1030 if (r.left() == r.right()) {
996 // x === x is always true if x != NaN 1031 // x === x is always true if x != NaN
997 if (!r.left_type()->Maybe(Type::NaN())) { 1032 if (!r.left_type()->Maybe(Type::NaN())) {
998 Node* replacement = jsgraph()->BooleanConstant(!invert); 1033 Node* replacement = jsgraph()->BooleanConstant(!invert);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 return r.ChangeToSpeculativeOperator( 1071 return r.ChangeToSpeculativeOperator(
1037 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean()); 1072 simplified()->SpeculativeNumberEqual(hint), invert, Type::Boolean());
1038 } else if (r.BothInputsAre(Type::Number())) { 1073 } else if (r.BothInputsAre(Type::Number())) {
1039 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); 1074 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert);
1040 } else if (r.IsReceiverCompareOperation()) { 1075 } else if (r.IsReceiverCompareOperation()) {
1041 // For strict equality, it's enough to know that one input is a Receiver, 1076 // For strict equality, it's enough to know that one input is a Receiver,
1042 // as a strict equality comparison with a Receiver can only yield true if 1077 // as a strict equality comparison with a Receiver can only yield true if
1043 // both sides refer to the same Receiver than. 1078 // both sides refer to the same Receiver than.
1044 r.CheckLeftInputToReceiver(); 1079 r.CheckLeftInputToReceiver();
1045 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert); 1080 return r.ChangeToPureOperator(simplified()->ReferenceEqual(), invert);
1081 } else if (r.IsStringCompareOperation()) {
1082 r.CheckInputsToString();
1083 return r.ChangeToPureOperator(simplified()->StringEqual(), invert);
1046 } 1084 }
1047 return NoChange(); 1085 return NoChange();
1048 } 1086 }
1049 1087
1050 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { 1088 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
1051 Node* const input = node->InputAt(0); 1089 Node* const input = node->InputAt(0);
1052 Type* const input_type = NodeProperties::GetType(input); 1090 Type* const input_type = NodeProperties::GetType(input);
1053 if (input_type->Is(Type::Boolean())) { 1091 if (input_type->Is(Type::Boolean())) {
1054 // JSToBoolean(x:boolean) => x 1092 // JSToBoolean(x:boolean) => x
1055 return Replace(input); 1093 return Replace(input);
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after
2476 } 2514 }
2477 2515
2478 2516
2479 CompilationDependencies* JSTypedLowering::dependencies() const { 2517 CompilationDependencies* JSTypedLowering::dependencies() const {
2480 return dependencies_; 2518 return dependencies_;
2481 } 2519 }
2482 2520
2483 } // namespace compiler 2521 } // namespace compiler
2484 } // namespace internal 2522 } // namespace internal
2485 } // namespace v8 2523 } // 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