Commit c9283148 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Cleanup Schedule and related classes.

- Move unit tests to schedule-unittests.cc.
- Remove pre-C++11 cruft.
- Fix some include weirdness.

R=mstarzinger@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26220}
parent 8ccc696b
......@@ -10,6 +10,7 @@
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/schedule.h"
......
......@@ -570,17 +570,15 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
PrintIndent();
os_ << "predecessors";
for (BasicBlock::Predecessors::iterator j = current->predecessors_begin();
j != current->predecessors_end(); ++j) {
os_ << " \"B" << (*j)->id() << "\"";
for (BasicBlock* predecessor : current->predecessors()) {
os_ << " \"B" << predecessor->id() << "\"";
}
os_ << "\n";
PrintIndent();
os_ << "successors";
for (BasicBlock::Successors::iterator j = current->successors_begin();
j != current->successors_end(); ++j) {
os_ << " \"B" << (*j)->id() << "\"";
for (BasicBlock* successor : current->successors()) {
os_ << " \"B" << successor->id() << "\"";
}
os_ << "\n";
......@@ -665,9 +663,8 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
os_ << -1 - current->id().ToInt() << " Goto";
}
os_ << " ->";
for (BasicBlock::Successors::iterator j = current->successors_begin();
j != current->successors_end(); ++j) {
os_ << " B" << (*j)->id();
for (BasicBlock* successor : current->successors()) {
os_ << " B" << successor->id();
}
if (FLAG_trace_turbo_types && current->control_input() != NULL) {
os_ << " ";
......
......@@ -10,6 +10,7 @@
#include "src/compiler/common-operator.h"
#include "src/compiler/instruction.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h"
#include "src/zone-containers.h"
namespace v8 {
......@@ -21,6 +22,8 @@ struct CallBuffer; // TODO(bmeurer): Remove this.
class FlagsContinuation;
class Linkage;
// Instruction selection generates an InstructionSequence for a given Schedule.
class InstructionSelector FINAL {
public:
// Forward declarations.
......
......@@ -387,14 +387,12 @@ static InstructionBlock* InstructionBlockFor(Zone* zone,
GetLoopEndRpo(block), block->deferred());
// Map successors and precessors
instr_block->successors().reserve(block->SuccessorCount());
for (auto it = block->successors_begin(); it != block->successors_end();
++it) {
instr_block->successors().push_back((*it)->GetRpoNumber());
for (BasicBlock* successor : block->successors()) {
instr_block->successors().push_back(successor->GetRpoNumber());
}
instr_block->predecessors().reserve(block->PredecessorCount());
for (auto it = block->predecessors_begin(); it != block->predecessors_end();
++it) {
instr_block->predecessors().push_back((*it)->GetRpoNumber());
for (BasicBlock* predecessor : block->predecessors()) {
instr_block->predecessors().push_back(predecessor->GetRpoNumber());
}
return instr_block;
}
......
......@@ -2,10 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/schedule.h"
#include "src/compiler/node.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/node-properties-inl.h"
#include "src/compiler/schedule.h"
#include "src/ostreams.h"
namespace v8 {
......@@ -235,13 +236,10 @@ void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
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;
for (BasicBlock* const successor : from->successors()) {
to->AddSuccessor(successor);
for (BasicBlock*& predecessor : successor->predecessors()) {
if (predecessor == from) predecessor = to;
}
}
from->ClearSuccessors();
......@@ -264,24 +262,18 @@ void Schedule::SetBlockForNode(BasicBlock* block, Node* node) {
std::ostream& operator<<(std::ostream& os, const Schedule& s) {
// TODO(svenpanne) Const-correct the RPO stuff/iterators.
BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order();
for (BasicBlockVectorIter i = rpo->begin(); i != rpo->end(); ++i) {
BasicBlock* block = *i;
for (BasicBlock* block : *s.rpo_order()) {
os << "--- BLOCK B" << block->id();
if (block->deferred()) os << " (deferred)";
if (block->PredecessorCount() != 0) os << " <- ";
bool comma = false;
for (BasicBlock::Predecessors::iterator j = block->predecessors_begin();
j != block->predecessors_end(); ++j) {
for (BasicBlock const* predecessor : block->predecessors()) {
if (comma) os << ", ";
comma = true;
os << "B" << (*j)->id();
os << "B" << predecessor->id();
}
os << " ---\n";
for (BasicBlock::const_iterator j = block->begin(); j != block->end();
++j) {
Node* node = *j;
for (Node* node : *block) {
os << " " << *node;
if (NodeProperties::IsTyped(node)) {
Bounds bounds = NodeProperties::GetBounds(node);
......@@ -304,11 +296,10 @@ std::ostream& operator<<(std::ostream& os, const Schedule& s) {
}
os << " -> ";
comma = false;
for (BasicBlock::Successors::iterator j = block->successors_begin();
j != block->successors_end(); ++j) {
for (BasicBlock const* successor : block->successors()) {
if (comma) os << ", ";
comma = true;
os << "B" << (*j)->id();
os << "B" << successor->id();
}
os << "\n";
}
......
......@@ -6,23 +6,24 @@
#define V8_COMPILER_SCHEDULE_H_
#include <iosfwd>
#include <vector>
#include "src/v8.h"
#include "src/compiler/node.h"
#include "src/compiler/opcodes.h"
#include "src/zone.h"
#include "src/zone-containers.h"
namespace v8 {
namespace internal {
namespace compiler {
// Forward declarations.
class BasicBlock;
class BasicBlockInstrumentor;
class Graph;
class ConstructScheduleData;
class CodeGenerator; // Because of a namespace bug in clang.
class ConstructScheduleData;
class Node;
typedef ZoneVector<BasicBlock*> BasicBlockVector;
typedef ZoneVector<Node*> NodeVector;
// A basic block contains an ordered list of nodes and ends with a control
// node. Note that if a basic block has phis, then all phis must appear as the
......@@ -83,36 +84,26 @@ class BasicBlock FINAL : public ZoneObject {
Id id() const { return id_; }
// Predecessors and successors.
typedef ZoneVector<BasicBlock*> Predecessors;
Predecessors::iterator predecessors_begin() { return predecessors_.begin(); }
Predecessors::iterator predecessors_end() { return predecessors_.end(); }
Predecessors::const_iterator predecessors_begin() const {
return predecessors_.begin();
}
Predecessors::const_iterator predecessors_end() const {
return predecessors_.end();
}
// Predecessors.
BasicBlockVector& predecessors() { return predecessors_; }
const BasicBlockVector& predecessors() const { return predecessors_; }
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;
Successors::iterator successors_begin() { return successors_.begin(); }
Successors::iterator successors_end() { return successors_.end(); }
Successors::const_iterator successors_begin() const {
return successors_.begin();
}
Successors::const_iterator successors_end() const {
return successors_.end();
}
// Successors.
BasicBlockVector& successors() { return successors_; }
const BasicBlockVector& successors() const { return successors_; }
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.
typedef Node* value_type;
bool empty() const { return nodes_.empty(); }
size_t size() const { return nodes_.size(); }
Node* NodeAt(size_t index) { return nodes_[index]; }
size_t NodeCount() const { return nodes_.size(); }
......@@ -191,20 +182,17 @@ class BasicBlock FINAL : public ZoneObject {
Node* control_input_; // Input value for control.
NodeVector nodes_; // nodes of this block in forward order.
Successors successors_;
Predecessors predecessors_;
BasicBlockVector successors_;
BasicBlockVector predecessors_;
Id id_;
DISALLOW_COPY_AND_ASSIGN(BasicBlock);
};
std::ostream& operator<<(std::ostream& os, const BasicBlock::Control& c);
std::ostream& operator<<(std::ostream& os, const BasicBlock::Id& id);
std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo);
std::ostream& operator<<(std::ostream&, const BasicBlock::Control&);
std::ostream& operator<<(std::ostream&, const BasicBlock::Id&);
std::ostream& operator<<(std::ostream&, const BasicBlock::RpoNumber&);
typedef ZoneVector<BasicBlock*> BasicBlockVector;
typedef BasicBlockVector::iterator BasicBlockVectorIter;
typedef BasicBlockVector::reverse_iterator BasicBlockVectorRIter;
// A schedule represents the result of assigning nodes to basic blocks
// and ordering them within basic blocks. Prior to computing a schedule,
......@@ -286,7 +274,7 @@ class Schedule FINAL : public ZoneObject {
DISALLOW_COPY_AND_ASSIGN(Schedule);
};
std::ostream& operator<<(std::ostream& os, const Schedule& s);
std::ostream& operator<<(std::ostream&, const Schedule&);
} // namespace compiler
} // namespace internal
......
......@@ -1032,8 +1032,8 @@ void Scheduler::ComputeSpecialRPONumbering() {
void Scheduler::PropagateImmediateDominators(BasicBlock* block) {
for (/*nop*/; block != NULL; block = block->rpo_next()) {
BasicBlock::Predecessors::iterator pred = block->predecessors_begin();
BasicBlock::Predecessors::iterator end = block->predecessors_end();
auto pred = block->predecessors().begin();
auto end = block->predecessors().end();
DCHECK(pred != end); // All blocks except start have predecessors.
BasicBlock* dominator = *pred;
// For multiple predecessors, walk up the dominator tree until a common
......
......@@ -7,6 +7,7 @@
#include "src/v8.h"
#include "src/compiler/node.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/schedule.h"
#include "src/compiler/zone-pool.h"
......@@ -16,10 +17,13 @@ namespace v8 {
namespace internal {
namespace compiler {
// Forward declarations.
class CFGBuilder;
class ControlEquivalence;
class Graph;
class SpecialRPONumberer;
// Computes a schedule from a graph, placing nodes into basic blocks and
// ordering the basic blocks in the special RPO order.
class Scheduler {
......
......@@ -840,15 +840,13 @@ void ScheduleVerifier::Run(Schedule* schedule) {
++b) {
CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
// All predecessors and successors should be in rpo and in this schedule.
for (BasicBlock::Predecessors::iterator j = (*b)->predecessors_begin();
j != (*b)->predecessors_end(); ++j) {
CHECK_GE((*j)->rpo_number(), 0);
CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
}
for (BasicBlock::Successors::iterator j = (*b)->successors_begin();
j != (*b)->successors_end(); ++j) {
CHECK_GE((*j)->rpo_number(), 0);
CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
for (BasicBlock const* predecessor : (*b)->predecessors()) {
CHECK_GE(predecessor->rpo_number(), 0);
CHECK_EQ(predecessor, schedule->GetBlockById(predecessor->id()));
}
for (BasicBlock const* successor : (*b)->successors()) {
CHECK_GE(successor->rpo_number(), 0);
CHECK_EQ(successor, schedule->GetBlockById(successor->id()));
}
}
......
......@@ -88,7 +88,6 @@
'compiler/test-run-properties.cc',
'compiler/test-run-stackcheck.cc',
'compiler/test-run-variables.cc',
'compiler/test-schedule.cc',
'compiler/test-scheduler.cc',
'compiler/test-simplified-lowering.cc',
'compiler/test-typer.cc',
......
......@@ -131,10 +131,7 @@ TEST(InstructionBasic) {
BasicBlockVector* blocks = R.schedule.rpo_order();
CHECK_EQ(static_cast<int>(blocks->size()), R.code->InstructionBlockCount());
int index = 0;
for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
i++, index++) {
BasicBlock* block = *i;
for (auto block : *blocks) {
CHECK_EQ(block->rpo_number(), R.BlockAt(block)->rpo_number().ToInt());
CHECK_EQ(block->id().ToInt(), R.BlockAt(block)->id().ToInt());
CHECK_EQ(NULL, block->loop_end());
......
// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/v8.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/machine-operator.h"
#include "src/compiler/node.h"
#include "src/compiler/operator.h"
#include "src/compiler/schedule.h"
#include "test/cctest/cctest.h"
using namespace v8::internal;
using namespace v8::internal::compiler;
static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
"dummy", 0, 0, 0, 0, 0, 0);
TEST(TestScheduleAllocation) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
CHECK_NE(NULL, schedule.start());
CHECK_EQ(schedule.start(), schedule.GetBlockById(BasicBlock::Id::FromInt(0)));
}
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);
BasicBlock* entry = schedule.start();
schedule.AddNode(entry, n0);
schedule.AddNode(entry, n1);
CHECK_EQ(entry, schedule.block(n0));
CHECK_EQ(entry, schedule.block(n1));
CHECK(schedule.SameBasicBlock(n0, n1));
Node* n2 = graph.NewNode(&dummy_operator);
CHECK_EQ(NULL, schedule.block(n2));
}
TEST(TestScheduleAddGoto) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
BasicBlock* entry = schedule.start();
BasicBlock* next = schedule.NewBasicBlock();
schedule.AddGoto(entry, next);
CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(next, entry->SuccessorAt(0));
CHECK_EQ(1, static_cast<int>(next->PredecessorCount()));
CHECK_EQ(entry, next->PredecessorAt(0));
CHECK_EQ(0, static_cast<int>(next->SuccessorCount()));
}
TEST(TestScheduleAddBranch) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
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()));
CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(tblock, entry->SuccessorAt(0));
CHECK_EQ(fblock, entry->SuccessorAt(1));
CHECK_EQ(1, static_cast<int>(tblock->PredecessorCount()));
CHECK_EQ(entry, tblock->PredecessorAt(0));
CHECK_EQ(0, static_cast<int>(tblock->SuccessorCount()));
CHECK_EQ(1, static_cast<int>(fblock->PredecessorCount()));
CHECK_EQ(entry, fblock->PredecessorAt(0));
CHECK_EQ(0, static_cast<int>(fblock->SuccessorCount()));
}
TEST(TestScheduleAddReturn) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
Graph graph(scope.main_zone());
Node* n0 = graph.NewNode(&dummy_operator);
BasicBlock* entry = schedule.start();
schedule.AddReturn(entry, n0);
CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
}
TEST(TestScheduleAddThrow) {
HandleAndZoneScope scope;
Schedule schedule(scope.main_zone());
Graph graph(scope.main_zone());
Node* n0 = graph.NewNode(&dummy_operator);
BasicBlock* entry = schedule.start();
schedule.AddThrow(entry, n0);
CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
}
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());
Graph graph(scope.main_zone());
CommonOperatorBuilder common(scope.main_zone());
// TODO(titzer): use test operators.
MachineOperatorBuilder machine(scope.main_zone());
Node* start = graph.NewNode(common.Start(0));
graph.SetStart(start);
Node* param0 = graph.NewNode(common.Parameter(0), graph.start());
Node* param1 = graph.NewNode(common.Parameter(1), graph.start());
Node* mul = graph.NewNode(machine.Int32Mul(), param0, param1);
Node* ret = graph.NewNode(common.Return(), mul, start);
USE(ret);
}
......@@ -86,21 +86,13 @@ static TestLoop* CreateLoop(Schedule* schedule, int count) {
}
static int GetScheduledNodeCount(Schedule* schedule) {
int node_count = 0;
for (BasicBlockVectorIter i = schedule->rpo_order()->begin();
i != schedule->rpo_order()->end(); ++i) {
BasicBlock* block = *i;
for (BasicBlock::const_iterator j = block->begin(); j != block->end();
++j) {
++node_count;
}
BasicBlock::Control control = block->control();
if (control != BasicBlock::kNone) {
++node_count;
}
static int GetScheduledNodeCount(const Schedule* schedule) {
size_t node_count = 0;
for (auto block : *schedule->rpo_order()) {
node_count += block->NodeCount();
if (block->control() != BasicBlock::kNone) ++node_count;
}
return node_count;
return static_cast<int>(node_count);
}
......
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/node.h"
#include "src/compiler/schedule.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"
using testing::ElementsAre;
namespace v8 {
namespace internal {
namespace compiler {
typedef TestWithZone ScheduleTest;
namespace {
const Operator kBranchOperator(IrOpcode::kBranch, Operator::kNoProperties,
"Branch", 0, 0, 0, 0, 0, 0);
const Operator kDummyOperator(IrOpcode::kParameter, Operator::kNoProperties,
"Dummy", 0, 0, 0, 0, 0, 0);
} // namespace
TEST_F(ScheduleTest, Constructor) {
Schedule schedule(zone());
EXPECT_NE(nullptr, schedule.start());
EXPECT_EQ(schedule.start(),
schedule.GetBlockById(BasicBlock::Id::FromInt(0)));
EXPECT_NE(nullptr, schedule.end());
EXPECT_EQ(schedule.end(), schedule.GetBlockById(BasicBlock::Id::FromInt(1)));
EXPECT_NE(schedule.start(), schedule.end());
}
TEST_F(ScheduleTest, AddNode) {
Schedule schedule(zone());
BasicBlock* start = schedule.start();
Node* node0 = Node::New(zone(), 0, &kDummyOperator, 0, nullptr, false);
EXPECT_EQ(nullptr, schedule.block(node0));
schedule.AddNode(start, node0);
EXPECT_EQ(start, schedule.block(node0));
EXPECT_THAT(*start, ElementsAre(node0));
Node* node1 = Node::New(zone(), 1, &kDummyOperator, 0, nullptr, false);
EXPECT_EQ(nullptr, schedule.block(node1));
schedule.AddNode(start, node1);
EXPECT_EQ(start, schedule.block(node1));
EXPECT_THAT(*start, ElementsAre(node0, node1));
EXPECT_TRUE(schedule.SameBasicBlock(node0, node1));
}
TEST_F(ScheduleTest, AddGoto) {
Schedule schedule(zone());
BasicBlock* start = schedule.start();
BasicBlock* end = schedule.end();
BasicBlock* block = schedule.NewBasicBlock();
schedule.AddGoto(start, block);
EXPECT_EQ(0u, start->PredecessorCount());
EXPECT_EQ(1u, start->SuccessorCount());
EXPECT_EQ(block, start->SuccessorAt(0));
EXPECT_THAT(start->successors(), ElementsAre(block));
EXPECT_EQ(1u, block->PredecessorCount());
EXPECT_EQ(0u, block->SuccessorCount());
EXPECT_EQ(start, block->PredecessorAt(0));
EXPECT_THAT(block->predecessors(), ElementsAre(start));
EXPECT_EQ(0u, end->PredecessorCount());
EXPECT_EQ(0u, end->SuccessorCount());
}
TEST_F(ScheduleTest, AddBranch) {
Schedule schedule(zone());
BasicBlock* start = schedule.start();
Node* branch = Node::New(zone(), 0, &kBranchOperator, 0, nullptr, false);
BasicBlock* tblock = schedule.NewBasicBlock();
BasicBlock* fblock = schedule.NewBasicBlock();
schedule.AddBranch(start, branch, tblock, fblock);
EXPECT_EQ(start, schedule.block(branch));
EXPECT_EQ(0u, start->PredecessorCount());
EXPECT_EQ(2u, start->SuccessorCount());
EXPECT_EQ(tblock, start->SuccessorAt(0));
EXPECT_EQ(fblock, start->SuccessorAt(1));
EXPECT_THAT(start->successors(), ElementsAre(tblock, fblock));
EXPECT_EQ(1u, tblock->PredecessorCount());
EXPECT_EQ(0u, tblock->SuccessorCount());
EXPECT_EQ(start, tblock->PredecessorAt(0));
EXPECT_THAT(tblock->predecessors(), ElementsAre(start));
EXPECT_EQ(1u, fblock->PredecessorCount());
EXPECT_EQ(0u, fblock->SuccessorCount());
EXPECT_EQ(start, fblock->PredecessorAt(0));
EXPECT_THAT(fblock->predecessors(), ElementsAre(start));
}
TEST_F(ScheduleTest, AddReturn) {
Schedule schedule(zone());
BasicBlock* start = schedule.start();
BasicBlock* end = schedule.end();
Node* node = Node::New(zone(), 0, &kDummyOperator, 0, nullptr, false);
schedule.AddReturn(start, node);
EXPECT_EQ(0u, start->PredecessorCount());
EXPECT_EQ(1u, start->SuccessorCount());
EXPECT_EQ(end, start->SuccessorAt(0));
EXPECT_THAT(start->successors(), ElementsAre(end));
}
TEST_F(ScheduleTest, InsertBranch) {
Schedule schedule(zone());
BasicBlock* start = schedule.start();
BasicBlock* end = schedule.end();
Node* node = Node::New(zone(), 0, &kDummyOperator, 0, nullptr, false);
Node* branch = Node::New(zone(), 0, &kBranchOperator, 0, nullptr, false);
BasicBlock* tblock = schedule.NewBasicBlock();
BasicBlock* fblock = schedule.NewBasicBlock();
BasicBlock* mblock = schedule.NewBasicBlock();
schedule.AddReturn(start, node);
schedule.AddGoto(tblock, mblock);
schedule.AddGoto(fblock, mblock);
schedule.InsertBranch(start, mblock, branch, tblock, fblock);
EXPECT_EQ(0u, start->PredecessorCount());
EXPECT_EQ(2u, start->SuccessorCount());
EXPECT_EQ(tblock, start->SuccessorAt(0));
EXPECT_EQ(fblock, start->SuccessorAt(1));
EXPECT_THAT(start->successors(), ElementsAre(tblock, fblock));
EXPECT_EQ(2u, mblock->PredecessorCount());
EXPECT_EQ(1u, mblock->SuccessorCount());
EXPECT_EQ(end, mblock->SuccessorAt(0));
EXPECT_THAT(mblock->predecessors(), ElementsAre(tblock, fblock));
EXPECT_THAT(mblock->successors(), ElementsAre(end));
EXPECT_EQ(1u, end->PredecessorCount());
EXPECT_EQ(0u, end->SuccessorCount());
EXPECT_EQ(mblock, end->PredecessorAt(0));
EXPECT_THAT(end->predecessors(), ElementsAre(mblock));
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -65,6 +65,7 @@
'compiler/node-unittest.cc',
'compiler/opcodes-unittest.cc',
'compiler/register-allocator-unittest.cc',
'compiler/schedule-unittest.cc',
'compiler/select-lowering-unittest.cc',
'compiler/simplified-operator-reducer-unittest.cc',
'compiler/simplified-operator-unittest.cc',
......
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