| 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 |