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 |