[turbofan] Cleanup Schedule and related classes.
authorbmeurer <bmeurer@chromium.org>
Thu, 22 Jan 2015 13:01:02 +0000 (05:01 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 22 Jan 2015 13:01:13 +0000 (13:01 +0000)
- 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}

15 files changed:
src/compiler/basic-block-instrumentor.cc
src/compiler/graph-visualizer.cc
src/compiler/instruction-selector.h
src/compiler/instruction.cc
src/compiler/schedule.cc
src/compiler/schedule.h
src/compiler/scheduler.cc
src/compiler/scheduler.h
src/compiler/verifier.cc
test/cctest/cctest.gyp
test/cctest/compiler/test-instruction.cc
test/cctest/compiler/test-schedule.cc [deleted file]
test/cctest/compiler/test-scheduler.cc
test/unittests/compiler/schedule-unittest.cc [new file with mode: 0644]
test/unittests/unittests.gyp

index d7d3ade..54f9d6b 100644 (file)
@@ -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"
 
index 0bad333..e09d987 100644 (file)
@@ -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_ << " ";
index d77fc02..dc8f1b8 100644 (file)
@@ -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.
index 9d6d5e2..6b0540a 100644 (file)
@@ -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;
 }
index 30bfbc8..0622386 100644 (file)
@@ -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";
     }
index 0bba689..ffce49f 100644 (file)
@@ -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
index 1b514a6..59a0140 100644 (file)
@@ -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
index 9da0b6d..886b755 100644 (file)
@@ -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 {
index aa5c9a4..82700f3 100644 (file)
@@ -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()));
     }
   }
 
index a962c47..aaf905e 100644 (file)
@@ -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',
index f1c9bcd..e6e44ea 100644 (file)
@@ -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());
diff --git a/test/cctest/compiler/test-schedule.cc b/test/cctest/compiler/test-schedule.cc
deleted file mode 100644 (file)
index 1eb3547..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-// 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);
-}
index 1b79ed5..6ad7905 100644 (file)
@@ -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);
 }
 
 
diff --git a/test/unittests/compiler/schedule-unittest.cc b/test/unittests/compiler/schedule-unittest.cc
new file mode 100644 (file)
index 0000000..fc94884
--- /dev/null
@@ -0,0 +1,163 @@
+// 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
index 7f8e71c..1327694 100644 (file)
@@ -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',