Switch ScheduleLateNodeVisitor to use explicit queue.

R=jarin@chromium.org

Review URL: https://codereview.chromium.org/672583002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24803 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6619a797
...@@ -535,27 +535,42 @@ void Scheduler::ScheduleEarly() { ...@@ -535,27 +535,42 @@ void Scheduler::ScheduleEarly() {
// Phase 4: Schedule nodes late. // Phase 4: Schedule nodes late.
class ScheduleLateNodeVisitor : public NullNodeVisitor { class ScheduleLateNodeVisitor {
public: public:
explicit ScheduleLateNodeVisitor(Scheduler* scheduler) ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler)
: scheduler_(scheduler), schedule_(scheduler_->schedule_) {} : scheduler_(scheduler), schedule_(scheduler_->schedule_), queue_(zone) {}
GenericGraphVisit::Control Pre(Node* node) { // Run the schedule late algorithm on a set of fixed root nodes.
// Don't schedule nodes that are already scheduled. void Run(NodeVector* roots) {
if (schedule_->IsScheduled(node)) { for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
return GenericGraphVisit::CONTINUE; ProcessQueue(*i);
}
} }
private:
void ProcessQueue(Node* root) {
for (InputIter i = root->inputs().begin(); i != root->inputs().end(); ++i) {
if (scheduler_->GetData(*i)->unscheduled_count_ != 0) continue;
queue_.push(*i);
while (!queue_.empty()) {
VisitNode(queue_.front());
queue_.pop();
}
}
}
// Visits one node from the queue of schedulable nodes and determines its
// schedule late position. Also hoists nodes out of loops to find a more
// optimal scheduling position.
void VisitNode(Node* node) {
DCHECK(scheduler_->GetData(node)->unscheduled_count_ == 0);
// Don't schedule nodes that are already scheduled.
if (schedule_->IsScheduled(node)) return;
Scheduler::SchedulerData* data = scheduler_->GetData(node); Scheduler::SchedulerData* data = scheduler_->GetData(node);
DCHECK_EQ(Scheduler::kSchedulable, data->placement_); DCHECK_EQ(Scheduler::kSchedulable, data->placement_);
// If all the uses of a node have been scheduled, then the node itself can
// be scheduled.
bool eligible = data->unscheduled_count_ == 0;
Trace("Testing for schedule eligibility for #%d:%s = %s\n", node->id(),
node->op()->mnemonic(), eligible ? "true" : "false");
if (!eligible) return GenericGraphVisit::DEFER;
// Determine the dominating block for all of the uses of this node. It is // Determine the dominating block for all of the uses of this node. It is
// the latest block that this node can be scheduled in. // the latest block that this node can be scheduled in.
BasicBlock* block = NULL; BasicBlock* block = NULL;
...@@ -600,11 +615,8 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -600,11 +615,8 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
} }
ScheduleNode(block, node); ScheduleNode(block, node);
return GenericGraphVisit::CONTINUE;
} }
private:
BasicBlock* GetBlockForUse(Node::Edge edge) { BasicBlock* GetBlockForUse(Node::Edge edge) {
Node* use = edge.from(); Node* use = edge.from();
IrOpcode::Value opcode = use->opcode(); IrOpcode::Value opcode = use->opcode();
...@@ -633,7 +645,8 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -633,7 +645,8 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node); scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
// Reduce the use count of the node's inputs to potentially make them // Reduce the use count of the node's inputs to potentially make them
// schedulable. // schedulable. If all the uses of a node have been scheduled, then the node
// itself can be scheduled.
for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
Scheduler::SchedulerData* data = scheduler_->GetData(*i); Scheduler::SchedulerData* data = scheduler_->GetData(*i);
DCHECK(data->unscheduled_count_ > 0); DCHECK(data->unscheduled_count_ > 0);
...@@ -642,10 +655,10 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -642,10 +655,10 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
Trace(" Use count for #%d:%s (used by #%d:%s)-- = %d\n", (*i)->id(), Trace(" Use count for #%d:%s (used by #%d:%s)-- = %d\n", (*i)->id(),
(*i)->op()->mnemonic(), i.edge().from()->id(), (*i)->op()->mnemonic(), i.edge().from()->id(),
i.edge().from()->op()->mnemonic(), data->unscheduled_count_); i.edge().from()->op()->mnemonic(), data->unscheduled_count_);
if (data->unscheduled_count_ == 0) {
Trace(" newly eligible #%d:%s\n", (*i)->id(),
(*i)->op()->mnemonic());
} }
if (data->unscheduled_count_ == 0) {
Trace(" newly eligible #%d:%s\n", (*i)->id(), (*i)->op()->mnemonic());
queue_.push(*i);
} }
} }
...@@ -663,10 +676,11 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -663,10 +676,11 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
"%d\n", "%d\n",
(*i)->id(), (*i)->op()->mnemonic(), node->id(), (*i)->id(), (*i)->op()->mnemonic(), node->id(),
node->op()->mnemonic(), data->unscheduled_count_); node->op()->mnemonic(), data->unscheduled_count_);
}
if (data->unscheduled_count_ == 0) { if (data->unscheduled_count_ == 0) {
Trace(" newly eligible #%d:%s\n", (*i)->id(), Trace(" newly eligible #%d:%s\n", (*i)->id(),
(*i)->op()->mnemonic()); (*i)->op()->mnemonic());
} queue_.push(*i);
} }
} }
} }
...@@ -675,6 +689,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -675,6 +689,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
Scheduler* scheduler_; Scheduler* scheduler_;
Schedule* schedule_; Schedule* schedule_;
ZoneQueue<Node*> queue_;
}; };
...@@ -690,15 +705,10 @@ void Scheduler::ScheduleLate() { ...@@ -690,15 +705,10 @@ void Scheduler::ScheduleLate() {
} }
// Schedule: Places nodes in dominator block of all their uses. // Schedule: Places nodes in dominator block of all their uses.
ScheduleLateNodeVisitor schedule_late_visitor(this);
{ {
ZonePool::Scope zone_scope(zone_pool_); ZonePool::Scope zone_scope(zone_pool_);
Zone* zone = zone_scope.zone(); ScheduleLateNodeVisitor schedule_late_visitor(zone_scope.zone(), this);
GenericGraphVisit::Visit<ScheduleLateNodeVisitor, schedule_late_visitor.Run(&schedule_root_nodes_);
NodeInputIterationTraits<Node> >(
graph_, zone, schedule_root_nodes_.begin(), schedule_root_nodes_.end(),
&schedule_late_visitor);
} }
// Add collected nodes for basic blocks to their blocks in the right order. // Add collected nodes for basic blocks to their blocks in the right order.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment