Chromium Code Reviews| 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/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
| 10 #include "src/compiler/instruction-selector-impl.h" | 10 #include "src/compiler/instruction-selector-impl.h" |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, | 337 void InstructionSelector::MarkAsRepresentation(MachineRepresentation rep, |
| 338 Node* node) { | 338 Node* node) { |
| 339 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); | 339 sequence()->MarkAsRepresentation(rep, GetVirtualRegister(node)); |
| 340 } | 340 } |
| 341 | 341 |
| 342 | 342 |
| 343 namespace { | 343 namespace { |
| 344 | 344 |
| 345 enum class FrameStateInputKind { kAny, kStackSlot }; | 345 enum class FrameStateInputKind { kAny, kStackSlot }; |
| 346 | 346 |
| 347 | |
| 348 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, | 347 InstructionOperand OperandForDeopt(OperandGenerator* g, Node* input, |
| 349 FrameStateInputKind kind) { | 348 FrameStateInputKind kind, |
| 349 MachineRepresentation rep) { | |
| 350 switch (input->opcode()) { | 350 switch (input->opcode()) { |
| 351 case IrOpcode::kInt32Constant: | 351 case IrOpcode::kInt32Constant: |
| 352 case IrOpcode::kNumberConstant: | 352 case IrOpcode::kNumberConstant: |
| 353 case IrOpcode::kFloat32Constant: | 353 case IrOpcode::kFloat32Constant: |
| 354 case IrOpcode::kFloat64Constant: | 354 case IrOpcode::kFloat64Constant: |
| 355 case IrOpcode::kHeapConstant: | 355 case IrOpcode::kHeapConstant: |
| 356 return g->UseImmediate(input); | 356 return g->UseImmediate(input); |
| 357 case IrOpcode::kObjectState: | 357 case IrOpcode::kObjectState: |
| 358 UNREACHABLE(); | 358 UNREACHABLE(); |
| 359 break; | 359 break; |
| 360 default: | 360 default: |
| 361 switch (kind) { | 361 if (rep == MachineRepresentation::kNone) { |
| 362 case FrameStateInputKind::kStackSlot: | 362 return g->TempImmediate(FrameStateDescriptor::kImpossibleValue); |
| 363 return g->UseUniqueSlot(input); | 363 } else { |
| 364 case FrameStateInputKind::kAny: | 364 switch (kind) { |
| 365 return g->UseAny(input); | 365 case FrameStateInputKind::kStackSlot: |
| 366 return g->UseUniqueSlot(input); | |
| 367 case FrameStateInputKind::kAny: | |
| 368 return g->UseAny(input); | |
| 369 } | |
| 366 } | 370 } |
| 367 } | 371 } |
| 368 UNREACHABLE(); | 372 UNREACHABLE(); |
| 369 return InstructionOperand(); | 373 return InstructionOperand(); |
| 370 } | 374 } |
| 371 | 375 |
| 372 | 376 |
| 373 class StateObjectDeduplicator { | 377 class StateObjectDeduplicator { |
| 374 public: | 378 public: |
| 375 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {} | 379 explicit StateObjectDeduplicator(Zone* zone) : objects_(zone) {} |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 421 // Crankshaft counts duplicate objects for the running id, so we have | 425 // Crankshaft counts duplicate objects for the running id, so we have |
| 422 // to push the input again. | 426 // to push the input again. |
| 423 deduplicator->InsertObject(input); | 427 deduplicator->InsertObject(input); |
| 424 descriptor->fields().push_back( | 428 descriptor->fields().push_back( |
| 425 StateValueDescriptor::Duplicate(zone, id)); | 429 StateValueDescriptor::Duplicate(zone, id)); |
| 426 return 0; | 430 return 0; |
| 427 } | 431 } |
| 428 break; | 432 break; |
| 429 } | 433 } |
| 430 default: { | 434 default: { |
| 431 inputs->push_back(OperandForDeopt(g, input, kind)); | 435 inputs->push_back(OperandForDeopt(g, input, kind, type.representation())); |
| 432 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type)); | 436 descriptor->fields().push_back(StateValueDescriptor::Plain(zone, type)); |
| 433 return 1; | 437 return 1; |
| 434 } | 438 } |
| 435 } | 439 } |
| 436 } | 440 } |
| 437 | 441 |
| 438 | 442 |
| 439 // Returns the number of instruction operands added to inputs. | 443 // Returns the number of instruction operands added to inputs. |
| 440 size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, | 444 size_t AddInputsToFrameStateDescriptor(FrameStateDescriptor* descriptor, |
| 441 Node* state, OperandGenerator* g, | 445 Node* state, OperandGenerator* g, |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 878 case IrOpcode::kParameter: { | 882 case IrOpcode::kParameter: { |
| 879 MachineType type = | 883 MachineType type = |
| 880 linkage()->GetParameterType(ParameterIndexOf(node->op())); | 884 linkage()->GetParameterType(ParameterIndexOf(node->op())); |
| 881 MarkAsRepresentation(type.representation(), node); | 885 MarkAsRepresentation(type.representation(), node); |
| 882 return VisitParameter(node); | 886 return VisitParameter(node); |
| 883 } | 887 } |
| 884 case IrOpcode::kOsrValue: | 888 case IrOpcode::kOsrValue: |
| 885 return MarkAsReference(node), VisitOsrValue(node); | 889 return MarkAsReference(node), VisitOsrValue(node); |
| 886 case IrOpcode::kPhi: { | 890 case IrOpcode::kPhi: { |
| 887 MachineRepresentation rep = PhiRepresentationOf(node->op()); | 891 MachineRepresentation rep = PhiRepresentationOf(node->op()); |
| 892 if (rep == MachineRepresentation::kNone) return; | |
| 888 MarkAsRepresentation(rep, node); | 893 MarkAsRepresentation(rep, node); |
| 889 return VisitPhi(node); | 894 return VisitPhi(node); |
| 890 } | 895 } |
| 891 case IrOpcode::kProjection: | 896 case IrOpcode::kProjection: |
| 892 return VisitProjection(node); | 897 return VisitProjection(node); |
| 893 case IrOpcode::kInt32Constant: | 898 case IrOpcode::kInt32Constant: |
| 894 case IrOpcode::kInt64Constant: | 899 case IrOpcode::kInt64Constant: |
| 895 case IrOpcode::kExternalConstant: | 900 case IrOpcode::kExternalConstant: |
| 896 case IrOpcode::kRelocatableInt32Constant: | 901 case IrOpcode::kRelocatableInt32Constant: |
| 897 case IrOpcode::kRelocatableInt64Constant: | 902 case IrOpcode::kRelocatableInt64Constant: |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1041 case IrOpcode::kChangeFloat32ToFloat64: | 1046 case IrOpcode::kChangeFloat32ToFloat64: |
| 1042 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); | 1047 return MarkAsFloat64(node), VisitChangeFloat32ToFloat64(node); |
| 1043 case IrOpcode::kChangeInt32ToFloat64: | 1048 case IrOpcode::kChangeInt32ToFloat64: |
| 1044 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); | 1049 return MarkAsFloat64(node), VisitChangeInt32ToFloat64(node); |
| 1045 case IrOpcode::kChangeUint32ToFloat64: | 1050 case IrOpcode::kChangeUint32ToFloat64: |
| 1046 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); | 1051 return MarkAsFloat64(node), VisitChangeUint32ToFloat64(node); |
| 1047 case IrOpcode::kChangeFloat64ToInt32: | 1052 case IrOpcode::kChangeFloat64ToInt32: |
| 1048 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); | 1053 return MarkAsWord32(node), VisitChangeFloat64ToInt32(node); |
| 1049 case IrOpcode::kChangeFloat64ToUint32: | 1054 case IrOpcode::kChangeFloat64ToUint32: |
| 1050 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); | 1055 return MarkAsWord32(node), VisitChangeFloat64ToUint32(node); |
| 1056 case IrOpcode::kImpossibleToWord32: | |
| 1057 return MarkAsWord32(node), VisitImpossibleToWord32(node); | |
| 1058 case IrOpcode::kImpossibleToWord64: | |
| 1059 return MarkAsWord64(node), VisitImpossibleToWord64(node); | |
| 1060 case IrOpcode::kImpossibleToFloat32: | |
| 1061 return MarkAsFloat32(node), VisitImpossibleToFloat32(node); | |
| 1062 case IrOpcode::kImpossibleToFloat64: | |
| 1063 return MarkAsFloat64(node), VisitImpossibleToFloat64(node); | |
| 1064 case IrOpcode::kImpossibleToTagged: | |
| 1065 MarkAsRepresentation(MachineType::PointerRepresentation(), node); | |
| 1066 return VisitImpossibleToTagged(node); | |
| 1067 case IrOpcode::kImpossibleToBit: | |
| 1068 return MarkAsWord32(node), VisitImpossibleToBit(node); | |
| 1051 case IrOpcode::kFloat64SilenceNaN: | 1069 case IrOpcode::kFloat64SilenceNaN: |
| 1052 MarkAsFloat64(node); | 1070 MarkAsFloat64(node); |
| 1053 if (CanProduceSignalingNaN(node->InputAt(0))) { | 1071 if (CanProduceSignalingNaN(node->InputAt(0))) { |
| 1054 return VisitFloat64SilenceNaN(node); | 1072 return VisitFloat64SilenceNaN(node); |
| 1055 } else { | 1073 } else { |
| 1056 return EmitIdentity(node); | 1074 return EmitIdentity(node); |
| 1057 } | 1075 } |
| 1058 case IrOpcode::kTruncateFloat64ToUint32: | 1076 case IrOpcode::kTruncateFloat64ToUint32: |
| 1059 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); | 1077 return MarkAsWord32(node), VisitTruncateFloat64ToUint32(node); |
| 1060 case IrOpcode::kTruncateFloat32ToInt32: | 1078 case IrOpcode::kTruncateFloat32ToInt32: |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1270 } | 1288 } |
| 1271 case IrOpcode::kAtomicStore: | 1289 case IrOpcode::kAtomicStore: |
| 1272 return VisitAtomicStore(node); | 1290 return VisitAtomicStore(node); |
| 1273 default: | 1291 default: |
| 1274 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", | 1292 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", |
| 1275 node->opcode(), node->op()->mnemonic(), node->id()); | 1293 node->opcode(), node->op()->mnemonic(), node->id()); |
| 1276 break; | 1294 break; |
| 1277 } | 1295 } |
| 1278 } | 1296 } |
| 1279 | 1297 |
| 1298 void InstructionSelector::VisitImpossibleToWord32(Node* node) { | |
| 1299 OperandGenerator g(this); | |
| 1300 Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0))); | |
| 1301 } | |
| 1302 | |
| 1303 void InstructionSelector::VisitImpossibleToWord64(Node* node) { | |
| 1304 OperandGenerator g(this); | |
| 1305 Emit(kArchImpossible, | |
| 1306 g.DefineAsConstant(node, Constant(static_cast<int64_t>(0)))); | |
| 1307 } | |
| 1308 | |
| 1309 void InstructionSelector::VisitImpossibleToFloat32(Node* node) { | |
| 1310 OperandGenerator g(this); | |
| 1311 Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0f))); | |
| 1312 } | |
| 1313 | |
| 1314 void InstructionSelector::VisitImpossibleToFloat64(Node* node) { | |
| 1315 OperandGenerator g(this); | |
| 1316 Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0.0))); | |
| 1317 } | |
| 1318 | |
| 1319 void InstructionSelector::VisitImpossibleToBit(Node* node) { | |
| 1320 OperandGenerator g(this); | |
| 1321 Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0))); | |
| 1322 } | |
| 1323 | |
| 1324 void InstructionSelector::VisitImpossibleToTagged(Node* node) { | |
| 1325 OperandGenerator g(this); | |
| 1326 #if V8_TARGET_ARCH_64_BIT | |
|
Benedikt Meurer
2016/07/24 17:23:41
How about a simpler approach?
Emit(kArchImpossibl
Jarin
2016/07/24 18:15:40
I tried that, did not compile on Mac. See the diff
Benedikt Meurer
2016/07/25 03:36:51
Mhm, that's weird.
| |
| 1327 Emit(kArchImpossible, | |
| 1328 g.DefineAsConstant(node, Constant(static_cast<int64_t>(0)))); | |
| 1329 #else // V8_TARGET_ARCH_64_BIT | |
| 1330 Emit(kArchImpossible, g.DefineAsConstant(node, Constant(0))); | |
| 1331 #endif // V8_TARGET_ARCH_64_BIT | |
| 1332 } | |
| 1280 | 1333 |
| 1281 void InstructionSelector::VisitLoadStackPointer(Node* node) { | 1334 void InstructionSelector::VisitLoadStackPointer(Node* node) { |
| 1282 OperandGenerator g(this); | 1335 OperandGenerator g(this); |
| 1283 Emit(kArchStackPointer, g.DefineAsRegister(node)); | 1336 Emit(kArchStackPointer, g.DefineAsRegister(node)); |
| 1284 } | 1337 } |
| 1285 | 1338 |
| 1286 | |
| 1287 void InstructionSelector::VisitLoadFramePointer(Node* node) { | 1339 void InstructionSelector::VisitLoadFramePointer(Node* node) { |
| 1288 OperandGenerator g(this); | 1340 OperandGenerator g(this); |
| 1289 Emit(kArchFramePointer, g.DefineAsRegister(node)); | 1341 Emit(kArchFramePointer, g.DefineAsRegister(node)); |
| 1290 } | 1342 } |
| 1291 | 1343 |
| 1292 void InstructionSelector::VisitLoadParentFramePointer(Node* node) { | 1344 void InstructionSelector::VisitLoadParentFramePointer(Node* node) { |
| 1293 OperandGenerator g(this); | 1345 OperandGenerator g(this); |
| 1294 Emit(kArchParentFramePointer, g.DefineAsRegister(node)); | 1346 Emit(kArchParentFramePointer, g.DefineAsRegister(node)); |
| 1295 } | 1347 } |
| 1296 | 1348 |
| (...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1990 return new (instruction_zone()) FrameStateDescriptor( | 2042 return new (instruction_zone()) FrameStateDescriptor( |
| 1991 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2043 instruction_zone(), state_info.type(), state_info.bailout_id(), |
| 1992 state_info.state_combine(), parameters, locals, stack, | 2044 state_info.state_combine(), parameters, locals, stack, |
| 1993 state_info.shared_info(), outer_state); | 2045 state_info.shared_info(), outer_state); |
| 1994 } | 2046 } |
| 1995 | 2047 |
| 1996 | 2048 |
| 1997 } // namespace compiler | 2049 } // namespace compiler |
| 1998 } // namespace internal | 2050 } // namespace internal |
| 1999 } // namespace v8 | 2051 } // namespace v8 |
| OLD | NEW |