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/bit-vector.h" | 10 #include "src/bit-vector.h" |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 | 1030 |
1031 void Scheduler::ComputeSpecialRPONumbering() { | 1031 void Scheduler::ComputeSpecialRPONumbering() { |
1032 Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n"); | 1032 Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n"); |
1033 | 1033 |
1034 // Compute the special reverse-post-order for basic blocks. | 1034 // Compute the special reverse-post-order for basic blocks. |
1035 special_rpo_ = new (zone_) SpecialRPONumberer(zone_, schedule_); | 1035 special_rpo_ = new (zone_) SpecialRPONumberer(zone_, schedule_); |
1036 special_rpo_->ComputeSpecialRPO(); | 1036 special_rpo_->ComputeSpecialRPO(); |
1037 } | 1037 } |
1038 | 1038 |
1039 | 1039 |
1040 void Scheduler::GenerateImmediateDominatorTree() { | 1040 void Scheduler::PropagateImmediateDominators(BasicBlock* block) { |
1041 Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n"); | 1041 for (/*nop*/; block != NULL; block = block->rpo_next()) { |
1042 | |
1043 // TODO(danno): Consider using Lengauer & Tarjan's if this becomes too slow. | |
1044 | |
1045 // Build the block dominator tree. | |
1046 schedule_->start()->set_dominator_depth(0); | |
1047 BasicBlock* second = schedule_->start()->rpo_next(); | |
1048 for (BasicBlock* block = second; block != NULL; block = block->rpo_next()) { | |
1049 BasicBlock::Predecessors::iterator pred = block->predecessors_begin(); | 1042 BasicBlock::Predecessors::iterator pred = block->predecessors_begin(); |
1050 BasicBlock::Predecessors::iterator end = block->predecessors_end(); | 1043 BasicBlock::Predecessors::iterator end = block->predecessors_end(); |
1051 DCHECK(pred != end); // All blocks except start have predecessors. | 1044 DCHECK(pred != end); // All blocks except start have predecessors. |
1052 BasicBlock* dominator = *pred; | 1045 BasicBlock* dominator = *pred; |
1053 // For multiple predecessors, walk up the dominator tree until a common | 1046 // For multiple predecessors, walk up the dominator tree until a common |
1054 // dominator is found. Visitation order guarantees that all predecessors | 1047 // dominator is found. Visitation order guarantees that all predecessors |
1055 // except for backwards edges have been visited. | 1048 // except for backwards edges have been visited. |
1056 for (++pred; pred != end; ++pred) { | 1049 for (++pred; pred != end; ++pred) { |
1057 // Don't examine backwards edges. | 1050 // Don't examine backwards edges. |
1058 if ((*pred)->dominator_depth() < 0) continue; | 1051 if ((*pred)->dominator_depth() < 0) continue; |
1059 dominator = GetCommonDominator(dominator, *pred); | 1052 dominator = GetCommonDominator(dominator, *pred); |
1060 } | 1053 } |
1061 block->set_dominator(dominator); | 1054 block->set_dominator(dominator); |
1062 block->set_dominator_depth(dominator->dominator_depth() + 1); | 1055 block->set_dominator_depth(dominator->dominator_depth() + 1); |
1063 // Propagate "deferredness" of the dominator. | 1056 // Propagate "deferredness" of the dominator. |
1064 if (dominator->deferred()) block->set_deferred(true); | 1057 if (dominator->deferred()) block->set_deferred(true); |
1065 Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(), | 1058 Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(), |
1066 dominator->id().ToInt(), block->dominator_depth()); | 1059 dominator->id().ToInt(), block->dominator_depth()); |
1067 } | 1060 } |
1068 } | 1061 } |
1069 | 1062 |
1070 | 1063 |
| 1064 void Scheduler::GenerateImmediateDominatorTree() { |
| 1065 Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n"); |
| 1066 |
| 1067 // Seed start block to be the first dominator. |
| 1068 schedule_->start()->set_dominator_depth(0); |
| 1069 |
| 1070 // Build the block dominator tree resulting from the above seed. |
| 1071 PropagateImmediateDominators(schedule_->start()->rpo_next()); |
| 1072 } |
| 1073 |
| 1074 |
1071 // ----------------------------------------------------------------------------- | 1075 // ----------------------------------------------------------------------------- |
1072 // Phase 3: Prepare use counts for nodes. | 1076 // Phase 3: Prepare use counts for nodes. |
1073 | 1077 |
1074 | 1078 |
1075 class PrepareUsesVisitor : public NullNodeVisitor { | 1079 class PrepareUsesVisitor : public NullNodeVisitor { |
1076 public: | 1080 public: |
1077 explicit PrepareUsesVisitor(Scheduler* scheduler) | 1081 explicit PrepareUsesVisitor(Scheduler* scheduler) |
1078 : scheduler_(scheduler), schedule_(scheduler->schedule_) {} | 1082 : scheduler_(scheduler), schedule_(scheduler->schedule_) {} |
1079 | 1083 |
1080 void Pre(Node* node) { | 1084 void Pre(Node* node) { |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 OFStream os(stdout); | 1431 OFStream os(stdout); |
1428 os << "Schedule before control flow fusion:\n" << *schedule_; | 1432 os << "Schedule before control flow fusion:\n" << *schedule_; |
1429 } | 1433 } |
1430 | 1434 |
1431 // Iterate on phase 1: Build control-flow graph. | 1435 // Iterate on phase 1: Build control-flow graph. |
1432 control_flow_builder_->Run(block, node); | 1436 control_flow_builder_->Run(block, node); |
1433 | 1437 |
1434 // Iterate on phase 2: Compute special RPO and dominator tree. | 1438 // Iterate on phase 2: Compute special RPO and dominator tree. |
1435 special_rpo_->UpdateSpecialRPO(block, schedule_->block(node)); | 1439 special_rpo_->UpdateSpecialRPO(block, schedule_->block(node)); |
1436 // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that. | 1440 // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that. |
1437 for (BasicBlock* block : schedule_->all_blocks_) { | 1441 for (BasicBlock* b = block->rpo_next(); b != NULL; b = b->rpo_next()) { |
1438 block->set_dominator_depth(-1); | 1442 b->set_dominator_depth(-1); |
1439 block->set_dominator(NULL); | 1443 b->set_dominator(NULL); |
1440 } | 1444 } |
1441 GenerateImmediateDominatorTree(); | 1445 PropagateImmediateDominators(block->rpo_next()); |
1442 | 1446 |
1443 // Iterate on phase 4: Schedule nodes early. | 1447 // Iterate on phase 4: Schedule nodes early. |
1444 // TODO(mstarzinger): The following loop gathering the propagation roots is a | 1448 // TODO(mstarzinger): The following loop gathering the propagation roots is a |
1445 // temporary solution and should be merged into the rest of the scheduler as | 1449 // temporary solution and should be merged into the rest of the scheduler as |
1446 // soon as the approach settled for all floating loops. | 1450 // soon as the approach settled for all floating loops. |
1447 NodeVector propagation_roots(control_flow_builder_->control_); | 1451 NodeVector propagation_roots(control_flow_builder_->control_); |
1448 for (Node* node : control_flow_builder_->control_) { | 1452 for (Node* node : control_flow_builder_->control_) { |
1449 for (Node* use : node->uses()) { | 1453 for (Node* use : node->uses()) { |
1450 if (use->opcode() == IrOpcode::kPhi || | 1454 if (use->opcode() == IrOpcode::kPhi || |
1451 use->opcode() == IrOpcode::kEffectPhi) { | 1455 use->opcode() == IrOpcode::kEffectPhi) { |
(...skipping 30 matching lines...) Expand all Loading... |
1482 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { | 1486 for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) { |
1483 schedule_->SetBlockForNode(to, *i); | 1487 schedule_->SetBlockForNode(to, *i); |
1484 scheduled_nodes_[to->id().ToSize()].push_back(*i); | 1488 scheduled_nodes_[to->id().ToSize()].push_back(*i); |
1485 } | 1489 } |
1486 nodes->clear(); | 1490 nodes->clear(); |
1487 } | 1491 } |
1488 | 1492 |
1489 } // namespace compiler | 1493 } // namespace compiler |
1490 } // namespace internal | 1494 } // namespace internal |
1491 } // namespace v8 | 1495 } // namespace v8 |
OLD | NEW |