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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 case BasicBlockData::kReturn: { | 416 case BasicBlockData::kReturn: { |
417 // If the result itself is a return, return its input. | 417 // If the result itself is a return, return its input. |
418 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) | 418 Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) |
419 ? input->InputAt(0) | 419 ? input->InputAt(0) |
420 : input; | 420 : input; |
421 return VisitReturn(value); | 421 return VisitReturn(value); |
422 } | 422 } |
423 case BasicBlockData::kThrow: | 423 case BasicBlockData::kThrow: |
424 return VisitThrow(input); | 424 return VisitThrow(input); |
425 case BasicBlockData::kDeoptimize: | 425 case BasicBlockData::kDeoptimize: |
426 return VisitDeoptimization(input); | 426 return VisitDeoptimize(input); |
427 case BasicBlockData::kCall: { | 427 case BasicBlockData::kCall: { |
428 BasicBlock* deoptimization = block->SuccessorAt(0); | 428 BasicBlock* deoptimization = block->SuccessorAt(0); |
429 BasicBlock* continuation = block->SuccessorAt(1); | 429 BasicBlock* continuation = block->SuccessorAt(1); |
430 VisitCall(input, continuation, deoptimization); | 430 VisitCall(input, continuation, deoptimization); |
431 break; | 431 break; |
432 } | 432 } |
433 case BasicBlockData::kNone: { | 433 case BasicBlockData::kNone: { |
434 // TODO(titzer): exit block doesn't have control. | 434 // TODO(titzer): exit block doesn't have control. |
435 DCHECK(input == NULL); | 435 DCHECK(input == NULL); |
436 break; | 436 break; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 return VisitConstant(node); | 483 return VisitConstant(node); |
484 case IrOpcode::kFloat64Constant: | 484 case IrOpcode::kFloat64Constant: |
485 return MarkAsDouble(node), VisitConstant(node); | 485 return MarkAsDouble(node), VisitConstant(node); |
486 case IrOpcode::kHeapConstant: | 486 case IrOpcode::kHeapConstant: |
487 case IrOpcode::kNumberConstant: | 487 case IrOpcode::kNumberConstant: |
488 // TODO(turbofan): only mark non-smis as references. | 488 // TODO(turbofan): only mark non-smis as references. |
489 return MarkAsReference(node), VisitConstant(node); | 489 return MarkAsReference(node), VisitConstant(node); |
490 case IrOpcode::kCall: | 490 case IrOpcode::kCall: |
491 return VisitCall(node, NULL, NULL); | 491 return VisitCall(node, NULL, NULL); |
492 case IrOpcode::kFrameState: | 492 case IrOpcode::kFrameState: |
493 // TODO(titzer): state nodes should be combined into their users. | 493 case IrOpcode::kStateValues: |
494 return; | 494 return; |
495 case IrOpcode::kLoad: { | 495 case IrOpcode::kLoad: { |
496 MachineRepresentation load_rep = OpParameter<MachineRepresentation>(node); | 496 MachineRepresentation load_rep = OpParameter<MachineRepresentation>(node); |
497 MarkAsRepresentation(load_rep, node); | 497 MarkAsRepresentation(load_rep, node); |
498 return VisitLoad(node); | 498 return VisitLoad(node); |
499 } | 499 } |
500 case IrOpcode::kStore: | 500 case IrOpcode::kStore: |
501 return VisitStore(node); | 501 return VisitStore(node); |
502 case IrOpcode::kWord32And: | 502 case IrOpcode::kWord32And: |
503 return VisitWord32And(node); | 503 return VisitWord32And(node); |
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 Emit(kArchRet, NULL); | 946 Emit(kArchRet, NULL); |
947 } | 947 } |
948 } | 948 } |
949 | 949 |
950 | 950 |
951 void InstructionSelector::VisitThrow(Node* value) { | 951 void InstructionSelector::VisitThrow(Node* value) { |
952 UNIMPLEMENTED(); // TODO(titzer) | 952 UNIMPLEMENTED(); // TODO(titzer) |
953 } | 953 } |
954 | 954 |
955 | 955 |
956 void InstructionSelector::VisitDeoptimization(Node* deopt) { | 956 static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) { |
| 957 switch (input->opcode()) { |
| 958 case IrOpcode::kInt32Constant: |
| 959 case IrOpcode::kNumberConstant: |
| 960 case IrOpcode::kFloat64Constant: |
| 961 case IrOpcode::kHeapConstant: |
| 962 return g->UseImmediate(input); |
| 963 default: |
| 964 return g->Use(input); |
| 965 } |
| 966 } |
| 967 |
| 968 |
| 969 void InstructionSelector::VisitDeoptimize(Node* deopt) { |
957 DCHECK(deopt->op()->opcode() == IrOpcode::kDeoptimize); | 970 DCHECK(deopt->op()->opcode() == IrOpcode::kDeoptimize); |
958 Node* state = deopt->InputAt(0); | 971 Node* state = deopt->InputAt(0); |
959 DCHECK(state->op()->opcode() == IrOpcode::kFrameState); | 972 DCHECK(state->op()->opcode() == IrOpcode::kFrameState); |
960 FrameStateDescriptor descriptor = OpParameter<FrameStateDescriptor>(state); | 973 BailoutId ast_id = OpParameter<BailoutId>(state); |
961 // TODO(jarin) We should also add an instruction input for every input to | 974 |
962 // the framestate node (and recurse for the inlined framestates). | 975 // Add the inputs. |
| 976 Node* parameters = state->InputAt(0); |
| 977 int parameters_count = OpParameter<int>(parameters); |
| 978 |
| 979 Node* locals = state->InputAt(1); |
| 980 int locals_count = OpParameter<int>(locals); |
| 981 |
| 982 Node* stack = state->InputAt(2); |
| 983 int stack_count = OpParameter<int>(stack); |
| 984 |
| 985 OperandGenerator g(this); |
| 986 std::vector<InstructionOperand*> inputs; |
| 987 inputs.reserve(parameters_count + locals_count + stack_count); |
| 988 for (int i = 0; i < parameters_count; i++) { |
| 989 inputs.push_back(UseOrImmediate(&g, parameters->InputAt(i))); |
| 990 } |
| 991 for (int i = 0; i < locals_count; i++) { |
| 992 inputs.push_back(UseOrImmediate(&g, locals->InputAt(i))); |
| 993 } |
| 994 for (int i = 0; i < stack_count; i++) { |
| 995 inputs.push_back(UseOrImmediate(&g, stack->InputAt(i))); |
| 996 } |
| 997 |
| 998 FrameStateDescriptor* descriptor = new (instruction_zone()) |
| 999 FrameStateDescriptor(ast_id, parameters_count, locals_count, stack_count); |
| 1000 |
| 1001 DCHECK_EQ(descriptor->size(), inputs.size()); |
| 1002 |
963 int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor); | 1003 int deoptimization_id = sequence()->AddDeoptimizationEntry(descriptor); |
964 Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), NULL); | 1004 Emit(kArchDeoptimize | MiscField::encode(deoptimization_id), 0, NULL, |
| 1005 inputs.size(), &inputs.front(), 0, NULL); |
965 } | 1006 } |
966 | 1007 |
967 | 1008 |
968 #if !V8_TURBOFAN_BACKEND | 1009 #if !V8_TURBOFAN_BACKEND |
969 | 1010 |
970 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ | 1011 #define DECLARE_UNIMPLEMENTED_SELECTOR(x) \ |
971 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } | 1012 void InstructionSelector::Visit##x(Node* node) { UNIMPLEMENTED(); } |
972 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) | 1013 MACHINE_OP_LIST(DECLARE_UNIMPLEMENTED_SELECTOR) |
973 #undef DECLARE_UNIMPLEMENTED_SELECTOR | 1014 #undef DECLARE_UNIMPLEMENTED_SELECTOR |
974 | 1015 |
(...skipping 28 matching lines...) Expand all Loading... |
1003 | 1044 |
1004 | 1045 |
1005 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1046 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
1006 BasicBlock* deoptimization) {} | 1047 BasicBlock* deoptimization) {} |
1007 | 1048 |
1008 #endif // !V8_TURBOFAN_BACKEND | 1049 #endif // !V8_TURBOFAN_BACKEND |
1009 | 1050 |
1010 } // namespace compiler | 1051 } // namespace compiler |
1011 } // namespace internal | 1052 } // namespace internal |
1012 } // namespace v8 | 1053 } // namespace v8 |
OLD | NEW |