OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <deque> | 5 #include <deque> |
6 #include <queue> | 6 #include <queue> |
7 | 7 |
8 #include "src/compiler/scheduler.h" | 8 #include "src/compiler/scheduler.h" |
9 | 9 |
10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 queue_(zone), | 234 queue_(zone), |
235 control_(zone), | 235 control_(zone), |
236 component_head_(NULL), | 236 component_head_(NULL), |
237 component_start_(NULL), | 237 component_start_(NULL), |
238 component_end_(NULL) {} | 238 component_end_(NULL) {} |
239 | 239 |
240 // Run the control flow graph construction algorithm by walking the graph | 240 // Run the control flow graph construction algorithm by walking the graph |
241 // backwards from end through control edges, building and connecting the | 241 // backwards from end through control edges, building and connecting the |
242 // basic blocks for control nodes. | 242 // basic blocks for control nodes. |
243 void Run() { | 243 void Run() { |
244 Graph* graph = scheduler_->graph_; | 244 Queue(scheduler_->graph_->end()); |
245 FixNode(schedule_->start(), graph->start()); | |
246 Queue(graph->end()); | |
247 | 245 |
248 while (!queue_.empty()) { // Breadth-first backwards traversal. | 246 while (!queue_.empty()) { // Breadth-first backwards traversal. |
249 Node* node = queue_.front(); | 247 Node* node = queue_.front(); |
250 queue_.pop(); | 248 queue_.pop(); |
251 int max = NodeProperties::PastControlIndex(node); | 249 int max = NodeProperties::PastControlIndex(node); |
252 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { | 250 for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) { |
253 Queue(node->InputAt(i)); | 251 Queue(node->InputAt(i)); |
254 } | 252 } |
255 } | 253 } |
256 | 254 |
257 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { | 255 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { |
258 ConnectBlocks(*i); // Connect block to its predecessor/successors. | 256 ConnectBlocks(*i); // Connect block to its predecessor/successors. |
259 } | 257 } |
260 | |
261 FixNode(schedule_->end(), graph->end()); | |
262 } | 258 } |
263 | 259 |
264 // Run the control flow graph construction for a minimal control-connected | 260 // Run the control flow graph construction for a minimal control-connected |
265 // component ending in {node} and merge that component into an existing | 261 // component ending in {node} and merge that component into an existing |
266 // control flow graph at the bottom of {block}. | 262 // control flow graph at the bottom of {block}. |
267 void Run(BasicBlock* block, Node* node) { | 263 void Run(BasicBlock* block, Node* node) { |
268 Queue(node); | 264 Queue(node); |
269 | 265 |
270 component_start_ = block; | 266 component_start_ = block; |
271 component_end_ = schedule_->block(node); | 267 component_end_ = schedule_->block(node); |
(...skipping 14 matching lines...) Expand all Loading... |
286 | 282 |
287 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { | 283 for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) { |
288 scheduler_->GetData(*i)->is_floating_control_ = false; | 284 scheduler_->GetData(*i)->is_floating_control_ = false; |
289 ConnectBlocks(*i); // Connect block to its predecessor/successors. | 285 ConnectBlocks(*i); // Connect block to its predecessor/successors. |
290 } | 286 } |
291 } | 287 } |
292 | 288 |
293 private: | 289 private: |
294 void FixNode(BasicBlock* block, Node* node) { | 290 void FixNode(BasicBlock* block, Node* node) { |
295 schedule_->AddNode(block, node); | 291 schedule_->AddNode(block, node); |
296 scheduler_->GetData(node)->is_connected_control_ = true; | |
297 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 292 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
298 } | 293 } |
299 | 294 |
300 void Queue(Node* node) { | 295 void Queue(Node* node) { |
301 // Mark the connected control nodes as they queued. | 296 // Mark the connected control nodes as they are queued. |
302 Scheduler::SchedulerData* data = scheduler_->GetData(node); | 297 Scheduler::SchedulerData* data = scheduler_->GetData(node); |
303 if (!data->is_connected_control_) { | 298 if (!data->is_connected_control_) { |
| 299 data->is_connected_control_ = true; |
304 BuildBlocks(node); | 300 BuildBlocks(node); |
305 queue_.push(node); | 301 queue_.push(node); |
306 control_.push_back(node); | 302 control_.push_back(node); |
307 data->is_connected_control_ = true; | |
308 } | 303 } |
309 } | 304 } |
310 | 305 |
311 | 306 |
312 void BuildBlocks(Node* node) { | 307 void BuildBlocks(Node* node) { |
313 switch (node->opcode()) { | 308 switch (node->opcode()) { |
| 309 case IrOpcode::kEnd: |
| 310 FixNode(schedule_->end(), node); |
| 311 break; |
| 312 case IrOpcode::kStart: |
| 313 FixNode(schedule_->start(), node); |
| 314 break; |
314 case IrOpcode::kLoop: | 315 case IrOpcode::kLoop: |
315 case IrOpcode::kMerge: | 316 case IrOpcode::kMerge: |
316 case IrOpcode::kTerminate: | |
317 BuildBlockForNode(node); | 317 BuildBlockForNode(node); |
318 break; | 318 break; |
| 319 case IrOpcode::kTerminate: { |
| 320 // Put Terminate in the loop to which it refers. |
| 321 Node* loop = NodeProperties::GetControlInput(node); |
| 322 BasicBlock* block = BuildBlockForNode(loop); |
| 323 FixNode(block, node); |
| 324 break; |
| 325 } |
319 case IrOpcode::kBranch: | 326 case IrOpcode::kBranch: |
320 BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse); | 327 BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse); |
321 break; | 328 break; |
322 default: | 329 default: |
323 break; | 330 break; |
324 } | 331 } |
325 } | 332 } |
326 | 333 |
327 void ConnectBlocks(Node* node) { | 334 void ConnectBlocks(Node* node) { |
328 switch (node->opcode()) { | 335 switch (node->opcode()) { |
329 case IrOpcode::kLoop: | 336 case IrOpcode::kLoop: |
330 case IrOpcode::kMerge: | 337 case IrOpcode::kMerge: |
331 ConnectMerge(node); | 338 ConnectMerge(node); |
332 break; | 339 break; |
333 case IrOpcode::kBranch: | 340 case IrOpcode::kBranch: |
334 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 341 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
335 ConnectBranch(node); | 342 ConnectBranch(node); |
336 break; | 343 break; |
337 case IrOpcode::kReturn: | 344 case IrOpcode::kReturn: |
338 scheduler_->UpdatePlacement(node, Scheduler::kFixed); | 345 scheduler_->UpdatePlacement(node, Scheduler::kFixed); |
339 ConnectReturn(node); | 346 ConnectReturn(node); |
340 break; | 347 break; |
341 default: | 348 default: |
342 break; | 349 break; |
343 } | 350 } |
344 } | 351 } |
345 | 352 |
346 void BuildBlockForNode(Node* node) { | 353 BasicBlock* BuildBlockForNode(Node* node) { |
347 if (schedule_->block(node) == NULL) { | 354 BasicBlock* block = schedule_->block(node); |
348 BasicBlock* block = schedule_->NewBasicBlock(); | 355 if (block == NULL) { |
| 356 block = schedule_->NewBasicBlock(); |
349 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), | 357 Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(), |
350 node->op()->mnemonic()); | 358 node->op()->mnemonic()); |
351 FixNode(block, node); | 359 FixNode(block, node); |
352 } | 360 } |
| 361 return block; |
353 } | 362 } |
354 | 363 |
355 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a, | 364 void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a, |
356 IrOpcode::Value b) { | 365 IrOpcode::Value b) { |
357 Node* successors[2]; | 366 Node* successors[2]; |
358 CollectSuccessorProjections(node, successors, a, b); | 367 CollectSuccessorProjections(node, successors, a, b); |
359 BuildBlockForNode(successors[0]); | 368 BuildBlockForNode(successors[0]); |
360 BuildBlockForNode(successors[1]); | 369 BuildBlockForNode(successors[1]); |
361 } | 370 } |
362 | 371 |
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1356 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1365 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
1357 schedule_->SetBlockForNode(to, *i); | 1366 schedule_->SetBlockForNode(to, *i); |
1358 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1367 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
1359 } | 1368 } |
1360 nodes->clear(); | 1369 nodes->clear(); |
1361 } | 1370 } |
1362 | 1371 |
1363 } // namespace compiler | 1372 } // namespace compiler |
1364 } // namespace internal | 1373 } // namespace internal |
1365 } // namespace v8 | 1374 } // namespace v8 |
OLD | NEW |