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" | |
8 #include "src/compiler/instruction-selector-impl.h" | 7 #include "src/compiler/instruction-selector-impl.h" |
9 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
11 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
12 | 11 |
13 namespace v8 { | 12 namespace v8 { |
14 namespace internal { | 13 namespace internal { |
15 namespace compiler { | 14 namespace compiler { |
16 | 15 |
17 InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph, | 16 InstructionSelector::InstructionSelector(Zone* zone, size_t node_count, |
18 Linkage* linkage, | 17 Linkage* linkage, |
19 InstructionSequence* sequence, | 18 InstructionSequence* sequence, |
20 Schedule* schedule, | 19 Schedule* schedule, |
21 SourcePositionTable* source_positions, | 20 SourcePositionTable* source_positions, |
22 Features features) | 21 Features features) |
23 : zone_(local_zone), | 22 : zone_(zone), |
24 linkage_(linkage), | 23 linkage_(linkage), |
25 sequence_(sequence), | 24 sequence_(sequence), |
26 source_positions_(source_positions), | 25 source_positions_(source_positions), |
27 features_(features), | 26 features_(features), |
28 schedule_(schedule), | 27 schedule_(schedule), |
29 node_map_(graph->NodeCount(), kNodeUnmapped, zone()), | |
30 current_block_(NULL), | 28 current_block_(NULL), |
31 instructions_(zone()), | 29 instructions_(zone), |
32 defined_(graph->NodeCount(), false, zone()), | 30 defined_(node_count, false, zone), |
33 used_(graph->NodeCount(), false, zone()) {} | 31 used_(node_count, false, zone), |
32 virtual_registers_(node_count, kNoVirtualRegister, zone) { | |
33 instructions_.reserve(node_count); | |
34 } | |
34 | 35 |
35 | 36 |
36 void InstructionSelector::SelectInstructions() { | 37 void InstructionSelector::SelectInstructions() { |
37 // Mark the inputs of all phis in loop headers as used. | 38 // Mark the inputs of all phis in loop headers as used. |
38 BasicBlockVector* blocks = schedule()->rpo_order(); | 39 BasicBlockVector* blocks = schedule()->rpo_order(); |
39 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 40 for (BasicBlock* const block : *blocks) { |
40 BasicBlock* block = *i; | |
41 if (!block->IsLoopHeader()) continue; | 41 if (!block->IsLoopHeader()) continue; |
42 DCHECK_NE(0, static_cast<int>(block->PredecessorCount())); | 42 DCHECK_LE(2, block->PredecessorCount()); |
43 DCHECK_NE(1, static_cast<int>(block->PredecessorCount())); | 43 for (Node* const phi : *block) { |
44 for (BasicBlock::const_iterator j = block->begin(); j != block->end(); | |
45 ++j) { | |
46 Node* phi = *j; | |
47 if (phi->opcode() != IrOpcode::kPhi) continue; | 44 if (phi->opcode() != IrOpcode::kPhi) continue; |
48 | 45 |
49 // Mark all inputs as used. | 46 // Mark all inputs as used. |
50 for (Node* const k : phi->inputs()) { | 47 for (Node* const input : phi->inputs()) { |
51 MarkAsUsed(k); | 48 MarkAsUsed(input); |
52 } | 49 } |
53 } | 50 } |
54 } | 51 } |
55 | 52 |
56 // Visit each basic block in post order. | 53 // Visit each basic block in post order. |
57 for (BasicBlockVectorRIter i = blocks->rbegin(); i != blocks->rend(); ++i) { | 54 for (auto i = blocks->rbegin(); i != blocks->rend(); ++i) { |
58 VisitBlock(*i); | 55 VisitBlock(*i); |
59 } | 56 } |
60 | 57 |
61 // Schedule the selected instructions. | 58 // Schedule the selected instructions. |
62 for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { | 59 for (BasicBlock* const block : *blocks) { |
dcarney
2015/01/08 12:54:09
what no auto?
Benedikt Meurer
2015/01/08 13:23:06
Done.
| |
63 BasicBlock* block = *i; | |
64 InstructionBlock* instruction_block = | 60 InstructionBlock* instruction_block = |
65 sequence()->InstructionBlockAt(block->GetRpoNumber()); | 61 sequence()->InstructionBlockAt(block->GetRpoNumber()); |
66 size_t end = instruction_block->code_end(); | 62 size_t end = instruction_block->code_end(); |
67 size_t start = instruction_block->code_start(); | 63 size_t start = instruction_block->code_start(); |
64 DCHECK_LE(end, start); | |
68 sequence()->StartBlock(block->GetRpoNumber()); | 65 sequence()->StartBlock(block->GetRpoNumber()); |
69 while (start-- > end) { | 66 while (start-- > end) { |
70 sequence()->AddInstruction(instructions_[start]); | 67 sequence()->AddInstruction(instructions_[start]); |
71 } | 68 } |
72 sequence()->EndBlock(block->GetRpoNumber()); | 69 sequence()->EndBlock(block->GetRpoNumber()); |
73 } | 70 } |
74 } | 71 } |
75 | 72 |
76 | 73 |
77 Instruction* InstructionSelector::Emit(InstructionCode opcode, | 74 Instruction* InstructionSelector::Emit(InstructionCode opcode, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 } | 170 } |
174 | 171 |
175 | 172 |
176 bool InstructionSelector::CanCover(Node* user, Node* node) const { | 173 bool InstructionSelector::CanCover(Node* user, Node* node) const { |
177 return node->OwnedBy(user) && | 174 return node->OwnedBy(user) && |
178 schedule()->block(node) == schedule()->block(user); | 175 schedule()->block(node) == schedule()->block(user); |
179 } | 176 } |
180 | 177 |
181 | 178 |
182 int InstructionSelector::GetVirtualRegister(const Node* node) { | 179 int InstructionSelector::GetVirtualRegister(const Node* node) { |
183 if (node_map_[node->id()] == kNodeUnmapped) { | 180 DCHECK_NOT_NULL(node); |
184 node_map_[node->id()] = sequence()->NextVirtualRegister(); | 181 size_t const id = node->id(); |
182 DCHECK_LT(id, virtual_registers_.size()); | |
183 int virtual_register = virtual_registers_[id]; | |
184 if (virtual_register == kNoVirtualRegister) { | |
185 virtual_register = sequence()->NextVirtualRegister(); | |
186 virtual_registers_[id] = virtual_register; | |
185 } | 187 } |
186 return node_map_[node->id()]; | 188 return virtual_register; |
187 } | 189 } |
188 | 190 |
189 | 191 |
190 int InstructionSelector::GetMappedVirtualRegister(const Node* node) const { | 192 const std::map<NodeId, int> InstructionSelector::GetVirtualRegistersForTesting() |
191 return node_map_[node->id()]; | 193 const { |
194 std::map<NodeId, int> virtual_registers; | |
195 for (size_t id = 0; id < virtual_registers_.size(); ++id) { | |
196 if (virtual_registers_[id] == kNoVirtualRegister) continue; | |
197 virtual_registers.insert(std::make_pair(id, virtual_registers_[id])); | |
198 } | |
199 return virtual_registers; | |
192 } | 200 } |
193 | 201 |
194 | 202 |
195 bool InstructionSelector::IsDefined(Node* node) const { | 203 bool InstructionSelector::IsDefined(Node* node) const { |
196 DCHECK_NOT_NULL(node); | 204 DCHECK_NOT_NULL(node); |
197 NodeId id = node->id(); | 205 size_t const id = node->id(); |
198 DCHECK(id >= 0); | 206 DCHECK_LT(id, defined_.size()); |
199 DCHECK(id < static_cast<NodeId>(defined_.size())); | |
200 return defined_[id]; | 207 return defined_[id]; |
201 } | 208 } |
202 | 209 |
203 | 210 |
204 void InstructionSelector::MarkAsDefined(Node* node) { | 211 void InstructionSelector::MarkAsDefined(Node* node) { |
205 DCHECK_NOT_NULL(node); | 212 DCHECK_NOT_NULL(node); |
206 NodeId id = node->id(); | 213 size_t const id = node->id(); |
207 DCHECK(id >= 0); | 214 DCHECK_LT(id, defined_.size()); |
208 DCHECK(id < static_cast<NodeId>(defined_.size())); | |
209 defined_[id] = true; | 215 defined_[id] = true; |
210 } | 216 } |
211 | 217 |
212 | 218 |
213 bool InstructionSelector::IsUsed(Node* node) const { | 219 bool InstructionSelector::IsUsed(Node* node) const { |
220 DCHECK_NOT_NULL(node); | |
214 if (!node->op()->HasProperty(Operator::kEliminatable)) return true; | 221 if (!node->op()->HasProperty(Operator::kEliminatable)) return true; |
215 NodeId id = node->id(); | 222 size_t const id = node->id(); |
216 DCHECK(id >= 0); | 223 DCHECK_LT(id, used_.size()); |
217 DCHECK(id < static_cast<NodeId>(used_.size())); | |
218 return used_[id]; | 224 return used_[id]; |
219 } | 225 } |
220 | 226 |
221 | 227 |
222 void InstructionSelector::MarkAsUsed(Node* node) { | 228 void InstructionSelector::MarkAsUsed(Node* node) { |
223 DCHECK_NOT_NULL(node); | 229 DCHECK_NOT_NULL(node); |
224 NodeId id = node->id(); | 230 size_t const id = node->id(); |
225 DCHECK(id >= 0); | 231 DCHECK_LT(id, used_.size()); |
226 DCHECK(id < static_cast<NodeId>(used_.size())); | |
227 used_[id] = true; | 232 used_[id] = true; |
228 } | 233 } |
229 | 234 |
230 | 235 |
231 bool InstructionSelector::IsDouble(const Node* node) const { | 236 bool InstructionSelector::IsDouble(const Node* node) const { |
232 DCHECK_NOT_NULL(node); | 237 DCHECK_NOT_NULL(node); |
233 int virtual_register = GetMappedVirtualRegister(node); | 238 int const virtual_register = virtual_registers_[node->id()]; |
234 if (virtual_register == kNodeUnmapped) return false; | 239 if (virtual_register == kNoVirtualRegister) return false; |
235 return sequence()->IsDouble(virtual_register); | 240 return sequence()->IsDouble(virtual_register); |
236 } | 241 } |
237 | 242 |
238 | 243 |
239 void InstructionSelector::MarkAsDouble(Node* node) { | 244 void InstructionSelector::MarkAsDouble(Node* node) { |
240 DCHECK_NOT_NULL(node); | 245 DCHECK_NOT_NULL(node); |
241 DCHECK(!IsReference(node)); | 246 DCHECK(!IsReference(node)); |
242 sequence()->MarkAsDouble(GetVirtualRegister(node)); | 247 sequence()->MarkAsDouble(GetVirtualRegister(node)); |
243 } | 248 } |
244 | 249 |
245 | 250 |
246 bool InstructionSelector::IsReference(const Node* node) const { | 251 bool InstructionSelector::IsReference(const Node* node) const { |
247 DCHECK_NOT_NULL(node); | 252 DCHECK_NOT_NULL(node); |
248 int virtual_register = GetMappedVirtualRegister(node); | 253 int const virtual_register = virtual_registers_[node->id()]; |
249 if (virtual_register == kNodeUnmapped) return false; | 254 if (virtual_register == kNoVirtualRegister) return false; |
250 return sequence()->IsReference(virtual_register); | 255 return sequence()->IsReference(virtual_register); |
251 } | 256 } |
252 | 257 |
253 | 258 |
254 void InstructionSelector::MarkAsReference(Node* node) { | 259 void InstructionSelector::MarkAsReference(Node* node) { |
255 DCHECK_NOT_NULL(node); | 260 DCHECK_NOT_NULL(node); |
256 DCHECK(!IsDouble(node)); | 261 DCHECK(!IsDouble(node)); |
257 sequence()->MarkAsReference(GetVirtualRegister(node)); | 262 sequence()->MarkAsReference(GetVirtualRegister(node)); |
258 } | 263 } |
259 | 264 |
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1137 MachineOperatorBuilder::Flags | 1142 MachineOperatorBuilder::Flags |
1138 InstructionSelector::SupportedMachineOperatorFlags() { | 1143 InstructionSelector::SupportedMachineOperatorFlags() { |
1139 return MachineOperatorBuilder::Flag::kNoFlags; | 1144 return MachineOperatorBuilder::Flag::kNoFlags; |
1140 } | 1145 } |
1141 | 1146 |
1142 #endif // !V8_TURBOFAN_BACKEND | 1147 #endif // !V8_TURBOFAN_BACKEND |
1143 | 1148 |
1144 } // namespace compiler | 1149 } // namespace compiler |
1145 } // namespace internal | 1150 } // namespace internal |
1146 } // namespace v8 | 1151 } // namespace v8 |
OLD | NEW |