Reviewers: jarin,
Description:
Add Schedule::InsertBranch to fuse control flow graphs.
[email protected]
TEST=cctest/test-schedule/TestScheduleInsertBranch
Please review this at https://codereview.chromium.org/675983002/
Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+78, -9 lines):
M src/compiler/schedule.h
M src/compiler/schedule.cc
M test/cctest/compiler/test-schedule.cc
Index: src/compiler/schedule.cc
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc
index
ede6eaa691cc119ebc8331f2303e249a44a9a469..51400cf04c2d12b71a1b6d1a3126e2da5f69458d
100644
--- a/src/compiler/schedule.cc
+++ b/src/compiler/schedule.cc
@@ -51,7 +51,6 @@ void BasicBlock::AddNode(Node* node) {
nodes_.push_back(node); }
void BasicBlock::set_control(Control control) {
- DCHECK(control_ == BasicBlock::kNone);
control_ = control;
}
@@ -215,12 +214,42 @@ void Schedule::AddThrow(BasicBlock* block, Node*
input) {
}
+void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node*
branch,
+ BasicBlock* tblock, BasicBlock* fblock) {
+ DCHECK(block->control() != BasicBlock::kNone);
+ DCHECK(end->control() == BasicBlock::kNone);
+ end->set_control(block->control());
+ block->set_control(BasicBlock::kBranch);
+ MoveSuccessors(block, end);
+ AddSuccessor(block, tblock);
+ AddSuccessor(block, fblock);
+ if (block->control_input() != NULL) {
+ SetControlInput(end, block->control_input());
+ }
+ SetControlInput(block, branch);
+}
+
+
void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
block->AddSuccessor(succ);
succ->AddPredecessor(block);
}
+void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) {
+ for (BasicBlock::Predecessors::iterator i = from->successors_begin();
+ i != from->successors_end(); ++i) {
+ BasicBlock* succ = *i;
+ to->AddSuccessor(succ);
+ for (BasicBlock::Predecessors::iterator j = succ->predecessors_begin();
+ j != succ->predecessors_end(); ++j) {
+ if (*j == from) *j = to;
+ }
+ }
+ from->ClearSuccessors();
+}
+
+
void Schedule::SetControlInput(BasicBlock* block, Node* node) {
block->set_control_input(node);
SetBlockForNode(block, node);
Index: src/compiler/schedule.h
diff --git a/src/compiler/schedule.h b/src/compiler/schedule.h
index
5ff554f821e6545f5666e0b3b5b0325f030885b9..fbb00b0ee8d56aa590fb7d403e84e82e09d38fa8
100644
--- a/src/compiler/schedule.h
+++ b/src/compiler/schedule.h
@@ -95,6 +95,7 @@ class BasicBlock FINAL : public ZoneObject {
}
size_t PredecessorCount() const { return predecessors_.size(); }
BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
+ void ClearPredecessors() { predecessors_.clear(); }
void AddPredecessor(BasicBlock* predecessor);
typedef ZoneVector<BasicBlock*> Successors;
@@ -108,6 +109,7 @@ class BasicBlock FINAL : public ZoneObject {
}
size_t SuccessorCount() const { return successors_.size(); }
BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
+ void ClearSuccessors() { successors_.clear(); }
void AddSuccessor(BasicBlock* successor);
// Nodes in the basic block.
@@ -240,7 +242,13 @@ class Schedule FINAL : public ZoneObject {
// BasicBlock building: add a throw at the end of {block}.
void AddThrow(BasicBlock* block, Node* input);
+ // BasicBlock mutation: insert a branch into the end of {block}.
+ void InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+ BasicBlock* tblock, BasicBlock* fblock);
+
+ // Exposed publicly for testing only.
void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+ void MoveSuccessors(BasicBlock* from, BasicBlock* to);
BasicBlockVector* rpo_order() { return &rpo_order_; }
const BasicBlockVector* rpo_order() const { return &rpo_order_; }
Index: test/cctest/compiler/test-schedule.cc
diff --git a/test/cctest/compiler/test-schedule.cc
b/test/cctest/compiler/test-schedule.cc
index
63e7c2c2b716b0da72afb148053f8c60678e5fe1..da52a66be5129d3f138d4a8d22aebae2e851d8a8
100644
--- a/test/cctest/compiler/test-schedule.cc
+++ b/test/cctest/compiler/test-schedule.cc
@@ -30,12 +30,11 @@ TEST(TestScheduleAllocation) {
TEST(TestScheduleAddNode) {
HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
Graph graph(scope.main_zone());
Node* n0 = graph.NewNode(&dummy_operator);
Node* n1 = graph.NewNode(&dummy_operator);
- Schedule schedule(scope.main_zone());
-
BasicBlock* entry = schedule.start();
schedule.AddNode(entry, n0);
schedule.AddNode(entry, n1);
@@ -51,8 +50,8 @@ TEST(TestScheduleAddNode) {
TEST(TestScheduleAddGoto) {
HandleAndZoneScope scope;
-
Schedule schedule(scope.main_zone());
+
BasicBlock* entry = schedule.start();
BasicBlock* next = schedule.NewBasicBlock();
@@ -71,16 +70,15 @@ TEST(TestScheduleAddGoto) {
TEST(TestScheduleAddBranch) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
-
- BasicBlock* entry = schedule.start();
- BasicBlock* tblock = schedule.NewBasicBlock();
- BasicBlock* fblock = schedule.NewBasicBlock();
-
Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone());
Node* n0 = graph.NewNode(&dummy_operator);
Node* b = graph.NewNode(common.Branch(), n0);
+ BasicBlock* entry = schedule.start();
+ BasicBlock* tblock = schedule.NewBasicBlock();
+ BasicBlock* fblock = schedule.NewBasicBlock();
+
schedule.AddBranch(entry, b, tblock, fblock);
CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
@@ -126,6 +124,40 @@ TEST(TestScheduleAddThrow) {
}
+TEST(TestScheduleInsertBranch) {
+ HandleAndZoneScope scope;
+ Schedule schedule(scope.main_zone());
+ Graph graph(scope.main_zone());
+ CommonOperatorBuilder common(scope.main_zone());
+ Node* n0 = graph.NewNode(&dummy_operator);
+ Node* n1 = graph.NewNode(&dummy_operator);
+ Node* b = graph.NewNode(common.Branch(), n1);
+
+ BasicBlock* entry = schedule.start();
+ BasicBlock* tblock = schedule.NewBasicBlock();
+ BasicBlock* fblock = schedule.NewBasicBlock();
+ BasicBlock* merge = schedule.NewBasicBlock();
+ schedule.AddReturn(entry, n0);
+ schedule.AddGoto(tblock, merge);
+ schedule.AddGoto(fblock, merge);
+
+ schedule.InsertBranch(entry, merge, b, tblock, fblock);
+
+ CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+ CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
+ CHECK_EQ(tblock, entry->SuccessorAt(0));
+ CHECK_EQ(fblock, entry->SuccessorAt(1));
+
+ CHECK_EQ(2, static_cast<int>(merge->PredecessorCount()));
+ CHECK_EQ(1, static_cast<int>(merge->SuccessorCount()));
+ CHECK_EQ(schedule.end(), merge->SuccessorAt(0));
+
+ CHECK_EQ(1, static_cast<int>(schedule.end()->PredecessorCount()));
+ CHECK_EQ(0, static_cast<int>(schedule.end()->SuccessorCount()));
+ CHECK_EQ(merge, schedule.end()->PredecessorAt(0));
+}
+
+
TEST(BuildMulNodeGraph) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.