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 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 BasicBlock* deopt_node) { | 245 BasicBlock* deopt_node) { |
246 OperandGenerator g(this); | 246 OperandGenerator g(this); |
247 ASSERT_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount()); | 247 ASSERT_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount()); |
248 ASSERT_EQ(NodeProperties::GetValueInputCount(call), buffer->input_count()); | 248 ASSERT_EQ(NodeProperties::GetValueInputCount(call), buffer->input_count()); |
249 | 249 |
250 if (buffer->descriptor->ReturnCount() > 0) { | 250 if (buffer->descriptor->ReturnCount() > 0) { |
251 // Collect the projections that represent multiple outputs from this call. | 251 // Collect the projections that represent multiple outputs from this call. |
252 if (buffer->descriptor->ReturnCount() == 1) { | 252 if (buffer->descriptor->ReturnCount() == 1) { |
253 buffer->output_nodes[0] = call; | 253 buffer->output_nodes[0] = call; |
254 } else { | 254 } else { |
255 // Iterate over all uses of {call} and collect the projections into the | 255 call->CollectProjections(buffer->descriptor->ReturnCount(), |
256 // {result} buffer. | 256 buffer->output_nodes); |
257 for (UseIter i = call->uses().begin(); i != call->uses().end(); ++i) { | |
258 if ((*i)->opcode() == IrOpcode::kProjection) { | |
259 int index = OpParameter<int32_t>(*i); | |
260 ASSERT_GE(index, 0); | |
261 ASSERT_LT(index, buffer->descriptor->ReturnCount()); | |
262 ASSERT_EQ(NULL, buffer->output_nodes[index]); | |
263 buffer->output_nodes[index] = *i; | |
264 } | |
265 } | |
266 } | 257 } |
267 | 258 |
268 // Filter out the outputs that aren't live because no projection uses them. | 259 // Filter out the outputs that aren't live because no projection uses them. |
269 for (int i = 0; i < buffer->descriptor->ReturnCount(); i++) { | 260 for (int i = 0; i < buffer->descriptor->ReturnCount(); i++) { |
270 if (buffer->output_nodes[i] != NULL) { | 261 if (buffer->output_nodes[i] != NULL) { |
271 Node* output = buffer->output_nodes[i]; | 262 Node* output = buffer->output_nodes[i]; |
272 LinkageLocation location = buffer->descriptor->GetReturnLocation(i); | 263 LinkageLocation location = buffer->descriptor->GetReturnLocation(i); |
273 MarkAsRepresentation(location.representation(), output); | 264 MarkAsRepresentation(location.representation(), output); |
274 buffer->outputs[buffer->output_count++] = | 265 buffer->outputs[buffer->output_count++] = |
275 g.DefineAsLocation(output, location); | 266 g.DefineAsLocation(output, location); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 } | 431 } |
441 switch (node->opcode()) { | 432 switch (node->opcode()) { |
442 case IrOpcode::kStart: | 433 case IrOpcode::kStart: |
443 case IrOpcode::kLoop: | 434 case IrOpcode::kLoop: |
444 case IrOpcode::kEnd: | 435 case IrOpcode::kEnd: |
445 case IrOpcode::kBranch: | 436 case IrOpcode::kBranch: |
446 case IrOpcode::kIfTrue: | 437 case IrOpcode::kIfTrue: |
447 case IrOpcode::kIfFalse: | 438 case IrOpcode::kIfFalse: |
448 case IrOpcode::kEffectPhi: | 439 case IrOpcode::kEffectPhi: |
449 case IrOpcode::kMerge: | 440 case IrOpcode::kMerge: |
450 case IrOpcode::kProjection: | |
451 case IrOpcode::kLazyDeoptimization: | 441 case IrOpcode::kLazyDeoptimization: |
452 case IrOpcode::kContinuation: | 442 case IrOpcode::kContinuation: |
453 // No code needed for these graph artifacts. | 443 // No code needed for these graph artifacts. |
454 return; | 444 return; |
455 case IrOpcode::kPhi: | |
456 return VisitPhi(node); | |
457 case IrOpcode::kParameter: { | 445 case IrOpcode::kParameter: { |
458 int index = OpParameter<int>(node); | 446 int index = OpParameter<int>(node); |
459 MachineRepresentation rep = linkage() | 447 MachineRepresentation rep = linkage() |
460 ->GetIncomingDescriptor() | 448 ->GetIncomingDescriptor() |
461 ->GetInputLocation(index) | 449 ->GetInputLocation(index) |
462 .representation(); | 450 .representation(); |
463 MarkAsRepresentation(rep, node); | 451 MarkAsRepresentation(rep, node); |
464 return VisitParameter(node); | 452 return VisitParameter(node); |
465 } | 453 } |
| 454 case IrOpcode::kPhi: |
| 455 return VisitPhi(node); |
| 456 case IrOpcode::kProjection: |
| 457 return VisitProjection(node); |
466 case IrOpcode::kInt32Constant: | 458 case IrOpcode::kInt32Constant: |
467 case IrOpcode::kInt64Constant: | 459 case IrOpcode::kInt64Constant: |
468 case IrOpcode::kExternalConstant: | 460 case IrOpcode::kExternalConstant: |
469 return VisitConstant(node); | 461 return VisitConstant(node); |
470 case IrOpcode::kFloat64Constant: | 462 case IrOpcode::kFloat64Constant: |
471 return MarkAsDouble(node), VisitConstant(node); | 463 return MarkAsDouble(node), VisitConstant(node); |
472 case IrOpcode::kHeapConstant: | 464 case IrOpcode::kHeapConstant: |
473 case IrOpcode::kNumberConstant: | 465 case IrOpcode::kNumberConstant: |
474 // TODO(turbofan): only mark non-smis as references. | 466 // TODO(turbofan): only mark non-smis as references. |
475 return MarkAsReference(node), VisitConstant(node); | 467 return MarkAsReference(node), VisitConstant(node); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 case IrOpcode::kWord64Shl: | 500 case IrOpcode::kWord64Shl: |
509 return VisitWord64Shl(node); | 501 return VisitWord64Shl(node); |
510 case IrOpcode::kWord64Shr: | 502 case IrOpcode::kWord64Shr: |
511 return VisitWord64Shr(node); | 503 return VisitWord64Shr(node); |
512 case IrOpcode::kWord64Sar: | 504 case IrOpcode::kWord64Sar: |
513 return VisitWord64Sar(node); | 505 return VisitWord64Sar(node); |
514 case IrOpcode::kWord64Equal: | 506 case IrOpcode::kWord64Equal: |
515 return VisitWord64Equal(node); | 507 return VisitWord64Equal(node); |
516 case IrOpcode::kInt32Add: | 508 case IrOpcode::kInt32Add: |
517 return VisitInt32Add(node); | 509 return VisitInt32Add(node); |
| 510 case IrOpcode::kInt32AddWithOverflow: |
| 511 return VisitInt32AddWithOverflow(node); |
518 case IrOpcode::kInt32Sub: | 512 case IrOpcode::kInt32Sub: |
519 return VisitInt32Sub(node); | 513 return VisitInt32Sub(node); |
520 case IrOpcode::kInt32Mul: | 514 case IrOpcode::kInt32Mul: |
521 return VisitInt32Mul(node); | 515 return VisitInt32Mul(node); |
522 case IrOpcode::kInt32Div: | 516 case IrOpcode::kInt32Div: |
523 return VisitInt32Div(node); | 517 return VisitInt32Div(node); |
524 case IrOpcode::kInt32UDiv: | 518 case IrOpcode::kInt32UDiv: |
525 return VisitInt32UDiv(node); | 519 return VisitInt32UDiv(node); |
526 case IrOpcode::kInt32Mod: | 520 case IrOpcode::kInt32Mod: |
527 return VisitInt32Mod(node); | 521 return VisitInt32Mod(node); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
729 | 723 |
730 | 724 |
731 void InstructionSelector::VisitWord64Compare(Node* node, | 725 void InstructionSelector::VisitWord64Compare(Node* node, |
732 FlagsContinuation* cont) { | 726 FlagsContinuation* cont) { |
733 UNIMPLEMENTED(); | 727 UNIMPLEMENTED(); |
734 } | 728 } |
735 | 729 |
736 #endif // V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_TARGET | 730 #endif // V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_TARGET |
737 | 731 |
738 | 732 |
| 733 void InstructionSelector::VisitParameter(Node* node) { |
| 734 OperandGenerator g(this); |
| 735 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( |
| 736 OpParameter<int>(node)))); |
| 737 } |
| 738 |
| 739 |
739 void InstructionSelector::VisitPhi(Node* node) { | 740 void InstructionSelector::VisitPhi(Node* node) { |
740 // TODO(bmeurer): Emit a PhiInstruction here. | 741 // TODO(bmeurer): Emit a PhiInstruction here. |
741 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { | 742 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { |
742 MarkAsUsed(*i); | 743 MarkAsUsed(*i); |
743 } | 744 } |
744 } | 745 } |
745 | 746 |
746 | 747 |
747 void InstructionSelector::VisitParameter(Node* node) { | 748 void InstructionSelector::VisitProjection(Node* node) { |
748 OperandGenerator g(this); | 749 for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { |
749 Emit(kArchNop, g.DefineAsLocation(node, linkage()->GetParameterLocation( | 750 MarkAsUsed(*i); |
750 OpParameter<int>(node)))); | 751 } |
751 } | 752 } |
752 | 753 |
753 | 754 |
754 void InstructionSelector::VisitConstant(Node* node) { | 755 void InstructionSelector::VisitConstant(Node* node) { |
755 // We must emit a NOP here because every live range needs a defining | 756 // We must emit a NOP here because every live range needs a defining |
756 // instruction in the register allocator. | 757 // instruction in the register allocator. |
757 OperandGenerator g(this); | 758 OperandGenerator g(this); |
758 Emit(kArchNop, g.DefineAsConstant(node)); | 759 Emit(kArchNop, g.DefineAsConstant(node)); |
759 } | 760 } |
760 | 761 |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
908 | 909 |
909 | 910 |
910 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, | 911 void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation, |
911 BasicBlock* deoptimization) {} | 912 BasicBlock* deoptimization) {} |
912 | 913 |
913 #endif | 914 #endif |
914 | 915 |
915 } // namespace compiler | 916 } // namespace compiler |
916 } // namespace internal | 917 } // namespace internal |
917 } // namespace v8 | 918 } // namespace v8 |
OLD | NEW |