Refactor BasicBlock to not use GenericNode.
authorjarin@chromium.org <jarin@chromium.org>
Tue, 30 Sep 2014 08:23:20 +0000 (08:23 +0000)
committerjarin@chromium.org <jarin@chromium.org>
Tue, 30 Sep 2014 08:23:20 +0000 (08:23 +0000)
To manage BasicBlock's predecessors and successors we now use plain
std::vector.

The change also moves bunch of method definitions from header files
to implementation files.

In zlib, the change brings 3x improvement in the scheduler's memory
consumption. The --turbo-stats flag says we go 169MB -> 55MB in
the scheduler, 383MB -> 268MB overall.

BUG=
R=bmeurer@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24308 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

20 files changed:
src/basic-block-profiler.cc
src/basic-block-profiler.h
src/compiler/basic-block-instrumentor.cc
src/compiler/code-generator-impl.h
src/compiler/code-generator.cc
src/compiler/code-generator.h
src/compiler/instruction-selector-impl.h
src/compiler/instruction-selector.cc
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/phi-reducer.h
src/compiler/register-allocator.cc
src/compiler/schedule.cc
src/compiler/schedule.h
src/compiler/scheduler.cc
src/compiler/scheduler.h
src/compiler/verifier.cc
src/compiler/x64/instruction-selector-x64.cc
test/cctest/compiler/test-schedule.cc
test/cctest/compiler/test-scheduler.cc

