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