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/graph.h" |
7 #include "src/compiler/instruction-selector-impl.h" | 8 #include "src/compiler/instruction-selector-impl.h" |
8 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/pipeline.h" | 11 #include "src/compiler/pipeline.h" |
11 | 12 |
12 namespace v8 { | 13 namespace v8 { |
13 namespace internal { | 14 namespace internal { |
14 namespace compiler { | 15 namespace compiler { |
15 | 16 |
16 InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage, | 17 InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph, |
| 18 Linkage* linkage, |
17 InstructionSequence* sequence, | 19 InstructionSequence* sequence, |
18 Schedule* schedule, | 20 Schedule* schedule, |
19 SourcePositionTable* source_positions, | 21 SourcePositionTable* source_positions, |
20 Features features) | 22 Features features) |
21 : zone_(local_zone), | 23 : zone_(local_zone), |
22 linkage_(linkage), | 24 linkage_(linkage), |
23 sequence_(sequence), | 25 sequence_(sequence), |
24 source_positions_(source_positions), | 26 source_positions_(source_positions), |
25 features_(features), | 27 features_(features), |
26 schedule_(schedule), | 28 schedule_(schedule), |
| 29 node_map_(graph->NodeCount(), kNodeUnmapped, zone()), |
27 current_block_(NULL), | 30 current_block_(NULL), |
28 instructions_(zone()), | 31 instructions_(zone()), |
29 defined_(sequence->node_count(), false, zone()), | 32 defined_(graph->NodeCount(), false, zone()), |
30 used_(sequence->node_count(), false, zone()) {} | 33 used_(graph->NodeCount(), false, zone()) {} |
31 | 34 |
32 | 35 |
33 void InstructionSelector::SelectInstructions() { | 36 void InstructionSelector::SelectInstructions() { |
34 // Mark the inputs of all phis in loop headers as used. | 37 // Mark the inputs of all phis in loop headers as used. |
35 BasicBlockVector* blocks = schedule()->rpo_order(); | 38 BasicBlockVector* blocks = schedule()->rpo_order(); |
36 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 39 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { |
37 BasicBlock* block = *i; | 40 BasicBlock* block = *i; |
38 if (!block->IsLoopHeader()) continue; | 41 if (!block->IsLoopHeader()) continue; |
39 DCHECK_NE(0, static_cast<int>(block->PredecessorCount())); | 42 DCHECK_NE(0, static_cast<int>(block->PredecessorCount())); |
40 DCHECK_NE(1, static_cast<int>(block->PredecessorCount())); | 43 DCHECK_NE(1, static_cast<int>(block->PredecessorCount())); |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 return current_block_->GetAoNumber().IsNext(block->GetAoNumber()); | 153 return current_block_->GetAoNumber().IsNext(block->GetAoNumber()); |
151 } | 154 } |
152 | 155 |
153 | 156 |
154 bool InstructionSelector::CanCover(Node* user, Node* node) const { | 157 bool InstructionSelector::CanCover(Node* user, Node* node) const { |
155 return node->OwnedBy(user) && | 158 return node->OwnedBy(user) && |
156 schedule()->block(node) == schedule()->block(user); | 159 schedule()->block(node) == schedule()->block(user); |
157 } | 160 } |
158 | 161 |
159 | 162 |
| 163 int InstructionSelector::GetVirtualRegister(const Node* node) { |
| 164 if (node_map_[node->id()] == kNodeUnmapped) { |
| 165 node_map_[node->id()] = sequence()->NextVirtualRegister(); |
| 166 } |
| 167 return node_map_[node->id()]; |
| 168 } |
| 169 |
| 170 |
| 171 int InstructionSelector::GetMappedVirtualRegister(const Node* node) const { |
| 172 return node_map_[node->id()]; |
| 173 } |
| 174 |
| 175 |
160 bool InstructionSelector::IsDefined(Node* node) const { | 176 bool InstructionSelector::IsDefined(Node* node) const { |
161 DCHECK_NOT_NULL(node); | 177 DCHECK_NOT_NULL(node); |
162 NodeId id = node->id(); | 178 NodeId id = node->id(); |
163 DCHECK(id >= 0); | 179 DCHECK(id >= 0); |
164 DCHECK(id < static_cast<NodeId>(defined_.size())); | 180 DCHECK(id < static_cast<NodeId>(defined_.size())); |
165 return defined_[id]; | 181 return defined_[id]; |
166 } | 182 } |
167 | 183 |
168 | 184 |
169 void InstructionSelector::MarkAsDefined(Node* node) { | 185 void InstructionSelector::MarkAsDefined(Node* node) { |
(...skipping 18 matching lines...) Expand all Loading... |
188 DCHECK_NOT_NULL(node); | 204 DCHECK_NOT_NULL(node); |
189 NodeId id = node->id(); | 205 NodeId id = node->id(); |
190 DCHECK(id >= 0); | 206 DCHECK(id >= 0); |
191 DCHECK(id < static_cast<NodeId>(used_.size())); | 207 DCHECK(id < static_cast<NodeId>(used_.size())); |
192 used_[id] = true; | 208 used_[id] = true; |
193 } | 209 } |
194 | 210 |
195 | 211 |
196 bool InstructionSelector::IsDouble(const Node* node) const { | 212 bool InstructionSelector::IsDouble(const Node* node) const { |
197 DCHECK_NOT_NULL(node); | 213 DCHECK_NOT_NULL(node); |
198 return sequence()->IsDouble(sequence()->GetVirtualRegister(node)); | 214 int virtual_register = GetMappedVirtualRegister(node); |
| 215 if (virtual_register == kNodeUnmapped) return false; |
| 216 return sequence()->IsDouble(virtual_register); |
199 } | 217 } |
200 | 218 |
201 | 219 |
202 void InstructionSelector::MarkAsDouble(Node* node) { | 220 void InstructionSelector::MarkAsDouble(Node* node) { |
203 DCHECK_NOT_NULL(node); | 221 DCHECK_NOT_NULL(node); |
204 DCHECK(!IsReference(node)); | 222 DCHECK(!IsReference(node)); |
205 sequence()->MarkAsDouble(sequence()->GetVirtualRegister(node)); | 223 sequence()->MarkAsDouble(GetVirtualRegister(node)); |
206 } | 224 } |
207 | 225 |
208 | 226 |
209 bool InstructionSelector::IsReference(const Node* node) const { | 227 bool InstructionSelector::IsReference(const Node* node) const { |
210 DCHECK_NOT_NULL(node); | 228 DCHECK_NOT_NULL(node); |
211 return sequence()->IsReference(sequence()->GetVirtualRegister(node)); | 229 int virtual_register = GetMappedVirtualRegister(node); |
| 230 if (virtual_register == kNodeUnmapped) return false; |
| 231 return sequence()->IsReference(virtual_register); |
212 } | 232 } |
213 | 233 |
214 | 234 |
215 void InstructionSelector::MarkAsReference(Node* node) { | 235 void InstructionSelector::MarkAsReference(Node* node) { |
216 DCHECK_NOT_NULL(node); | 236 DCHECK_NOT_NULL(node); |
217 DCHECK(!IsDouble(node)); | 237 DCHECK(!IsDouble(node)); |
218 sequence()->MarkAsReference(sequence()->GetVirtualRegister(node)); | 238 sequence()->MarkAsReference(GetVirtualRegister(node)); |
219 } | 239 } |
220 | 240 |
221 | 241 |
222 void InstructionSelector::MarkAsRepresentation(MachineType rep, | 242 void InstructionSelector::MarkAsRepresentation(MachineType rep, |
223 InstructionOperand* op) { | 243 InstructionOperand* op) { |
224 UnallocatedOperand* unalloc = UnallocatedOperand::cast(op); | 244 UnallocatedOperand* unalloc = UnallocatedOperand::cast(op); |
225 switch (RepresentationOf(rep)) { | 245 switch (RepresentationOf(rep)) { |
226 case kRepFloat32: | 246 case kRepFloat32: |
227 case kRepFloat64: | 247 case kRepFloat64: |
228 sequence()->MarkAsDouble(unalloc->virtual_register()); | 248 sequence()->MarkAsDouble(unalloc->virtual_register()); |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 int index = OpParameter<int>(node); | 905 int index = OpParameter<int>(node); |
886 Emit(kArchNop, | 906 Emit(kArchNop, |
887 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), | 907 g.DefineAsLocation(node, linkage()->GetParameterLocation(index), |
888 linkage()->GetParameterType(index))); | 908 linkage()->GetParameterType(index))); |
889 } | 909 } |
890 | 910 |
891 | 911 |
892 void InstructionSelector::VisitPhi(Node* node) { | 912 void InstructionSelector::VisitPhi(Node* node) { |
893 // TODO(bmeurer): Emit a PhiInstruction here. | 913 // TODO(bmeurer): Emit a PhiInstruction here. |
894 PhiInstruction* phi = new (instruction_zone()) | 914 PhiInstruction* phi = new (instruction_zone()) |
895 PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node)); | 915 PhiInstruction(instruction_zone(), GetVirtualRegister(node)); |
896 sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi); | 916 sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi); |
897 const int input_count = node->op()->InputCount(); | 917 const int input_count = node->op()->InputCount(); |
898 phi->operands().reserve(static_cast<size_t>(input_count)); | 918 phi->operands().reserve(static_cast<size_t>(input_count)); |
899 for (int i = 0; i < input_count; ++i) { | 919 for (int i = 0; i < input_count; ++i) { |
900 Node* const input = node->InputAt(i); | 920 Node* const input = node->InputAt(i); |
901 MarkAsUsed(input); | 921 MarkAsUsed(input); |
902 phi->operands().push_back(sequence()->GetVirtualRegister(input)); | 922 phi->operands().push_back(GetVirtualRegister(input)); |
903 } | 923 } |
904 } | 924 } |
905 | 925 |
906 | 926 |
907 void InstructionSelector::VisitProjection(Node* node) { | 927 void InstructionSelector::VisitProjection(Node* node) { |
908 OperandGenerator g(this); | 928 OperandGenerator g(this); |
909 Node* value = node->InputAt(0); | 929 Node* value = node->InputAt(0); |
910 switch (value->opcode()) { | 930 switch (value->opcode()) { |
911 case IrOpcode::kInt32AddWithOverflow: | 931 case IrOpcode::kInt32AddWithOverflow: |
912 case IrOpcode::kInt32SubWithOverflow: | 932 case IrOpcode::kInt32SubWithOverflow: |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 MachineOperatorBuilder::Flags | 1099 MachineOperatorBuilder::Flags |
1080 InstructionSelector::SupportedMachineOperatorFlags() { | 1100 InstructionSelector::SupportedMachineOperatorFlags() { |
1081 return MachineOperatorBuilder::Flag::kNoFlags; | 1101 return MachineOperatorBuilder::Flag::kNoFlags; |
1082 } | 1102 } |
1083 | 1103 |
1084 #endif // !V8_TURBOFAN_BACKEND | 1104 #endif // !V8_TURBOFAN_BACKEND |
1085 | 1105 |
1086 } // namespace compiler | 1106 } // namespace compiler |
1087 } // namespace internal | 1107 } // namespace internal |
1088 } // namespace v8 | 1108 } // namespace v8 |
OLD | NEW |