index ef68ac6..110c505 100644 (file)
@@ -8,7 +8,7 @@ namespace v8 {
 namespace internal {
 
 BasicBlockProfiler::Data::Data(size_t n_blocks)
-    : n_blocks_(n_blocks), block_ids_(n_blocks_, -1), counts_(n_blocks_, 0) {}
+    : n_blocks_(n_blocks), block_ids_(n_blocks_), counts_(n_blocks_, 0) {}
 
 
 BasicBlockProfiler::Data::~Data() {}
@@ -34,7 +34,7 @@ void BasicBlockProfiler::Data::SetSchedule(OStringStream* os) {
 }
 
 
-void BasicBlockProfiler::Data::SetBlockId(size_t offset, int block_id) {
+void BasicBlockProfiler::Data::SetBlockId(size_t offset, size_t block_id) {
   DCHECK(offset < n_blocks_);
   block_ids_[offset] = block_id;
 }
index e625cd2..58e8542 100644 (file)
@@ -25,7 +25,7 @@ class BasicBlockProfiler {
     void SetCode(OStringStream* os);
     void SetFunctionName(OStringStream* os);
     void SetSchedule(OStringStream* os);
-    void SetBlockId(size_t offset, int block_id);
+    void SetBlockId(size_t offset, size_t block_id);
     uint32_t* GetCounterAddress(size_t offset);
 
    private:
@@ -38,7 +38,7 @@ class BasicBlockProfiler {
     void ResetCounts();
 
     const size_t n_blocks_;
-    std::vector<int> block_ids_;
+    std::vector<size_t> block_ids_;
     std::vector<uint32_t> counts_;
     std::string function_name_;
     std::string schedule_;
index 119a44b..3ee2bb2 100644 (file)
@@ -15,9 +15,9 @@ namespace compiler {
 
 // Find the first place to insert new nodes in a block that's already been
 // scheduled that won't upset the register allocator.
-static NodeVector::iterator FindInsertionPoint(NodeVector* nodes) {
-  NodeVector::iterator i = nodes->begin();
-  for (; i != nodes->end(); ++i) {
+static NodeVector::iterator FindInsertionPoint(BasicBlock* block) {
+  NodeVector::iterator i = block->begin();
+  for (; i != block->end(); ++i) {
     const Operator* op = (*i)->op();
     if (OperatorProperties::IsBasicBlockBegin(op)) continue;
     switch (op->opcode()) {
@@ -72,7 +72,7 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
   for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
        ++it, ++block_number) {
     BasicBlock* block = (*it);
-    data->SetBlockId(block_number, block->id());
+    data->SetBlockId(block_number, block->id().ToSize());
     // TODO(dcarney): wire effect and control deps for load and store.
     // Construct increment operation.
     Node* base = graph->NewNode(
@@ -86,10 +86,9 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
     static const int kArraySize = 6;
     Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
     int insertion_start = block_number == 0 ? 0 : 2;
-    NodeVector* nodes = &block->nodes_;
-    NodeVector::iterator insertion_point = FindInsertionPoint(nodes);
-    nodes->insert(insertion_point, &to_insert[insertion_start],
-                  &to_insert[kArraySize]);
+    NodeVector::iterator insertion_point = FindInsertionPoint(block);
+    block->InsertNodes(insertion_point, &to_insert[insertion_start],
+                       &to_insert[kArraySize]);
     // Tell the scheduler about the new nodes.
     for (int i = insertion_start; i < kArraySize; ++i) {
       schedule->SetBlockForNode(block, to_insert[i]);
index a3f7e4c..318b7e9 100644 (file)
@@ -65,11 +65,8 @@ class InstructionOperandConverter {
   }
 
   BasicBlock* InputBlock(int index) {
-    NodeId block_id = static_cast<NodeId>(InputInt32(index));
-    // operand should be a block id.
-    DCHECK(block_id >= 0);
-    DCHECK(block_id < gen_->schedule()->BasicBlockCount());
-    return gen_->schedule()->GetBlockById(block_id);
+    int block_id = InputInt32(index);
+    return gen_->schedule()->GetBlockById(BasicBlock::Id::FromInt(block_id));
   }
 
   Register OutputRegister(int index = 0) {
index ea1466d..d68c92c 100644 (file)
@@ -107,7 +107,7 @@ void CodeGenerator::AssembleInstruction(Instruction* instr) {
     if (FLAG_code_comments) {
       // TODO(titzer): these code comments are a giant memory leak.
       Vector<char> buffer = Vector<char>::New(32);
-      SNPrintF(buffer, "-- B%d start --", block_start->block()->id());
+      SNPrintF(buffer, "-- B%d start --", block_start->block()->id().ToInt());
       masm()->RecordComment(buffer.start());
     }
     masm()->bind(block_start->label());
index ddc2f9a..ae93551 100644 (file)
@@ -41,8 +41,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   // Checks if {block} will appear directly after {current_block_} when
   // assembling code, in which case, a fall-through can be used.
   bool IsNextInAssemblyOrder(const BasicBlock* block) const {
-    return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
-           block->deferred_ == current_block_->deferred_;
+    return block->rpo_number() == (current_block_->rpo_number() + 1) &&
+           block->deferred() == current_block_->deferred();
   }
 
   // Record a safepoint with the given pointer map.
index b860bc5..ac7c486 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
 #define V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
 
+#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/linkage.h"
@@ -129,7 +130,7 @@ class OperandGenerator {
 
   InstructionOperand* Label(BasicBlock* block) {
     // TODO(bmeurer): We misuse ImmediateOperand here.
-    return TempImmediate(block->id());
+    return TempImmediate(block->id().ToInt());
   }
 
  protected:
index f36b07e..e3e883d 100644 (file)
@@ -55,8 +55,8 @@ void InstructionSelector::SelectInstructions() {
   // Schedule the selected instructions.
   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     BasicBlock* block = *i;
-    size_t end = block->code_end_;
-    size_t start = block->code_start_;
+    size_t end = block->code_end();
+    size_t start = block->code_start();
     sequence()->StartBlock(block);
     while (start-- > end) {
       sequence()->AddInstruction(instructions_[start], block);
@@ -141,8 +141,8 @@ Instruction* InstructionSelector::Emit(Instruction* instr) {
 
 
 bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
-  return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
-         block->deferred_ == current_block_->deferred_;
+  return block->rpo_number() == (current_block_->rpo_number() + 1) &&
+         block->deferred() == current_block_->deferred();
 }
 
 
@@ -383,8 +383,8 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
 
   // We're done with the block.
   // TODO(bmeurer): We should not mutate the schedule.
-  block->code_end_ = current_block_end;
-  block->code_start_ = static_cast<int>(instructions_.size());
+  block->set_code_start(static_cast<int>(instructions_.size()));
+  block->set_code_end(current_block_end);
 
   current_block_ = NULL;
 }
@@ -402,11 +402,11 @@ static inline void CheckNoPhis(const BasicBlock* block) {
 
 
 void InstructionSelector::VisitControl(BasicBlock* block) {
-  Node* input = block->control_input_;
-  switch (block->control_) {
-    case BasicBlockData::kGoto:
+  Node* input = block->control_input();
+  switch (block->control()) {
+    case BasicBlock::kGoto:
       return VisitGoto(block->SuccessorAt(0));
-    case BasicBlockData::kBranch: {
+    case BasicBlock::kBranch: {
       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
       BasicBlock* tbranch = block->SuccessorAt(0);
       BasicBlock* fbranch = block->SuccessorAt(1);
@@ -417,16 +417,16 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
       if (tbranch == fbranch) return VisitGoto(tbranch);
       return VisitBranch(input, tbranch, fbranch);
     }
-    case BasicBlockData::kReturn: {
+    case BasicBlock::kReturn: {
       // If the result itself is a return, return its input.
       Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
                         ? input->InputAt(0)
                         : input;
       return VisitReturn(value);
     }
-    case BasicBlockData::kThrow:
+    case BasicBlock::kThrow:
       return VisitThrow(input);
-    case BasicBlockData::kNone: {
+    case BasicBlock::kNone: {
       // TODO(titzer): exit block doesn't have control.
       DCHECK(input == NULL);
       break;
index 3523280..b7bd9fe 100644 (file)
@@ -5,6 +5,7 @@
 #include "src/compiler/instruction.h"
 
 #include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -320,12 +321,12 @@ Label* InstructionSequence::GetLabel(BasicBlock* block) {
 
 
 BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) {
-  return BlockStartInstruction::cast(InstructionAt(block->code_start_));
+  return BlockStartInstruction::cast(InstructionAt(block->code_start()));
 }
 
 
 void InstructionSequence::StartBlock(BasicBlock* block) {
-  block->code_start_ = static_cast<int>(instructions_.size());
+  block->set_code_start(static_cast<int>(instructions_.size()));
   BlockStartInstruction* block_start =
       BlockStartInstruction::New(zone(), block);
   AddInstruction(block_start, block);
@@ -334,8 +335,8 @@ void InstructionSequence::StartBlock(BasicBlock* block) {
 
 void InstructionSequence::EndBlock(BasicBlock* block) {
   int end = static_cast<int>(instructions_.size());
-  DCHECK(block->code_start_ >= 0 && block->code_start_ < end);
-  block->code_end_ = end;
+  DCHECK(block->code_start() >= 0 && block->code_start() < end);
+  block->set_code_end(end);
 }
 
 
@@ -427,19 +428,17 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) {
   for (int i = 0; i < code.BasicBlockCount(); i++) {
     BasicBlock* block = code.BlockAt(i);
 
-    int bid = block->id();
-    os << "RPO#" << block->rpo_number_ << ": B" << bid;
-    CHECK(block->rpo_number_ == i);
+    os << "RPO#" << block->rpo_number() << ": B" << block->id();
+    CHECK(block->rpo_number() == i);
     if (block->IsLoopHeader()) {
-      os << " loop blocks: [" << block->rpo_number_ << ", " << block->loop_end_
-         << ")";
+      os << " loop blocks: [" << block->rpo_number() << ", "
+         << block->loop_end() << ")";
     }
-    os << "  instructions: [" << block->code_start_ << ", " << block->code_end_
-       << ")\n  predecessors:";
+    os << "  instructions: [" << block->code_start() << ", "
+       << block->code_end() << ")\n  predecessors:";
 
-    BasicBlock::Predecessors predecessors = block->predecessors();
-    for (BasicBlock::Predecessors::iterator iter = predecessors.begin();
-         iter != predecessors.end(); ++iter) {
+    for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin();
+         iter != block->predecessors_end(); ++iter) {
       os << " B" << (*iter)->id();
     }
     os << "\n";
@@ -465,15 +464,14 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) {
       os << "   " << buf.start() << ": " << *code.InstructionAt(j);
     }
 
-    os << "  " << block->control_;
+    os << "  " << block->control();
 
-    if (block->control_input_ != NULL) {
-      os << " v" << block->control_input_->id();
+    if (block->control_input() != NULL) {
+      os << " v" << block->control_input()->id();
     }
 
-    BasicBlock::Successors successors = block->successors();
-    for (BasicBlock::Successors::iterator iter = successors.begin();
-         iter != successors.end(); ++iter) {
+    for (BasicBlock::Successors::iterator iter = block->successors_begin();
+         iter != block->successors_end(); ++iter) {
       os << " B" << (*iter)->id();
     }
     os << "\n";
index 4b18120..6043baa 100644 (file)
@@ -836,10 +836,10 @@ class InstructionSequence FINAL {
   }
 
   BasicBlock* GetContainingLoop(BasicBlock* block) {
-    return block->loop_header_;
+    return block->loop_header();
   }
 
-  int GetLoopEnd(BasicBlock* block) const { return block->loop_end_; }
+  int GetLoopEnd(BasicBlock* block) const { return block->loop_end(); }
 
   BasicBlock* GetBasicBlock(int instruction_index);
 
index 5870d04..787db1c 100644 (file)
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_PHI_REDUCER_H_
 #define V8_COMPILER_PHI_REDUCER_H_
 
+#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph-reducer.h"
 
 namespace v8 {
index 0dd358e..ff196ea 100644 (file)
@@ -4,6 +4,7 @@
 
 #include "src/compiler/register-allocator.h"
 
+#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/linkage.h"
 #include "src/hydrogen.h"
 #include "src/string-stream.h"
@@ -530,25 +531,23 @@ BitVector* RegisterAllocator::ComputeLiveOut(BasicBlock* block) {
       new (zone()) BitVector(code()->VirtualRegisterCount(), zone());
 
   // Process all successor blocks.
-  BasicBlock::Successors successors = block->successors();
-  for (BasicBlock::Successors::iterator i = successors.begin();
-       i != successors.end(); ++i) {
+  for (BasicBlock::Successors::iterator i = block->successors_begin();
+       i != block->successors_end(); ++i) {
     // Add values live on entry to the successor. Note the successor's
     // live_in will not be computed yet for backwards edges.
     BasicBlock* successor = *i;
-    BitVector* live_in = live_in_sets_[successor->rpo_number_];
+    BitVector* live_in = live_in_sets_[successor->rpo_number()];
     if (live_in != NULL) live_out->Union(*live_in);
 
     // All phi input operands corresponding to this successor edge are live
     // out from this block.
-    int index = successor->PredecessorIndexOf(block);
-    DCHECK(index >= 0);
-    DCHECK(index < static_cast<int>(successor->PredecessorCount()));
+    size_t index = successor->PredecessorIndexOf(block);
+    DCHECK(index < successor->PredecessorCount());
     for (BasicBlock::const_iterator j = successor->begin();
          j != successor->end(); ++j) {
       Node* phi = *j;
       if (phi->opcode() != IrOpcode::kPhi) continue;
-      Node* input = phi->InputAt(index);
+      Node* input = phi->InputAt(static_cast<int>(index));
       live_out->Add(input->id());
     }
   }
@@ -772,9 +771,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
         assigned = true;
       }
 
-      BasicBlock::Successors successors = block->successors();
-      for (BasicBlock::Successors::iterator succ = successors.begin();
-           succ != successors.end(); ++succ) {
+      for (BasicBlock::Successors::iterator succ = block->successors_begin();
+           succ != block->successors_end(); ++succ) {
         DCHECK((*succ)->PredecessorCount() == 1);
         int gap_index = (*succ)->first_instruction_index() + 1;
         DCHECK(code()->IsGapAt(gap_index));
@@ -790,9 +788,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
     }
 
     if (!assigned) {
-      BasicBlock::Successors successors = block->successors();
-      for (BasicBlock::Successors::iterator succ = successors.begin();
-           succ != successors.end(); ++succ) {
+      for (BasicBlock::Successors::iterator succ = block->successors_begin();
+           succ != block->successors_end(); ++succ) {
         DCHECK((*succ)->PredecessorCount() == 1);
         int gap_index = (*succ)->first_instruction_index() + 1;
         range->SetSpillStartIndex(gap_index);
@@ -1071,7 +1068,7 @@ void RegisterAllocator::ResolvePhis(BasicBlock* block) {
         new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE);
     phi_operand->set_virtual_register(phi->id());
 
-    int j = 0;
+    size_t j = 0;
     Node::Inputs inputs = phi->inputs();
     for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
          ++iter, ++j) {
@@ -1253,7 +1250,7 @@ void RegisterAllocator::ConnectRanges() {
 
 bool RegisterAllocator::CanEagerlyResolveControlFlow(BasicBlock* block) const {
   if (block->PredecessorCount() != 1) return false;
-  return block->PredecessorAt(0)->rpo_number_ == block->rpo_number_ - 1;
+  return block->PredecessorAt(0)->rpo_number() == block->rpo_number() - 1;
 }
 
 
@@ -1262,13 +1259,12 @@ void RegisterAllocator::ResolveControlFlow() {
   for (int block_id = 1; block_id < code()->BasicBlockCount(); ++block_id) {
     BasicBlock* block = code()->BlockAt(block_id);
     if (CanEagerlyResolveControlFlow(block)) continue;
-    BitVector* live = live_in_sets_[block->rpo_number_];
+    BitVector* live = live_in_sets_[block->rpo_number()];
     BitVector::Iterator iterator(live);
     while (!iterator.Done()) {
       int operand_index = iterator.Current();
-      BasicBlock::Predecessors predecessors = block->predecessors();
-      for (BasicBlock::Predecessors::iterator i = predecessors.begin();
-           i != predecessors.end(); ++i) {
+      for (BasicBlock::Predecessors::iterator i = block->predecessors_begin();
+           i != block->predecessors_end(); ++i) {
         BasicBlock* cur = *i;
         LiveRange* cur_range = LiveRangeFor(operand_index);
         ResolveControlFlow(cur_range, block, cur);
@@ -1338,7 +1334,7 @@ void RegisterAllocator::BuildLiveRanges() {
       LifetimePosition start = LifetimePosition::FromInstructionIndex(
           block->first_instruction_index());
       int end_index =
-          code()->BlockAt(block->loop_end_)->last_instruction_index();
+          code()->BlockAt(block->loop_end())->last_instruction_index();
       LifetimePosition end =
           LifetimePosition::FromInstructionIndex(end_index).NextInstruction();
       while (!iterator.Done()) {
@@ -1349,7 +1345,7 @@ void RegisterAllocator::BuildLiveRanges() {
       }
 
       // Insert all values into the live in sets of all blocks in the loop.
-      for (int i = block->rpo_number_ + 1; i < block->loop_end_; ++i) {
+      for (int i = block->rpo_number() + 1; i < block->loop_end(); ++i) {
         live_in_sets_[i]->Union(*live);
       }
     }
@@ -2098,8 +2094,8 @@ LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
   // Find header of outermost loop.
   // TODO(titzer): fix redundancy below.
   while (code()->GetContainingLoop(block) != NULL &&
-         code()->GetContainingLoop(block)->rpo_number_ >
-             start_block->rpo_number_) {
+         code()->GetContainingLoop(block)->rpo_number() >
+             start_block->rpo_number()) {
     block = code()->GetContainingLoop(block);
   }
 
index a3b5ed3..989505a 100644 (file)
@@ -12,17 +12,115 @@ namespace v8 {
 namespace internal {
 namespace compiler {
 
-OStream& operator<<(OStream& os, const BasicBlockData::Control& c) {
+
+BasicBlock::BasicBlock(Zone* zone, Id id)
+    : rpo_number_(-1),
+      dominator_(NULL),
+      loop_header_(NULL),
+      loop_depth_(0),
+      loop_end_(-1),
+      code_start_(-1),
+      code_end_(-1),
+      deferred_(false),
+      control_(kNone),
+      control_input_(NULL),
+      nodes_(zone),
+      successors_(zone),
+      predecessors_(zone),
+      id_(id) {}
+
+
+bool BasicBlock::LoopContains(BasicBlock* block) const {
+  // RPO numbers must be initialized.
+  DCHECK(rpo_number_ >= 0);
+  DCHECK(block->rpo_number_ >= 0);
+  if (loop_end_ < 0) return false;  // This is not a loop.
+  return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_;
+}
+
+
+BasicBlock* BasicBlock::ContainingLoop() {
+  if (IsLoopHeader()) return this;
+  return loop_header();
+}
+
+
+void BasicBlock::AddSuccessor(BasicBlock* successor) {
+  successors_.push_back(successor);
+}
+
+
+void BasicBlock::AddPredecessor(BasicBlock* predecessor) {
+  predecessors_.push_back(predecessor);
+}
+
+
+void BasicBlock::AddNode(Node* node) { nodes_.push_back(node); }
+
+
+void BasicBlock::set_control(Control control) {
+  DCHECK(control_ == BasicBlock::kNone);
+  control_ = control;
+}
+
+
+void BasicBlock::set_control_input(Node* control_input) {
+  control_input_ = control_input;
+}
+
+
+void BasicBlock::set_dominator(BasicBlock* dominator) {
+  dominator_ = dominator;
+}
+
+
+void BasicBlock::set_loop_depth(int32_t loop_depth) {
+  loop_depth_ = loop_depth;
+}
+
+
+void BasicBlock::set_rpo_number(int32_t rpo_number) {
+  rpo_number_ = rpo_number;
+}
+
+
+void BasicBlock::set_loop_end(int32_t loop_end) { loop_end_ = loop_end; }
+
+
+void BasicBlock::set_code_start(int32_t code_start) {
+  code_start_ = code_start;
+}
+
+
+void BasicBlock::set_code_end(int32_t code_end) { code_end_ = code_end; }
+
+
+void BasicBlock::set_loop_header(BasicBlock* loop_header) {
+  loop_header_ = loop_header;
+}
+
+
+size_t BasicBlock::PredecessorIndexOf(BasicBlock* predecessor) {
+  size_t j = 0;
+  for (BasicBlock::Predecessors::iterator i = predecessors_.begin();
+       i != predecessors_.end(); ++i, ++j) {
+    if (*i == predecessor) break;
+  }
+  return j;
+}
+
+
+OStream& operator<<(OStream& os, const BasicBlock::Control& c) {
   switch (c) {
-    case BasicBlockData::kNone:
+    case BasicBlock::kNone:
       return os << "none";
-    case BasicBlockData::kGoto:
+    case BasicBlock::kGoto:
       return os << "goto";
-    case BasicBlockData::kBranch:
+    case BasicBlock::kBranch:
       return os << "branch";
-    case BasicBlockData::kReturn:
+    case BasicBlock::kReturn:
       return os << "return";
-    case BasicBlockData::kThrow:
+    case BasicBlock::kThrow:
       return os << "throw";
   }
   UNREACHABLE();
@@ -30,6 +128,145 @@ OStream& operator<<(OStream& os, const BasicBlockData::Control& c) {
 }
 
 
+OStream& operator<<(OStream& os, const BasicBlock::Id& id) {
+  return os << id.ToSize();
+}
+
+
+Schedule::Schedule(Zone* zone, size_t node_count_hint)
+    : zone_(zone),
+      all_blocks_(zone),
+      nodeid_to_block_(zone),
+      rpo_order_(zone),
+      start_(NewBasicBlock()),
+      end_(NewBasicBlock()) {
+  nodeid_to_block_.reserve(node_count_hint);
+}
+
+
+BasicBlock* Schedule::block(Node* node) const {
+  if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
+    return nodeid_to_block_[node->id()];
+  }
+  return NULL;
+}
+
+
+bool Schedule::IsScheduled(Node* node) {
+  int length = static_cast<int>(nodeid_to_block_.size());
+  if (node->id() >= length) return false;
+  return nodeid_to_block_[node->id()] != NULL;
+}
+
+
+BasicBlock* Schedule::GetBlockById(BasicBlock::Id block_id) {
+  DCHECK(block_id.ToSize() < all_blocks_.size());
+  return all_blocks_[block_id.ToSize()];
+}
+
+
+bool Schedule::SameBasicBlock(Node* a, Node* b) const {
+  BasicBlock* block = this->block(a);
+  return block != NULL && block == this->block(b);
+}
+
+
+BasicBlock* Schedule::NewBasicBlock() {
+  BasicBlock* block = new (zone_)
+      BasicBlock(zone_, BasicBlock::Id::FromSize(all_blocks_.size()));
+  all_blocks_.push_back(block);
+  return block;
+}
+
+
+void Schedule::PlanNode(BasicBlock* block, Node* node) {
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Planning #" << node->id() << ":" << node->op()->mnemonic()
+       << " for future add to B" << block->id() << "\n";
+  }
+  DCHECK(this->block(node) == NULL);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::AddNode(BasicBlock* block, Node* node) {
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Adding #" << node->id() << ":" << node->op()->mnemonic() << " to B"
+       << block->id() << "\n";
+  }
+  DCHECK(this->block(node) == NULL || this->block(node) == block);
+  block->AddNode(node);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::AddGoto(BasicBlock* block, BasicBlock* succ) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kGoto);
+  AddSuccessor(block, succ);
+}
+
+
+void Schedule::AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
+                         BasicBlock* fblock) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  DCHECK(branch->opcode() == IrOpcode::kBranch);
+  block->set_control(BasicBlock::kBranch);
+  AddSuccessor(block, tblock);
+  AddSuccessor(block, fblock);
+  SetControlInput(block, branch);
+  if (branch->opcode() == IrOpcode::kBranch) {
+    // TODO(titzer): require a Branch node here. (sloppy tests).
+    SetBlockForNode(block, branch);
+  }
+}
+
+
+void Schedule::AddReturn(BasicBlock* block, Node* input) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kReturn);
+  SetControlInput(block, input);
+  if (block != end()) {
+    AddSuccessor(block, end());
+  }
+  if (input->opcode() == IrOpcode::kReturn) {
+    // TODO(titzer): require a Return node here. (sloppy tests).
+    SetBlockForNode(block, input);
+  }
+}
+
+
+void Schedule::AddThrow(BasicBlock* block, Node* input) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kThrow);
+  SetControlInput(block, input);
+  if (block != end()) AddSuccessor(block, end());
+}
+
+
+void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
+  block->AddSuccessor(succ);
+  succ->AddPredecessor(block);
+}
+
+
+void Schedule::SetControlInput(BasicBlock* block, Node* node) {
+  block->set_control_input(node);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::SetBlockForNode(BasicBlock* block, Node* node) {
+  int length = static_cast<int>(nodeid_to_block_.size());
+  if (node->id() >= length) {
+    nodeid_to_block_.resize(node->id() + 1);
+  }
+  nodeid_to_block_[node->id()] = block;
+}
+
+
 OStream& operator<<(OStream& os, const Schedule& s) {
   // TODO(svenpanne) Const-correct the RPO stuff/iterators.
   BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order();
@@ -37,10 +274,9 @@ OStream& operator<<(OStream& os, const Schedule& s) {
     BasicBlock* block = *i;
     os << "--- BLOCK B" << block->id();
     if (block->PredecessorCount() != 0) os << " <- ";
-    BasicBlock::Predecessors predecessors = block->predecessors();
     bool comma = false;
-    for (BasicBlock::Predecessors::iterator j = predecessors.begin();
-         j != predecessors.end(); ++j) {
+    for (BasicBlock::Predecessors::iterator j = block->predecessors_begin();
+         j != block->predecessors_end(); ++j) {
       if (comma) os << ", ";
       comma = true;
       os << "B" << (*j)->id();
@@ -61,19 +297,18 @@ OStream& operator<<(OStream& os, const Schedule& s) {
       }
       os << "\n";
     }
-    BasicBlock::Control control = block->control_;
+    BasicBlock::Control control = block->control();
     if (control != BasicBlock::kNone) {
       os << "  ";
-      if (block->control_input_ != NULL) {
-        os << *block->control_input_;
+      if (block->control_input() != NULL) {
+        os << *block->control_input();
       } else {
         os << "Goto";
       }
       os << " -> ";
-      BasicBlock::Successors successors = block->successors();
       comma = false;
-      for (BasicBlock::Successors::iterator j = successors.begin();
-           j != successors.end(); ++j) {
+      for (BasicBlock::Successors::iterator j = block->successors_begin();
+           j != block->successors_end(); ++j) {
         if (comma) os << ", ";
         comma = true;
         os << "B" << (*j)->id();
index 0094d57..6954b75 100644 (file)
@@ -9,10 +9,6 @@
 
 #include "src/v8.h"
 
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/opcodes.h"
 #include "src/zone.h"
@@ -27,7 +23,10 @@ class Graph;
 class ConstructScheduleData;
 class CodeGenerator;  // Because of a namespace bug in clang.
 
-class BasicBlockData {
+// 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
+// first nodes in the block.
+class BasicBlock FINAL : public ZoneObject {
  public:
   // Possible control nodes that can end a block.
   enum Control {
@@ -38,42 +37,23 @@ class BasicBlockData {
     kThrow    // Throw an exception.
   };
 
-  int32_t rpo_number_;       // special RPO number of the block.
-  BasicBlock* dominator_;    // Immediate dominator of the block.
-  BasicBlock* loop_header_;  // Pointer to dominating loop header basic block,
-                             // NULL if none. For loop headers, this points to
-                             // enclosing loop header.
-  int32_t loop_depth_;       // loop nesting, 0 is top-level
-  int32_t loop_end_;         // end of the loop, if this block is a loop header.
-  int32_t code_start_;       // start index of arch-specific code.
-  int32_t code_end_;         // end index of arch-specific code.
-  bool deferred_;            // {true} if this block is considered the slow
-                             // path.
-  Control control_;          // Control at the end of the block.
-  Node* control_input_;      // Input value for control.
-  NodeVector nodes_;         // nodes of this block in forward order.
+  class Id {
+   public:
+    int ToInt() const { return static_cast<int>(index_); }
+    size_t ToSize() const { return index_; }
+    static Id FromSize(size_t index) { return Id(index); }
+    static Id FromInt(int index) { return Id(static_cast<size_t>(index)); }
 
-  explicit BasicBlockData(Zone* zone)
-      : rpo_number_(-1),
-        dominator_(NULL),
-        loop_header_(NULL),
-        loop_depth_(0),
-        loop_end_(-1),
-        code_start_(-1),
-        code_end_(-1),
-        deferred_(false),
-        control_(kNone),
-        control_input_(NULL),
-        nodes_(zone) {}
+   private:
+    explicit Id(size_t index) : index_(index) {}
+    size_t index_;
+  };
 
-  inline bool IsLoopHeader() const { return loop_end_ >= 0; }
-  inline bool LoopContains(BasicBlockData* block) const {
-    // RPO numbers must be initialized.
-    DCHECK(rpo_number_ >= 0);
-    DCHECK(block->rpo_number_ >= 0);
-    if (loop_end_ < 0) return false;  // This is not a loop.
-    return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_;
-  }
+  BasicBlock(Zone* zone, Id id);
+
+  Id id() const { return id_; }
+
+  // Instruction indexes (used by the register allocator).
   int first_instruction_index() {
     DCHECK(code_start_ >= 0);
     DCHECK(code_end_ > 0);
@@ -86,46 +66,26 @@ class BasicBlockData {
     DCHECK(code_end_ >= code_start_);
     return code_end_ - 1;
   }
-};
 
-OStream& operator<<(OStream& os, const BasicBlockData::Control& c);
+  // Predecessors and successors.
+  typedef ZoneVector<BasicBlock*> Predecessors;
+  Predecessors::iterator predecessors_begin() { return predecessors_.begin(); }
+  Predecessors::iterator predecessors_end() { return predecessors_.end(); }
+  size_t PredecessorCount() const { return predecessors_.size(); }
+  BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
+  size_t PredecessorIndexOf(BasicBlock* predecessor);
+  void AddPredecessor(BasicBlock* predecessor);
 
-// 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
-// first nodes in the block.
-class BasicBlock FINAL : public GenericNode<BasicBlockData, BasicBlock> {
- public:
-  BasicBlock(GenericGraphBase* graph, int input_count)
-      : GenericNode<BasicBlockData, BasicBlock>(graph, input_count) {}
-
-  typedef Uses Successors;
-  typedef Inputs Predecessors;
-
-  Successors successors() { return static_cast<Successors>(uses()); }
-  Predecessors predecessors() { return static_cast<Predecessors>(inputs()); }
+  typedef ZoneVector<BasicBlock*> Successors;
+  Successors::iterator successors_begin() { return successors_.begin(); }
+  Successors::iterator successors_end() { return successors_.end(); }
+  size_t SuccessorCount() const { return successors_.size(); }
+  BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
+  void AddSuccessor(BasicBlock* successor);
 
-  int PredecessorCount() { return InputCount(); }
-  BasicBlock* PredecessorAt(int index) { return InputAt(index); }
-
-  int SuccessorCount() { return UseCount(); }
-  BasicBlock* SuccessorAt(int index) { return UseAt(index); }
-
-  int PredecessorIndexOf(BasicBlock* predecessor) {
-    BasicBlock::Predecessors predecessors = this->predecessors();
-    for (BasicBlock::Predecessors::iterator i = predecessors.begin();
-         i != predecessors.end(); ++i) {
-      if (*i == predecessor) return i.index();
-    }
-    return -1;
-  }
-
-  inline BasicBlock* loop_header() {
-    return static_cast<BasicBlock*>(loop_header_);
-  }
-  inline BasicBlock* ContainingLoop() {
-    if (IsLoopHeader()) return this;
-    return static_cast<BasicBlock*>(loop_header_);
-  }
+  // Nodes in the basic block.
+  Node* NodeAt(size_t index) { return nodes_[index]; }
+  size_t NodeCount() const { return nodes_.size(); }
 
   typedef NodeVector::iterator iterator;
   iterator begin() { return nodes_.begin(); }
@@ -139,12 +99,73 @@ class BasicBlock FINAL : public GenericNode<BasicBlockData, BasicBlock> {
   reverse_iterator rbegin() { return nodes_.rbegin(); }
   reverse_iterator rend() { return nodes_.rend(); }
 
+  void AddNode(Node* node);
+  template <class InputIterator>
+  void InsertNodes(iterator insertion_point, InputIterator insertion_start,
+                   InputIterator insertion_end) {
+    nodes_.insert(insertion_point, insertion_start, insertion_end);
+  }
+
+  // Accessors.
+  Control control() const { return control_; }
+  void set_control(Control control);
+
+  Node* control_input() const { return control_input_; }
+  void set_control_input(Node* control_input);
+
+  BasicBlock* dominator() const { return dominator_; }
+  void set_dominator(BasicBlock* dominator);
+
+  BasicBlock* loop_header() const { return loop_header_; }
+  void set_loop_header(BasicBlock* loop_header);
+
+  int32_t loop_depth() const { return loop_depth_; }
+  void set_loop_depth(int32_t loop_depth);
+
+  int32_t loop_end() const { return loop_end_; }
+  void set_loop_end(int32_t loop_end);
+
+  int32_t rpo_number() const { return rpo_number_; }
+  void set_rpo_number(int32_t rpo_number);
+
+  int32_t code_start() const { return code_start_; }
+  void set_code_start(int32_t start);
+
+  int32_t code_end() const { return code_end_; }
+  void set_code_end(int32_t end);
+
+  bool deferred() const { return deferred_; }
+
+  // Loop membership helpers.
+  inline bool IsLoopHeader() const { return loop_end_ >= 0; }
+  bool LoopContains(BasicBlock* block) const;
+  BasicBlock* ContainingLoop();
+
  private:
+  int32_t rpo_number_;       // special RPO number of the block.
+  BasicBlock* dominator_;    // Immediate dominator of the block.
+  BasicBlock* loop_header_;  // Pointer to dominating loop header basic block,
+                             // NULL if none. For loop headers, this points to
+                             // enclosing loop header.
+  int32_t loop_depth_;       // loop nesting, 0 is top-level
+  int32_t loop_end_;         // end of the loop, if this block is a loop header.
+  int32_t code_start_;       // start index of arch-specific code.
+  int32_t code_end_;         // end index of arch-specific code.
+  bool deferred_;            // {true} if this block is considered the slow
+                             // path.
+  Control control_;          // Control at the end of the block.
+  Node* control_input_;      // Input value for control.
+  NodeVector nodes_;         // nodes of this block in forward order.
+
+  Successors successors_;
+  Predecessors predecessors_;
+  Id id_;
+
   DISALLOW_COPY_AND_ASSIGN(BasicBlock);
 };
 
-typedef GenericGraphVisit::NullNodeVisitor<BasicBlockData, BasicBlock>
-    NullBasicBlockVisitor;
+OStream& operator<<(OStream& os, const BasicBlock::Control& c);
+OStream& operator<<(OStream& os, const BasicBlock::Id& id);
 
 typedef ZoneVector<BasicBlock*> BasicBlockVector;
 typedef BasicBlockVector::iterator BasicBlockVectorIter;
@@ -154,151 +175,69 @@ typedef BasicBlockVector::reverse_iterator BasicBlockVectorRIter;
 // and ordering them within basic blocks. Prior to computing a schedule,
 // a graph has no notion of control flow ordering other than that induced
 // by the graph's dependencies. A schedule is required to generate code.
-class Schedule : public GenericGraph<BasicBlock> {
+class Schedule FINAL : public ZoneObject {
  public:
-  explicit Schedule(Zone* zone, size_t node_count_hint = 0)
-      : GenericGraph<BasicBlock>(zone),
-        zone_(zone),
-        all_blocks_(zone),
-        nodeid_to_block_(zone),
-        rpo_order_(zone) {
-    SetStart(NewBasicBlock());  // entry.
-    SetEnd(NewBasicBlock());    // exit.
-    nodeid_to_block_.reserve(node_count_hint);
-  }
+  explicit Schedule(Zone* zone, size_t node_count_hint = 0);
 
   // Return the block which contains {node}, if any.
-  BasicBlock* block(Node* node) const {
-    if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
-      return nodeid_to_block_[node->id()];
-    }
-    return NULL;
-  }
+  BasicBlock* block(Node* node) const;
 
-  bool IsScheduled(Node* node) {
-    int length = static_cast<int>(nodeid_to_block_.size());
-    if (node->id() >= length) return false;
-    return nodeid_to_block_[node->id()] != NULL;
-  }
+  bool IsScheduled(Node* node);
+  BasicBlock* GetBlockById(BasicBlock::Id block_id);
 
-  BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; }
-
-  int BasicBlockCount() const { return NodeCount(); }
-  int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); }
-
-  typedef ContainerPointerWrapper<BasicBlockVector> BasicBlocks;
-
-  // Return a list of all the blocks in the schedule, in arbitrary order.
-  BasicBlocks all_blocks() { return BasicBlocks(&all_blocks_); }
+  size_t BasicBlockCount() const { return all_blocks_.size(); }
+  size_t RpoBlockCount() const { return rpo_order_.size(); }
 
   // Check if nodes {a} and {b} are in the same block.
-  inline bool SameBasicBlock(Node* a, Node* b) const {
-    BasicBlock* block = this->block(a);
-    return block != NULL && block == this->block(b);
-  }
+  bool SameBasicBlock(Node* a, Node* b) const;
 
   // BasicBlock building: create a new block.
-  inline BasicBlock* NewBasicBlock() {
-    BasicBlock* block =
-        BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL));
-    all_blocks_.push_back(block);
-    return block;
-  }
+  BasicBlock* NewBasicBlock();
 
   // BasicBlock building: records that a node will later be added to a block but
   // doesn't actually add the node to the block.
-  inline void PlanNode(BasicBlock* block, Node* node) {
-    if (FLAG_trace_turbo_scheduler) {
-      PrintF("Planning #%d:%s for future add to B%d\n", node->id(),
-             node->op()->mnemonic(), block->id());
-    }
-    DCHECK(this->block(node) == NULL);
-    SetBlockForNode(block, node);
-  }
+  void PlanNode(BasicBlock* block, Node* node);
 
   // BasicBlock building: add a node to the end of the block.
-  inline void AddNode(BasicBlock* block, Node* node) {
-    if (FLAG_trace_turbo_scheduler) {
-      PrintF("Adding #%d:%s to B%d\n", node->id(), node->op()->mnemonic(),
-             block->id());
-    }
-    DCHECK(this->block(node) == NULL || this->block(node) == block);
-    block->nodes_.push_back(node);
-    SetBlockForNode(block, node);
-  }
+  void AddNode(BasicBlock* block, Node* node);
 
   // BasicBlock building: add a goto to the end of {block}.
-  void AddGoto(BasicBlock* block, BasicBlock* succ) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kGoto;
-    AddSuccessor(block, succ);
-  }
+  void AddGoto(BasicBlock* block, BasicBlock* succ);
 
   // BasicBlock building: add a branch at the end of {block}.
   void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
-                 BasicBlock* fblock) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    DCHECK(branch->opcode() == IrOpcode::kBranch);
-    block->control_ = BasicBlock::kBranch;
-    AddSuccessor(block, tblock);
-    AddSuccessor(block, fblock);
-    SetControlInput(block, branch);
-    if (branch->opcode() == IrOpcode::kBranch) {
-      // TODO(titzer): require a Branch node here. (sloppy tests).
-      SetBlockForNode(block, branch);
-    }
-  }
+                 BasicBlock* fblock);
 
   // BasicBlock building: add a return at the end of {block}.
-  void AddReturn(BasicBlock* block, Node* input) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kReturn;
-    SetControlInput(block, input);
-    if (block != end()) AddSuccessor(block, end());
-    if (input->opcode() == IrOpcode::kReturn) {
-      // TODO(titzer): require a Return node here. (sloppy tests).
-      SetBlockForNode(block, input);
-    }
-  }
+  void AddReturn(BasicBlock* block, Node* input);
 
   // BasicBlock building: add a throw at the end of {block}.
-  void AddThrow(BasicBlock* block, Node* input) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kThrow;
-    SetControlInput(block, input);
-    if (block != end()) AddSuccessor(block, end());
-  }
+  void AddThrow(BasicBlock* block, Node* input);
 
-  friend class Scheduler;
-  friend class CodeGenerator;
-
-  void AddSuccessor(BasicBlock* block, BasicBlock* succ) {
-    succ->AppendInput(zone_, block);
-  }
+  void AddSuccessor(BasicBlock* block, BasicBlock* succ);
 
   BasicBlockVector* rpo_order() { return &rpo_order_; }
 
+  BasicBlock* start() { return start_; }
+  BasicBlock* end() { return end_; }
+
+  Zone* zone() { return zone_; }
+
  private:
+  friend class Scheduler;
+  friend class CodeGenerator;
   friend class ScheduleVisualizer;
   friend class BasicBlockInstrumentor;
 
-  void SetControlInput(BasicBlock* block, Node* node) {
-    block->control_input_ = node;
-    SetBlockForNode(block, node);
-  }
-
-  void SetBlockForNode(BasicBlock* block, Node* node) {
-    int length = static_cast<int>(nodeid_to_block_.size());
-    if (node->id() >= length) {
-      nodeid_to_block_.resize(node->id() + 1);
-    }
-    nodeid_to_block_[node->id()] = block;
-  }
+  void SetControlInput(BasicBlock* block, Node* node);
+  void SetBlockForNode(BasicBlock* block, Node* node);
 
   Zone* zone_;
   BasicBlockVector all_blocks_;           // All basic blocks in the schedule.
   BasicBlockVector nodeid_to_block_;      // Map from node to containing block.
   BasicBlockVector rpo_order_;            // Reverse-post-order block list.
+  BasicBlock* start_;
+  BasicBlock* end_;
 };
 
 OStream& operator<<(OStream& os, const Schedule& s);
index 58878a0..add00ad 100644 (file)
@@ -122,7 +122,7 @@ class CFGBuilder {
   void BuildBlockForNode(Node* node) {
     if (schedule_->block(node) == NULL) {
       BasicBlock* block = schedule_->NewBasicBlock();
-      Trace("Create block B%d for #%d:%s\n", block->id(), node->id(),
+      Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
             node->op()->mnemonic());
       FixNode(block, node);
     }
@@ -209,10 +209,10 @@ class CFGBuilder {
     DCHECK_NE(NULL, block);
     if (succ == NULL) {
       Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
-            block->id());
+            block->id().ToInt());
     } else {
       Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
-            block->id(), succ->id());
+            block->id().ToInt(), succ->id().ToInt());
     }
   }
 };
@@ -311,9 +311,9 @@ BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
     int b2_rpo = GetRPONumber(b2);
     DCHECK(b1_rpo != b2_rpo);
     if (b1_rpo < b2_rpo) {
-      b2 = b2->dominator_;
+      b2 = b2->dominator();
     } else {
-      b1 = b1->dominator_;
+      b1 = b1->dominator();
     }
   }
   return b1;
@@ -328,9 +328,8 @@ void Scheduler::GenerateImmediateDominatorTree() {
     BasicBlock* current_rpo = schedule_->rpo_order_[i];
     if (current_rpo != schedule_->start()) {
       BasicBlock::Predecessors::iterator current_pred =
-          current_rpo->predecessors().begin();
-      BasicBlock::Predecessors::iterator end =
-          current_rpo->predecessors().end();
+          current_rpo->predecessors_begin();
+      BasicBlock::Predecessors::iterator end = current_rpo->predecessors_end();
       DCHECK(current_pred != end);
       BasicBlock* dominator = *current_pred;
       ++current_pred;
@@ -345,8 +344,9 @@ void Scheduler::GenerateImmediateDominatorTree() {
         }
         ++current_pred;
       }
-      current_rpo->dominator_ = dominator;
-      Trace("Block %d's idom is %d\n", current_rpo->id(), dominator->id());
+      current_rpo->set_dominator(dominator);
+      Trace("Block %d's idom is %d\n", current_rpo->id(),
+            dominator->id().ToInt());
     }
   }
 }
@@ -365,7 +365,7 @@ class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
     if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
       BasicBlock* block = schedule_->block(node);
       DCHECK(block != NULL);
-      max_rpo = block->rpo_number_;
+      max_rpo = block->rpo_number();
       if (scheduler_->GetData(node)->minimum_rpo_ != max_rpo) {
         has_changed_rpo_constraints_ = true;
       }
@@ -513,27 +513,28 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
     Trace(
         "Schedule late conservative for #%d:%s is B%d at loop depth %d, "
         "minimum_rpo = %d\n",
-        node->id(), node->op()->mnemonic(), block->id(), block->loop_depth_,
-        min_rpo);
+        node->id(), node->op()->mnemonic(), block->id().ToInt(),
+        block->loop_depth(), min_rpo);
     // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
     // into enclosing loop pre-headers until they would preceed their
     // ScheduleEarly position.
     BasicBlock* hoist_block = block;
-    while (hoist_block != NULL && hoist_block->rpo_number_ >= min_rpo) {
-      if (hoist_block->loop_depth_ < block->loop_depth_) {
+    while (hoist_block != NULL && hoist_block->rpo_number() >= min_rpo) {
+      if (hoist_block->loop_depth() < block->loop_depth()) {
         block = hoist_block;
         Trace("  hoisting #%d:%s to block %d\n", node->id(),
-              node->op()->mnemonic(), block->id());
+              node->op()->mnemonic(), block->id().ToInt());
       }
       // Try to hoist to the pre-header of the loop header.
       hoist_block = hoist_block->loop_header();
       if (hoist_block != NULL) {
-        BasicBlock* pre_header = hoist_block->dominator_;
+        BasicBlock* pre_header = hoist_block->dominator();
         DCHECK(pre_header == NULL ||
-               *hoist_block->predecessors().begin() == pre_header);
+               *hoist_block->predecessors_begin() == pre_header);
         Trace(
             "  hoist to pre-header B%d of loop header B%d, depth would be %d\n",
-            pre_header->id(), hoist_block->id(), pre_header->loop_depth_);
+            pre_header->id().ToInt(), hoist_block->id().ToInt(),
+            pre_header->loop_depth());
         hoist_block = pre_header;
       }
     }
@@ -563,13 +564,13 @@ class ScheduleLateNodeVisitor : public NullNodeVisitor {
     BasicBlock* result = schedule_->block(use);
     if (result == NULL) return NULL;
     Trace("  must dominate use #%d:%s in B%d\n", use->id(),
-          use->op()->mnemonic(), result->id());
+          use->op()->mnemonic(), result->id().ToInt());
     return result;
   }
 
   void ScheduleNode(BasicBlock* block, Node* node) {
     schedule_->PlanNode(block, node);
-    scheduler_->scheduled_nodes_[block->id()].push_back(node);
+    scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
 
     // Reduce the use count of the node's inputs to potentially make them
     // schedulable.
@@ -643,13 +644,13 @@ bool Scheduler::ConnectFloatingControl() {
     // basic block because scheduling currently can interleave phis from
     // one subgraph with the merges from another subgraph.
     bool one_placed = false;
-    for (int j = static_cast<int>(block->nodes_.size()) - 1; j >= 0; j--) {
-      Node* node = block->nodes_[j];
+    for (size_t j = 0; j < block->NodeCount(); j++) {
+      Node* node = block->NodeAt(block->NodeCount() - 1 - j);
       SchedulerData* data = GetData(node);
       if (data->is_floating_control_ && !data->is_connected_control_ &&
           !one_placed) {
         Trace("  Floating control #%d:%s was scheduled in B%d\n", node->id(),
-              node->op()->mnemonic(), block->id());
+              node->op()->mnemonic(), block->id().ToInt());
         ConnectFloatingControlSubgraph(block, node);
         one_placed = true;
       }
@@ -661,7 +662,7 @@ bool Scheduler::ConnectFloatingControl() {
 
 
 void Scheduler::ConnectFloatingControlSubgraph(BasicBlock* block, Node* end) {
-  Node* block_start = block->nodes_[0];
+  Node* block_start = block->NodeAt(0);
   DCHECK(IrOpcode::IsControlOpcode(block_start->opcode()));
   // Find the current "control successor" of the node that starts the block
   // by searching the control uses for a control input edge from a connected
@@ -733,7 +734,7 @@ static const int kBlockUnvisited2 = kBlockVisited1;
 
 struct SpecialRPOStackFrame {
   BasicBlock* block;
-  int index;
+  size_t index;
 };
 
 struct BlockList {
@@ -749,7 +750,7 @@ struct BlockList {
 
   void Serialize(BasicBlockVector* final_order) {
     for (BlockList* l = this; l != NULL; l = l->next) {
-      l->block->rpo_number_ = static_cast<int>(final_order->size());
+      l->block->set_rpo_number(static_cast<int>(final_order->size()));
       final_order->push_back(l->block);
     }
   }
@@ -772,10 +773,10 @@ struct LoopInfo {
 
 static int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child,
                 int unvisited) {
-  if (child->rpo_number_ == unvisited) {
+  if (child->rpo_number() == unvisited) {
     stack[depth].block = child;
     stack[depth].index = 0;
-    child->rpo_number_ = kBlockOnStack;
+    child->set_rpo_number(kBlockOnStack);
     return depth + 1;
   }
   return depth;
@@ -784,8 +785,8 @@ static int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child,
 
 // Computes loop membership from the backedges of the control flow graph.
 static LoopInfo* ComputeLoopInfo(
-    Zone* zone, SpecialRPOStackFrame* queue, int num_loops, int num_blocks,
-    ZoneList<std::pair<BasicBlock*, int> >* backedges) {
+    Zone* zone, SpecialRPOStackFrame* queue, int num_loops, size_t num_blocks,
+    ZoneList<std::pair<BasicBlock*, size_t> >* backedges) {
   LoopInfo* loops = zone->NewArray<LoopInfo>(num_loops);
   memset(loops, 0, num_loops * sizeof(LoopInfo));
 
@@ -794,18 +795,19 @@ static LoopInfo* ComputeLoopInfo(
   for (int i = 0; i < backedges->length(); i++) {
     BasicBlock* member = backedges->at(i).first;
     BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
-    int loop_num = header->loop_end_;
+    int loop_num = header->loop_end();
     if (loops[loop_num].header == NULL) {
       loops[loop_num].header = header;
-      loops[loop_num].members = new (zone) BitVector(num_blocks, zone);
+      loops[loop_num].members =
+          new (zone) BitVector(static_cast<int>(num_blocks), zone);
     }
 
     int queue_length = 0;
     if (member != header) {
       // As long as the header doesn't have a backedge to itself,
       // Push the member onto the queue and process its predecessors.
-      if (!loops[loop_num].members->Contains(member->id())) {
-        loops[loop_num].members->Add(member->id());
+      if (!loops[loop_num].members->Contains(member->id().ToInt())) {
+        loops[loop_num].members->Add(member->id().ToInt());
       }
       queue[queue_length++].block = member;
     }
@@ -814,11 +816,11 @@ static LoopInfo* ComputeLoopInfo(
     // loop header H are members of the loop too. O(|blocks between M and H|).
     while (queue_length > 0) {
       BasicBlock* block = queue[--queue_length].block;
-      for (int i = 0; i < block->PredecessorCount(); i++) {
+      for (size_t i = 0; i < block->PredecessorCount(); i++) {
         BasicBlock* pred = block->PredecessorAt(i);
         if (pred != header) {
-          if (!loops[loop_num].members->Contains(pred->id())) {
-            loops[loop_num].members->Add(pred->id());
+          if (!loops[loop_num].members->Contains(pred->id().ToInt())) {
+            loops[loop_num].members->Add(pred->id().ToInt());
             queue[queue_length++].block = pred;
           }
         }
@@ -831,32 +833,36 @@ static LoopInfo* ComputeLoopInfo(
 
 #if DEBUG
 static void PrintRPO(int num_loops, LoopInfo* loops, BasicBlockVector* order) {
-  PrintF("-- RPO with %d loops ", num_loops);
+  OFStream os(stdout);
+  os << "-- RPO with " << num_loops << " loops ";
   if (num_loops > 0) {
-    PrintF("(");
+    os << "(";
     for (int i = 0; i < num_loops; i++) {
-      if (i > 0) PrintF(" ");
-      PrintF("B%d", loops[i].header->id());
+      if (i > 0) os << " ";
+      os << "B" << loops[i].header->id();
     }
-    PrintF(") ");
+    os << ") ";
   }
-  PrintF("-- \n");
+  os << "-- \n";
 
-  for (int i = 0; i < static_cast<int>(order->size()); i++) {
+  for (size_t i = 0; i < order->size(); i++) {
     BasicBlock* block = (*order)[i];
-    int bid = block->id();
-    PrintF("%5d:", i);
-    for (int i = 0; i < num_loops; i++) {
-      bool membership = loops[i].members->Contains(bid);
-      bool range = loops[i].header->LoopContains(block);
-      PrintF(membership ? " |" : "  ");
-      PrintF(range ? "x" : " ");
+    BasicBlock::Id bid = block->id();
+    // TODO(jarin,svenpanne): Add formatting here once we have support for that
+    // in streams (we want an equivalent of PrintF("%5d:", i) here).
+    os << i << ":";
+    for (int j = 0; j < num_loops; j++) {
+      bool membership = loops[j].members->Contains(bid.ToInt());
+      bool range = loops[j].header->LoopContains(block);
+      os << (membership ? " |" : "  ");
+      os << (range ? "x" : " ");
     }
-    PrintF("  B%d: ", bid);
-    if (block->loop_end_ >= 0) {
-      PrintF(" range: [%d, %d)", block->rpo_number_, block->loop_end_);
+    os << "  B" << bid << ": ";
+    if (block->loop_end() >= 0) {
+      os << " range: [" << block->rpo_number() << ", " << block->loop_end()
+         << ")";
     }
-    PrintF("\n");
+    os << "\n";
   }
 }
 
@@ -864,18 +870,18 @@ static void PrintRPO(int num_loops, LoopInfo* loops, BasicBlockVector* order) {
 static void VerifySpecialRPO(int num_loops, LoopInfo* loops,
                              BasicBlockVector* order) {
   DCHECK(order->size() > 0);
-  DCHECK((*order)[0]->id() == 0);  // entry should be first.
+  DCHECK((*order)[0]->id().ToInt() == 0);  // entry should be first.
 
   for (int i = 0; i < num_loops; i++) {
     LoopInfo* loop = &loops[i];
     BasicBlock* header = loop->header;
 
     DCHECK(header != NULL);
-    DCHECK(header->rpo_number_ >= 0);
-    DCHECK(header->rpo_number_ < static_cast<int>(order->size()));
-    DCHECK(header->loop_end_ >= 0);
-    DCHECK(header->loop_end_ <= static_cast<int>(order->size()));
-    DCHECK(header->loop_end_ > header->rpo_number_);
+    DCHECK(header->rpo_number() >= 0);
+    DCHECK(header->rpo_number() < static_cast<int>(order->size()));
+    DCHECK(header->loop_end() >= 0);
+    DCHECK(header->loop_end() <= static_cast<int>(order->size()));
+    DCHECK(header->loop_end() > header->rpo_number());
 
     // Verify the start ... end list relationship.
     int links = 0;
@@ -888,27 +894,27 @@ static void VerifySpecialRPO(int num_loops, LoopInfo* loops,
         break;
       }
       // The list should be in same order as the final result.
-      DCHECK(l->block->rpo_number_ == links + loop->header->rpo_number_);
+      DCHECK(l->block->rpo_number() == links + loop->header->rpo_number());
       links++;
       l = l->next;
       DCHECK(links < static_cast<int>(2 * order->size()));  // cycle?
     }
     DCHECK(links > 0);
-    DCHECK(links == (header->loop_end_ - header->rpo_number_));
+    DCHECK(links == (header->loop_end() - header->rpo_number()));
     DCHECK(end_found);
 
     // Check the contiguousness of loops.
     int count = 0;
     for (int j = 0; j < static_cast<int>(order->size()); j++) {
       BasicBlock* block = order->at(j);
-      DCHECK(block->rpo_number_ == j);
-      if (j < header->rpo_number_ || j >= header->loop_end_) {
-        DCHECK(!loop->members->Contains(block->id()));
+      DCHECK(block->rpo_number() == j);
+      if (j < header->rpo_number() || j >= header->loop_end()) {
+        DCHECK(!loop->members->Contains(block->id().ToInt()));
       } else {
         if (block == header) {
-          DCHECK(!loop->members->Contains(block->id()));
+          DCHECK(!loop->members->Contains(block->id().ToInt()));
         } else {
-          DCHECK(loop->members->Contains(block->id()));
+          DCHECK(loop->members->Contains(block->id().ToInt()));
         }
         count++;
       }
@@ -935,14 +941,14 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
   Zone* zone = &tmp_zone;
   Trace("------------- COMPUTING SPECIAL RPO ---------------\n");
   // RPO should not have been computed for this schedule yet.
-  CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number_);
+  CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number());
   CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size()));
 
   // Perform an iterative RPO traversal using an explicit stack,
   // recording backedges that form cycles. O(|B|).
-  ZoneList<std::pair<BasicBlock*, int> > backedges(1, zone);
-  SpecialRPOStackFrame* stack =
-      zone->NewArray<SpecialRPOStackFrame>(schedule->BasicBlockCount());
+  ZoneList<std::pair<BasicBlock*, size_t> > backedges(1, zone);
+  SpecialRPOStackFrame* stack = zone->NewArray<SpecialRPOStackFrame>(
+      static_cast<int>(schedule->BasicBlockCount()));
   BasicBlock* entry = schedule->start();
   BlockList* order = NULL;
   int stack_depth = Push(stack, 0, entry, kBlockUnvisited1);
@@ -955,24 +961,25 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
     if (frame->index < frame->block->SuccessorCount()) {
       // Process the next successor.
       BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
-      if (succ->rpo_number_ == kBlockVisited1) continue;
-      if (succ->rpo_number_ == kBlockOnStack) {
+      if (succ->rpo_number() == kBlockVisited1) continue;
+      if (succ->rpo_number() == kBlockOnStack) {
         // The successor is on the stack, so this is a backedge (cycle).
         backedges.Add(
-            std::pair<BasicBlock*, int>(frame->block, frame->index - 1), zone);
-        if (succ->loop_end_ < 0) {
+            std::pair<BasicBlock*, size_t>(frame->block, frame->index - 1),
+            zone);
+        if (succ->loop_end() < 0) {
           // Assign a new loop number to the header if it doesn't have one.
-          succ->loop_end_ = num_loops++;
+          succ->set_loop_end(num_loops++);
         }
       } else {
         // Push the successor onto the stack.
-        DCHECK(succ->rpo_number_ == kBlockUnvisited1);
+        DCHECK(succ->rpo_number() == kBlockUnvisited1);
         stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1);
       }
     } else {
       // Finished with all successors; pop the stack and add the block.
       order = order->Add(zone, frame->block);
-      frame->block->rpo_number_ = kBlockVisited1;
+      frame->block->set_rpo_number(kBlockVisited1);
       stack_depth--;
     }
   }
@@ -986,7 +993,7 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
                             &backedges);
 
     // Initialize the "loop stack". Note the entry could be a loop header.
-    LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end_] : NULL;
+    LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end()] : NULL;
     order = NULL;
 
     // Perform an iterative post-order traversal, visiting loop bodies before
@@ -1004,13 +1011,13 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
         succ = block->SuccessorAt(frame->index++);
       } else if (block->IsLoopHeader()) {
         // Process additional outgoing edges from the loop header.
-        if (block->rpo_number_ == kBlockOnStack) {
+        if (block->rpo_number() == kBlockOnStack) {
           // Finish the loop body the first time the header is left on the
           // stack.
           DCHECK(loop != NULL && loop->header == block);
           loop->start = order->Add(zone, block);
           order = loop->end;
-          block->rpo_number_ = kBlockVisited2;
+          block->set_rpo_number(kBlockVisited2);
           // Pop the loop stack and continue visiting outgoing edges within the
           // the context of the outer loop, if any.
           loop = loop->prev;
@@ -1019,8 +1026,9 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
         }
 
         // Use the next outgoing edge if there are any.
-        int outgoing_index = frame->index - block->SuccessorCount();
-        LoopInfo* info = &loops[block->loop_end_];
+        int outgoing_index =
+            static_cast<int>(frame->index - block->SuccessorCount());
+        LoopInfo* info = &loops[block->loop_end()];
         DCHECK(loop != info);
         if (info->outgoing != NULL &&
             outgoing_index < info->outgoing->length()) {
@@ -1031,10 +1039,10 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
 
       if (succ != NULL) {
         // Process the next successor.
-        if (succ->rpo_number_ == kBlockOnStack) continue;
-        if (succ->rpo_number_ == kBlockVisited2) continue;
-        DCHECK(succ->rpo_number_ == kBlockUnvisited2);
-        if (loop != NULL && !loop->members->Contains(succ->id())) {
+        if (succ->rpo_number() == kBlockOnStack) continue;
+        if (succ->rpo_number() == kBlockVisited2) continue;
+        DCHECK(succ->rpo_number() == kBlockUnvisited2);
+        if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) {
           // The successor is not in the current loop or any nested loop.
           // Add it to the outgoing edges of this loop and visit it later.
           loop->AddOutgoing(zone, succ);
@@ -1043,8 +1051,8 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
           stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2);
           if (succ->IsLoopHeader()) {
             // Push the inner loop onto the loop stack.
-            DCHECK(succ->loop_end_ >= 0 && succ->loop_end_ < num_loops);
-            LoopInfo* next = &loops[succ->loop_end_];
+            DCHECK(succ->loop_end() >= 0 && succ->loop_end() < num_loops);
+            LoopInfo* next = &loops[succ->loop_end()];
             next->end = order;
             next->prev = loop;
             loop = next;
@@ -1054,7 +1062,7 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
         // Finished with all successors of the current block.
         if (block->IsLoopHeader()) {
           // If we are going to pop a loop header, then add its entire body.
-          LoopInfo* info = &loops[block->loop_end_];
+          LoopInfo* info = &loops[block->loop_end()];
           for (BlockList* l = info->start; true; l = l->next) {
             if (l->next == info->end) {
               l->next = order;
@@ -1066,7 +1074,7 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
         } else {
           // Pop a single node off the stack and add it to the order.
           order = order->Add(zone, block);
-          block->rpo_number_ = kBlockVisited2;
+          block->set_rpo_number(kBlockVisited2);
         }
         stack_depth--;
       }
@@ -1085,19 +1093,19 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
   for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
        ++i) {
     BasicBlock* current = *i;
-    current->loop_header_ = current_header;
+    current->set_loop_header(current_header);
     if (current->IsLoopHeader()) {
       loop_depth++;
-      current_loop = &loops[current->loop_end_];
+      current_loop = &loops[current->loop_end()];
       BlockList* end = current_loop->end;
-      current->loop_end_ = end == NULL ? static_cast<int>(final_order->size())
-                                       : end->block->rpo_number_;
+      current->set_loop_end(end == NULL ? static_cast<int>(final_order->size())
+                                        : end->block->rpo_number());
       current_header = current_loop->header;
-      Trace("B%d is a loop header, increment loop depth to %d\n", current->id(),
-            loop_depth);
+      Trace("B%d is a loop header, increment loop depth to %d\n",
+            current->id().ToInt(), loop_depth);
     } else {
       while (current_header != NULL &&
-             current->rpo_number_ >= current_header->loop_end_) {
+             current->rpo_number() >= current_header->loop_end()) {
         DCHECK(current_header->IsLoopHeader());
         DCHECK(current_loop != NULL);
         current_loop = current_loop->prev;
@@ -1105,13 +1113,13 @@ BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
         --loop_depth;
       }
     }
-    current->loop_depth_ = loop_depth;
-    if (current->loop_header_ == NULL) {
-      Trace("B%d is not in a loop (depth == %d)\n", current->id(),
-            current->loop_depth_);
+    current->set_loop_depth(loop_depth);
+    if (current->loop_header() == NULL) {
+      Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
+            current->loop_depth());
     } else {
-      Trace("B%d has loop header B%d, (depth == %d)\n", current->id(),
-            current->loop_header_->id(), current->loop_depth_);
+      Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
+            current->loop_header()->id().ToInt(), current->loop_depth());
     }
   }
 
index b21662f..854e27d 100644 (file)
@@ -66,10 +66,11 @@ class Scheduler {
   Placement GetPlacement(Node* node);
 
   int GetRPONumber(BasicBlock* block) {
-    DCHECK(block->rpo_number_ >= 0 &&
-           block->rpo_number_ < static_cast<int>(schedule_->rpo_order_.size()));
-    DCHECK(schedule_->rpo_order_[block->rpo_number_] == block);
-    return block->rpo_number_;
+    DCHECK(block->rpo_number() >= 0 &&
+           block->rpo_number() <
+               static_cast<int>(schedule_->rpo_order_.size()));
+    DCHECK(schedule_->rpo_order_[block->rpo_number()] == block);
+    return block->rpo_number();
   }
 
   void GenerateImmediateDominatorTree();
index 23cec7a..1bbd9da 100644 (file)
@@ -259,13 +259,13 @@ static bool HasDominatingDef(Schedule* schedule, Node* node,
   BasicBlock* block = use_block;
   while (true) {
     while (use_pos >= 0) {
-      if (block->nodes_[use_pos] == node) return true;
+      if (block->NodeAt(use_pos) == node) return true;
       use_pos--;
     }
-    block = block->dominator_;
+    block = block->dominator();
     if (block == NULL) break;
-    use_pos = static_cast<int>(block->nodes_.size()) - 1;
-    if (node == block->control_input_) return true;
+    use_pos = static_cast<int>(block->NodeCount()) - 1;
+    if (node == block->control_input()) return true;
   }
   return false;
 }
@@ -278,7 +278,7 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
     BasicBlock* use_block = block;
     if (node->opcode() == IrOpcode::kPhi) {
       use_block = use_block->PredecessorAt(j);
-      use_pos = static_cast<int>(use_block->nodes_.size()) - 1;
+      use_pos = static_cast<int>(use_block->NodeCount()) - 1;
     }
     Node* input = node->InputAt(j);
     if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
@@ -293,14 +293,14 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
 
 
 void ScheduleVerifier::Run(Schedule* schedule) {
-  const int count = schedule->BasicBlockCount();
+  const size_t count = schedule->BasicBlockCount();
   Zone tmp_zone(schedule->zone()->isolate());
   Zone* zone = &tmp_zone;
   BasicBlock* start = schedule->start();
   BasicBlockVector* rpo_order = schedule->rpo_order();
 
   // Verify the RPO order contains only blocks from this schedule.
-  CHECK_GE(count, static_cast<int>(rpo_order->size()));
+  CHECK_GE(count, rpo_order->size());
   for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
        ++b) {
     CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
@@ -310,86 +310,86 @@ void ScheduleVerifier::Run(Schedule* schedule) {
   CHECK_EQ(start, rpo_order->at(0));  // Start should be first.
   for (size_t b = 0; b < rpo_order->size(); b++) {
     BasicBlock* block = rpo_order->at(b);
-    CHECK_EQ(static_cast<int>(b), block->rpo_number_);
-    BasicBlock* dom = block->dominator_;
+    CHECK_EQ(static_cast<int>(b), block->rpo_number());
+    BasicBlock* dom = block->dominator();
     if (b == 0) {
       // All blocks except start should have a dominator.
       CHECK_EQ(NULL, dom);
     } else {
       // Check that the immediate dominator appears somewhere before the block.
       CHECK_NE(NULL, dom);
-      CHECK_LT(dom->rpo_number_, block->rpo_number_);
+      CHECK_LT(dom->rpo_number(), block->rpo_number());
     }
   }
 
   // Verify that all blocks reachable from start are in the RPO.
-  BoolVector marked(count, false, zone);
+  BoolVector marked(static_cast<int>(count), false, zone);
   {
     ZoneQueue<BasicBlock*> queue(zone);
     queue.push(start);
-    marked[start->id()] = true;
+    marked[start->id().ToSize()] = true;
     while (!queue.empty()) {
       BasicBlock* block = queue.front();
       queue.pop();
-      for (int s = 0; s < block->SuccessorCount(); s++) {
+      for (size_t s = 0; s < block->SuccessorCount(); s++) {
         BasicBlock* succ = block->SuccessorAt(s);
-        if (!marked[succ->id()]) {
-          marked[succ->id()] = true;
+        if (!marked[succ->id().ToSize()]) {
+          marked[succ->id().ToSize()] = true;
           queue.push(succ);
         }
       }
     }
   }
   // Verify marked blocks are in the RPO.
-  for (int i = 0; i < count; i++) {
-    BasicBlock* block = schedule->GetBlockById(i);
+  for (size_t i = 0; i < count; i++) {
+    BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
     if (marked[i]) {
-      CHECK_GE(block->rpo_number_, 0);
-      CHECK_EQ(block, rpo_order->at(block->rpo_number_));
+      CHECK_GE(block->rpo_number(), 0);
+      CHECK_EQ(block, rpo_order->at(block->rpo_number()));
     }
   }
   // Verify RPO blocks are marked.
   for (size_t b = 0; b < rpo_order->size(); b++) {
-    CHECK(marked[rpo_order->at(b)->id()]);
+    CHECK(marked[rpo_order->at(b)->id().ToSize()]);
   }
 
   {
     // Verify the dominance relation.
-    ZoneList<BitVector*> dominators(count, zone);
-    dominators.Initialize(count, zone);
-    dominators.AddBlock(NULL, count, zone);
+    ZoneVector<BitVector*> dominators(zone);
+    dominators.resize(count, NULL);
 
     // Compute a set of all the nodes that dominate a given node by using
     // a forward fixpoint. O(n^2).
     ZoneQueue<BasicBlock*> queue(zone);
     queue.push(start);
-    dominators[start->id()] = new (zone) BitVector(count, zone);
+    dominators[start->id().ToSize()] =
+        new (zone) BitVector(static_cast<int>(count), zone);
     while (!queue.empty()) {
       BasicBlock* block = queue.front();
       queue.pop();
-      BitVector* block_doms = dominators[block->id()];
-      BasicBlock* idom = block->dominator_;
-      if (idom != NULL && !block_doms->Contains(idom->id())) {
+      BitVector* block_doms = dominators[block->id().ToSize()];
+      BasicBlock* idom = block->dominator();
+      if (idom != NULL && !block_doms->Contains(idom->id().ToInt())) {
         V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
-                 block->id(), idom->id());
+                 block->id().ToInt(), idom->id().ToInt());
       }
-      for (int s = 0; s < block->SuccessorCount(); s++) {
+      for (size_t s = 0; s < block->SuccessorCount(); s++) {
         BasicBlock* succ = block->SuccessorAt(s);
-        BitVector* succ_doms = dominators[succ->id()];
+        BitVector* succ_doms = dominators[succ->id().ToSize()];
 
         if (succ_doms == NULL) {
           // First time visiting the node. S.doms = B U B.doms
-          succ_doms = new (zone) BitVector(count, zone);
+          succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
           succ_doms->CopyFrom(*block_doms);
-          succ_doms->Add(block->id());
-          dominators[succ->id()] = succ_doms;
+          succ_doms->Add(block->id().ToInt());
+          dominators[succ->id().ToSize()] = succ_doms;
           queue.push(succ);
         } else {
           // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
-          bool had = succ_doms->Contains(block->id());
-          if (had) succ_doms->Remove(block->id());
+          bool had = succ_doms->Contains(block->id().ToInt());
+          if (had) succ_doms->Remove(block->id().ToInt());
           if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
-          if (had) succ_doms->Add(block->id());
+          if (had) succ_doms->Add(block->id().ToInt());
         }
       }
     }
@@ -398,16 +398,18 @@ void ScheduleVerifier::Run(Schedule* schedule) {
     for (BasicBlockVector::iterator b = rpo_order->begin();
          b != rpo_order->end(); ++b) {
       BasicBlock* block = *b;
-      BasicBlock* idom = block->dominator_;
+      BasicBlock* idom = block->dominator();
       if (idom == NULL) continue;
-      BitVector* block_doms = dominators[block->id()];
+      BitVector* block_doms = dominators[block->id().ToSize()];
 
       for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
-        BasicBlock* dom = schedule->GetBlockById(it.Current());
-        if (dom != idom && !dominators[idom->id()]->Contains(dom->id())) {
+        BasicBlock* dom =
+            schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
+        if (dom != idom &&
+            !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
           V8_Fatal(__FILE__, __LINE__,
-                   "Block B%d is not immediately dominated by B%d", block->id(),
-                   idom->id());
+                   "Block B%d is not immediately dominated by B%d",
+                   block->id().ToInt(), idom->id().ToInt());
         }
       }
     }
@@ -437,15 +439,15 @@ void ScheduleVerifier::Run(Schedule* schedule) {
     BasicBlock* block = *b;
 
     // Check inputs to control for this block.
-    Node* control = block->control_input_;
+    Node* control = block->control_input();
     if (control != NULL) {
       CHECK_EQ(block, schedule->block(control));
       CheckInputsDominate(schedule, block, control,
-                          static_cast<int>(block->nodes_.size()) - 1);
+                          static_cast<int>(block->NodeCount()) - 1);
     }
     // Check inputs for all nodes in the block.
-    for (size_t i = 0; i < block->nodes_.size(); i++) {
-      Node* node = block->nodes_[i];
+    for (size_t i = 0; i < block->NodeCount(); i++) {
+      Node* node = block->NodeAt(i);
       CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
     }
   }
index 82d1e33..843f088 100644 (file)
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
 
index 6c05c05..63e7c2c 100644 (file)
@@ -24,7 +24,7 @@ TEST(TestScheduleAllocation) {
   Schedule schedule(scope.main_zone());
 
   CHECK_NE(NULL, schedule.start());
-  CHECK_EQ(schedule.start(), *(schedule.all_blocks().begin()));
+  CHECK_EQ(schedule.start(), schedule.GetBlockById(BasicBlock::Id::FromInt(0)));
 }
 
 
@@ -58,13 +58,13 @@ TEST(TestScheduleAddGoto) {
 
   schedule.AddGoto(entry, next);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  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, next->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(next->PredecessorCount()));
   CHECK_EQ(entry, next->PredecessorAt(0));
-  CHECK_EQ(0, next->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(next->SuccessorCount()));
 }
 
 
@@ -83,18 +83,18 @@ TEST(TestScheduleAddBranch) {
 
   schedule.AddBranch(entry, b, tblock, fblock);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(2, entry->SuccessorCount());
+  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, tblock->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(tblock->PredecessorCount()));
   CHECK_EQ(entry, tblock->PredecessorAt(0));
-  CHECK_EQ(0, tblock->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(tblock->SuccessorCount()));
 
-  CHECK_EQ(1, fblock->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(fblock->PredecessorCount()));
   CHECK_EQ(entry, fblock->PredecessorAt(0));
-  CHECK_EQ(0, fblock->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(fblock->SuccessorCount()));
 }
 
 
@@ -106,8 +106,8 @@ TEST(TestScheduleAddReturn) {
   BasicBlock* entry = schedule.start();
   schedule.AddReturn(entry, n0);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
 }
 
@@ -120,8 +120,8 @@ TEST(TestScheduleAddThrow) {
   BasicBlock* entry = schedule.start();
   schedule.AddThrow(entry, n0);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
 }
 
index cf33123..9a8c30e 100644 (file)
@@ -44,25 +44,25 @@ static TestLoop* CreateLoop(Schedule* schedule, int count) {
 }
 
 
-static void CheckRPONumbers(BasicBlockVector* order, int expected,
+static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
                             bool loops_allowed) {
-  CHECK_EQ(expected, static_cast<int>(order->size()));
+  CHECK(expected == order->size());
   for (int i = 0; i < static_cast<int>(order->size()); i++) {
-    CHECK(order->at(i)->rpo_number_ == i);
-    if (!loops_allowed) CHECK_LT(order->at(i)->loop_end_, 0);
+    CHECK(order->at(i)->rpo_number() == i);
+    if (!loops_allowed) CHECK_LT(order->at(i)->loop_end(), 0);
   }
 }
 
 
 static void CheckLoopContains(BasicBlock** blocks, int body_size) {
   BasicBlock* header = blocks[0];
-  CHECK_GT(header->loop_end_, 0);
-  CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_));
+  CHECK_GT(header->loop_end(), 0);
+  CHECK_EQ(body_size, (header->loop_end() - header->rpo_number()));
   for (int i = 0; i < body_size; i++) {
-    int num = blocks[i]->rpo_number_;
-    CHECK(num >= header->rpo_number_ && num < header->loop_end_);
+    int num = blocks[i]->rpo_number();
+    CHECK(num >= header->rpo_number() && num < header->loop_end());
     CHECK(header->LoopContains(blocks[i]));
-    CHECK(header->IsLoopHeader() || blocks[i]->loop_header_ == header);
+    CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header);
   }
 }
 
@@ -76,7 +76,7 @@ static int GetScheduledNodeCount(Schedule* schedule) {
          ++j) {
       ++node_count;
     }
-    BasicBlock::Control control = block->control_;
+    BasicBlock::Control control = block->control();
     if (control != BasicBlock::kNone) {
       ++node_count;
     }
@@ -140,12 +140,10 @@ TEST(RPOLine) {
     BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
     CheckRPONumbers(order, 1 + i, false);
 
-    Schedule::BasicBlocks blocks(schedule.all_blocks());
-    for (Schedule::BasicBlocks::iterator iter = blocks.begin();
-         iter != blocks.end(); ++iter) {
-      BasicBlock* block = *iter;
-      if (block->rpo_number_ >= 0 && block->SuccessorCount() == 1) {
-        CHECK(block->rpo_number_ + 1 == block->SuccessorAt(0)->rpo_number_);
+    for (size_t i = 0; i < schedule.BasicBlockCount(); i++) {
+      BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i));
+      if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) {
+        CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number());
       }
     }
   }
@@ -215,10 +213,10 @@ TEST(RPODiamond) {
   BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
   CheckRPONumbers(order, 4, false);
 
-  CHECK_EQ(0, A->rpo_number_);
-  CHECK((B->rpo_number_ == 1 && C->rpo_number_ == 2) ||
-        (B->rpo_number_ == 2 && C->rpo_number_ == 1));
-  CHECK_EQ(3, D->rpo_number_);
+  CHECK_EQ(0, A->rpo_number());
+  CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) ||
+        (B->rpo_number() == 2 && C->rpo_number() == 1));
+  CHECK_EQ(3, D->rpo_number());
 }
 
 
@@ -392,7 +390,8 @@ TEST(RPOLoopFollow1) {
 
   CheckLoopContains(loop1->nodes, loop1->count);
 
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
   CheckLoopContains(loop1->nodes, loop1->count);
   CheckLoopContains(loop2->nodes, loop2->count);
 }
@@ -418,7 +417,8 @@ TEST(RPOLoopFollow2) {
 
   CheckLoopContains(loop1->nodes, loop1->count);
 
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
   CheckLoopContains(loop1->nodes, loop1->count);
   CheckLoopContains(loop2->nodes, loop2->count);
 }
@@ -441,7 +441,8 @@ TEST(RPOLoopFollowN) {
       BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
       CheckLoopContains(loop1->nodes, loop1->count);
 
-      CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+      CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+               static_cast<int>(order->size()));
       CheckLoopContains(loop1->nodes, loop1->count);
       CheckLoopContains(loop2->nodes, loop2->count);
     }
@@ -472,7 +473,8 @@ TEST(RPONestedLoopFollow1) {
 
   CheckLoopContains(loop1->nodes, loop1->count);
 
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
   CheckLoopContains(loop1->nodes, loop1->count);
   CheckLoopContains(loop2->nodes, loop2->count);