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

Side by Side Diff: src/compiler/representation-change.cc

Issue 2362173003: [turbofan] Improve representation selection for Smi checking. (Closed)
Patch Set: Address comments Created 4 years, 3 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/representation-change.h ('k') | src/compiler/simplified-lowering.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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/representation-change.h" 5 #include "src/compiler/representation-change.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // Both are words less than or equal to 32-bits. 135 // Both are words less than or equal to 32-bits.
136 // Since loads of integers from memory implicitly sign or zero extend the 136 // Since loads of integers from memory implicitly sign or zero extend the
137 // value to the full machine word size and stores implicitly truncate, 137 // value to the full machine word size and stores implicitly truncate,
138 // no representation change is necessary. 138 // no representation change is necessary.
139 return node; 139 return node;
140 } 140 }
141 } 141 }
142 142
143 switch (use_info.representation()) { 143 switch (use_info.representation()) {
144 case MachineRepresentation::kTaggedSigned: 144 case MachineRepresentation::kTaggedSigned:
145 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 145 DCHECK(use_info.type_check() == TypeCheckKind::kNone ||
146 return GetTaggedSignedRepresentationFor(node, output_rep, output_type); 146 use_info.type_check() == TypeCheckKind::kSignedSmall);
147 return GetTaggedSignedRepresentationFor(node, output_rep, output_type,
148 use_node, use_info);
147 case MachineRepresentation::kTaggedPointer: 149 case MachineRepresentation::kTaggedPointer:
148 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 150 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
149 return GetTaggedPointerRepresentationFor(node, output_rep, output_type); 151 return GetTaggedPointerRepresentationFor(node, output_rep, output_type);
150 case MachineRepresentation::kTagged: 152 case MachineRepresentation::kTagged:
151 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 153 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
152 return GetTaggedRepresentationFor(node, output_rep, output_type, 154 return GetTaggedRepresentationFor(node, output_rep, output_type,
153 use_info.truncation()); 155 use_info.truncation());
154 case MachineRepresentation::kFloat32: 156 case MachineRepresentation::kFloat32:
155 DCHECK(use_info.type_check() == TypeCheckKind::kNone); 157 DCHECK(use_info.type_check() == TypeCheckKind::kNone);
156 return GetFloat32RepresentationFor(node, output_rep, output_type, 158 return GetFloat32RepresentationFor(node, output_rep, output_type,
(...skipping 16 matching lines...) Expand all
173 // TODO(bbudge) Handle conversions between tagged and untagged. 175 // TODO(bbudge) Handle conversions between tagged and untagged.
174 break; 176 break;
175 case MachineRepresentation::kNone: 177 case MachineRepresentation::kNone:
176 return node; 178 return node;
177 } 179 }
178 UNREACHABLE(); 180 UNREACHABLE();
179 return nullptr; 181 return nullptr;
180 } 182 }
181 183
182 Node* RepresentationChanger::GetTaggedSignedRepresentationFor( 184 Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
183 Node* node, MachineRepresentation output_rep, Type* output_type) { 185 Node* node, MachineRepresentation output_rep, Type* output_type,
186 Node* use_node, UseInfo use_info) {
184 // Eagerly fold representation changes for constants. 187 // Eagerly fold representation changes for constants.
185 switch (node->opcode()) { 188 switch (node->opcode()) {
186 case IrOpcode::kNumberConstant: { 189 case IrOpcode::kNumberConstant:
187 int32_t value = OpParameter<int32_t>(node); 190 if (output_type->Is(Type::SignedSmall())) {
188 if (Smi::IsValid(value)) { 191 return node;
189 return jsgraph()->Constant(value);
190 } 192 }
191 return TypeError(node, output_rep, output_type, 193 break;
192 MachineRepresentation::kTaggedSigned);
193 }
194 case IrOpcode::kHeapConstant:
195 return TypeError(node, output_rep, output_type,
196 MachineRepresentation::kTaggedSigned);
197 case IrOpcode::kInt32Constant:
198 if (output_type->Is(Type::SignedSmall())) {
199 int32_t value = OpParameter<int32_t>(node);
200 return jsgraph()->Constant(value);
201 } else {
202 return TypeError(node, output_rep, output_type,
203 MachineRepresentation::kTaggedSigned);
204 }
205 case IrOpcode::kFloat64Constant:
206 case IrOpcode::kFloat32Constant:
207 return TypeError(node, output_rep, output_type,
208 MachineRepresentation::kTaggedSigned);
209 default: 194 default:
210 break; 195 break;
211 } 196 }
212 // Select the correct X -> Tagged operator. 197 // Select the correct X -> Tagged operator.
213 const Operator* op; 198 const Operator* op;
214 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) { 199 if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
215 // This is an impossible value; it should not be used at runtime. 200 // This is an impossible value; it should not be used at runtime.
216 // We just provide a dummy value here. 201 // We just provide a dummy value here.
217 return jsgraph()->Constant(0); 202 return jsgraph()->Constant(0);
218 } else if (IsWord(output_rep)) { 203 } else if (IsWord(output_rep)) {
219 if (output_type->Is(Type::Signed31())) { 204 if (output_type->Is(Type::Signed31())) {
220 op = simplified()->ChangeInt31ToTaggedSigned(); 205 op = simplified()->ChangeInt31ToTaggedSigned();
221 } else if (machine()->Is64() && output_type->Is(Type::Signed32())) { 206 } else if (output_type->Is(Type::Signed32())) {
222 op = simplified()->ChangeInt32ToTagged(); 207 if (SmiValuesAre32Bits()) {
208 op = simplified()->ChangeInt32ToTagged();
209 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
210 op = simplified()->CheckedInt32ToTaggedSigned();
211 } else {
212 return TypeError(node, output_rep, output_type,
213 MachineRepresentation::kTaggedSigned);
214 }
215 } else if (output_type->Is(Type::Unsigned32()) &&
216 use_info.type_check() == TypeCheckKind::kSignedSmall) {
217 op = simplified()->CheckedUint32ToTaggedSigned();
223 } else { 218 } else {
224 return TypeError(node, output_rep, output_type, 219 return TypeError(node, output_rep, output_type,
225 MachineRepresentation::kTaggedSigned); 220 MachineRepresentation::kTaggedSigned);
226 } 221 }
222 } else if (output_rep == MachineRepresentation::kFloat64) {
223 if (output_type->Is(Type::Signed31())) {
224 // float64 -> int32 -> tagged signed
225 node = InsertChangeFloat64ToInt32(node);
226 op = simplified()->ChangeInt31ToTaggedSigned();
227 } else if (output_type->Is(Type::Signed32())) {
228 // float64 -> int32 -> tagged signed
229 node = InsertChangeFloat64ToInt32(node);
230 if (SmiValuesAre32Bits()) {
231 op = simplified()->ChangeInt32ToTagged();
232 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
233 op = simplified()->CheckedInt32ToTaggedSigned();
234 } else {
235 return TypeError(node, output_rep, output_type,
236 MachineRepresentation::kTaggedSigned);
237 }
238 } else if (output_type->Is(Type::Unsigned32()) &&
239 use_info.type_check() == TypeCheckKind::kSignedSmall) {
240 // float64 -> uint32 -> tagged signed
241 node = InsertChangeFloat64ToUint32(node);
242 op = simplified()->CheckedUint32ToTaggedSigned();
243 } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) {
244 op = simplified()->CheckedFloat64ToInt32(
245 output_type->Maybe(Type::MinusZero())
246 ? CheckForMinusZeroMode::kCheckForMinusZero
247 : CheckForMinusZeroMode::kDontCheckForMinusZero);
248 node = InsertConversion(node, op, use_node);
249 if (SmiValuesAre32Bits()) {
250 op = simplified()->ChangeInt32ToTagged();
251 } else {
252 op = simplified()->CheckedInt32ToTaggedSigned();
253 }
254 } else {
255 return TypeError(node, output_rep, output_type,
256 MachineRepresentation::kTaggedSigned);
257 }
258 } else if (CanBeTaggedPointer(output_rep) &&
259 use_info.type_check() == TypeCheckKind::kSignedSmall) {
260 op = simplified()->CheckedTaggedToTaggedSigned();
261 } else if (output_rep == MachineRepresentation::kBit &&
262 use_info.type_check() == TypeCheckKind::kSignedSmall) {
263 // TODO(turbofan): Consider adding a Bailout operator that just deopts.
264 // Also use that for MachineRepresentation::kPointer case above.
265 node = InsertChangeBitToTagged(node);
266 op = simplified()->CheckedTaggedToTaggedSigned();
227 } else { 267 } else {
228 return TypeError(node, output_rep, output_type, 268 return TypeError(node, output_rep, output_type,
229 MachineRepresentation::kTaggedSigned); 269 MachineRepresentation::kTaggedSigned);
230 } 270 }
231 return jsgraph()->graph()->NewNode(op, node); 271 return InsertConversion(node, op, use_node);
232 } 272 }
233 273
234 Node* RepresentationChanger::GetTaggedPointerRepresentationFor( 274 Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
235 Node* node, MachineRepresentation output_rep, Type* output_type) { 275 Node* node, MachineRepresentation output_rep, Type* output_type) {
236 // Eagerly fold representation changes for constants. 276 // Eagerly fold representation changes for constants.
237 switch (node->opcode()) { 277 switch (node->opcode()) {
238 case IrOpcode::kHeapConstant: 278 case IrOpcode::kHeapConstant:
239 return node; // No change necessary. 279 return node; // No change necessary.
240 case IrOpcode::kInt32Constant: 280 case IrOpcode::kInt32Constant:
241 if (output_type->Is(Type::Boolean())) { 281 if (output_type->Is(Type::Boolean())) {
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
926 966
927 V8_Fatal(__FILE__, __LINE__, 967 V8_Fatal(__FILE__, __LINE__,
928 "RepresentationChangerError: node #%d:%s of " 968 "RepresentationChangerError: node #%d:%s of "
929 "%s cannot be changed to %s", 969 "%s cannot be changed to %s",
930 node->id(), node->op()->mnemonic(), out_str.str().c_str(), 970 node->id(), node->op()->mnemonic(), out_str.str().c_str(),
931 use_str.str().c_str()); 971 use_str.str().c_str());
932 } 972 }
933 return node; 973 return node;
934 } 974 }
935 975
976 Node* RepresentationChanger::InsertChangeBitToTagged(Node* node) {
977 return jsgraph()->graph()->NewNode(simplified()->ChangeBitToTagged(), node);
978 }
936 979
937 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) { 980 Node* RepresentationChanger::InsertChangeFloat32ToFloat64(Node* node) {
938 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node); 981 return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(), node);
939 } 982 }
940 983
941 Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) { 984 Node* RepresentationChanger::InsertChangeFloat64ToUint32(Node* node) {
942 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node); 985 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToUint32(), node);
943 } 986 }
944 987
945 Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) { 988 Node* RepresentationChanger::InsertChangeFloat64ToInt32(Node* node) {
946 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node); 989 return jsgraph()->graph()->NewNode(machine()->ChangeFloat64ToInt32(), node);
947 } 990 }
948 991
949 Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) { 992 Node* RepresentationChanger::InsertChangeTaggedSignedToInt32(Node* node) {
950 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), 993 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(),
951 node); 994 node);
952 } 995 }
953 996
954 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) { 997 Node* RepresentationChanger::InsertChangeTaggedToFloat64(Node* node) {
955 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(), 998 return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
956 node); 999 node);
957 } 1000 }
958 1001
959 } // namespace compiler 1002 } // namespace compiler
960 } // namespace internal 1003 } // namespace internal
961 } // namespace v8 1004 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698