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() {}
}
-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;
}
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:
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_;
// 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()) {
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(
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]);
}
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) {
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());
// 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.
#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"
InstructionOperand* Label(BasicBlock* block) {
// TODO(bmeurer): We misuse ImmediateOperand here.
- return TempImmediate(block->id());
+ return TempImmediate(block->id().ToInt());
}
protected:
// 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);
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();
}
// 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;
}
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);
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;
#include "src/compiler/instruction.h"
#include "src/compiler/common-operator.h"
+#include "src/compiler/generic-node-inl.h"
namespace v8 {
namespace internal {
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);
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);
}
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";
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";
}
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);
#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 {
#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"
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());
}
}
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));
}
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);
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) {
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;
}
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);
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()) {
}
// 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);
}
}
// 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);
}
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();
}
+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();
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();
}
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();
#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"
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 {
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);
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(); }
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;
// 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);
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);
}
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());
}
}
};
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;
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;
}
++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());
}
}
}
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;
}
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;
}
}
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.
// 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;
}
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
struct SpecialRPOStackFrame {
BasicBlock* block;
- int index;
+ size_t index;
};
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);
}
}
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;
// 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));
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;
}
// 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;
}
}
#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";
}
}
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;
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++;
}
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);
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--;
}
}
&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
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;
}
// 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()) {
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);
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;
// 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;
} 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--;
}
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;
--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());
}
}
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();
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;
}
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,
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()));
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());
}
}
}
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());
}
}
}
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);
}
}
// 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"
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)));
}
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()));
}
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()));
}
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));
}
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));
}
}
-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);
}
}
++j) {
++node_count;
}
- BasicBlock::Control control = block->control_;
+ BasicBlock::Control control = block->control();
if (control != BasicBlock::kNone) {
++node_count;
}
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());
}
}
}
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());
}
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);
}
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);
}
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);
}
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);