Commit 6a07181c authored by jarin@chromium.org's avatar jarin@chromium.org

Refactor BasicBlock to not use GenericNode.

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
parent 381616fb
...@@ -8,7 +8,7 @@ namespace v8 { ...@@ -8,7 +8,7 @@ namespace v8 {
namespace internal { namespace internal {
BasicBlockProfiler::Data::Data(size_t n_blocks) 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() {} BasicBlockProfiler::Data::~Data() {}
...@@ -34,7 +34,7 @@ void BasicBlockProfiler::Data::SetSchedule(OStringStream* os) { ...@@ -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_); DCHECK(offset < n_blocks_);
block_ids_[offset] = block_id; block_ids_[offset] = block_id;
} }
......
...@@ -25,7 +25,7 @@ class BasicBlockProfiler { ...@@ -25,7 +25,7 @@ class BasicBlockProfiler {
void SetCode(OStringStream* os); void SetCode(OStringStream* os);
void SetFunctionName(OStringStream* os); void SetFunctionName(OStringStream* os);
void SetSchedule(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); uint32_t* GetCounterAddress(size_t offset);
private: private:
...@@ -38,7 +38,7 @@ class BasicBlockProfiler { ...@@ -38,7 +38,7 @@ class BasicBlockProfiler {
void ResetCounts(); void ResetCounts();
const size_t n_blocks_; const size_t n_blocks_;
std::vector<int> block_ids_; std::vector<size_t> block_ids_;
std::vector<uint32_t> counts_; std::vector<uint32_t> counts_;
std::string function_name_; std::string function_name_;
std::string schedule_; std::string schedule_;
......
...@@ -15,9 +15,9 @@ namespace compiler { ...@@ -15,9 +15,9 @@ namespace compiler {
// Find the first place to insert new nodes in a block that's already been // Find the first place to insert new nodes in a block that's already been
// scheduled that won't upset the register allocator. // scheduled that won't upset the register allocator.
static NodeVector::iterator FindInsertionPoint(NodeVector* nodes) { static NodeVector::iterator FindInsertionPoint(BasicBlock* block) {
NodeVector::iterator i = nodes->begin(); NodeVector::iterator i = block->begin();
for (; i != nodes->end(); ++i) { for (; i != block->end(); ++i) {
const Operator* op = (*i)->op(); const Operator* op = (*i)->op();
if (OperatorProperties::IsBasicBlockBegin(op)) continue; if (OperatorProperties::IsBasicBlockBegin(op)) continue;
switch (op->opcode()) { switch (op->opcode()) {
...@@ -72,7 +72,7 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument( ...@@ -72,7 +72,7 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks; for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
++it, ++block_number) { ++it, ++block_number) {
BasicBlock* block = (*it); 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. // TODO(dcarney): wire effect and control deps for load and store.
// Construct increment operation. // Construct increment operation.
Node* base = graph->NewNode( Node* base = graph->NewNode(
...@@ -86,10 +86,9 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument( ...@@ -86,10 +86,9 @@ BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
static const int kArraySize = 6; static const int kArraySize = 6;
Node* to_insert[kArraySize] = {zero, one, base, load, inc, store}; Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
int insertion_start = block_number == 0 ? 0 : 2; int insertion_start = block_number == 0 ? 0 : 2;
NodeVector* nodes = &block->nodes_; NodeVector::iterator insertion_point = FindInsertionPoint(block);
NodeVector::iterator insertion_point = FindInsertionPoint(nodes); block->InsertNodes(insertion_point, &to_insert[insertion_start],
nodes->insert(insertion_point, &to_insert[insertion_start], &to_insert[kArraySize]);
&to_insert[kArraySize]);
// Tell the scheduler about the new nodes. // Tell the scheduler about the new nodes.
for (int i = insertion_start; i < kArraySize; ++i) { for (int i = insertion_start; i < kArraySize; ++i) {
schedule->SetBlockForNode(block, to_insert[i]); schedule->SetBlockForNode(block, to_insert[i]);
......
...@@ -65,11 +65,8 @@ class InstructionOperandConverter { ...@@ -65,11 +65,8 @@ class InstructionOperandConverter {
} }
BasicBlock* InputBlock(int index) { BasicBlock* InputBlock(int index) {
NodeId block_id = static_cast<NodeId>(InputInt32(index)); int block_id = InputInt32(index);
// operand should be a block id. return gen_->schedule()->GetBlockById(BasicBlock::Id::FromInt(block_id));
DCHECK(block_id >= 0);
DCHECK(block_id < gen_->schedule()->BasicBlockCount());
return gen_->schedule()->GetBlockById(block_id);
} }
Register OutputRegister(int index = 0) { Register OutputRegister(int index = 0) {
......
...@@ -107,7 +107,7 @@ void CodeGenerator::AssembleInstruction(Instruction* instr) { ...@@ -107,7 +107,7 @@ void CodeGenerator::AssembleInstruction(Instruction* instr) {
if (FLAG_code_comments) { if (FLAG_code_comments) {
// TODO(titzer): these code comments are a giant memory leak. // TODO(titzer): these code comments are a giant memory leak.
Vector<char> buffer = Vector<char>::New(32); 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()->RecordComment(buffer.start());
} }
masm()->bind(block_start->label()); masm()->bind(block_start->label());
......
...@@ -41,8 +41,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler { ...@@ -41,8 +41,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
// Checks if {block} will appear directly after {current_block_} when // Checks if {block} will appear directly after {current_block_} when
// assembling code, in which case, a fall-through can be used. // assembling code, in which case, a fall-through can be used.
bool IsNextInAssemblyOrder(const BasicBlock* block) const { bool IsNextInAssemblyOrder(const BasicBlock* block) const {
return block->rpo_number_ == (current_block_->rpo_number_ + 1) && return block->rpo_number() == (current_block_->rpo_number() + 1) &&
block->deferred_ == current_block_->deferred_; block->deferred() == current_block_->deferred();
} }
// Record a safepoint with the given pointer map. // Record a safepoint with the given pointer map.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_ #ifndef V8_COMPILER_INSTRUCTION_SELECTOR_IMPL_H_
#define 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.h"
#include "src/compiler/instruction-selector.h" #include "src/compiler/instruction-selector.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
...@@ -129,7 +130,7 @@ class OperandGenerator { ...@@ -129,7 +130,7 @@ class OperandGenerator {
InstructionOperand* Label(BasicBlock* block) { InstructionOperand* Label(BasicBlock* block) {
// TODO(bmeurer): We misuse ImmediateOperand here. // TODO(bmeurer): We misuse ImmediateOperand here.
return TempImmediate(block->id()); return TempImmediate(block->id().ToInt());
} }
protected: protected:
......
...@@ -55,8 +55,8 @@ void InstructionSelector::SelectInstructions() { ...@@ -55,8 +55,8 @@ void InstructionSelector::SelectInstructions() {
// Schedule the selected instructions. // Schedule the selected instructions.
for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) { for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
BasicBlock* block = *i; BasicBlock* block = *i;
size_t end = block->code_end_; size_t end = block->code_end();
size_t start = block->code_start_; size_t start = block->code_start();
sequence()->StartBlock(block); sequence()->StartBlock(block);
while (start-- > end) { while (start-- > end) {
sequence()->AddInstruction(instructions_[start], block); sequence()->AddInstruction(instructions_[start], block);
...@@ -141,8 +141,8 @@ Instruction* InstructionSelector::Emit(Instruction* instr) { ...@@ -141,8 +141,8 @@ Instruction* InstructionSelector::Emit(Instruction* instr) {
bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const { bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
return block->rpo_number_ == (current_block_->rpo_number_ + 1) && return block->rpo_number() == (current_block_->rpo_number() + 1) &&
block->deferred_ == current_block_->deferred_; block->deferred() == current_block_->deferred();
} }
...@@ -383,8 +383,8 @@ void InstructionSelector::VisitBlock(BasicBlock* block) { ...@@ -383,8 +383,8 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
// We're done with the block. // We're done with the block.
// TODO(bmeurer): We should not mutate the schedule. // TODO(bmeurer): We should not mutate the schedule.
block->code_end_ = current_block_end; block->set_code_start(static_cast<int>(instructions_.size()));
block->code_start_ = static_cast<int>(instructions_.size()); block->set_code_end(current_block_end);
current_block_ = NULL; current_block_ = NULL;
} }
...@@ -402,11 +402,11 @@ static inline void CheckNoPhis(const BasicBlock* block) { ...@@ -402,11 +402,11 @@ static inline void CheckNoPhis(const BasicBlock* block) {
void InstructionSelector::VisitControl(BasicBlock* block) { void InstructionSelector::VisitControl(BasicBlock* block) {
Node* input = block->control_input_; Node* input = block->control_input();
switch (block->control_) { switch (block->control()) {
case BasicBlockData::kGoto: case BasicBlock::kGoto:
return VisitGoto(block->SuccessorAt(0)); return VisitGoto(block->SuccessorAt(0));
case BasicBlockData::kBranch: { case BasicBlock::kBranch: {
DCHECK_EQ(IrOpcode::kBranch, input->opcode()); DCHECK_EQ(IrOpcode::kBranch, input->opcode());
BasicBlock* tbranch = block->SuccessorAt(0); BasicBlock* tbranch = block->SuccessorAt(0);
BasicBlock* fbranch = block->SuccessorAt(1); BasicBlock* fbranch = block->SuccessorAt(1);
...@@ -417,16 +417,16 @@ void InstructionSelector::VisitControl(BasicBlock* block) { ...@@ -417,16 +417,16 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
if (tbranch == fbranch) return VisitGoto(tbranch); if (tbranch == fbranch) return VisitGoto(tbranch);
return VisitBranch(input, tbranch, fbranch); return VisitBranch(input, tbranch, fbranch);
} }
case BasicBlockData::kReturn: { case BasicBlock::kReturn: {
// If the result itself is a return, return its input. // If the result itself is a return, return its input.
Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn) Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
? input->InputAt(0) ? input->InputAt(0)
: input; : input;
return VisitReturn(value); return VisitReturn(value);
} }
case BasicBlockData::kThrow: case BasicBlock::kThrow:
return VisitThrow(input); return VisitThrow(input);
case BasicBlockData::kNone: { case BasicBlock::kNone: {
// TODO(titzer): exit block doesn't have control. // TODO(titzer): exit block doesn't have control.
DCHECK(input == NULL); DCHECK(input == NULL);
break; break;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "src/compiler/instruction.h" #include "src/compiler/instruction.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/generic-node-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -320,12 +321,12 @@ Label* InstructionSequence::GetLabel(BasicBlock* block) { ...@@ -320,12 +321,12 @@ Label* InstructionSequence::GetLabel(BasicBlock* block) {
BlockStartInstruction* InstructionSequence::GetBlockStart(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) { 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* block_start =
BlockStartInstruction::New(zone(), block); BlockStartInstruction::New(zone(), block);
AddInstruction(block_start, block); AddInstruction(block_start, block);
...@@ -334,8 +335,8 @@ void InstructionSequence::StartBlock(BasicBlock* block) { ...@@ -334,8 +335,8 @@ void InstructionSequence::StartBlock(BasicBlock* block) {
void InstructionSequence::EndBlock(BasicBlock* block) { void InstructionSequence::EndBlock(BasicBlock* block) {
int end = static_cast<int>(instructions_.size()); int end = static_cast<int>(instructions_.size());
DCHECK(block->code_start_ >= 0 && block->code_start_ < end); DCHECK(block->code_start() >= 0 && block->code_start() < end);
block->code_end_ = end; block->set_code_end(end);
} }
...@@ -427,19 +428,17 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) { ...@@ -427,19 +428,17 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) {
for (int i = 0; i < code.BasicBlockCount(); i++) { for (int i = 0; i < code.BasicBlockCount(); i++) {
BasicBlock* block = code.BlockAt(i); BasicBlock* block = code.BlockAt(i);
int bid = block->id(); os << "RPO#" << block->rpo_number() << ": B" << block->id();
os << "RPO#" << block->rpo_number_ << ": B" << bid; CHECK(block->rpo_number() == i);
CHECK(block->rpo_number_ == i);
if (block->IsLoopHeader()) { 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_ os << " instructions: [" << block->code_start() << ", "
<< ")\n predecessors:"; << block->code_end() << ")\n predecessors:";
BasicBlock::Predecessors predecessors = block->predecessors(); for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin();
for (BasicBlock::Predecessors::iterator iter = predecessors.begin(); iter != block->predecessors_end(); ++iter) {
iter != predecessors.end(); ++iter) {
os << " B" << (*iter)->id(); os << " B" << (*iter)->id();
} }
os << "\n"; os << "\n";
...@@ -465,15 +464,14 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) { ...@@ -465,15 +464,14 @@ OStream& operator<<(OStream& os, const InstructionSequence& code) {
os << " " << buf.start() << ": " << *code.InstructionAt(j); os << " " << buf.start() << ": " << *code.InstructionAt(j);
} }
os << " " << block->control_; os << " " << block->control();
if (block->control_input_ != NULL) { if (block->control_input() != NULL) {
os << " v" << block->control_input_->id(); os << " v" << block->control_input()->id();
} }
BasicBlock::Successors successors = block->successors(); for (BasicBlock::Successors::iterator iter = block->successors_begin();
for (BasicBlock::Successors::iterator iter = successors.begin(); iter != block->successors_end(); ++iter) {
iter != successors.end(); ++iter) {
os << " B" << (*iter)->id(); os << " B" << (*iter)->id();
} }
os << "\n"; os << "\n";
......
...@@ -836,10 +836,10 @@ class InstructionSequence FINAL { ...@@ -836,10 +836,10 @@ class InstructionSequence FINAL {
} }
BasicBlock* GetContainingLoop(BasicBlock* block) { 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); BasicBlock* GetBasicBlock(int instruction_index);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_COMPILER_PHI_REDUCER_H_ #ifndef V8_COMPILER_PHI_REDUCER_H_
#define V8_COMPILER_PHI_REDUCER_H_ #define V8_COMPILER_PHI_REDUCER_H_
#include "src/compiler/generic-node-inl.h"
#include "src/compiler/graph-reducer.h" #include "src/compiler/graph-reducer.h"
namespace v8 { namespace v8 {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "src/compiler/register-allocator.h" #include "src/compiler/register-allocator.h"
#include "src/compiler/generic-node-inl.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
#include "src/hydrogen.h" #include "src/hydrogen.h"
#include "src/string-stream.h" #include "src/string-stream.h"
...@@ -530,25 +531,23 @@ BitVector* RegisterAllocator::ComputeLiveOut(BasicBlock* block) { ...@@ -530,25 +531,23 @@ BitVector* RegisterAllocator::ComputeLiveOut(BasicBlock* block) {
new (zone()) BitVector(code()->VirtualRegisterCount(), zone()); new (zone()) BitVector(code()->VirtualRegisterCount(), zone());
// Process all successor blocks. // Process all successor blocks.
BasicBlock::Successors successors = block->successors(); for (BasicBlock::Successors::iterator i = block->successors_begin();
for (BasicBlock::Successors::iterator i = successors.begin(); i != block->successors_end(); ++i) {
i != successors.end(); ++i) {
// Add values live on entry to the successor. Note the successor's // Add values live on entry to the successor. Note the successor's
// live_in will not be computed yet for backwards edges. // live_in will not be computed yet for backwards edges.
BasicBlock* successor = *i; 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); if (live_in != NULL) live_out->Union(*live_in);
// All phi input operands corresponding to this successor edge are live // All phi input operands corresponding to this successor edge are live
// out from this block. // out from this block.
int index = successor->PredecessorIndexOf(block); size_t index = successor->PredecessorIndexOf(block);
DCHECK(index >= 0); DCHECK(index < successor->PredecessorCount());
DCHECK(index < static_cast<int>(successor->PredecessorCount()));
for (BasicBlock::const_iterator j = successor->begin(); for (BasicBlock::const_iterator j = successor->begin();
j != successor->end(); ++j) { j != successor->end(); ++j) {
Node* phi = *j; Node* phi = *j;
if (phi->opcode() != IrOpcode::kPhi) continue; if (phi->opcode() != IrOpcode::kPhi) continue;
Node* input = phi->InputAt(index); Node* input = phi->InputAt(static_cast<int>(index));
live_out->Add(input->id()); live_out->Add(input->id());
} }
} }
...@@ -772,9 +771,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( ...@@ -772,9 +771,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
assigned = true; assigned = true;
} }
BasicBlock::Successors successors = block->successors(); for (BasicBlock::Successors::iterator succ = block->successors_begin();
for (BasicBlock::Successors::iterator succ = successors.begin(); succ != block->successors_end(); ++succ) {
succ != successors.end(); ++succ) {
DCHECK((*succ)->PredecessorCount() == 1); DCHECK((*succ)->PredecessorCount() == 1);
int gap_index = (*succ)->first_instruction_index() + 1; int gap_index = (*succ)->first_instruction_index() + 1;
DCHECK(code()->IsGapAt(gap_index)); DCHECK(code()->IsGapAt(gap_index));
...@@ -790,9 +788,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( ...@@ -790,9 +788,8 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
} }
if (!assigned) { if (!assigned) {
BasicBlock::Successors successors = block->successors(); for (BasicBlock::Successors::iterator succ = block->successors_begin();
for (BasicBlock::Successors::iterator succ = successors.begin(); succ != block->successors_end(); ++succ) {
succ != successors.end(); ++succ) {
DCHECK((*succ)->PredecessorCount() == 1); DCHECK((*succ)->PredecessorCount() == 1);
int gap_index = (*succ)->first_instruction_index() + 1; int gap_index = (*succ)->first_instruction_index() + 1;
range->SetSpillStartIndex(gap_index); range->SetSpillStartIndex(gap_index);
...@@ -1071,7 +1068,7 @@ void RegisterAllocator::ResolvePhis(BasicBlock* block) { ...@@ -1071,7 +1068,7 @@ void RegisterAllocator::ResolvePhis(BasicBlock* block) {
new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE); new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE);
phi_operand->set_virtual_register(phi->id()); phi_operand->set_virtual_register(phi->id());
int j = 0; size_t j = 0;
Node::Inputs inputs = phi->inputs(); Node::Inputs inputs = phi->inputs();
for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end(); for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
++iter, ++j) { ++iter, ++j) {
...@@ -1253,7 +1250,7 @@ void RegisterAllocator::ConnectRanges() { ...@@ -1253,7 +1250,7 @@ void RegisterAllocator::ConnectRanges() {
bool RegisterAllocator::CanEagerlyResolveControlFlow(BasicBlock* block) const { bool RegisterAllocator::CanEagerlyResolveControlFlow(BasicBlock* block) const {
if (block->PredecessorCount() != 1) return false; 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() { ...@@ -1262,13 +1259,12 @@ void RegisterAllocator::ResolveControlFlow() {
for (int block_id = 1; block_id < code()->BasicBlockCount(); ++block_id) { for (int block_id = 1; block_id < code()->BasicBlockCount(); ++block_id) {
BasicBlock* block = code()->BlockAt(block_id); BasicBlock* block = code()->BlockAt(block_id);
if (CanEagerlyResolveControlFlow(block)) continue; if (CanEagerlyResolveControlFlow(block)) continue;
BitVector* live = live_in_sets_[block->rpo_number_]; BitVector* live = live_in_sets_[block->rpo_number()];
BitVector::Iterator iterator(live); BitVector::Iterator iterator(live);
while (!iterator.Done()) { while (!iterator.Done()) {
int operand_index = iterator.Current(); int operand_index = iterator.Current();
BasicBlock::Predecessors predecessors = block->predecessors(); for (BasicBlock::Predecessors::iterator i = block->predecessors_begin();
for (BasicBlock::Predecessors::iterator i = predecessors.begin(); i != block->predecessors_end(); ++i) {
i != predecessors.end(); ++i) {
BasicBlock* cur = *i; BasicBlock* cur = *i;
LiveRange* cur_range = LiveRangeFor(operand_index); LiveRange* cur_range = LiveRangeFor(operand_index);
ResolveControlFlow(cur_range, block, cur); ResolveControlFlow(cur_range, block, cur);
...@@ -1338,7 +1334,7 @@ void RegisterAllocator::BuildLiveRanges() { ...@@ -1338,7 +1334,7 @@ void RegisterAllocator::BuildLiveRanges() {
LifetimePosition start = LifetimePosition::FromInstructionIndex( LifetimePosition start = LifetimePosition::FromInstructionIndex(
block->first_instruction_index()); block->first_instruction_index());
int end_index = int end_index =
code()->BlockAt(block->loop_end_)->last_instruction_index(); code()->BlockAt(block->loop_end())->last_instruction_index();
LifetimePosition end = LifetimePosition end =
LifetimePosition::FromInstructionIndex(end_index).NextInstruction(); LifetimePosition::FromInstructionIndex(end_index).NextInstruction();
while (!iterator.Done()) { while (!iterator.Done()) {
...@@ -1349,7 +1345,7 @@ void RegisterAllocator::BuildLiveRanges() { ...@@ -1349,7 +1345,7 @@ void RegisterAllocator::BuildLiveRanges() {
} }
// Insert all values into the live in sets of all blocks in the loop. // 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); live_in_sets_[i]->Union(*live);
} }
} }
...@@ -2098,8 +2094,8 @@ LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start, ...@@ -2098,8 +2094,8 @@ LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
// Find header of outermost loop. // Find header of outermost loop.
// TODO(titzer): fix redundancy below. // TODO(titzer): fix redundancy below.
while (code()->GetContainingLoop(block) != NULL && while (code()->GetContainingLoop(block) != NULL &&
code()->GetContainingLoop(block)->rpo_number_ > code()->GetContainingLoop(block)->rpo_number() >
start_block->rpo_number_) { start_block->rpo_number()) {
block = code()->GetContainingLoop(block); block = code()->GetContainingLoop(block);
} }
......
...@@ -12,17 +12,115 @@ namespace v8 { ...@@ -12,17 +12,115 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { 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) { switch (c) {
case BasicBlockData::kNone: case BasicBlock::kNone:
return os << "none"; return os << "none";
case BasicBlockData::kGoto: case BasicBlock::kGoto:
return os << "goto"; return os << "goto";
case BasicBlockData::kBranch: case BasicBlock::kBranch:
return os << "branch"; return os << "branch";
case BasicBlockData::kReturn: case BasicBlock::kReturn:
return os << "return"; return os << "return";
case BasicBlockData::kThrow: case BasicBlock::kThrow:
return os << "throw"; return os << "throw";
} }
UNREACHABLE(); UNREACHABLE();
...@@ -30,6 +128,145 @@ OStream& operator<<(OStream& os, const BasicBlockData::Control& c) { ...@@ -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) { OStream& operator<<(OStream& os, const Schedule& s) {
// TODO(svenpanne) Const-correct the RPO stuff/iterators. // TODO(svenpanne) Const-correct the RPO stuff/iterators.
BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order(); BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order();
...@@ -37,10 +274,9 @@ OStream& operator<<(OStream& os, const Schedule& s) { ...@@ -37,10 +274,9 @@ OStream& operator<<(OStream& os, const Schedule& s) {
BasicBlock* block = *i; BasicBlock* block = *i;
os << "--- BLOCK B" << block->id(); os << "--- BLOCK B" << block->id();
if (block->PredecessorCount() != 0) os << " <- "; if (block->PredecessorCount() != 0) os << " <- ";
BasicBlock::Predecessors predecessors = block->predecessors();
bool comma = false; bool comma = false;
for (BasicBlock::Predecessors::iterator j = predecessors.begin(); for (BasicBlock::Predecessors::iterator j = block->predecessors_begin();
j != predecessors.end(); ++j) { j != block->predecessors_end(); ++j) {
if (comma) os << ", "; if (comma) os << ", ";
comma = true; comma = true;
os << "B" << (*j)->id(); os << "B" << (*j)->id();
...@@ -61,19 +297,18 @@ OStream& operator<<(OStream& os, const Schedule& s) { ...@@ -61,19 +297,18 @@ OStream& operator<<(OStream& os, const Schedule& s) {
} }
os << "\n"; os << "\n";
} }
BasicBlock::Control control = block->control_; BasicBlock::Control control = block->control();
if (control != BasicBlock::kNone) { if (control != BasicBlock::kNone) {
os << " "; os << " ";
if (block->control_input_ != NULL) { if (block->control_input() != NULL) {
os << *block->control_input_; os << *block->control_input();
} else { } else {
os << "Goto"; os << "Goto";
} }
os << " -> "; os << " -> ";
BasicBlock::Successors successors = block->successors();
comma = false; comma = false;
for (BasicBlock::Successors::iterator j = successors.begin(); for (BasicBlock::Successors::iterator j = block->successors_begin();
j != successors.end(); ++j) { j != block->successors_end(); ++j) {
if (comma) os << ", "; if (comma) os << ", ";
comma = true; comma = true;
os << "B" << (*j)->id(); os << "B" << (*j)->id();
......
This diff is collapsed.
This diff is collapsed.
...@@ -66,10 +66,11 @@ class Scheduler { ...@@ -66,10 +66,11 @@ class Scheduler {
Placement GetPlacement(Node* node); Placement GetPlacement(Node* node);
int GetRPONumber(BasicBlock* block) { int GetRPONumber(BasicBlock* block) {
DCHECK(block->rpo_number_ >= 0 && DCHECK(block->rpo_number() >= 0 &&
block->rpo_number_ < static_cast<int>(schedule_->rpo_order_.size())); block->rpo_number() <
DCHECK(schedule_->rpo_order_[block->rpo_number_] == block); static_cast<int>(schedule_->rpo_order_.size()));
return block->rpo_number_; DCHECK(schedule_->rpo_order_[block->rpo_number()] == block);
return block->rpo_number();
} }
void GenerateImmediateDominatorTree(); void GenerateImmediateDominatorTree();
......
...@@ -259,13 +259,13 @@ static bool HasDominatingDef(Schedule* schedule, Node* node, ...@@ -259,13 +259,13 @@ static bool HasDominatingDef(Schedule* schedule, Node* node,
BasicBlock* block = use_block; BasicBlock* block = use_block;
while (true) { while (true) {
while (use_pos >= 0) { while (use_pos >= 0) {
if (block->nodes_[use_pos] == node) return true; if (block->NodeAt(use_pos) == node) return true;
use_pos--; use_pos--;
} }
block = block->dominator_; block = block->dominator();
if (block == NULL) break; if (block == NULL) break;
use_pos = static_cast<int>(block->nodes_.size()) - 1; use_pos = static_cast<int>(block->NodeCount()) - 1;
if (node == block->control_input_) return true; if (node == block->control_input()) return true;
} }
return false; return false;
} }
...@@ -278,7 +278,7 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block, ...@@ -278,7 +278,7 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
BasicBlock* use_block = block; BasicBlock* use_block = block;
if (node->opcode() == IrOpcode::kPhi) { if (node->opcode() == IrOpcode::kPhi) {
use_block = use_block->PredecessorAt(j); 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); Node* input = node->InputAt(j);
if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block, if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
...@@ -293,14 +293,14 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block, ...@@ -293,14 +293,14 @@ static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
void ScheduleVerifier::Run(Schedule* schedule) { void ScheduleVerifier::Run(Schedule* schedule) {
const int count = schedule->BasicBlockCount(); const size_t count = schedule->BasicBlockCount();
Zone tmp_zone(schedule->zone()->isolate()); Zone tmp_zone(schedule->zone()->isolate());
Zone* zone = &tmp_zone; Zone* zone = &tmp_zone;
BasicBlock* start = schedule->start(); BasicBlock* start = schedule->start();
BasicBlockVector* rpo_order = schedule->rpo_order(); BasicBlockVector* rpo_order = schedule->rpo_order();
// Verify the RPO order contains only blocks from this schedule. // 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(); for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
++b) { ++b) {
CHECK_EQ((*b), schedule->GetBlockById((*b)->id())); CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
...@@ -310,86 +310,86 @@ void ScheduleVerifier::Run(Schedule* schedule) { ...@@ -310,86 +310,86 @@ void ScheduleVerifier::Run(Schedule* schedule) {
CHECK_EQ(start, rpo_order->at(0)); // Start should be first. CHECK_EQ(start, rpo_order->at(0)); // Start should be first.
for (size_t b = 0; b < rpo_order->size(); b++) { for (size_t b = 0; b < rpo_order->size(); b++) {
BasicBlock* block = rpo_order->at(b); BasicBlock* block = rpo_order->at(b);
CHECK_EQ(static_cast<int>(b), block->rpo_number_); CHECK_EQ(static_cast<int>(b), block->rpo_number());
BasicBlock* dom = block->dominator_; BasicBlock* dom = block->dominator();
if (b == 0) { if (b == 0) {
// All blocks except start should have a dominator. // All blocks except start should have a dominator.
CHECK_EQ(NULL, dom); CHECK_EQ(NULL, dom);
} else { } else {
// Check that the immediate dominator appears somewhere before the block. // Check that the immediate dominator appears somewhere before the block.
CHECK_NE(NULL, dom); 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. // 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); ZoneQueue<BasicBlock*> queue(zone);
queue.push(start); queue.push(start);
marked[start->id()] = true; marked[start->id().ToSize()] = true;
while (!queue.empty()) { while (!queue.empty()) {
BasicBlock* block = queue.front(); BasicBlock* block = queue.front();
queue.pop(); queue.pop();
for (int s = 0; s < block->SuccessorCount(); s++) { for (size_t s = 0; s < block->SuccessorCount(); s++) {
BasicBlock* succ = block->SuccessorAt(s); BasicBlock* succ = block->SuccessorAt(s);
if (!marked[succ->id()]) { if (!marked[succ->id().ToSize()]) {
marked[succ->id()] = true; marked[succ->id().ToSize()] = true;
queue.push(succ); queue.push(succ);
} }
} }
} }
} }
// Verify marked blocks are in the RPO. // Verify marked blocks are in the RPO.
for (int i = 0; i < count; i++) { for (size_t i = 0; i < count; i++) {
BasicBlock* block = schedule->GetBlockById(i); BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
if (marked[i]) { if (marked[i]) {
CHECK_GE(block->rpo_number_, 0); CHECK_GE(block->rpo_number(), 0);
CHECK_EQ(block, rpo_order->at(block->rpo_number_)); CHECK_EQ(block, rpo_order->at(block->rpo_number()));
} }
} }
// Verify RPO blocks are marked. // Verify RPO blocks are marked.
for (size_t b = 0; b < rpo_order->size(); b++) { 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. // Verify the dominance relation.
ZoneList<BitVector*> dominators(count, zone); ZoneVector<BitVector*> dominators(zone);
dominators.Initialize(count, zone); dominators.resize(count, NULL);
dominators.AddBlock(NULL, count, zone);
// Compute a set of all the nodes that dominate a given node by using // Compute a set of all the nodes that dominate a given node by using
// a forward fixpoint. O(n^2). // a forward fixpoint. O(n^2).
ZoneQueue<BasicBlock*> queue(zone); ZoneQueue<BasicBlock*> queue(zone);
queue.push(start); 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()) { while (!queue.empty()) {
BasicBlock* block = queue.front(); BasicBlock* block = queue.front();
queue.pop(); queue.pop();
BitVector* block_doms = dominators[block->id()]; BitVector* block_doms = dominators[block->id().ToSize()];
BasicBlock* idom = block->dominator_; BasicBlock* idom = block->dominator();
if (idom != NULL && !block_doms->Contains(idom->id())) { if (idom != NULL && !block_doms->Contains(idom->id().ToInt())) {
V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d", 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); BasicBlock* succ = block->SuccessorAt(s);
BitVector* succ_doms = dominators[succ->id()]; BitVector* succ_doms = dominators[succ->id().ToSize()];
if (succ_doms == NULL) { if (succ_doms == NULL) {
// First time visiting the node. S.doms = B U B.doms // 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->CopyFrom(*block_doms);
succ_doms->Add(block->id()); succ_doms->Add(block->id().ToInt());
dominators[succ->id()] = succ_doms; dominators[succ->id().ToSize()] = succ_doms;
queue.push(succ); queue.push(succ);
} else { } else {
// Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms) // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
bool had = succ_doms->Contains(block->id()); bool had = succ_doms->Contains(block->id().ToInt());
if (had) succ_doms->Remove(block->id()); if (had) succ_doms->Remove(block->id().ToInt());
if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ); 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) { ...@@ -398,16 +398,18 @@ void ScheduleVerifier::Run(Schedule* schedule) {
for (BasicBlockVector::iterator b = rpo_order->begin(); for (BasicBlockVector::iterator b = rpo_order->begin();
b != rpo_order->end(); ++b) { b != rpo_order->end(); ++b) {
BasicBlock* block = *b; BasicBlock* block = *b;
BasicBlock* idom = block->dominator_; BasicBlock* idom = block->dominator();
if (idom == NULL) continue; 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()) { for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
BasicBlock* dom = schedule->GetBlockById(it.Current()); BasicBlock* dom =
if (dom != idom && !dominators[idom->id()]->Contains(dom->id())) { schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
if (dom != idom &&
!dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
V8_Fatal(__FILE__, __LINE__, V8_Fatal(__FILE__, __LINE__,
"Block B%d is not immediately dominated by B%d", block->id(), "Block B%d is not immediately dominated by B%d",
idom->id()); block->id().ToInt(), idom->id().ToInt());
} }
} }
} }
...@@ -437,15 +439,15 @@ void ScheduleVerifier::Run(Schedule* schedule) { ...@@ -437,15 +439,15 @@ void ScheduleVerifier::Run(Schedule* schedule) {
BasicBlock* block = *b; BasicBlock* block = *b;
// Check inputs to control for this block. // Check inputs to control for this block.
Node* control = block->control_input_; Node* control = block->control_input();
if (control != NULL) { if (control != NULL) {
CHECK_EQ(block, schedule->block(control)); CHECK_EQ(block, schedule->block(control));
CheckInputsDominate(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. // Check inputs for all nodes in the block.
for (size_t i = 0; i < block->nodes_.size(); i++) { for (size_t i = 0; i < block->NodeCount(); i++) {
Node* node = block->nodes_[i]; Node* node = block->NodeAt(i);
CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1); CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
} }
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/generic-node-inl.h"
#include "src/compiler/instruction-selector-impl.h" #include "src/compiler/instruction-selector-impl.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
......
...@@ -24,7 +24,7 @@ TEST(TestScheduleAllocation) { ...@@ -24,7 +24,7 @@ TEST(TestScheduleAllocation) {
Schedule schedule(scope.main_zone()); Schedule schedule(scope.main_zone());
CHECK_NE(NULL, schedule.start()); 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) { ...@@ -58,13 +58,13 @@ TEST(TestScheduleAddGoto) {
schedule.AddGoto(entry, next); schedule.AddGoto(entry, next);
CHECK_EQ(0, entry->PredecessorCount()); CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, entry->SuccessorCount()); CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(next, entry->SuccessorAt(0)); 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(entry, next->PredecessorAt(0));
CHECK_EQ(0, next->SuccessorCount()); CHECK_EQ(0, static_cast<int>(next->SuccessorCount()));
} }
...@@ -83,18 +83,18 @@ TEST(TestScheduleAddBranch) { ...@@ -83,18 +83,18 @@ TEST(TestScheduleAddBranch) {
schedule.AddBranch(entry, b, tblock, fblock); schedule.AddBranch(entry, b, tblock, fblock);
CHECK_EQ(0, entry->PredecessorCount()); CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(2, entry->SuccessorCount()); CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(tblock, entry->SuccessorAt(0)); CHECK_EQ(tblock, entry->SuccessorAt(0));
CHECK_EQ(fblock, entry->SuccessorAt(1)); 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(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(entry, fblock->PredecessorAt(0));
CHECK_EQ(0, fblock->SuccessorCount()); CHECK_EQ(0, static_cast<int>(fblock->SuccessorCount()));
} }
...@@ -106,8 +106,8 @@ TEST(TestScheduleAddReturn) { ...@@ -106,8 +106,8 @@ TEST(TestScheduleAddReturn) {
BasicBlock* entry = schedule.start(); BasicBlock* entry = schedule.start();
schedule.AddReturn(entry, n0); schedule.AddReturn(entry, n0);
CHECK_EQ(0, entry->PredecessorCount()); CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, entry->SuccessorCount()); CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(schedule.end(), entry->SuccessorAt(0)); CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
} }
...@@ -120,8 +120,8 @@ TEST(TestScheduleAddThrow) { ...@@ -120,8 +120,8 @@ TEST(TestScheduleAddThrow) {
BasicBlock* entry = schedule.start(); BasicBlock* entry = schedule.start();
schedule.AddThrow(entry, n0); schedule.AddThrow(entry, n0);
CHECK_EQ(0, entry->PredecessorCount()); CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
CHECK_EQ(1, entry->SuccessorCount()); CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
CHECK_EQ(schedule.end(), entry->SuccessorAt(0)); CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
} }
......
...@@ -44,25 +44,25 @@ static TestLoop* CreateLoop(Schedule* schedule, int count) { ...@@ -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) { 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++) { for (int i = 0; i < static_cast<int>(order->size()); i++) {
CHECK(order->at(i)->rpo_number_ == i); CHECK(order->at(i)->rpo_number() == i);
if (!loops_allowed) CHECK_LT(order->at(i)->loop_end_, 0); if (!loops_allowed) CHECK_LT(order->at(i)->loop_end(), 0);
} }
} }
static void CheckLoopContains(BasicBlock** blocks, int body_size) { static void CheckLoopContains(BasicBlock** blocks, int body_size) {
BasicBlock* header = blocks[0]; BasicBlock* header = blocks[0];
CHECK_GT(header->loop_end_, 0); CHECK_GT(header->loop_end(), 0);
CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_)); CHECK_EQ(body_size, (header->loop_end() - header->rpo_number()));
for (int i = 0; i < body_size; i++) { for (int i = 0; i < body_size; i++) {
int num = blocks[i]->rpo_number_; int num = blocks[i]->rpo_number();
CHECK(num >= header->rpo_number_ && num < header->loop_end_); CHECK(num >= header->rpo_number() && num < header->loop_end());
CHECK(header->LoopContains(blocks[i])); 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) { ...@@ -76,7 +76,7 @@ static int GetScheduledNodeCount(Schedule* schedule) {
++j) { ++j) {
++node_count; ++node_count;
} }
BasicBlock::Control control = block->control_; BasicBlock::Control control = block->control();
if (control != BasicBlock::kNone) { if (control != BasicBlock::kNone) {
++node_count; ++node_count;
} }
...@@ -140,12 +140,10 @@ TEST(RPOLine) { ...@@ -140,12 +140,10 @@ TEST(RPOLine) {
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
CheckRPONumbers(order, 1 + i, false); CheckRPONumbers(order, 1 + i, false);
Schedule::BasicBlocks blocks(schedule.all_blocks()); for (size_t i = 0; i < schedule.BasicBlockCount(); i++) {
for (Schedule::BasicBlocks::iterator iter = blocks.begin(); BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i));
iter != blocks.end(); ++iter) { if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) {
BasicBlock* block = *iter; CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number());
if (block->rpo_number_ >= 0 && block->SuccessorCount() == 1) {
CHECK(block->rpo_number_ + 1 == block->SuccessorAt(0)->rpo_number_);
} }
} }
} }
...@@ -215,10 +213,10 @@ TEST(RPODiamond) { ...@@ -215,10 +213,10 @@ TEST(RPODiamond) {
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
CheckRPONumbers(order, 4, false); CheckRPONumbers(order, 4, false);
CHECK_EQ(0, A->rpo_number_); CHECK_EQ(0, A->rpo_number());
CHECK((B->rpo_number_ == 1 && C->rpo_number_ == 2) || CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) ||
(B->rpo_number_ == 2 && C->rpo_number_ == 1)); (B->rpo_number() == 2 && C->rpo_number() == 1));
CHECK_EQ(3, D->rpo_number_); CHECK_EQ(3, D->rpo_number());
} }
...@@ -392,7 +390,8 @@ TEST(RPOLoopFollow1) { ...@@ -392,7 +390,8 @@ TEST(RPOLoopFollow1) {
CheckLoopContains(loop1->nodes, loop1->count); 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(loop1->nodes, loop1->count);
CheckLoopContains(loop2->nodes, loop2->count); CheckLoopContains(loop2->nodes, loop2->count);
} }
...@@ -418,7 +417,8 @@ TEST(RPOLoopFollow2) { ...@@ -418,7 +417,8 @@ TEST(RPOLoopFollow2) {
CheckLoopContains(loop1->nodes, loop1->count); 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(loop1->nodes, loop1->count);
CheckLoopContains(loop2->nodes, loop2->count); CheckLoopContains(loop2->nodes, loop2->count);
} }
...@@ -441,7 +441,8 @@ TEST(RPOLoopFollowN) { ...@@ -441,7 +441,8 @@ TEST(RPOLoopFollowN) {
BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule); BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
CheckLoopContains(loop1->nodes, loop1->count); 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(loop1->nodes, loop1->count);
CheckLoopContains(loop2->nodes, loop2->count); CheckLoopContains(loop2->nodes, loop2->count);
} }
...@@ -472,7 +473,8 @@ TEST(RPONestedLoopFollow1) { ...@@ -472,7 +473,8 @@ TEST(RPONestedLoopFollow1) {
CheckLoopContains(loop1->nodes, loop1->count); 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(loop1->nodes, loop1->count);
CheckLoopContains(loop2->nodes, loop2->count); CheckLoopContains(loop2->nodes, loop2->count);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment