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

Unified Diff: src/compiler/scheduler.cc

Issue 900543002: [WIP] Node splitting in Scheduler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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 | « src/compiler/scheduler.h ('k') | src/flag-definitions.h » ('j') | 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 6281371abacc6b737045d38ac1f5de4ef32c4bcb..5bf9a839b47eb422e55d443fd362c9565b68c90b 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -27,20 +27,21 @@ static inline void Trace(const char* msg, ...) {
}
-Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule)
+Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule, Flags flags)
: zone_(zone),
graph_(graph),
schedule_(schedule),
+ flags_(flags),
scheduled_nodes_(zone),
schedule_root_nodes_(zone),
schedule_queue_(zone),
node_data_(graph_->NodeCount(), DefaultSchedulerData(), zone) {}
-Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph) {
+Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph, Flags flags) {
Schedule* schedule = new (graph->zone())
Schedule(graph->zone(), static_cast<size_t>(graph->NodeCount()));
- Scheduler scheduler(zone, graph, schedule);
+ Scheduler scheduler(zone, graph, schedule, flags);
scheduler.BuildCFG();
scheduler.ComputeSpecialRPONumbering();
@@ -1226,7 +1227,10 @@ void Scheduler::ScheduleEarly() {
class ScheduleLateNodeVisitor {
public:
ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler)
- : scheduler_(scheduler), schedule_(scheduler_->schedule_) {}
+ : scheduler_(scheduler),
+ schedule_(scheduler_->schedule_),
+ visited_(scheduler->zone_),
+ stack_(scheduler->zone_) {}
// Run the schedule late algorithm on a set of fixed root nodes.
void Run(NodeVector* roots) {
@@ -1249,8 +1253,9 @@ class ScheduleLateNodeVisitor {
queue->push(node);
while (!queue->empty()) {
- VisitNode(queue->front());
+ Node* const node = queue->front();
queue->pop();
+ VisitNode(node);
}
}
}
@@ -1282,13 +1287,21 @@ class ScheduleLateNodeVisitor {
// into enclosing loop pre-headers until they would preceed their schedule
// early position.
BasicBlock* hoist_block = GetPreHeader(block);
- while (hoist_block != NULL &&
- hoist_block->dominator_depth() >= min_block->dominator_depth()) {
- Trace(" hoisting #%d:%s to block B%d\n", node->id(),
- node->op()->mnemonic(), hoist_block->id().ToInt());
- DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
- block = hoist_block;
- hoist_block = GetPreHeader(hoist_block);
+ if (hoist_block &&
+ hoist_block->dominator_depth() >= min_block->dominator_depth()) {
+ do {
+ Trace(" hoisting #%d:%s to block B%d\n", node->id(),
+ node->op()->mnemonic(), hoist_block->id().ToInt());
+ DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+ block = hoist_block;
+ hoist_block = GetPreHeader(hoist_block);
+ } while (hoist_block &&
+ hoist_block->dominator_depth() >= min_block->dominator_depth());
+ } else if (scheduler_->flags_ & Scheduler::kSplitNodes &&
+ block->SuccessorCount() >= 2 &&
+ node->op()->HasProperty(Operator::kPure)) {
+ // Split the {node} if beneficial and return the new {block} for it.
+ if (SplitNode(block, node)) return;
}
// Schedule the node or a floating control structure.
@@ -1299,6 +1312,86 @@ class ScheduleLateNodeVisitor {
}
}
+ bool SplitNode(BasicBlock* block, Node* node) {
+ std::fill(visited_.begin(), visited_.end(), false);
+ visited_.resize(schedule_->BasicBlockCount() + 1, false);
+ stack_.clear();
+
+ // Check if the {node} has uses in {block}.
+ for (Edge edge : node->use_edges()) {
+ BasicBlock* use_block = GetBlockForUse(edge);
+ if (use_block == block) {
+ Trace(" not splitting #%d:%s, it is used in B%d\n", node->id(),
+ node->op()->mnemonic(), block->id().ToInt());
+ return false;
+ }
+ if (use_block) {
+ visited_[use_block->id().ToSize()] = true;
+ for (BasicBlock* predecessor : use_block->predecessors()) {
+ stack_.push_back(predecessor);
+ }
+ }
+ }
+
+ while (!stack_.empty()) {
+ BasicBlock* block = stack_.back();
+ stack_.pop_back();
+ bool visited = visited_[block->id().ToSize()];
+ if (visited) continue;
+ visited = true;
+ for (BasicBlock* successor : block->successors()) {
+ if (!visited_[successor->id().ToSize()]) {
+ visited = false;
+ break;
+ }
+ }
+ if (visited) {
+ visited_[block->id().ToSize()] = true;
+ for (BasicBlock* predecessor : block->predecessors()) {
+ stack_.push_back(predecessor);
+ }
+ }
+ }
+
+ if (visited_[block->id().ToSize()]) {
+ return false;
+ }
+
+ std::map<BasicBlock*, Node*> dominators;
+ for (Edge edge : node->use_edges()) {
+ BasicBlock* use_block = GetBlockForUse(edge);
+ if (!use_block) continue;
+ BasicBlock* dominator = use_block;
+ DCHECK(visited_[dominator->id().ToSize()]);
+ while (visited_[dominator->dominator()->id().ToSize()]) {
+ dominator = dominator->dominator();
+ }
+ if (dominators.find(dominator) == dominators.end()) {
+ if (dominators.size() == 0) {
+ dominators.insert(std::make_pair(dominator, node));
+ scheduler_->schedule_queue_.push(node);
+ } else {
+ Node* copy = CloneNode(node);
+ dominators.insert(std::make_pair(dominator, copy));
+ scheduler_->schedule_queue_.push(copy);
+ }
+ }
+ }
+
+ for (Edge edge : node->use_edges()) {
+ BasicBlock* use_block = GetBlockForUse(edge);
+ if (!use_block) continue;
+ for (;; use_block = use_block->dominator()) {
+ DCHECK(visited_[use_block->id().ToSize()]);
+ if (Node* node = dominators[use_block]) {
+ edge.UpdateTo(node);
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
BasicBlock* GetPreHeader(BasicBlock* block) {
if (block->IsLoopHeader()) {
return block->dominator();
@@ -1310,7 +1403,7 @@ class ScheduleLateNodeVisitor {
}
BasicBlock* GetCommonDominatorOfUses(Node* node) {
- BasicBlock* block = NULL;
+ BasicBlock* block = nullptr;
for (Edge edge : node->use_edges()) {
BasicBlock* use_block = GetBlockForUse(edge);
block = block == NULL ? use_block : use_block == NULL
@@ -1361,8 +1454,25 @@ class ScheduleLateNodeVisitor {
scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
}
+ Node* CloneNode(Node* node) {
+ int const input_count = node->InputCount();
+ Node** const inputs = scheduler_->zone_->NewArray<Node*>(input_count);
+ for (int index = 0; index < input_count; ++index) {
+ Node* const input = node->InputAt(index);
+ scheduler_->IncrementUnscheduledUseCount(input, index, node);
+ inputs[index] = input;
+ }
+ Node* copy = scheduler_->graph_->NewNode(node->op(), input_count, inputs);
+ scheduler_->node_data_.resize(copy->id() + 1,
+ scheduler_->DefaultSchedulerData());
+ scheduler_->node_data_[copy->id()] = scheduler_->node_data_[node->id()];
+ return copy;
+ }
+
Scheduler* scheduler_;
Schedule* schedule_;
+ BoolVector visited_;
+ BasicBlockVector stack_;
};
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698