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 |