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

Unified Diff: src/compiler/scheduler.cc

Issue 892513003: [turbofan] Initial support for Switch. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Wuschelstudio build. Created 5 years, 10 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/schedule.cc ('k') | src/compiler/verifier.cc » ('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 2e12dd36af6a3bf25d2af21634efd7808ff86d94..555625691723db9b9e754931896c28fd51120915 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -218,7 +218,8 @@ void Scheduler::DecrementUnscheduledUseCount(Node* node, int index,
class CFGBuilder : public ZoneObject {
public:
CFGBuilder(Zone* zone, Scheduler* scheduler)
- : scheduler_(scheduler),
+ : zone_(zone),
+ scheduler_(scheduler),
schedule_(scheduler->schedule_),
queued_(scheduler->graph_, 2),
queue_(zone),
@@ -316,7 +317,8 @@ class CFGBuilder : public ZoneObject {
BuildBlockForNode(node);
break;
case IrOpcode::kBranch:
- BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse);
+ case IrOpcode::kSwitch:
+ BuildBlocksForSuccessors(node);
break;
default:
break;
@@ -333,6 +335,10 @@ class CFGBuilder : public ZoneObject {
scheduler_->UpdatePlacement(node, Scheduler::kFixed);
ConnectBranch(node);
break;
+ case IrOpcode::kSwitch:
+ scheduler_->UpdatePlacement(node, Scheduler::kFixed);
+ ConnectSwitch(node);
+ break;
case IrOpcode::kReturn:
scheduler_->UpdatePlacement(node, Scheduler::kFixed);
ConnectReturn(node);
@@ -357,49 +363,67 @@ class CFGBuilder : public ZoneObject {
return block;
}
- void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a,
- IrOpcode::Value b) {
- Node* successors[2];
- CollectSuccessorProjections(node, successors, a, b);
- BuildBlockForNode(successors[0]);
- BuildBlockForNode(successors[1]);
+ void BuildBlocksForSuccessors(Node* node) {
+ size_t const successor_count = node->op()->ControlOutputCount();
+ Node** successors =
+ zone_->NewArray<Node*>(static_cast<int>(successor_count));
+ CollectSuccessorProjections(node, successors, successor_count);
+ for (size_t index = 0; index < successor_count; ++index) {
+ BuildBlockForNode(successors[index]);
+ }
}
// Collect the branch-related projections from a node, such as IfTrue,
- // IfFalse.
- // TODO(titzer): consider moving this to node.h
- void CollectSuccessorProjections(Node* node, Node** buffer,
- IrOpcode::Value true_opcode,
- IrOpcode::Value false_opcode) {
- buffer[0] = NULL;
- buffer[1] = NULL;
- for (Node* use : node->uses()) {
- if (use->opcode() == true_opcode) {
- DCHECK(!buffer[0]);
- buffer[0] = use;
- }
- if (use->opcode() == false_opcode) {
- DCHECK(!buffer[1]);
- buffer[1] = use;
+ // IfFalse, and Case.
+ void CollectSuccessorProjections(Node* node, Node** successors,
+ size_t successor_count) {
+#ifdef DEBUG
+ DCHECK_EQ(static_cast<int>(successor_count), node->UseCount());
+ std::memset(successors, 0, sizeof(*successors) * successor_count);
+#endif
+ for (Node* const use : node->uses()) {
+ size_t index;
+ switch (use->opcode()) {
+ default:
+ UNREACHABLE();
+ // Fall through.
+ case IrOpcode::kIfTrue:
+ DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+ index = 0;
+ break;
+ case IrOpcode::kIfFalse:
+ DCHECK_EQ(IrOpcode::kBranch, node->opcode());
+ index = 1;
+ break;
+ case IrOpcode::kCase:
+ DCHECK_EQ(IrOpcode::kSwitch, node->opcode());
+ index = CaseIndexOf(use->op());
+ break;
}
+ DCHECK_LT(index, successor_count);
+ DCHECK(successors[index] == nullptr);
+ successors[index] = use;
+ }
+#ifdef DEBUG
+ for (size_t index = 0; index < successor_count; ++index) {
+ DCHECK_NOT_NULL(successors[index]);
}
- DCHECK(buffer[0]);
- DCHECK(buffer[1]);
+#endif
}
- void CollectSuccessorBlocks(Node* node, BasicBlock** buffer,
- IrOpcode::Value true_opcode,
- IrOpcode::Value false_opcode) {
- Node* successors[2];
- CollectSuccessorProjections(node, successors, true_opcode, false_opcode);
- buffer[0] = schedule_->block(successors[0]);
- buffer[1] = schedule_->block(successors[1]);
+ void CollectSuccessorBlocks(Node* node, BasicBlock** successor_blocks,
+ size_t successor_count) {
+ Node** successors = reinterpret_cast<Node**>(successor_blocks);
+ CollectSuccessorProjections(node, successors, successor_count);
+ for (size_t index = 0; index < successor_count; ++index) {
+ successor_blocks[index] = schedule_->block(successors[index]);
+ }
}
void ConnectBranch(Node* branch) {
BasicBlock* successor_blocks[2];
- CollectSuccessorBlocks(branch, successor_blocks, IrOpcode::kIfTrue,
- IrOpcode::kIfFalse);
+ CollectSuccessorBlocks(branch, successor_blocks,
+ arraysize(successor_blocks));
// Consider branch hints.
switch (BranchHintOf(branch->op())) {
@@ -421,7 +445,7 @@ class CFGBuilder : public ZoneObject {
} else {
Node* branch_block_node = NodeProperties::GetControlInput(branch);
BasicBlock* branch_block = schedule_->block(branch_block_node);
- DCHECK(branch_block != NULL);
+ DCHECK_NOT_NULL(branch_block);
TraceConnect(branch, branch_block, successor_blocks[0]);
TraceConnect(branch, branch_block, successor_blocks[1]);
@@ -430,12 +454,36 @@ class CFGBuilder : public ZoneObject {
}
}
+ void ConnectSwitch(Node* sw) {
+ size_t const successor_count = sw->op()->ControlOutputCount();
+ BasicBlock** successor_blocks =
+ zone_->NewArray<BasicBlock*>(static_cast<int>(successor_count));
+ CollectSuccessorBlocks(sw, successor_blocks, successor_count);
+
+ if (sw == component_entry_) {
+ for (size_t index = 0; index < successor_count; ++index) {
+ TraceConnect(sw, component_start_, successor_blocks[index]);
+ }
+ schedule_->InsertSwitch(component_start_, component_end_, sw,
+ successor_blocks, successor_count);
+ } else {
+ Node* sw_block_node = NodeProperties::GetControlInput(sw);
+ BasicBlock* sw_block = schedule_->block(sw_block_node);
+ DCHECK_NOT_NULL(sw_block);
+
+ for (size_t index = 0; index < successor_count; ++index) {
+ TraceConnect(sw, sw_block, successor_blocks[index]);
+ }
+ schedule_->AddSwitch(sw_block, sw, successor_blocks, successor_count);
+ }
+ }
+
void ConnectMerge(Node* merge) {
// Don't connect the special merge at the end to its predecessors.
if (IsFinalMerge(merge)) return;
BasicBlock* block = schedule_->block(merge);
- DCHECK(block != NULL);
+ DCHECK_NOT_NULL(block);
// For all of the merge's control inputs, add a goto at the end to the
// merge's basic block.
for (Node* const input : merge->inputs()) {
@@ -460,7 +508,7 @@ class CFGBuilder : public ZoneObject {
}
void TraceConnect(Node* node, BasicBlock* block, BasicBlock* succ) {
- DCHECK(block);
+ DCHECK_NOT_NULL(block);
if (succ == NULL) {
Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
block->id().ToInt());
@@ -487,6 +535,7 @@ class CFGBuilder : public ZoneObject {
DCHECK(control_.empty());
}
+ Zone* zone_;
Scheduler* scheduler_;
Schedule* schedule_;
NodeMarker<bool> queued_; // Mark indicating whether node is queued.
« no previous file with comments | « src/compiler/schedule.cc ('k') | src/compiler/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698