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" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 namespace compiler { | 14 namespace compiler { |
15 | 15 |
16 InstructionSelector::InstructionSelector(InstructionSequence* sequence, | 16 InstructionSelector::InstructionSelector(InstructionSequence* sequence, |
| 17 Schedule* schedule, |
17 SourcePositionTable* source_positions, | 18 SourcePositionTable* source_positions, |
18 Features features) | 19 Features features) |
19 : zone_(sequence->isolate()), | 20 : zone_(sequence->isolate()), |
20 sequence_(sequence), | 21 sequence_(sequence), |
21 source_positions_(source_positions), | 22 source_positions_(source_positions), |
22 features_(features), | 23 features_(features), |
| 24 schedule_(schedule), |
23 current_block_(NULL), | 25 current_block_(NULL), |
24 instructions_(zone()), | 26 instructions_(zone()), |
25 defined_(sequence->node_count(), false, zone()), | 27 defined_(sequence->node_count(), false, zone()), |
26 used_(sequence->node_count(), false, zone()) {} | 28 used_(sequence->node_count(), false, zone()) {} |
27 | 29 |
28 | 30 |
29 void InstructionSelector::SelectInstructions() { | 31 void InstructionSelector::SelectInstructions() { |
30 // Mark the inputs of all phis in loop headers as used. | 32 // Mark the inputs of all phis in loop headers as used. |
31 BasicBlockVector* blocks = schedule()->rpo_order(); | 33 BasicBlockVector* blocks = schedule()->rpo_order(); |
32 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 34 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
(...skipping 15 matching lines...) Expand all Loading... |
48 } | 50 } |
49 | 51 |
50 // Visit each basic block in post order. | 52 // Visit each basic block in post order. |
51 for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { | 53 for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { |
52 VisitBlock(*i); | 54 VisitBlock(*i); |
53 } | 55 } |
54 | 56 |
55 // Schedule the selected instructions. | 57 // Schedule the selected instructions. |
56 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 58 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
57 BasicBlock* block = *i; | 59 BasicBlock* block = *i; |
58 size_t end = sequence()->code_end(block); | 60 InstructionBlock* instruction_block = |
59 size_t start = sequence()->code_start(block); | 61 sequence()->InstructionBlockAt(block->GetRpoNumber()); |
| 62 size_t end = instruction_block->code_end(); |
| 63 size_t start = instruction_block->code_start(); |
60 sequence()->StartBlock(block); | 64 sequence()->StartBlock(block); |
61 while (start-- > end) { | 65 while (start-- > end) { |
62 sequence()->AddInstruction(instructions_[start]); | 66 sequence()->AddInstruction(instructions_[start]); |
63 } | 67 } |
64 sequence()->EndBlock(block); | 68 sequence()->EndBlock(block); |
65 } | 69 } |
66 } | 70 } |
67 | 71 |
68 | 72 |
69 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 73 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 // Skip nodes that are unused or already defined. | 380 // Skip nodes that are unused or already defined. |
377 if (!IsUsed(node) || IsDefined(node)) continue; | 381 if (!IsUsed(node) || IsDefined(node)) continue; |
378 // Generate code for this node "top down", but schedule the code "bottom | 382 // Generate code for this node "top down", but schedule the code "bottom |
379 // up". | 383 // up". |
380 size_t current_node_end = instructions_.size(); | 384 size_t current_node_end = instructions_.size(); |
381 VisitNode(node); | 385 VisitNode(node); |
382 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); | 386 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); |
383 } | 387 } |
384 | 388 |
385 // We're done with the block. | 389 // We're done with the block. |
386 sequence()->set_code_start(block, static_cast<int>(instructions_.size())); | 390 InstructionBlock* instruction_block = |
387 sequence()->set_code_end(block, current_block_end); | 391 sequence()->InstructionBlockAt(block->GetRpoNumber()); |
| 392 instruction_block->set_code_start(static_cast<int>(instructions_.size())); |
| 393 instruction_block->set_code_end(current_block_end); |
388 | 394 |
389 current_block_ = NULL; | 395 current_block_ = NULL; |
390 } | 396 } |
391 | 397 |
392 | 398 |
393 static inline void CheckNoPhis(const BasicBlock* block) { | 399 static inline void CheckNoPhis(const BasicBlock* block) { |
394 #ifdef DEBUG | 400 #ifdef DEBUG |
395 // Branch targets should not have phis. | 401 // Branch targets should not have phis. |
396 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { | 402 for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) { |
397 const Node* node = *i; | 403 const Node* node = *i; |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), | 855 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), |
850 linkage()->GetParameterType(index))); | 856 linkage()->GetParameterType(index))); |
851 } | 857 } |
852 | 858 |
853 | 859 |
854 void InstructionSelector::VisitPhi(Node* node) { | 860 void InstructionSelector::VisitPhi(Node* node) { |
855 // TODO(bmeurer): Emit a PhiInstruction here. | 861 // TODO(bmeurer): Emit a PhiInstruction here. |
856 PhiInstruction* phi = new (instruction_zone()) | 862 PhiInstruction* phi = new (instruction_zone()) |
857 PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node)); | 863 PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node)); |
858 sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi); | 864 sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi); |
859 Node::Inputs inputs = node->inputs(); | 865 const int input_count = node->op()->InputCount(); |
860 size_t j = 0; | 866 phi->operands().reserve(static_cast<size_t>(input_count)); |
861 for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); | 867 for (int i = 0; i < input_count; ++i) { |
862 ++iter, ++j) { | 868 Node* const input = node->InputAt(i); |
863 MarkAsUsed(*iter); | 869 MarkAsUsed(input); |
864 // TODO(mstarzinger): Use a ValueInputIterator instead. | 870 phi->operands().push_back(sequence()->GetVirtualRegister(input)); |
865 if (j >= current_block_->PredecessorCount()) continue; | |
866 phi->operands().push_back(sequence()->GetVirtualRegister(*iter)); | |
867 } | 871 } |
868 } | 872 } |
869 | 873 |
870 | 874 |
871 void InstructionSelector::VisitProjection(Node* node) { | 875 void InstructionSelector::VisitProjection(Node* node) { |
872 OperandGenerator g(this); | 876 OperandGenerator g(this); |
873 Node* value = node->InputAt(0); | 877 Node* value = node->InputAt(0); |
874 switch (value->opcode()) { | 878 switch (value->opcode()) { |
875 case IrOpcode::kInt32AddWithOverflow: | 879 case IrOpcode::kInt32AddWithOverflow: |
876 case IrOpcode::kInt32SubWithOverflow: | 880 case IrOpcode::kInt32SubWithOverflow: |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1033 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, | 1037 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, |
1034 BasicBlock* fbranch) { | 1038 BasicBlock* fbranch) { |
1035 UNIMPLEMENTED(); | 1039 UNIMPLEMENTED(); |
1036 } | 1040 } |
1037 | 1041 |
1038 #endif // !V8_TURBOFAN_BACKEND | 1042 #endif // !V8_TURBOFAN_BACKEND |
1039 | 1043 |
1040 } // namespace compiler | 1044 } // namespace compiler |
1041 } // namespace internal | 1045 } // namespace internal |
1042 } // namespace v8 | 1046 } // namespace v8 |
OLD | NEW |