Switch schedule early phase to basic blocks.

R=jarin@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24568 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d1e693a4
...@@ -63,7 +63,7 @@ Schedule* Scheduler::ComputeSchedule(Graph* graph) { ...@@ -63,7 +63,7 @@ Schedule* Scheduler::ComputeSchedule(Graph* graph) {
Scheduler::SchedulerData Scheduler::DefaultSchedulerData() { Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
SchedulerData def = {0, -1, false, false, kUnknown}; SchedulerData def = {NULL, 0, false, false, kUnknown};
return def; return def;
} }
...@@ -315,7 +315,7 @@ class CFGBuilder { ...@@ -315,7 +315,7 @@ class CFGBuilder {
void Scheduler::BuildCFG() { void Scheduler::BuildCFG() {
Trace("---------------- CREATING CFG ------------------\n"); Trace("--- CREATING CFG -------------------------------------------\n");
CFGBuilder cfg_builder(zone_, this); CFGBuilder cfg_builder(zone_, this);
cfg_builder.Run(); cfg_builder.Run();
// Initialize per-block data. // Initialize per-block data.
...@@ -326,7 +326,7 @@ void Scheduler::BuildCFG() { ...@@ -326,7 +326,7 @@ void Scheduler::BuildCFG() {
void Scheduler::GenerateImmediateDominatorTree() { void Scheduler::GenerateImmediateDominatorTree() {
// Build the dominator graph. TODO(danno): consider using Lengauer & Tarjan's // Build the dominator graph. TODO(danno): consider using Lengauer & Tarjan's
// if this becomes really slow. // if this becomes really slow.
Trace("------------ IMMEDIATE BLOCK DOMINATORS -----------\n"); Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
for (size_t i = 0; i < schedule_->rpo_order_.size(); i++) { for (size_t i = 0; i < schedule_->rpo_order_.size(); i++) {
BasicBlock* current_rpo = schedule_->rpo_order_[i]; BasicBlock* current_rpo = schedule_->rpo_order_[i];
if (current_rpo != schedule_->start()) { if (current_rpo != schedule_->start()) {
...@@ -405,7 +405,7 @@ class PrepareUsesVisitor : public NullNodeVisitor { ...@@ -405,7 +405,7 @@ class PrepareUsesVisitor : public NullNodeVisitor {
void Scheduler::PrepareUses() { void Scheduler::PrepareUses() {
Trace("------------------- PREPARE USES ------------------\n"); Trace("--- PREPARE USES -------------------------------------------\n");
// Count the uses of every node, it will be used to ensure that all of a // Count the uses of every node, it will be used to ensure that all of a
// node's uses are scheduled before the node itself. // node's uses are scheduled before the node itself.
...@@ -424,59 +424,55 @@ class ScheduleEarlyNodeVisitor : public NullNodeVisitor { ...@@ -424,59 +424,55 @@ class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
: scheduler_(scheduler), schedule_(scheduler->schedule_) {} : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
GenericGraphVisit::Control Pre(Node* node) { GenericGraphVisit::Control Pre(Node* node) {
Scheduler::SchedulerData* data = scheduler_->GetData(node);
if (scheduler_->GetPlacement(node) == Scheduler::kFixed) { if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
// Fixed nodes already know their schedule early position. // Fixed nodes already know their schedule early position.
Scheduler::SchedulerData* data = scheduler_->GetData(node); if (data->minimum_block_ == NULL) {
BasicBlock* block = schedule_->block(node); data->minimum_block_ = schedule_->block(node);
DCHECK(block != NULL);
if (data->minimum_rpo_ < 0) {
data->minimum_rpo_ = block->rpo_number();
Trace("Preschedule #%d:%s minimum_rpo = %d (fixed)\n", node->id(), Trace("Preschedule #%d:%s minimum_rpo = %d (fixed)\n", node->id(),
node->op()->mnemonic(), data->minimum_rpo_); node->op()->mnemonic(), data->minimum_block_->rpo_number());
} }
} else { } else {
// For unfixed nodes the minimum RPO is the max of all of the inputs. // For unfixed nodes the minimum RPO is the max of all of the inputs.
Scheduler::SchedulerData* data = scheduler_->GetData(node); if (data->minimum_block_ == NULL) {
if (data->minimum_rpo_ < 0) { data->minimum_block_ = ComputeMaximumInputRPO(node);
data->minimum_rpo_ = ComputeMaximumInputRPO(node); if (data->minimum_block_ == NULL) return GenericGraphVisit::REENTER;
if (data->minimum_rpo_ < 0) return GenericGraphVisit::REENTER;
Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(), Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(),
node->op()->mnemonic(), data->minimum_rpo_); node->op()->mnemonic(), data->minimum_block_->rpo_number());
} }
DCHECK_GE(data->minimum_rpo_, 0);
} }
DCHECK_NE(data->minimum_block_, NULL);
return GenericGraphVisit::CONTINUE; return GenericGraphVisit::CONTINUE;
} }
GenericGraphVisit::Control Post(Node* node) { GenericGraphVisit::Control Post(Node* node) {
Scheduler::SchedulerData* data = scheduler_->GetData(node);
if (scheduler_->GetPlacement(node) != Scheduler::kFixed) { if (scheduler_->GetPlacement(node) != Scheduler::kFixed) {
Scheduler::SchedulerData* data = scheduler_->GetData(node);
// For unfixed nodes the minimum RPO is the max of all of the inputs. // For unfixed nodes the minimum RPO is the max of all of the inputs.
if (data->minimum_rpo_ < 0) { if (data->minimum_block_ == NULL) {
data->minimum_rpo_ = ComputeMaximumInputRPO(node); data->minimum_block_ = ComputeMaximumInputRPO(node);
Trace("Postschedule #%d:%s minimum_rpo = %d\n", node->id(), Trace("Postschedule #%d:%s minimum_rpo = %d\n", node->id(),
node->op()->mnemonic(), data->minimum_rpo_); node->op()->mnemonic(), data->minimum_block_->rpo_number());
} }
DCHECK_GE(data->minimum_rpo_, 0);
} }
DCHECK_NE(data->minimum_block_, NULL);
return GenericGraphVisit::CONTINUE; return GenericGraphVisit::CONTINUE;
} }
// Computes the maximum of the minimum RPOs for all inputs. If the maximum // 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 not known), // cannot be determined (i.e. minimum RPO for at least one input is {NULL}),
// then a negative number is returned. // then {NULL} is returned.
int ComputeMaximumInputRPO(Node* node) { BasicBlock* ComputeMaximumInputRPO(Node* node) {
int max_rpo = 0; BasicBlock* max_block = schedule_->start();
for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) { for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
DCHECK_NE(node, *i); // Loops only exist for fixed nodes. DCHECK_NE(node, *i); // Loops only exist for fixed nodes.
int control_rpo = scheduler_->GetData(*i)->minimum_rpo_; BasicBlock* block = scheduler_->GetData(*i)->minimum_block_;
if (control_rpo > max_rpo) { if (block == NULL) return NULL;
max_rpo = control_rpo; if (block->rpo_number() > max_block->rpo_number()) {
} else if (control_rpo < 0) { max_block = block;
return control_rpo;
} }
} }
return max_rpo; return max_block;
} }
private: private:
...@@ -486,7 +482,7 @@ class ScheduleEarlyNodeVisitor : public NullNodeVisitor { ...@@ -486,7 +482,7 @@ class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
void Scheduler::ScheduleEarly() { void Scheduler::ScheduleEarly() {
Trace("------------------- SCHEDULE EARLY ----------------\n"); Trace("--- SCHEDULE EARLY -----------------------------------------\n");
// Compute the minimum RPO for each node thereby determining the earliest // Compute the minimum RPO for each node thereby determining the earliest
// position each node could be placed within a valid schedule. // position each node could be placed within a valid schedule.
...@@ -532,7 +528,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -532,7 +528,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
} }
DCHECK(block != NULL); DCHECK(block != NULL);
int min_rpo = data->minimum_rpo_; int min_rpo = data->minimum_block_->rpo_number();
Trace( Trace(
"Schedule late conservative for #%d:%s is B%d at loop depth %d, " "Schedule late conservative for #%d:%s is B%d at loop depth %d, "
"minimum_rpo = %d\n", "minimum_rpo = %d\n",
...@@ -619,7 +615,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor { ...@@ -619,7 +615,7 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
void Scheduler::ScheduleLate() { void Scheduler::ScheduleLate() {
Trace("------------------- SCHEDULE LATE -----------------\n"); Trace("--- SCHEDULE LATE ------------------------------------------\n");
if (FLAG_trace_turbo_scheduler) { if (FLAG_trace_turbo_scheduler) {
Trace("roots: "); Trace("roots: ");
for (NodeVectorIter i = schedule_root_nodes_.begin(); for (NodeVectorIter i = schedule_root_nodes_.begin();
...@@ -965,7 +961,7 @@ static void VerifySpecialRPO(int num_loops, LoopInfo* loops, ...@@ -965,7 +961,7 @@ static void VerifySpecialRPO(int num_loops, LoopInfo* loops,
BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) { BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
Zone tmp_zone(schedule->zone()->isolate()); Zone tmp_zone(schedule->zone()->isolate());
Zone* zone = &tmp_zone; Zone* zone = &tmp_zone;
Trace("------------- COMPUTING SPECIAL RPO ---------------\n"); Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n");
// RPO should not have been computed for this schedule yet. // RPO should not have been computed for this schedule yet.
CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number()); CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number());
CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size())); CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size()));
......
...@@ -31,8 +31,8 @@ class Scheduler { ...@@ -31,8 +31,8 @@ class Scheduler {
// Per-node data tracked during scheduling. // Per-node data tracked during scheduling.
struct SchedulerData { struct SchedulerData {
BasicBlock* minimum_block_; // Minimum legal RPO placement.
int unscheduled_count_; // Number of unscheduled uses of this node. int unscheduled_count_; // Number of unscheduled uses of this node.
int minimum_rpo_; // Minimum legal RPO placement.
bool is_connected_control_; // {true} if control-connected to the end node. bool is_connected_control_; // {true} if control-connected to the end node.
bool is_floating_control_; // {true} if control, but not control-connected bool is_floating_control_; // {true} if control, but not control-connected
// to the end node. // to the end node.
......
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