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 "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 DCHECK(input == NULL); | 433 DCHECK(input == NULL); |
434 break; | 434 break; |
435 } | 435 } |
436 default: | 436 default: |
437 UNREACHABLE(); | 437 UNREACHABLE(); |
438 break; | 438 break; |
439 } | 439 } |
440 } | 440 } |
441 | 441 |
442 | 442 |
| 443 MachineType InstructionSelector::GetMachineType(Node* node) { |
| 444 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. |
| 445 switch (node->opcode()) { |
| 446 case IrOpcode::kStart: |
| 447 case IrOpcode::kLoop: |
| 448 case IrOpcode::kEnd: |
| 449 case IrOpcode::kBranch: |
| 450 case IrOpcode::kIfTrue: |
| 451 case IrOpcode::kIfFalse: |
| 452 case IrOpcode::kEffectPhi: |
| 453 case IrOpcode::kMerge: |
| 454 // No code needed for these graph artifacts. |
| 455 return kMachNone; |
| 456 case IrOpcode::kFinish: |
| 457 return kMachAnyTagged; |
| 458 case IrOpcode::kParameter: |
| 459 return linkage()->GetParameterType(OpParameter<int>(node)); |
| 460 case IrOpcode::kPhi: |
| 461 return OpParameter<MachineType>(node); |
| 462 case IrOpcode::kProjection: |
| 463 // TODO(jarin) Really project from outputs. |
| 464 return kMachAnyTagged; |
| 465 case IrOpcode::kInt32Constant: |
| 466 return kMachInt32; |
| 467 case IrOpcode::kInt64Constant: |
| 468 return kMachInt64; |
| 469 case IrOpcode::kExternalConstant: |
| 470 return kMachPtr; |
| 471 case IrOpcode::kFloat64Constant: |
| 472 return kMachFloat64; |
| 473 case IrOpcode::kHeapConstant: |
| 474 case IrOpcode::kNumberConstant: |
| 475 return kMachAnyTagged; |
| 476 case IrOpcode::kCall: |
| 477 return kMachAnyTagged; |
| 478 case IrOpcode::kFrameState: |
| 479 case IrOpcode::kStateValues: |
| 480 return kMachNone; |
| 481 case IrOpcode::kLoad: |
| 482 return OpParameter<LoadRepresentation>(node); |
| 483 case IrOpcode::kStore: |
| 484 return kMachNone; |
| 485 case IrOpcode::kWord32And: |
| 486 case IrOpcode::kWord32Or: |
| 487 case IrOpcode::kWord32Xor: |
| 488 case IrOpcode::kWord32Shl: |
| 489 case IrOpcode::kWord32Shr: |
| 490 case IrOpcode::kWord32Sar: |
| 491 case IrOpcode::kWord32Ror: |
| 492 return kMachInt32; |
| 493 case IrOpcode::kWord32Equal: |
| 494 return kMachBool; |
| 495 case IrOpcode::kWord64And: |
| 496 case IrOpcode::kWord64Or: |
| 497 case IrOpcode::kWord64Xor: |
| 498 case IrOpcode::kWord64Shl: |
| 499 case IrOpcode::kWord64Shr: |
| 500 case IrOpcode::kWord64Sar: |
| 501 case IrOpcode::kWord64Ror: |
| 502 return kMachInt64; |
| 503 case IrOpcode::kWord64Equal: |
| 504 return kMachBool; |
| 505 case IrOpcode::kInt32Add: |
| 506 case IrOpcode::kInt32AddWithOverflow: |
| 507 case IrOpcode::kInt32Sub: |
| 508 case IrOpcode::kInt32SubWithOverflow: |
| 509 case IrOpcode::kInt32Mul: |
| 510 case IrOpcode::kInt32Div: |
| 511 case IrOpcode::kInt32Mod: |
| 512 return kMachInt32; |
| 513 case IrOpcode::kInt32LessThan: |
| 514 case IrOpcode::kInt32LessThanOrEqual: |
| 515 case IrOpcode::kUint32LessThan: |
| 516 case IrOpcode::kUint32LessThanOrEqual: |
| 517 return kMachBool; |
| 518 case IrOpcode::kInt64Add: |
| 519 case IrOpcode::kInt64Sub: |
| 520 case IrOpcode::kInt64Mul: |
| 521 case IrOpcode::kInt64Div: |
| 522 case IrOpcode::kInt64Mod: |
| 523 return kMachInt64; |
| 524 case IrOpcode::kInt64LessThan: |
| 525 case IrOpcode::kInt64LessThanOrEqual: |
| 526 return kMachBool; |
| 527 case IrOpcode::kChangeFloat32ToFloat64: |
| 528 case IrOpcode::kChangeInt32ToFloat64: |
| 529 case IrOpcode::kChangeUint32ToFloat64: |
| 530 return kMachFloat64; |
| 531 case IrOpcode::kChangeFloat64ToInt32: |
| 532 return kMachInt32; |
| 533 case IrOpcode::kChangeFloat64ToUint32: |
| 534 return kMachUint32; |
| 535 case IrOpcode::kChangeInt32ToInt64: |
| 536 return kMachInt64; |
| 537 case IrOpcode::kChangeUint32ToUint64: |
| 538 return kMachUint64; |
| 539 case IrOpcode::kTruncateFloat64ToFloat32: |
| 540 return kMachFloat32; |
| 541 case IrOpcode::kTruncateFloat64ToInt32: |
| 542 case IrOpcode::kTruncateInt64ToInt32: |
| 543 return kMachInt32; |
| 544 case IrOpcode::kFloat64Add: |
| 545 case IrOpcode::kFloat64Sub: |
| 546 case IrOpcode::kFloat64Mul: |
| 547 case IrOpcode::kFloat64Div: |
| 548 case IrOpcode::kFloat64Mod: |
| 549 case IrOpcode::kFloat64Sqrt: |
| 550 return kMachFloat64; |
| 551 case IrOpcode::kFloat64Equal: |
| 552 case IrOpcode::kFloat64LessThan: |
| 553 case IrOpcode::kFloat64LessThanOrEqual: |
| 554 return kMachBool; |
| 555 default: |
| 556 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", |
| 557 node->opcode(), node->op()->mnemonic(), node->id()); |
| 558 } |
| 559 return kMachNone; |
| 560 } |
| 561 |
| 562 |
443 void InstructionSelector::VisitNode(Node* node) { | 563 void InstructionSelector::VisitNode(Node* node) { |
444 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. | 564 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. |
445 SourcePosition source_position = source_positions_->GetSourcePosition(node); | 565 SourcePosition source_position = source_positions_->GetSourcePosition(node); |
446 if (!source_position.IsUnknown()) { | 566 if (!source_position.IsUnknown()) { |
447 DCHECK(!source_position.IsInvalid()); | 567 DCHECK(!source_position.IsInvalid()); |
448 if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) { | 568 if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) { |
449 Emit(SourcePositionInstruction::New(instruction_zone(), source_position)); | 569 Emit(SourcePositionInstruction::New(instruction_zone(), source_position)); |
450 } | 570 } |
451 } | 571 } |
452 switch (node->opcode()) { | 572 switch (node->opcode()) { |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 Emit(kArchRet, NULL); | 1123 Emit(kArchRet, NULL); |
1004 } | 1124 } |
1005 } | 1125 } |
1006 | 1126 |
1007 | 1127 |
1008 void InstructionSelector::VisitThrow(Node* value) { | 1128 void InstructionSelector::VisitThrow(Node* value) { |
1009 UNIMPLEMENTED(); // TODO(titzer) | 1129 UNIMPLEMENTED(); // TODO(titzer) |
1010 } | 1130 } |
1011 | 1131 |
1012 | 1132 |
| 1133 void InstructionSelector::FillTypeVectorFromStateValues( |
| 1134 ZoneVector<MachineType>* types, Node* state_values) { |
| 1135 DCHECK(state_values->opcode() == IrOpcode::kStateValues); |
| 1136 int count = OpParameter<int>(state_values); |
| 1137 types->reserve(static_cast<size_t>(count)); |
| 1138 for (int i = 0; i < count; i++) { |
| 1139 types->push_back(GetMachineType(state_values->InputAt(i))); |
| 1140 } |
| 1141 } |
| 1142 |
| 1143 |
1013 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1144 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
1014 Node* state) { | 1145 Node* state) { |
1015 DCHECK(state->opcode() == IrOpcode::kFrameState); | 1146 DCHECK(state->opcode() == IrOpcode::kFrameState); |
1016 DCHECK_EQ(5, state->InputCount()); | 1147 DCHECK_EQ(5, state->InputCount()); |
1017 FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state); | 1148 FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state); |
| 1149 |
1018 int parameters = OpParameter<int>(state->InputAt(0)); | 1150 int parameters = OpParameter<int>(state->InputAt(0)); |
1019 int locals = OpParameter<int>(state->InputAt(1)); | 1151 int locals = OpParameter<int>(state->InputAt(1)); |
1020 int stack = OpParameter<int>(state->InputAt(2)); | 1152 int stack = OpParameter<int>(state->InputAt(2)); |
1021 | 1153 |
1022 FrameStateDescriptor* outer_state = NULL; | 1154 FrameStateDescriptor* outer_state = NULL; |
1023 Node* outer_node = state->InputAt(4); | 1155 Node* outer_node = state->InputAt(4); |
1024 if (outer_node->opcode() == IrOpcode::kFrameState) { | 1156 if (outer_node->opcode() == IrOpcode::kFrameState) { |
1025 outer_state = GetFrameStateDescriptor(outer_node); | 1157 outer_state = GetFrameStateDescriptor(outer_node); |
1026 } | 1158 } |
1027 | 1159 |
1028 return new (instruction_zone()) | 1160 return new (instruction_zone()) FrameStateDescriptor( |
1029 FrameStateDescriptor(state_info, parameters, locals, stack, outer_state); | 1161 instruction_zone(), state_info, parameters, locals, stack, outer_state); |
1030 } | 1162 } |
1031 | 1163 |
1032 | 1164 |
1033 static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) { | 1165 static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) { |
1034 switch (input->opcode()) { | 1166 switch (input->opcode()) { |
1035 case IrOpcode::kInt32Constant: | 1167 case IrOpcode::kInt32Constant: |
1036 case IrOpcode::kNumberConstant: | 1168 case IrOpcode::kNumberConstant: |
1037 case IrOpcode::kFloat64Constant: | 1169 case IrOpcode::kFloat64Constant: |
1038 case IrOpcode::kHeapConstant: | 1170 case IrOpcode::kHeapConstant: |
1039 return g->UseImmediate(input); | 1171 return g->UseImmediate(input); |
(...skipping 19 matching lines...) Expand all Loading... |
1059 | 1191 |
1060 DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode()); | 1192 DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode()); |
1061 DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode()); | 1193 DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode()); |
1062 DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode()); | 1194 DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode()); |
1063 | 1195 |
1064 DCHECK_EQ(static_cast<int>(descriptor->parameters_count()), | 1196 DCHECK_EQ(static_cast<int>(descriptor->parameters_count()), |
1065 parameters->InputCount()); | 1197 parameters->InputCount()); |
1066 DCHECK_EQ(static_cast<int>(descriptor->locals_count()), locals->InputCount()); | 1198 DCHECK_EQ(static_cast<int>(descriptor->locals_count()), locals->InputCount()); |
1067 DCHECK_EQ(static_cast<int>(descriptor->stack_count()), stack->InputCount()); | 1199 DCHECK_EQ(static_cast<int>(descriptor->stack_count()), stack->InputCount()); |
1068 | 1200 |
| 1201 ZoneVector<MachineType> types(instruction_zone()); |
| 1202 types.reserve(descriptor->GetSize()); |
| 1203 |
1069 OperandGenerator g(this); | 1204 OperandGenerator g(this); |
| 1205 size_t value_index = 0; |
1070 for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) { | 1206 for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) { |
1071 inputs->push_back(UseOrImmediate(&g, parameters->InputAt(i))); | 1207 Node* input_node = parameters->InputAt(i); |
| 1208 inputs->push_back(UseOrImmediate(&g, input_node)); |
| 1209 descriptor->SetType(value_index++, GetMachineType(input_node)); |
1072 } | 1210 } |
1073 if (descriptor->HasContext()) { | 1211 if (descriptor->HasContext()) { |
1074 inputs->push_back(UseOrImmediate(&g, context)); | 1212 inputs->push_back(UseOrImmediate(&g, context)); |
| 1213 descriptor->SetType(value_index++, kMachAnyTagged); |
1075 } | 1214 } |
1076 for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) { | 1215 for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) { |
1077 inputs->push_back(UseOrImmediate(&g, locals->InputAt(i))); | 1216 Node* input_node = locals->InputAt(i); |
| 1217 inputs->push_back(UseOrImmediate(&g, input_node)); |
| 1218 descriptor->SetType(value_index++, GetMachineType(input_node)); |
1078 } | 1219 } |
1079 for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) { | 1220 for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) { |
1080 inputs->push_back(UseOrImmediate(&g, stack->InputAt(i))); | 1221 Node* input_node = stack->InputAt(i); |
| 1222 inputs->push_back(UseOrImmediate(&g, input_node)); |
| 1223 descriptor->SetType(value_index++, GetMachineType(input_node)); |
1081 } | 1224 } |
| 1225 DCHECK(value_index == descriptor->GetSize()); |
1082 } | 1226 } |
1083 | 1227 |
1084 | 1228 |
1085 #if !V8_TURBOFAN_BACKEND | 1229 #if !V8_TURBOFAN_BACKEND |
1086 | 1230 |
1087 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ | 1231 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ |
1088 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } | 1232 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } |
1089 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) | 1233 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) |
1090 #undef DECLARE_UNIMPLEMENTED_SELECTOR | 1234 #undef DECLARE_UNIMPLEMENTED_SELECTOR |
1091 | 1235 |
(...skipping 28 matching lines...) Expand all Loading... |
1120 | 1264 |
1121 | 1265 |
1122 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1266 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
1123 BasicBlock* deoptimization) {} | 1267 BasicBlock* deoptimization) {} |
1124 | 1268 |
1125 #endif // !V8_TURBOFAN_BACKEND | 1269 #endif // !V8_TURBOFAN_BACKEND |
1126 | 1270 |
1127 } // namespace compiler | 1271 } // namespace compiler |
1128 } // namespace internal | 1272 } // namespace internal |
1129 } // namespace v8 | 1273 } // namespace v8 |
OLD | NEW |