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

Unified Diff: src/compiler/scheduler.cc

Issue 738613005: Restrict floating control to minimal control-connected component. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@local_scheduler-loop-1
Patch Set: Rebased and adapted. Created 6 years 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/zone-allocator.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 5252d42dadb0680e5f1e8152ee1f4a0dadbdca66..03c4c377f913ad1e432f495ffaa45124fb4ce77c 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -8,6 +8,7 @@
#include "src/compiler/scheduler.h"
#include "src/bit-vector.h"
+#include "src/compiler/control-equivalence.h"
#include "src/compiler/graph.h"
#include "src/compiler/graph-inl.h"
#include "src/compiler/node.h"
@@ -58,7 +59,7 @@ Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph) {
Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
- SchedulerData def = {schedule_->start(), 0, false, false, kUnknown};
+ SchedulerData def = {schedule_->start(), 0, false, kUnknown};
return def;
}
@@ -85,17 +86,12 @@ Scheduler::Placement Scheduler::GetPlacement(Node* node) {
data->placement_ = (p == kFixed ? kFixed : kCoupled);
break;
}
-#define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V:
- CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE)
-#undef DEFINE_FLOATING_CONTROL_CASE
+#define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
+ CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
+#undef DEFINE_CONTROL_CASE
{
// Control nodes that were not control-reachable from end may float.
data->placement_ = kSchedulable;
- if (!data->is_connected_control_) {
- data->is_floating_control_ = true;
- Trace("Floating control found: #%d:%s\n", node->id(),
- node->op()->mnemonic());
- }
break;
}
default:
@@ -125,9 +121,9 @@ void Scheduler::UpdatePlacement(Node* node, Placement placement) {
schedule_->AddNode(block, node);
break;
}
-#define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V:
- CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE)
-#undef DEFINE_FLOATING_CONTROL_CASE
+#define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
+ CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
+#undef DEFINE_CONTROL_CASE
{
// Control nodes force coupled uses to be placed.
Node::Uses uses = node->uses();
@@ -241,7 +237,7 @@ class CFGBuilder : public ZoneObject {
schedule_(scheduler->schedule_),
queue_(zone),
control_(zone),
- component_head_(NULL),
+ component_entry_(NULL),
component_start_(NULL),
component_end_(NULL) {}
@@ -267,31 +263,37 @@ class CFGBuilder : public ZoneObject {
}
// Run the control flow graph construction for a minimal control-connected
- // component ending in {node} and merge that component into an existing
+ // component ending in {exit} and merge that component into an existing
// control flow graph at the bottom of {block}.
- void Run(BasicBlock* block, Node* node) {
+ void Run(BasicBlock* block, Node* exit) {
ResetDataStructures();
- Queue(node);
+ Queue(exit);
+ component_entry_ = NULL;
component_start_ = block;
- component_end_ = schedule_->block(node);
+ component_end_ = schedule_->block(exit);
+ scheduler_->equivalence_->Run(exit);
while (!queue_.empty()) { // Breadth-first backwards traversal.
Node* node = queue_.front();
queue_.pop();
- bool is_dom = true;
+
+ // Use control dependence equivalence to find a canonical single-entry
+ // single-exit region that makes up a minimal component to be scheduled.
+ if (IsSingleEntrySingleExitRegion(node, exit)) {
+ Trace("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
+ DCHECK_EQ(NULL, component_entry_);
+ component_entry_ = node;
+ continue;
+ }
+
int max = NodeProperties::PastControlIndex(node);
for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
- is_dom = is_dom &&
- !scheduler_->GetData(node->InputAt(i))->is_floating_control_;
Queue(node->InputAt(i));
}
- // TODO(mstarzinger): This is a hacky way to find component dominator.
- if (is_dom) component_head_ = node;
}
- DCHECK_NOT_NULL(component_head_);
+ DCHECK_NE(NULL, component_entry_);
for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
- scheduler_->GetData(*i)->is_floating_control_ = false;
ConnectBlocks(*i); // Connect block to its predecessor/successors.
}
}
@@ -316,7 +318,6 @@ class CFGBuilder : public ZoneObject {
}
}
-
void BuildBlocks(Node* node) {
switch (node->opcode()) {
case IrOpcode::kEnd:
@@ -390,14 +391,14 @@ class CFGBuilder : public ZoneObject {
IrOpcode::Value false_opcode) {
buffer[0] = NULL;
buffer[1] = NULL;
- for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) {
- if ((*i)->opcode() == true_opcode) {
+ for (Node* use : node->uses()) {
+ if (use->opcode() == true_opcode) {
DCHECK_EQ(NULL, buffer[0]);
- buffer[0] = *i;
+ buffer[0] = use;
}
- if ((*i)->opcode() == false_opcode) {
+ if (use->opcode() == false_opcode) {
DCHECK_EQ(NULL, buffer[1]);
- buffer[1] = *i;
+ buffer[1] = use;
}
}
DCHECK_NE(NULL, buffer[0]);
@@ -430,7 +431,7 @@ class CFGBuilder : public ZoneObject {
break;
}
- if (branch == component_head_) {
+ if (branch == component_entry_) {
TraceConnect(branch, component_start_, successor_blocks[0]);
TraceConnect(branch, component_start_, successor_blocks[1]);
schedule_->InsertBranch(component_start_, component_end_, branch,
@@ -455,8 +456,8 @@ class CFGBuilder : public ZoneObject {
DCHECK(block != NULL);
// For all of the merge's control inputs, add a goto at the end to the
// merge's basic block.
- for (Node* const j : merge->inputs()) {
- BasicBlock* predecessor_block = schedule_->block(j);
+ for (Node* const input : merge->inputs()) {
+ BasicBlock* predecessor_block = schedule_->block(input);
TraceConnect(merge, predecessor_block, block);
schedule_->AddGoto(predecessor_block, block);
}
@@ -485,6 +486,12 @@ class CFGBuilder : public ZoneObject {
node == scheduler_->graph_->end()->InputAt(0));
}
+ bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const {
+ size_t entry_class = scheduler_->equivalence_->ClassOf(entry);
+ size_t exit_class = scheduler_->equivalence_->ClassOf(exit);
+ return entry != exit && entry_class == exit_class;
+ }
+
void ResetDataStructures() {
control_.clear();
DCHECK(queue_.empty());
@@ -495,7 +502,7 @@ class CFGBuilder : public ZoneObject {
Schedule* schedule_;
ZoneQueue<Node*> queue_;
NodeVector control_;
- Node* component_head_;
+ Node* component_entry_;
BasicBlock* component_start_;
BasicBlock* component_end_;
};
@@ -504,6 +511,9 @@ class CFGBuilder : public ZoneObject {
void Scheduler::BuildCFG() {
Trace("--- CREATING CFG -------------------------------------------\n");
+ // Instantiate a new control equivalence algorithm for the graph.
+ equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
+
// Build a control-flow graph for the main control-connected component that
// is being spanned by the graph's start and end nodes.
control_flow_builder_ = new (zone_) CFGBuilder(zone_, this);
@@ -1363,7 +1373,6 @@ class ScheduleLateNodeVisitor {
}
void ScheduleFloatingControl(BasicBlock* block, Node* node) {
- DCHECK(scheduler_->GetData(node)->is_floating_control_);
scheduler_->FuseFloatingControl(block, node);
}
« no previous file with comments | « src/compiler/scheduler.h ('k') | src/zone-allocator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698