}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
}
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
}
Label* InputLabel(size_t index) { return ToLabel(instr_->InputAt(index)); }
- BasicBlock::RpoNumber InputRpo(size_t index) {
+ RpoNumber InputRpo(size_t index) {
return ToRpoNumber(instr_->InputAt(index));
}
return gen_->GetLabel(ToRpoNumber(op));
}
- BasicBlock::RpoNumber ToRpoNumber(InstructionOperand* op) {
+ RpoNumber ToRpoNumber(InstructionOperand* op) {
return ToConstant(op).ToRpoNumber();
}
code_(code),
info_(info),
labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
- current_block_(BasicBlock::RpoNumber::Invalid()),
+ current_block_(RpoNumber::Invalid()),
current_source_position_(SourcePosition::Invalid()),
masm_(info->isolate(), NULL, 0),
resolver_(this),
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->id().ToInt());
+ SNPrintF(buffer, "-- B%d start --", block->rpo_number().ToInt());
masm()->RecordComment(buffer.start());
}
masm()->bind(GetLabel(current_block_));
}
-bool CodeGenerator::IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const {
+bool CodeGenerator::IsNextInAssemblyOrder(RpoNumber block) const {
return code()->InstructionBlockAt(current_block_)->ao_number().IsNext(
code()->InstructionBlockAt(block)->ao_number());
}
if (mode == kFlags_branch) {
// Assemble a branch after this instruction.
InstructionOperandConverter i(this, instr);
- BasicBlock::RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
- BasicBlock::RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
+ RpoNumber true_rpo = i.InputRpo(instr->InputCount() - 2);
+ RpoNumber false_rpo = i.InputRpo(instr->InputCount() - 1);
if (true_rpo == false_rpo) {
// redundant branch.
if (flags & CallDescriptor::kHasExceptionHandler) {
InstructionOperandConverter i(this, instr);
- BasicBlock::RpoNumber handler_rpo =
+ RpoNumber handler_rpo =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
handlers_.push_back({GetLabel(handler_rpo), masm()->pc_offset()});
}
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
- UNIMPLEMENTED();
-}
+void CodeGenerator::AssembleArchJump(RpoNumber target) { UNIMPLEMENTED(); }
void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
Isolate* isolate() const { return info_->isolate(); }
Linkage* linkage() const { return linkage_; }
- Label* GetLabel(BasicBlock::RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
+ Label* GetLabel(RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
private:
MacroAssembler* masm() { return &masm_; }
// Checks if {block} will appear directly after {current_block_} when
// assembling code, in which case, a fall-through can be used.
- bool IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const;
+ bool IsNextInAssemblyOrder(RpoNumber block) const;
// Record a safepoint with the given pointer map.
void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
// ===========================================================================
void AssembleArchInstruction(Instruction* instr);
- void AssembleArchJump(BasicBlock::RpoNumber target);
+ void AssembleArchJump(RpoNumber target);
void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
void AssembleArchLookupSwitch(Instruction* instr);
InstructionSequence* const code_;
CompilationInfo* const info_;
Label* const labels_;
- BasicBlock::RpoNumber current_block_;
+ RpoNumber current_block_;
SourcePosition current_source_position_;
MacroAssembler masm_;
GapResolver resolver_;
void PrintStringProperty(const char* name, const char* value);
void PrintLongProperty(const char* name, int64_t value);
void PrintIntProperty(const char* name, int value);
- void PrintBlockProperty(const char* name, BasicBlock::Id block_id);
+ void PrintBlockProperty(const char* name, int rpo_number);
void PrintNodeId(Node* n);
void PrintNode(Node* n);
void PrintInputs(Node* n);
}
-void GraphC1Visualizer::PrintBlockProperty(const char* name,
- BasicBlock::Id block_id) {
+void GraphC1Visualizer::PrintBlockProperty(const char* name, int rpo_number) {
PrintIndent();
- os_ << name << " \"B" << block_id << "\"\n";
+ os_ << name << " \"B" << rpo_number << "\"\n";
}
for (size_t i = 0; i < rpo->size(); i++) {
BasicBlock* current = (*rpo)[i];
Tag block_tag(this, "block");
- PrintBlockProperty("name", current->id());
+ PrintBlockProperty("name", current->rpo_number());
PrintIntProperty("from_bci", -1);
PrintIntProperty("to_bci", -1);
PrintIndent();
os_ << "predecessors";
for (BasicBlock* predecessor : current->predecessors()) {
- os_ << " \"B" << predecessor->id() << "\"";
+ os_ << " \"B" << predecessor->rpo_number() << "\"";
}
os_ << "\n";
PrintIndent();
os_ << "successors";
for (BasicBlock* successor : current->successors()) {
- os_ << " \"B" << successor->id() << "\"";
+ os_ << " \"B" << successor->rpo_number() << "\"";
}
os_ << "\n";
os_ << "flags\n";
if (current->dominator() != NULL) {
- PrintBlockProperty("dominator", current->dominator()->id());
+ PrintBlockProperty("dominator", current->dominator()->rpo_number());
}
PrintIntProperty("loop_depth", current->loop_depth());
const InstructionBlock* instruction_block =
- instructions->InstructionBlockAt(current->GetRpoNumber());
+ instructions->InstructionBlockAt(
+ RpoNumber::FromInt(current->rpo_number()));
if (instruction_block->code_start() >= 0) {
int first_index = instruction_block->first_instruction_index();
int last_index = instruction_block->last_instruction_index();
if (current->control_input() != NULL) {
PrintNode(current->control_input());
} else {
- os_ << -1 - current->id().ToInt() << " Goto";
+ os_ << -1 - current->rpo_number() << " Goto";
}
os_ << " ->";
for (BasicBlock* successor : current->successors()) {
- os_ << " B" << successor->id();
+ os_ << " B" << successor->rpo_number();
}
if (FLAG_trace_turbo_types && current->control_input() != NULL) {
os_ << " ";
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
}
#include "src/compiler/instruction.h"
#include "src/compiler/instruction-selector.h"
#include "src/compiler/linkage.h"
+#include "src/compiler/schedule.h"
#include "src/macro-assembler.h"
namespace v8 {
}
InstructionOperand Label(BasicBlock* block) {
- int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
+ int index = sequence()->AddImmediate(
+ Constant(RpoNumber::FromInt(block->rpo_number())));
return ImmediateOperand(index);
}
#include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/pipeline.h"
+#include "src/compiler/schedule.h"
namespace v8 {
namespace internal {
// Schedule the selected instructions.
for (auto const block : *blocks) {
InstructionBlock* instruction_block =
- sequence()->InstructionBlockAt(block->GetRpoNumber());
+ sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
size_t end = instruction_block->code_end();
size_t start = instruction_block->code_start();
DCHECK_LE(end, start);
- sequence()->StartBlock(block->GetRpoNumber());
+ sequence()->StartBlock(RpoNumber::FromInt(block->rpo_number()));
while (start-- > end) {
sequence()->AddInstruction(instructions_[start]);
}
- sequence()->EndBlock(block->GetRpoNumber());
+ sequence()->EndBlock(RpoNumber::FromInt(block->rpo_number()));
}
}
// We're done with the block.
InstructionBlock* instruction_block =
- sequence()->InstructionBlockAt(block->GetRpoNumber());
+ sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number()));
instruction_block->set_code_start(static_cast<int>(instructions_.size()));
instruction_block->set_code_end(current_block_end);
PhiInstruction* phi = new (instruction_zone())
PhiInstruction(instruction_zone(), GetVirtualRegister(node),
static_cast<size_t>(input_count));
- sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi);
+ sequence()
+ ->InstructionBlockAt(RpoNumber::FromInt(current_block_->rpo_number()))
+ ->AddPhi(phi);
for (int i = 0; i < input_count; ++i) {
Node* const input = node->InputAt(i);
MarkAsUsed(input);
namespace compiler {
// Forward declarations.
+class BasicBlock;
struct CallBuffer; // TODO(bmeurer): Remove this.
class FlagsContinuation;
class Linkage;
-
typedef ZoneVector<InstructionOperand> InstructionOperandVector;
#include "src/compiler/common-operator.h"
#include "src/compiler/graph.h"
#include "src/compiler/instruction.h"
+#include "src/compiler/schedule.h"
namespace v8 {
namespace internal {
}
-InstructionBlock::InstructionBlock(Zone* zone, BasicBlock::Id id,
- BasicBlock::RpoNumber rpo_number,
- BasicBlock::RpoNumber loop_header,
- BasicBlock::RpoNumber loop_end,
+InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
+ RpoNumber loop_header, RpoNumber loop_end,
bool deferred)
: successors_(zone),
predecessors_(zone),
phis_(zone),
- id_(id),
ao_number_(rpo_number),
rpo_number_(rpo_number),
loop_header_(loop_header),
deferred_(deferred) {}
-size_t InstructionBlock::PredecessorIndexOf(
- BasicBlock::RpoNumber rpo_number) const {
+size_t InstructionBlock::PredecessorIndexOf(RpoNumber rpo_number) const {
size_t j = 0;
for (InstructionBlock::Predecessors::const_iterator i = predecessors_.begin();
i != predecessors_.end(); ++i, ++j) {
}
-static BasicBlock::RpoNumber GetRpo(BasicBlock* block) {
- if (block == NULL) return BasicBlock::RpoNumber::Invalid();
- return block->GetRpoNumber();
+static RpoNumber GetRpo(const BasicBlock* block) {
+ if (block == NULL) return RpoNumber::Invalid();
+ return RpoNumber::FromInt(block->rpo_number());
}
-static BasicBlock::RpoNumber GetLoopEndRpo(const BasicBlock* block) {
- if (!block->IsLoopHeader()) return BasicBlock::RpoNumber::Invalid();
- return block->loop_end()->GetRpoNumber();
+static RpoNumber GetLoopEndRpo(const BasicBlock* block) {
+ if (!block->IsLoopHeader()) return RpoNumber::Invalid();
+ return RpoNumber::FromInt(block->loop_end()->rpo_number());
}
static InstructionBlock* InstructionBlockFor(Zone* zone,
const BasicBlock* block) {
- InstructionBlock* instr_block = new (zone) InstructionBlock(
- zone, block->id(), block->GetRpoNumber(), GetRpo(block->loop_header()),
- GetLoopEndRpo(block), block->deferred());
+ InstructionBlock* instr_block = new (zone)
+ InstructionBlock(zone, GetRpo(block), GetRpo(block->loop_header()),
+ GetLoopEndRpo(block), block->deferred());
// Map successors and precessors
instr_block->successors().reserve(block->SuccessorCount());
for (BasicBlock* successor : block->successors()) {
- instr_block->successors().push_back(successor->GetRpoNumber());
+ instr_block->successors().push_back(GetRpo(successor));
}
instr_block->predecessors().reserve(block->PredecessorCount());
for (BasicBlock* predecessor : block->predecessors()) {
- instr_block->predecessors().push_back(predecessor->GetRpoNumber());
+ instr_block->predecessors().push_back(GetRpo(predecessor));
}
return instr_block;
}
for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin();
it != schedule->rpo_order()->end(); ++it, ++rpo_number) {
DCHECK(!(*blocks)[rpo_number]);
- DCHECK((*it)->GetRpoNumber().ToSize() == rpo_number);
+ DCHECK(GetRpo(*it).ToSize() == rpo_number);
(*blocks)[rpo_number] = InstructionBlockFor(zone, *it);
}
ComputeAssemblyOrder(blocks);
int ao = 0;
for (auto const block : *blocks) {
if (!block->IsDeferred()) {
- block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+ block->set_ao_number(RpoNumber::FromInt(ao++));
}
}
for (auto const block : *blocks) {
if (block->IsDeferred()) {
- block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+ block->set_ao_number(RpoNumber::FromInt(ao++));
}
}
}
}
-GapInstruction* InstructionSequence::GetBlockStart(
- BasicBlock::RpoNumber rpo) const {
+GapInstruction* InstructionSequence::GetBlockStart(RpoNumber rpo) const {
const InstructionBlock* block = InstructionBlockAt(rpo);
return GapInstruction::cast(InstructionAt(block->code_start()));
}
-void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
+void InstructionSequence::StartBlock(RpoNumber rpo) {
DCHECK(block_starts_.size() == rpo.ToSize());
InstructionBlock* block = InstructionBlockAt(rpo);
int code_start = static_cast<int>(instructions_.size());
}
-void InstructionSequence::EndBlock(BasicBlock::RpoNumber rpo) {
+void InstructionSequence::EndBlock(RpoNumber rpo) {
int end = static_cast<int>(instructions_.size());
InstructionBlock* block = InstructionBlockAt(rpo);
if (block->code_start() == end) { // Empty block. Insert a nop.
}
+std::ostream& operator<<(std::ostream& os, const RpoNumber& rpo) {
+ return os << rpo.ToSize();
+}
+
+
std::ostream& operator<<(std::ostream& os,
const PrintableInstructionSequence& printable) {
const InstructionSequence& code = *printable.sequence_;
os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n";
}
for (int i = 0; i < code.InstructionBlockCount(); i++) {
- BasicBlock::RpoNumber rpo = BasicBlock::RpoNumber::FromInt(i);
+ RpoNumber rpo = RpoNumber::FromInt(i);
const InstructionBlock* block = code.InstructionBlockAt(rpo);
CHECK(block->rpo_number() == rpo);
- os << "RPO#" << block->rpo_number();
+ os << "B" << block->rpo_number();
os << ": AO#" << block->ao_number();
- os << ": B" << block->id();
if (block->IsDeferred()) os << " (deferred)";
if (block->IsLoopHeader()) {
os << " loop blocks: [" << block->rpo_number() << ", "
<< block->code_end() << ")\n predecessors:";
for (auto pred : block->predecessors()) {
- const InstructionBlock* pred_block = code.InstructionBlockAt(pred);
- os << " B" << pred_block->id();
+ os << " B" << pred.ToInt();
}
os << "\n";
}
for (auto succ : block->successors()) {
- const InstructionBlock* succ_block = code.InstructionBlockAt(succ);
- os << " B" << succ_block->id();
+ os << " B" << succ.ToInt();
}
os << "\n";
}
#include "src/compiler/instruction-codes.h"
#include "src/compiler/opcodes.h"
#include "src/compiler/register-configuration.h"
-#include "src/compiler/schedule.h"
#include "src/compiler/source-position.h"
#include "src/zone-allocator.h"
namespace internal {
namespace compiler {
+class Schedule;
+
// A couple of reserved opcodes are used for internal use.
const InstructionCode kGapInstruction = -1;
const InstructionCode kSourcePositionInstruction = -2;
};
+class RpoNumber FINAL {
+ public:
+ static const int kInvalidRpoNumber = -1;
+ int ToInt() const {
+ DCHECK(IsValid());
+ return index_;
+ }
+ size_t ToSize() const {
+ DCHECK(IsValid());
+ return static_cast<size_t>(index_);
+ }
+ bool IsValid() const { return index_ >= 0; }
+ static RpoNumber FromInt(int index) { return RpoNumber(index); }
+ static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
+
+ bool IsNext(const RpoNumber other) const {
+ DCHECK(IsValid());
+ return other.index_ == this->index_ + 1;
+ }
+
+ bool operator==(RpoNumber other) const {
+ return this->index_ == other.index_;
+ }
+
+ private:
+ explicit RpoNumber(int32_t index) : index_(index) {}
+ int32_t index_;
+};
+
+
+std::ostream& operator<<(std::ostream&, const RpoNumber&);
+
+
class Constant FINAL {
public:
enum Type {
: type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {}
explicit Constant(Handle<HeapObject> obj)
: type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
- explicit Constant(BasicBlock::RpoNumber rpo)
- : type_(kRpoNumber), value_(rpo.ToInt()) {}
+ explicit Constant(RpoNumber rpo) : type_(kRpoNumber), value_(rpo.ToInt()) {}
Type type() const { return type_; }
return bit_cast<ExternalReference>(static_cast<intptr_t>(value_));
}
- BasicBlock::RpoNumber ToRpoNumber() const {
+ RpoNumber ToRpoNumber() const {
DCHECK_EQ(kRpoNumber, type());
- return BasicBlock::RpoNumber::FromInt(static_cast<int>(value_));
+ return RpoNumber::FromInt(static_cast<int>(value_));
}
Handle<HeapObject> ToHeapObject() const {
// Analogue of BasicBlock for Instructions instead of Nodes.
class InstructionBlock FINAL : public ZoneObject {
public:
- InstructionBlock(Zone* zone, BasicBlock::Id id,
- BasicBlock::RpoNumber rpo_number,
- BasicBlock::RpoNumber loop_header,
- BasicBlock::RpoNumber loop_end, bool deferred);
+ InstructionBlock(Zone* zone, RpoNumber rpo_number, RpoNumber loop_header,
+ RpoNumber loop_end, bool deferred);
// Instruction indexes (used by the register allocator).
int first_instruction_index() const {
bool IsDeferred() const { return deferred_; }
- BasicBlock::Id id() const { return id_; }
- BasicBlock::RpoNumber ao_number() const { return ao_number_; }
- BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
- BasicBlock::RpoNumber loop_header() const { return loop_header_; }
- BasicBlock::RpoNumber loop_end() const {
+ RpoNumber ao_number() const { return ao_number_; }
+ RpoNumber rpo_number() const { return rpo_number_; }
+ RpoNumber loop_header() const { return loop_header_; }
+ RpoNumber loop_end() const {
DCHECK(IsLoopHeader());
return loop_end_;
}
inline bool IsLoopHeader() const { return loop_end_.IsValid(); }
- typedef ZoneVector<BasicBlock::RpoNumber> Predecessors;
+ typedef ZoneVector<RpoNumber> Predecessors;
Predecessors& predecessors() { return predecessors_; }
const Predecessors& predecessors() const { return predecessors_; }
size_t PredecessorCount() const { return predecessors_.size(); }
- size_t PredecessorIndexOf(BasicBlock::RpoNumber rpo_number) const;
+ size_t PredecessorIndexOf(RpoNumber rpo_number) const;
- typedef ZoneVector<BasicBlock::RpoNumber> Successors;
+ typedef ZoneVector<RpoNumber> Successors;
Successors& successors() { return successors_; }
const Successors& successors() const { return successors_; }
size_t SuccessorCount() const { return successors_.size(); }
const PhiInstructions& phis() const { return phis_; }
void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); }
- void set_ao_number(BasicBlock::RpoNumber ao_number) {
- ao_number_ = ao_number;
- }
+ void set_ao_number(RpoNumber ao_number) { ao_number_ = ao_number; }
private:
Successors successors_;
Predecessors predecessors_;
PhiInstructions phis_;
- const BasicBlock::Id id_;
- BasicBlock::RpoNumber ao_number_; // Assembly order number.
- const BasicBlock::RpoNumber rpo_number_;
- const BasicBlock::RpoNumber loop_header_;
- const BasicBlock::RpoNumber loop_end_;
+ RpoNumber ao_number_; // Assembly order number.
+ const RpoNumber rpo_number_;
+ const RpoNumber loop_header_;
+ const RpoNumber loop_end_;
int32_t code_start_; // start index of arch-specific code.
int32_t code_end_; // end index of arch-specific code.
const bool deferred_; // Block contains deferred code.
return static_cast<int>(instruction_blocks_->size());
}
- InstructionBlock* InstructionBlockAt(BasicBlock::RpoNumber rpo_number) {
+ InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) {
return instruction_blocks_->at(rpo_number.ToSize());
}
->last_instruction_index();
}
- const InstructionBlock* InstructionBlockAt(
- BasicBlock::RpoNumber rpo_number) const {
+ const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const {
return instruction_blocks_->at(rpo_number.ToSize());
}
void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
- GapInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const;
+ GapInstruction* GetBlockStart(RpoNumber rpo) const;
typedef InstructionDeque::const_iterator const_iterator;
const_iterator begin() const { return instructions_.begin(); }
// Used by the instruction selector while adding instructions.
int AddInstruction(Instruction* instr);
- void StartBlock(BasicBlock::RpoNumber rpo);
- void EndBlock(BasicBlock::RpoNumber rpo);
+ void StartBlock(RpoNumber rpo);
+ void EndBlock(RpoNumber rpo);
int AddConstant(int virtual_register, Constant constant) {
// TODO(titzer): allow RPO numbers as constants?
FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id);
int GetFrameStateDescriptorCount();
- BasicBlock::RpoNumber InputRpo(Instruction* instr, size_t index) {
+ RpoNumber InputRpo(Instruction* instr, size_t index) {
InstructionOperand* operand = instr->InputAt(index);
Constant constant = operand->IsImmediate() ? GetImmediate(operand->index())
: GetConstant(operand->index());
namespace internal {
namespace compiler {
-typedef BasicBlock::RpoNumber RpoNumber;
-
#define TRACE(x) \
if (FLAG_trace_turbo_jt) PrintF x
while (!state.stack.empty()) {
InstructionBlock* block = code->InstructionBlockAt(state.stack.top());
// Process the instructions in a block up to a non-empty instruction.
- TRACE(("jt [%d] B%d RPO%d\n", static_cast<int>(stack.size()),
- block->id().ToInt(), block->rpo_number().ToInt()));
+ TRACE(("jt [%d] B%d\n", static_cast<int>(stack.size()),
+ block->rpo_number().ToInt()));
bool fallthru = true;
RpoNumber fw = block->rpo_number();
for (int i = block->code_start(); i < block->code_end(); ++i) {
if (FLAG_trace_turbo_jt) {
for (int i = 0; i < static_cast<int>(result.size()); i++) {
- TRACE(("RPO%d B%d ", i,
- code->InstructionBlockAt(RpoNumber::FromInt(i))->id().ToInt()));
+ TRACE(("B%d ", i));
int to = result[i].ToInt();
if (i != to) {
- TRACE(("-> B%d\n",
- code->InstructionBlockAt(RpoNumber::FromInt(to))->id().ToInt()));
+ TRACE(("-> B%d\n", to));
} else {
TRACE(("\n"));
}
public:
// Compute the forwarding map of basic blocks to their ultimate destination.
// Returns {true} if there is at least one block that is forwarded.
- static bool ComputeForwarding(Zone* local_zone,
- ZoneVector<BasicBlock::RpoNumber>& result,
+ static bool ComputeForwarding(Zone* local_zone, ZoneVector<RpoNumber>& result,
InstructionSequence* code);
// Rewrite the instructions to forward jumps and branches.
// May also negate some branches.
- static void ApplyForwarding(ZoneVector<BasicBlock::RpoNumber>& forwarding,
+ static void ApplyForwarding(ZoneVector<RpoNumber>& forwarding,
InstructionSequence* code);
};
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
}
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
}
static const char* phase_name() { return "jump threading"; }
void Run(PipelineData* data, Zone* temp_zone) {
- ZoneVector<BasicBlock::RpoNumber> result(temp_zone);
+ ZoneVector<RpoNumber> result(temp_zone);
if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) {
JumpThreading::ApplyForwarding(result, data->sequence());
}
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
}
namespace {
-typedef BasicBlock::RpoNumber Rpo;
+typedef RpoNumber Rpo;
static const int kInvalidVreg = InstructionOperand::kInvalidVirtualRegister;
// Process the blocks in reverse order.
for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
--block_id) {
- auto block =
- code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id));
+ auto block = code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
auto live = ComputeLiveOut(block);
// Initially consider all live_out values live for the entire block. We
// will shorten these intervals if necessary.
}
-std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo) {
- return os << rpo.ToSize();
-}
-
-
Schedule::Schedule(Zone* zone, size_t node_count_hint)
: zone_(zone),
all_blocks_(zone),
std::ostream& operator<<(std::ostream& os, const Schedule& s) {
for (BasicBlock* block : *s.rpo_order()) {
- os << "--- BLOCK B" << block->id();
+ os << "--- BLOCK B" << block->rpo_number();
if (block->deferred()) os << " (deferred)";
if (block->PredecessorCount() != 0) os << " <- ";
bool comma = false;
for (BasicBlock const* predecessor : block->predecessors()) {
if (comma) os << ", ";
comma = true;
- os << "B" << predecessor->id();
+ os << "B" << predecessor->rpo_number();
}
os << " ---\n";
for (Node* node : *block) {
for (BasicBlock const* successor : block->successors()) {
if (comma) os << ", ";
comma = true;
- os << "B" << successor->id();
+ os << "B" << successor->rpo_number();
}
os << "\n";
}
size_t index_;
};
- static const int kInvalidRpoNumber = -1;
- class RpoNumber FINAL {
- public:
- int ToInt() const {
- DCHECK(IsValid());
- return index_;
- }
- size_t ToSize() const {
- DCHECK(IsValid());
- return static_cast<size_t>(index_);
- }
- bool IsValid() const { return index_ >= 0; }
- static RpoNumber FromInt(int index) { return RpoNumber(index); }
- static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
-
- bool IsNext(const RpoNumber other) const {
- DCHECK(IsValid());
- return other.index_ == this->index_ + 1;
- }
-
- bool operator==(RpoNumber other) const {
- return this->index_ == other.index_;
- }
-
- private:
- explicit RpoNumber(int32_t index) : index_(index) {}
- int32_t index_;
- };
-
BasicBlock(Zone* zone, Id id);
Id id() const { return id_; }
int32_t loop_number() const { return loop_number_; }
void set_loop_number(int32_t loop_number) { loop_number_ = loop_number; }
- RpoNumber GetRpoNumber() const { return RpoNumber::FromInt(rpo_number_); }
int32_t rpo_number() const { return rpo_number_; }
void set_rpo_number(int32_t rpo_number);
std::ostream& operator<<(std::ostream&, const BasicBlock::Control&);
std::ostream& operator<<(std::ostream&, const BasicBlock::Id&);
-std::ostream& operator<<(std::ostream&, const BasicBlock::RpoNumber&);
// A schedule represents the result of assigning nodes to basic blocks
use_pos)) {
V8_Fatal(__FILE__, __LINE__,
"Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
- node->id(), node->op()->mnemonic(), block->id().ToInt(), j,
+ node->id(), node->op()->mnemonic(), block->rpo_number(), j,
input->id(), input->op()->mnemonic());
}
}
if (!Dominates(schedule, ctl, node)) {
V8_Fatal(__FILE__, __LINE__,
"Node #%d:%s in B%d is not dominated by control input #%d:%s",
- node->id(), node->op()->mnemonic(), block->id(), ctl->id(),
- ctl->op()->mnemonic());
+ node->id(), node->op()->mnemonic(), block->rpo_number(),
+ ctl->id(), ctl->op()->mnemonic());
}
}
}
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().ToInt(), idom->id().ToInt());
+ block->rpo_number(), idom->rpo_number());
}
for (size_t s = 0; s < block->SuccessorCount(); s++) {
BasicBlock* succ = block->SuccessorAt(s);
!dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
V8_Fatal(__FILE__, __LINE__,
"Block B%d is not immediately dominated by B%d",
- block->id().ToInt(), idom->id().ToInt());
+ block->rpo_number(), idom->rpo_number());
}
}
}
}
-void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+void CodeGenerator::AssembleArchJump(RpoNumber target) {
if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
}
return UnallocatedOperand(UnallocatedOperand::ANY, vreg).Copy(zone());
}
+ RpoNumber RpoFor(BasicBlock* block) {
+ return RpoNumber::FromInt(block->rpo_number());
+ }
+
InstructionBlock* BlockAt(BasicBlock* block) {
- return code->InstructionBlockAt(block->GetRpoNumber());
+ return code->InstructionBlockAt(RpoFor(block));
}
BasicBlock* GetBasicBlock(int instruction_index) {
const InstructionBlock* block =
for (auto block : *blocks) {
CHECK_EQ(block->rpo_number(), R.BlockAt(block)->rpo_number().ToInt());
- CHECK_EQ(block->id().ToInt(), R.BlockAt(block)->id().ToInt());
CHECK(!block->loop_end());
}
}
R.allocCode();
- R.code->StartBlock(b0->GetRpoNumber());
+ R.code->StartBlock(R.RpoFor(b0));
int i0 = R.NewInstr();
int i1 = R.NewInstr();
- R.code->EndBlock(b0->GetRpoNumber());
- R.code->StartBlock(b1->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b0));
+ R.code->StartBlock(R.RpoFor(b1));
int i2 = R.NewInstr();
int i3 = R.NewInstr();
int i4 = R.NewInstr();
int i5 = R.NewInstr();
- R.code->EndBlock(b1->GetRpoNumber());
- R.code->StartBlock(b2->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b1));
+ R.code->StartBlock(R.RpoFor(b2));
int i6 = R.NewInstr();
int i7 = R.NewInstr();
int i8 = R.NewInstr();
- R.code->EndBlock(b2->GetRpoNumber());
- R.code->StartBlock(b3->GetRpoNumber());
- R.code->EndBlock(b3->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b2));
+ R.code->StartBlock(R.RpoFor(b3));
+ R.code->EndBlock(R.RpoFor(b3));
CHECK_EQ(b0, R.GetBasicBlock(i0));
CHECK_EQ(b0, R.GetBasicBlock(i1));
R.allocCode();
TestInstr* i0 = TestInstr::New(R.zone(), 100);
TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
- R.code->StartBlock(b0->GetRpoNumber());
+ R.code->StartBlock(R.RpoFor(b0));
R.code->AddInstruction(i0);
R.code->AddInstruction(g);
- R.code->EndBlock(b0->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b0));
CHECK(R.code->instructions().size() == 4);
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
R.allocCode();
TestInstr* i0 = TestInstr::New(R.zone(), 100);
TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
- R.code->StartBlock(b0->GetRpoNumber());
+ R.code->StartBlock(R.RpoFor(b0));
R.code->AddInstruction(i0);
R.code->AddInstruction(g);
- R.code->EndBlock(b0->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b0));
TestInstr* i1 = TestInstr::New(R.zone(), 102);
TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
- R.code->StartBlock(b1->GetRpoNumber());
+ R.code->StartBlock(R.RpoFor(b1));
R.code->AddInstruction(i1);
R.code->AddInstruction(g1);
- R.code->EndBlock(b1->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b1));
CHECK(R.code->instructions().size() == 8);
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
R.allocCode();
TestInstr* i0 = TestInstr::New(R.zone(), 100);
TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
- R.code->StartBlock(b0->GetRpoNumber());
+ R.code->StartBlock(R.RpoFor(b0));
R.code->AddInstruction(i0);
R.code->AddInstruction(g);
- R.code->EndBlock(b0->GetRpoNumber());
+ R.code->EndBlock(R.RpoFor(b0));
CHECK(R.code->instructions().size() == 4);
for (size_t i = 0; i < R.code->instructions().size(); ++i) {
namespace internal {
namespace compiler {
-typedef BasicBlock::RpoNumber RpoNumber;
-
class TestCode : public HandleAndZoneScope {
public:
TestCode()
}
void Start(bool deferred = false) {
if (current_ == NULL) {
- current_ = new (main_zone()) InstructionBlock(
- main_zone(), BasicBlock::Id::FromInt(rpo_number_.ToInt()),
- rpo_number_, RpoNumber::Invalid(), RpoNumber::Invalid(), deferred);
+ current_ = new (main_zone())
+ InstructionBlock(main_zone(), rpo_number_, RpoNumber::Invalid(),
+ RpoNumber::Invalid(), deferred);
blocks_.push_back(current_);
sequence_.StartBlock(rpo_number_);
}
#include "test/unittests/compiler/instruction-selector-unittest.h"
#include "src/compiler/graph.h"
+#include "src/compiler/schedule.h"
#include "src/flags.h"
#include "test/unittests/compiler/compiler-test-utils.h"
InstructionBlock* InstructionSequenceTest::NewBlock() {
CHECK(current_block_ == nullptr);
- auto block_id = BasicBlock::Id::FromSize(instruction_blocks_.size());
- Rpo rpo = Rpo::FromInt(block_id.ToInt());
+ Rpo rpo = Rpo::FromInt(static_cast<int>(instruction_blocks_.size()));
Rpo loop_header = Rpo::Invalid();
Rpo loop_end = Rpo::Invalid();
if (!loop_blocks_.empty()) {
auto& loop_data = loop_blocks_.back();
// This is a loop header.
if (!loop_data.loop_header_.IsValid()) {
- loop_end = Rpo::FromInt(block_id.ToInt() + loop_data.expected_blocks_);
+ loop_end = Rpo::FromInt(rpo.ToInt() + loop_data.expected_blocks_);
loop_data.expected_blocks_--;
loop_data.loop_header_ = rpo;
} else {
}
}
// Construct instruction block.
- auto instruction_block = new (zone())
- InstructionBlock(zone(), block_id, rpo, loop_header, loop_end, false);
+ auto instruction_block =
+ new (zone()) InstructionBlock(zone(), rpo, loop_header, loop_end, false);
instruction_blocks_.push_back(instruction_block);
current_block_ = instruction_block;
sequence()->StartBlock(rpo);
static const int kDefaultNRegs = 4;
static const int kNoValue = kMinInt;
- typedef BasicBlock::RpoNumber Rpo;
+ typedef RpoNumber Rpo;
struct VReg {
VReg() : value_(kNoValue) {}