| 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/compiler/instruction-selector-impl.h" | 9 #include "src/compiler/instruction-selector-impl.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 DCHECK_NULL(input); | 567 DCHECK_NULL(input); |
| 568 break; | 568 break; |
| 569 } | 569 } |
| 570 default: | 570 default: |
| 571 UNREACHABLE(); | 571 UNREACHABLE(); |
| 572 break; | 572 break; |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 MachineType InstructionSelector::GetMachineType(Node* node) { | |
| 578 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. | |
| 579 switch (node->opcode()) { | |
| 580 case IrOpcode::kStart: | |
| 581 case IrOpcode::kLoop: | |
| 582 case IrOpcode::kEnd: | |
| 583 case IrOpcode::kBranch: | |
| 584 case IrOpcode::kIfTrue: | |
| 585 case IrOpcode::kIfFalse: | |
| 586 case IrOpcode::kSwitch: | |
| 587 case IrOpcode::kIfValue: | |
| 588 case IrOpcode::kIfDefault: | |
| 589 case IrOpcode::kEffectPhi: | |
| 590 case IrOpcode::kEffectSet: | |
| 591 case IrOpcode::kMerge: | |
| 592 // No code needed for these graph artifacts. | |
| 593 return kMachNone; | |
| 594 case IrOpcode::kFinish: | |
| 595 return kMachAnyTagged; | |
| 596 case IrOpcode::kParameter: | |
| 597 return linkage()->GetParameterType(OpParameter<int>(node)); | |
| 598 case IrOpcode::kOsrValue: | |
| 599 return kMachAnyTagged; | |
| 600 case IrOpcode::kPhi: | |
| 601 return OpParameter<MachineType>(node); | |
| 602 case IrOpcode::kProjection: | |
| 603 // TODO(jarin) Really project from outputs. | |
| 604 return kMachAnyTagged; | |
| 605 case IrOpcode::kInt32Constant: | |
| 606 return kMachInt32; | |
| 607 case IrOpcode::kInt64Constant: | |
| 608 return kMachInt64; | |
| 609 case IrOpcode::kExternalConstant: | |
| 610 return kMachPtr; | |
| 611 case IrOpcode::kFloat64Constant: | |
| 612 return kMachFloat64; | |
| 613 case IrOpcode::kHeapConstant: | |
| 614 case IrOpcode::kNumberConstant: | |
| 615 return kMachAnyTagged; | |
| 616 case IrOpcode::kCall: | |
| 617 return kMachAnyTagged; | |
| 618 case IrOpcode::kFrameState: | |
| 619 case IrOpcode::kStateValues: | |
| 620 return kMachNone; | |
| 621 case IrOpcode::kLoad: | |
| 622 return OpParameter<LoadRepresentation>(node); | |
| 623 case IrOpcode::kStore: | |
| 624 return kMachNone; | |
| 625 case IrOpcode::kCheckedLoad: | |
| 626 return OpParameter<MachineType>(node); | |
| 627 case IrOpcode::kCheckedStore: | |
| 628 return kMachNone; | |
| 629 case IrOpcode::kWord32And: | |
| 630 case IrOpcode::kWord32Or: | |
| 631 case IrOpcode::kWord32Xor: | |
| 632 case IrOpcode::kWord32Shl: | |
| 633 case IrOpcode::kWord32Shr: | |
| 634 case IrOpcode::kWord32Sar: | |
| 635 case IrOpcode::kWord32Ror: | |
| 636 return kMachInt32; | |
| 637 case IrOpcode::kWord32Equal: | |
| 638 return kMachBool; | |
| 639 case IrOpcode::kWord64And: | |
| 640 case IrOpcode::kWord64Or: | |
| 641 case IrOpcode::kWord64Xor: | |
| 642 case IrOpcode::kWord64Shl: | |
| 643 case IrOpcode::kWord64Shr: | |
| 644 case IrOpcode::kWord64Sar: | |
| 645 case IrOpcode::kWord64Ror: | |
| 646 return kMachInt64; | |
| 647 case IrOpcode::kWord64Equal: | |
| 648 return kMachBool; | |
| 649 case IrOpcode::kInt32Add: | |
| 650 case IrOpcode::kInt32AddWithOverflow: | |
| 651 case IrOpcode::kInt32Sub: | |
| 652 case IrOpcode::kInt32SubWithOverflow: | |
| 653 case IrOpcode::kInt32Mul: | |
| 654 case IrOpcode::kInt32Div: | |
| 655 case IrOpcode::kInt32Mod: | |
| 656 return kMachInt32; | |
| 657 case IrOpcode::kInt32LessThan: | |
| 658 case IrOpcode::kInt32LessThanOrEqual: | |
| 659 case IrOpcode::kUint32LessThan: | |
| 660 case IrOpcode::kUint32LessThanOrEqual: | |
| 661 return kMachBool; | |
| 662 case IrOpcode::kInt64Add: | |
| 663 case IrOpcode::kInt64Sub: | |
| 664 case IrOpcode::kInt64Mul: | |
| 665 case IrOpcode::kInt64Div: | |
| 666 case IrOpcode::kInt64Mod: | |
| 667 return kMachInt64; | |
| 668 case IrOpcode::kInt64LessThan: | |
| 669 case IrOpcode::kInt64LessThanOrEqual: | |
| 670 return kMachBool; | |
| 671 case IrOpcode::kChangeFloat32ToFloat64: | |
| 672 case IrOpcode::kChangeInt32ToFloat64: | |
| 673 case IrOpcode::kChangeUint32ToFloat64: | |
| 674 return kMachFloat64; | |
| 675 case IrOpcode::kChangeFloat64ToInt32: | |
| 676 return kMachInt32; | |
| 677 case IrOpcode::kChangeFloat64ToUint32: | |
| 678 return kMachUint32; | |
| 679 case IrOpcode::kChangeInt32ToInt64: | |
| 680 return kMachInt64; | |
| 681 case IrOpcode::kChangeUint32ToUint64: | |
| 682 return kMachUint64; | |
| 683 case IrOpcode::kTruncateFloat64ToFloat32: | |
| 684 return kMachFloat32; | |
| 685 case IrOpcode::kTruncateFloat64ToInt32: | |
| 686 case IrOpcode::kTruncateInt64ToInt32: | |
| 687 return kMachInt32; | |
| 688 case IrOpcode::kFloat64Add: | |
| 689 case IrOpcode::kFloat64Sub: | |
| 690 case IrOpcode::kFloat64Mul: | |
| 691 case IrOpcode::kFloat64Div: | |
| 692 case IrOpcode::kFloat64Mod: | |
| 693 case IrOpcode::kFloat64Max: | |
| 694 case IrOpcode::kFloat64Min: | |
| 695 case IrOpcode::kFloat64Sqrt: | |
| 696 case IrOpcode::kFloat64RoundDown: | |
| 697 case IrOpcode::kFloat64RoundTruncate: | |
| 698 case IrOpcode::kFloat64RoundTiesAway: | |
| 699 return kMachFloat64; | |
| 700 case IrOpcode::kFloat64Equal: | |
| 701 case IrOpcode::kFloat64LessThan: | |
| 702 case IrOpcode::kFloat64LessThanOrEqual: | |
| 703 return kMachBool; | |
| 704 case IrOpcode::kFloat64ExtractLowWord32: | |
| 705 case IrOpcode::kFloat64ExtractHighWord32: | |
| 706 return kMachInt32; | |
| 707 case IrOpcode::kFloat64InsertLowWord32: | |
| 708 case IrOpcode::kFloat64InsertHighWord32: | |
| 709 return kMachFloat64; | |
| 710 default: | |
| 711 V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d", | |
| 712 node->opcode(), node->op()->mnemonic(), node->id()); | |
| 713 } | |
| 714 return kMachNone; | |
| 715 } | |
| 716 | |
| 717 | |
| 718 void InstructionSelector::VisitNode(Node* node) { | 577 void InstructionSelector::VisitNode(Node* node) { |
| 719 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. | 578 DCHECK_NOT_NULL(schedule()->block(node)); // should only use scheduled nodes. |
| 720 SourcePosition source_position = source_positions_->GetSourcePosition(node); | 579 SourcePosition source_position = source_positions_->GetSourcePosition(node); |
| 721 if (!source_position.IsUnknown()) { | 580 if (!source_position.IsUnknown()) { |
| 722 DCHECK(!source_position.IsInvalid()); | 581 DCHECK(!source_position.IsInvalid()); |
| 723 if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) { | 582 if (FLAG_turbo_source_positions || node->opcode() == IrOpcode::kCall) { |
| 724 Emit(SourcePositionInstruction::New(instruction_zone(), source_position)); | 583 Emit(SourcePositionInstruction::New(instruction_zone(), source_position)); |
| 725 } | 584 } |
| 726 } | 585 } |
| 727 switch (node->opcode()) { | 586 switch (node->opcode()) { |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1142 void InstructionSelector::VisitThrow(Node* value) { | 1001 void InstructionSelector::VisitThrow(Node* value) { |
| 1143 OperandGenerator g(this); | 1002 OperandGenerator g(this); |
| 1144 Emit(kArchNop, g.NoOutput()); // TODO(titzer) | 1003 Emit(kArchNop, g.NoOutput()); // TODO(titzer) |
| 1145 } | 1004 } |
| 1146 | 1005 |
| 1147 | 1006 |
| 1148 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( | 1007 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( |
| 1149 Node* state) { | 1008 Node* state) { |
| 1150 DCHECK(state->opcode() == IrOpcode::kFrameState); | 1009 DCHECK(state->opcode() == IrOpcode::kFrameState); |
| 1151 DCHECK_EQ(5, state->InputCount()); | 1010 DCHECK_EQ(5, state->InputCount()); |
| 1152 DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(0)->opcode()); | 1011 DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(0)->opcode()); |
| 1153 DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(1)->opcode()); | 1012 DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(1)->opcode()); |
| 1154 DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(2)->opcode()); | 1013 DCHECK_EQ(IrOpcode::kTypedStateValues, state->InputAt(2)->opcode()); |
| 1155 FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state); | 1014 FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state); |
| 1156 | 1015 |
| 1157 int parameters = | 1016 int parameters = |
| 1158 static_cast<int>(StateValuesAccess(state->InputAt(0)).size()); | 1017 static_cast<int>(StateValuesAccess(state->InputAt(0)).size()); |
| 1159 int locals = static_cast<int>(StateValuesAccess(state->InputAt(1)).size()); | 1018 int locals = static_cast<int>(StateValuesAccess(state->InputAt(1)).size()); |
| 1160 int stack = static_cast<int>(StateValuesAccess(state->InputAt(2)).size()); | 1019 int stack = static_cast<int>(StateValuesAccess(state->InputAt(2)).size()); |
| 1161 | 1020 |
| 1162 FrameStateDescriptor* outer_state = NULL; | 1021 FrameStateDescriptor* outer_state = NULL; |
| 1163 Node* outer_node = state->InputAt(4); | 1022 Node* outer_node = state->InputAt(4); |
| 1164 if (outer_node->opcode() == IrOpcode::kFrameState) { | 1023 if (outer_node->opcode() == IrOpcode::kFrameState) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1190 | 1049 |
| 1191 if (descriptor->outer_state() != NULL) { | 1050 if (descriptor->outer_state() != NULL) { |
| 1192 AddFrameStateInputs(state->InputAt(4), inputs, descriptor->outer_state()); | 1051 AddFrameStateInputs(state->InputAt(4), inputs, descriptor->outer_state()); |
| 1193 } | 1052 } |
| 1194 | 1053 |
| 1195 Node* parameters = state->InputAt(0); | 1054 Node* parameters = state->InputAt(0); |
| 1196 Node* locals = state->InputAt(1); | 1055 Node* locals = state->InputAt(1); |
| 1197 Node* stack = state->InputAt(2); | 1056 Node* stack = state->InputAt(2); |
| 1198 Node* context = state->InputAt(3); | 1057 Node* context = state->InputAt(3); |
| 1199 | 1058 |
| 1200 DCHECK_EQ(IrOpcode::kStateValues, parameters->op()->opcode()); | 1059 DCHECK_EQ(IrOpcode::kTypedStateValues, parameters->op()->opcode()); |
| 1201 DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode()); | 1060 DCHECK_EQ(IrOpcode::kTypedStateValues, locals->op()->opcode()); |
| 1202 DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode()); | 1061 DCHECK_EQ(IrOpcode::kTypedStateValues, stack->op()->opcode()); |
| 1203 | 1062 |
| 1204 DCHECK_EQ(descriptor->parameters_count(), | 1063 DCHECK_EQ(descriptor->parameters_count(), |
| 1205 StateValuesAccess(parameters).size()); | 1064 StateValuesAccess(parameters).size()); |
| 1206 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); | 1065 DCHECK_EQ(descriptor->locals_count(), StateValuesAccess(locals).size()); |
| 1207 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); | 1066 DCHECK_EQ(descriptor->stack_count(), StateValuesAccess(stack).size()); |
| 1208 | 1067 |
| 1209 ZoneVector<MachineType> types(instruction_zone()); | 1068 ZoneVector<MachineType> types(instruction_zone()); |
| 1210 types.reserve(descriptor->GetSize()); | 1069 types.reserve(descriptor->GetSize()); |
| 1211 | 1070 |
| 1212 OperandGenerator g(this); | 1071 OperandGenerator g(this); |
| 1213 size_t value_index = 0; | 1072 size_t value_index = 0; |
| 1214 for (Node* input_node : StateValuesAccess(parameters)) { | 1073 for (StateValuesAccess::TypedNode input_node : |
| 1215 inputs->push_back(UseOrImmediate(&g, input_node)); | 1074 StateValuesAccess(parameters)) { |
| 1216 descriptor->SetType(value_index++, GetMachineType(input_node)); | 1075 inputs->push_back(UseOrImmediate(&g, input_node.node)); |
| 1076 descriptor->SetType(value_index++, input_node.type); |
| 1217 } | 1077 } |
| 1218 if (descriptor->HasContext()) { | 1078 if (descriptor->HasContext()) { |
| 1219 inputs->push_back(UseOrImmediate(&g, context)); | 1079 inputs->push_back(UseOrImmediate(&g, context)); |
| 1220 descriptor->SetType(value_index++, kMachAnyTagged); | 1080 descriptor->SetType(value_index++, kMachAnyTagged); |
| 1221 } | 1081 } |
| 1222 for (Node* input_node : StateValuesAccess(locals)) { | 1082 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) { |
| 1223 inputs->push_back(UseOrImmediate(&g, input_node)); | 1083 inputs->push_back(UseOrImmediate(&g, input_node.node)); |
| 1224 descriptor->SetType(value_index++, GetMachineType(input_node)); | 1084 descriptor->SetType(value_index++, input_node.type); |
| 1225 } | 1085 } |
| 1226 for (Node* input_node : StateValuesAccess(stack)) { | 1086 for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) { |
| 1227 inputs->push_back(UseOrImmediate(&g, input_node)); | 1087 inputs->push_back(UseOrImmediate(&g, input_node.node)); |
| 1228 descriptor->SetType(value_index++, GetMachineType(input_node)); | 1088 descriptor->SetType(value_index++, input_node.type); |
| 1229 } | 1089 } |
| 1230 DCHECK(value_index == descriptor->GetSize()); | 1090 DCHECK(value_index == descriptor->GetSize()); |
| 1231 } | 1091 } |
| 1232 | 1092 |
| 1233 | 1093 |
| 1234 #if !V8_TURBOFAN_BACKEND | 1094 #if !V8_TURBOFAN_BACKEND |
| 1235 | 1095 |
| 1236 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ | 1096 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ |
| 1237 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } | 1097 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } |
| 1238 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) | 1098 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1262 MachineOperatorBuilder::Flags | 1122 MachineOperatorBuilder::Flags |
| 1263 InstructionSelector::SupportedMachineOperatorFlags() { | 1123 InstructionSelector::SupportedMachineOperatorFlags() { |
| 1264 return MachineOperatorBuilder::Flag::kNoFlags; | 1124 return MachineOperatorBuilder::Flag::kNoFlags; |
| 1265 } | 1125 } |
| 1266 | 1126 |
| 1267 #endif // !V8_TURBOFAN_BACKEND | 1127 #endif // !V8_TURBOFAN_BACKEND |
| 1268 | 1128 |
| 1269 } // namespace compiler | 1129 } // namespace compiler |
| 1270 } // namespace internal | 1130 } // namespace internal |
| 1271 } // namespace v8 | 1131 } // namespace v8 |
| OLD | NEW |