| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 buffer->output_nodes.push_back(call); | 289 buffer->output_nodes.push_back(call); |
| 290 } else { | 290 } else { |
| 291 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); | 291 buffer->output_nodes.resize(buffer->descriptor->ReturnCount(), NULL); |
| 292 call->CollectProjections(&buffer->output_nodes); | 292 call->CollectProjections(&buffer->output_nodes); |
| 293 } | 293 } |
| 294 | 294 |
| 295 // Filter out the outputs that aren't live because no projection uses them. | 295 // Filter out the outputs that aren't live because no projection uses them. |
| 296 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { | 296 for (size_t i = 0; i < buffer->output_nodes.size(); i++) { |
| 297 if (buffer->output_nodes[i] != NULL) { | 297 if (buffer->output_nodes[i] != NULL) { |
| 298 Node* output = buffer->output_nodes[i]; | 298 Node* output = buffer->output_nodes[i]; |
| 299 MachineType type = |
| 300 buffer->descriptor->GetReturnType(static_cast<int>(i)); |
| 299 LinkageLocation location = | 301 LinkageLocation location = |
| 300 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); | 302 buffer->descriptor->GetReturnLocation(static_cast<int>(i)); |
| 301 MarkAsRepresentation(location.representation(), output); | 303 MarkAsRepresentation(type, output); |
| 302 buffer->outputs.push_back(g.DefineAsLocation(output, location)); | 304 buffer->outputs.push_back(g.DefineAsLocation(output, location, type)); |
| 303 } | 305 } |
| 304 } | 306 } |
| 305 } | 307 } |
| 306 | 308 |
| 307 // The first argument is always the callee code. | 309 // The first argument is always the callee code. |
| 308 Node* callee = call->InputAt(0); | 310 Node* callee = call->InputAt(0); |
| 309 switch (buffer->descriptor->kind()) { | 311 switch (buffer->descriptor->kind()) { |
| 310 case CallDescriptor::kCallCodeObject: | 312 case CallDescriptor::kCallCodeObject: |
| 311 buffer->instruction_args.push_back( | 313 buffer->instruction_args.push_back( |
| 312 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) | 314 (call_code_immediate && callee->opcode() == IrOpcode::kHeapConstant) |
| 313 ? g.UseImmediate(callee) | 315 ? g.UseImmediate(callee) |
| 314 : g.UseRegister(callee)); | 316 : g.UseRegister(callee)); |
| 315 break; | 317 break; |
| 316 case CallDescriptor::kCallAddress: | 318 case CallDescriptor::kCallAddress: |
| 317 buffer->instruction_args.push_back( | 319 buffer->instruction_args.push_back( |
| 318 (call_address_immediate && | 320 (call_address_immediate && |
| 319 (callee->opcode() == IrOpcode::kInt32Constant || | 321 (callee->opcode() == IrOpcode::kInt32Constant || |
| 320 callee->opcode() == IrOpcode::kInt64Constant)) | 322 callee->opcode() == IrOpcode::kInt64Constant)) |
| 321 ? g.UseImmediate(callee) | 323 ? g.UseImmediate(callee) |
| 322 : g.UseRegister(callee)); | 324 : g.UseRegister(callee)); |
| 323 break; | 325 break; |
| 324 case CallDescriptor::kCallJSFunction: | 326 case CallDescriptor::kCallJSFunction: |
| 325 buffer->instruction_args.push_back( | 327 buffer->instruction_args.push_back( |
| 326 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0))); | 328 g.UseLocation(callee, buffer->descriptor->GetInputLocation(0), |
| 329 buffer->descriptor->GetInputType(0))); |
| 327 break; | 330 break; |
| 328 } | 331 } |
| 329 DCHECK_EQ(1, buffer->instruction_args.size()); | 332 DCHECK_EQ(1, buffer->instruction_args.size()); |
| 330 | 333 |
| 331 // If the call needs a frame state, we insert the state information as | 334 // If the call needs a frame state, we insert the state information as |
| 332 // follows (n is the number of value inputs to the frame state): | 335 // follows (n is the number of value inputs to the frame state): |
| 333 // arg 1 : deoptimization id. | 336 // arg 1 : deoptimization id. |
| 334 // arg 2 - arg (n + 1) : value inputs to the frame state. | 337 // arg 2 - arg (n + 1) : value inputs to the frame state. |
| 335 if (buffer->frame_state_descriptor != NULL) { | 338 if (buffer->frame_state_descriptor != NULL) { |
| 336 InstructionSequence::StateId state_id = | 339 InstructionSequence::StateId state_id = |
| 337 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); | 340 sequence()->AddFrameStateDescriptor(buffer->frame_state_descriptor); |
| 338 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); | 341 buffer->instruction_args.push_back(g.TempImmediate(state_id.ToInt())); |
| 339 | 342 |
| 340 Node* frame_state = call->InputAt(buffer->descriptor->InputCount()); | 343 Node* frame_state = |
| 344 call->InputAt(static_cast<int>(buffer->descriptor->InputCount())); |
| 341 AddFrameStateInputs(frame_state, &buffer->instruction_args, | 345 AddFrameStateInputs(frame_state, &buffer->instruction_args, |
| 342 buffer->frame_state_descriptor); | 346 buffer->frame_state_descriptor); |
| 343 } | 347 } |
| 344 DCHECK_EQ(1 + buffer->frame_state_value_count(), | 348 DCHECK(1 + buffer->frame_state_value_count() == |
| 345 buffer->instruction_args.size()); | 349 buffer->instruction_args.size()); |
| 346 | 350 |
| 347 int input_count = buffer->input_count(); | 351 size_t input_count = static_cast<size_t>(buffer->input_count()); |
| 348 | 352 |
| 349 // Split the arguments into pushed_nodes and instruction_args. Pushed | 353 // Split the arguments into pushed_nodes and instruction_args. Pushed |
| 350 // arguments require an explicit push instruction before the call and do | 354 // arguments require an explicit push instruction before the call and do |
| 351 // not appear as arguments to the call. Everything else ends up | 355 // not appear as arguments to the call. Everything else ends up |
| 352 // as an InstructionOperand argument to the call. | 356 // as an InstructionOperand argument to the call. |
| 353 InputIter iter(call->inputs().begin()); | 357 InputIter iter(call->inputs().begin()); |
| 354 int pushed_count = 0; | 358 int pushed_count = 0; |
| 355 for (int index = 0; index < input_count; ++iter, ++index) { | 359 for (size_t index = 0; index < input_count; ++iter, ++index) { |
| 356 DCHECK(iter != call->inputs().end()); | 360 DCHECK(iter != call->inputs().end()); |
| 357 DCHECK(index == iter.index()); | 361 DCHECK(index == static_cast<size_t>(iter.index())); |
| 358 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); | 362 DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); |
| 359 if (index == 0) continue; // The first argument (callee) is already done. | 363 if (index == 0) continue; // The first argument (callee) is already done. |
| 360 InstructionOperand* op = | 364 InstructionOperand* op = |
| 361 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index)); | 365 g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), |
| 366 buffer->descriptor->GetInputType(index)); |
| 362 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { | 367 if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { |
| 363 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; | 368 int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; |
| 364 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { | 369 if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) { |
| 365 buffer->pushed_nodes.resize(stack_index + 1, NULL); | 370 buffer->pushed_nodes.resize(stack_index + 1, NULL); |
| 366 } | 371 } |
| 367 DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); | 372 DCHECK_EQ(NULL, buffer->pushed_nodes[stack_index]); |
| 368 buffer->pushed_nodes[stack_index] = *iter; | 373 buffer->pushed_nodes[stack_index] = *iter; |
| 369 pushed_count++; | 374 pushed_count++; |
| 370 } else { | 375 } else { |
| 371 buffer->instruction_args.push_back(op); | 376 buffer->instruction_args.push_back(op); |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 case IrOpcode::kBranch: | 480 case IrOpcode::kBranch: |
| 476 case IrOpcode::kIfTrue: | 481 case IrOpcode::kIfTrue: |
| 477 case IrOpcode::kIfFalse: | 482 case IrOpcode::kIfFalse: |
| 478 case IrOpcode::kEffectPhi: | 483 case IrOpcode::kEffectPhi: |
| 479 case IrOpcode::kMerge: | 484 case IrOpcode::kMerge: |
| 480 // No code needed for these graph artifacts. | 485 // No code needed for these graph artifacts. |
| 481 return; | 486 return; |
| 482 case IrOpcode::kFinish: | 487 case IrOpcode::kFinish: |
| 483 return MarkAsReference(node), VisitFinish(node); | 488 return MarkAsReference(node), VisitFinish(node); |
| 484 case IrOpcode::kParameter: { | 489 case IrOpcode::kParameter: { |
| 485 LinkageLocation location = | 490 MachineType type = linkage()->GetParameterType(OpParameter<int>(node)); |
| 486 linkage()->GetParameterLocation(OpParameter<int>(node)); | 491 MarkAsRepresentation(type, node); |
| 487 MarkAsRepresentation(location.representation(), node); | |
| 488 return VisitParameter(node); | 492 return VisitParameter(node); |
| 489 } | 493 } |
| 490 case IrOpcode::kPhi: | 494 case IrOpcode::kPhi: |
| 491 return VisitPhi(node); | 495 return VisitPhi(node); |
| 492 case IrOpcode::kProjection: | 496 case IrOpcode::kProjection: |
| 493 return VisitProjection(node); | 497 return VisitProjection(node); |
| 494 case IrOpcode::kInt32Constant: | 498 case IrOpcode::kInt32Constant: |
| 495 case IrOpcode::kInt64Constant: | 499 case IrOpcode::kInt64Constant: |
| 496 case IrOpcode::kExternalConstant: | 500 case IrOpcode::kExternalConstant: |
| 497 return VisitConstant(node); | 501 return VisitConstant(node); |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 | 817 |
| 814 void InstructionSelector::VisitFinish(Node* node) { | 818 void InstructionSelector::VisitFinish(Node* node) { |
| 815 OperandGenerator g(this); | 819 OperandGenerator g(this); |
| 816 Node* value = node->InputAt(0); | 820 Node* value = node->InputAt(0); |
| 817 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); | 821 Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value)); |
| 818 } | 822 } |
| 819 | 823 |
| 820 | 824 |
| 821 void InstructionSelector::VisitParameter(Node* node) { | 825 void InstructionSelector::VisitParameter(Node* node) { |
| 822 OperandGenerator g(this); | 826 OperandGenerator g(this); |
| 823 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( | 827 int index = OpParameter<int>(node); |
| 824 OpParameter<int>(node)))); | 828 Emit(kArchNop, |
| 829 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), |
| 830 linkage()->GetParameterType(index))); |
| 825 } | 831 } |
| 826 | 832 |
| 827 | 833 |
| 828 void InstructionSelector::VisitPhi(Node* node) { | 834 void InstructionSelector::VisitPhi(Node* node) { |
| 829 // TODO(bmeurer): Emit a PhiInstruction here. | 835 // TODO(bmeurer): Emit a PhiInstruction here. |
| 830 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 836 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { |
| 831 MarkAsUsed(*i); | 837 MarkAsUsed(*i); |
| 832 } | 838 } |
| 833 } | 839 } |
| 834 | 840 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 } | 984 } |
| 979 | 985 |
| 980 // Branch could not be combined with a compare, emit compare against 0. | 986 // Branch could not be combined with a compare, emit compare against 0. |
| 981 VisitWord32Test(value, &cont); | 987 VisitWord32Test(value, &cont); |
| 982 } | 988 } |
| 983 | 989 |
| 984 | 990 |
| 985 void InstructionSelector::VisitReturn(Node* value) { | 991 void InstructionSelector::VisitReturn(Node* value) { |
| 986 OperandGenerator g(this); | 992 OperandGenerator g(this); |
| 987 if (value != NULL) { | 993 if (value != NULL) { |
| 988 Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation())); | 994 Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), |
| 995 linkage()->GetReturnType())); |
| 989 } else { | 996 } else { |
| 990 Emit(kArchRet, NULL); | 997 Emit(kArchRet, NULL); |
| 991 } | 998 } |
| 992 } | 999 } |
| 993 | 1000 |
| 994 | 1001 |
| 995 void InstructionSelector::VisitThrow(Node* value) { | 1002 void InstructionSelector::VisitThrow(Node* value) { |
| 996 UNIMPLEMENTED(); // TODO(titzer) | 1003 UNIMPLEMENTED(); // TODO(titzer) |
| 997 } | 1004 } |
| 998 | 1005 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 | 1101 |
| 1095 | 1102 |
| 1096 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 1103 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
| 1097 BasicBlock* deoptimization) {} | 1104 BasicBlock* deoptimization) {} |
| 1098 | 1105 |
| 1099 #endif // !V8_TURBOFAN_BACKEND | 1106 #endif // !V8_TURBOFAN_BACKEND |
| 1100 | 1107 |
| 1101 } // namespace compiler | 1108 } // namespace compiler |
| 1102 } // namespace internal | 1109 } // namespace internal |
| 1103 } // namespace v8 | 1110 } // namespace v8 |
| OLD | NEW |