| 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 |