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