Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Unified Diff: src/compiler/scheduler.cc

Issue 655833005: Switch schedule early phase to use forward propagation. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Jaro. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/scheduler.cc
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
index 346e0722d9d36034c6c7d92a897f26eaa79e3d6b..1ee1e2d3d54f58e9b165d43100280553bbf37cbd 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -64,7 +64,7 @@ Schedule* Scheduler::ComputeSchedule(ZonePool* zone_pool, Graph* graph) {
Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
- SchedulerData def = {NULL, 0, false, false, kUnknown};
+ SchedulerData def = {schedule_->start(), 0, false, false, kUnknown};
return def;
}
@@ -952,76 +952,86 @@ void Scheduler::PrepareUses() {
// Phase 4: Schedule nodes early.
-class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
+class ScheduleEarlyNodeVisitor {
public:
- explicit ScheduleEarlyNodeVisitor(Scheduler* scheduler)
- : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
+ ScheduleEarlyNodeVisitor(Zone* zone, Scheduler* scheduler)
+ : scheduler_(scheduler), schedule_(scheduler->schedule_), queue_(zone) {}
- GenericGraphVisit::Control Pre(Node* node) {
- Scheduler::SchedulerData* data = scheduler_->GetData(node);
- if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
- // Fixed nodes already know their schedule early position.
- if (data->minimum_block_ == NULL) {
- data->minimum_block_ = schedule_->block(node);
- Trace("Preschedule #%d:%s minimum_rpo = %d (fixed)\n", node->id(),
- node->op()->mnemonic(), data->minimum_block_->rpo_number());
- }
- } else {
- // For unfixed nodes the minimum RPO is the max of all of the inputs.
- if (data->minimum_block_ == NULL) {
- data->minimum_block_ = ComputeMaximumInputRPO(node);
- if (data->minimum_block_ == NULL) return GenericGraphVisit::REENTER;
- Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(),
- node->op()->mnemonic(), data->minimum_block_->rpo_number());
+ // Run the schedule early algorithm on a set of fixed root nodes.
+ void Run(NodeVector* roots) {
+ for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
+ queue_.push(*i);
+ while (!queue_.empty()) {
+ VisitNode(queue_.front());
+ queue_.pop();
}
}
- DCHECK_NE(data->minimum_block_, NULL);
- return GenericGraphVisit::CONTINUE;
}
- GenericGraphVisit::Control Post(Node* node) {
+ private:
+ // Visits one node from the queue and propagates its current schedule early
+ // position to all uses. This in turn might push more nodes onto the queue.
+ void VisitNode(Node* node) {
Scheduler::SchedulerData* data = scheduler_->GetData(node);
- if (scheduler_->GetPlacement(node) != Scheduler::kFixed) {
- // For unfixed nodes the minimum RPO is the max of all of the inputs.
- if (data->minimum_block_ == NULL) {
- data->minimum_block_ = ComputeMaximumInputRPO(node);
- Trace("Postschedule #%d:%s minimum_rpo = %d\n", node->id(),
- node->op()->mnemonic(), data->minimum_block_->rpo_number());
- }
+
+ // Fixed nodes already know their schedule early position.
+ if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
+ DCHECK_EQ(schedule_->start(), data->minimum_block_);
+ data->minimum_block_ = schedule_->block(node);
+ Trace("Fixing #%d:%s minimum_rpo = %d\n", node->id(),
+ node->op()->mnemonic(), data->minimum_block_->rpo_number());
+ }
+
+ // No need to propagate unconstrained schedule early positions.
+ if (data->minimum_block_ == schedule_->start()) return;
+
+ // Propagate schedule early position.
+ DCHECK(data->minimum_block_ != NULL);
+ Node::Uses uses = node->uses();
+ for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
+ PropagateMinimumRPOToNode(data->minimum_block_, *i);
}
- DCHECK_NE(data->minimum_block_, NULL);
- return GenericGraphVisit::CONTINUE;
}
- // Computes the maximum of the minimum RPOs for all inputs. If the maximum
- // cannot be determined (i.e. minimum RPO for at least one input is {NULL}),
- // then {NULL} is returned.
- BasicBlock* ComputeMaximumInputRPO(Node* node) {
- BasicBlock* max_block = schedule_->start();
- for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
- DCHECK_NE(node, *i); // Loops only exist for fixed nodes.
- BasicBlock* block = scheduler_->GetData(*i)->minimum_block_;
- if (block == NULL) return NULL;
- if (block->rpo_number() > max_block->rpo_number()) {
- max_block = block;
- }
+ // Propagates {block} as another minimum RPO placement into the given {node}.
+ // This has the net effect of computing the maximum of the minimum RPOs for
+ // all inputs to {node} when the queue has been fully processed.
+ void PropagateMinimumRPOToNode(BasicBlock* block, Node* node) {
+ Scheduler::SchedulerData* data = scheduler_->GetData(node);
+
+ // No need to propagate to fixed node, it's guaranteed to be a root.
+ if (scheduler_->GetPlacement(node) == Scheduler::kFixed) return;
+
+ // Propagate new position if it is larger than the current.
+ if (block->rpo_number() > data->minimum_block_->rpo_number()) {
+ data->minimum_block_ = block;
+ queue_.push(node);
+ Trace("Propagating #%d:%s minimum_rpo = %d\n", node->id(),
+ node->op()->mnemonic(), data->minimum_block_->rpo_number());
}
- return max_block;
}
- private:
Scheduler* scheduler_;
Schedule* schedule_;
+ ZoneQueue<Node*> queue_;
};
void Scheduler::ScheduleEarly() {
Trace("--- SCHEDULE EARLY -----------------------------------------\n");
+ if (FLAG_trace_turbo_scheduler) {
+ Trace("roots: ");
+ for (NodeVectorIter i = schedule_root_nodes_.begin();
+ i != schedule_root_nodes_.end(); ++i) {
+ Trace("#%d:%s ", (*i)->id(), (*i)->op()->mnemonic());
+ }
+ Trace("\n");
+ }
// Compute the minimum RPO for each node thereby determining the earliest
// position each node could be placed within a valid schedule.
- ScheduleEarlyNodeVisitor visitor(this);
- graph_->VisitNodeInputsFromEnd(&visitor);
+ ScheduleEarlyNodeVisitor schedule_early_visitor(zone_, this);
+ schedule_early_visitor.Run(&schedule_root_nodes_);
}
@@ -1098,7 +1108,6 @@ class ScheduleLateNodeVisitor {
ScheduleNode(block, node);
}
- private:
BasicBlock* GetPreHeader(BasicBlock* block) {
if (block->IsLoopHeader()) {
return block->dominator();
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698