Commit 720dc926 authored by dcarney@chromium.org's avatar dcarney@chromium.org

[turbofan] move label generation to code generator

R=bmeurer@chromium.org

BUG=

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

Cr-Commit-Position: refs/heads/master@{#25201}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25201 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e0cbbd2d
......@@ -243,7 +243,7 @@ class CpuFeatures : public AllStatic {
// unknown pc location. Assembler::bind() is used to bind a label to the
// current pc. A label can be bound only once.
class Label BASE_EMBEDDED {
class Label {
public:
enum Distance {
kNear, kFar
......
......@@ -193,7 +193,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kArchJmp:
__ b(code_->GetLabel(i.InputRpo(0)));
__ b(GetLabel(i.InputRpo(0)));
DCHECK_EQ(LeaveCC, i.OutputSBit());
break;
case kArchNop:
......@@ -515,8 +515,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
BasicBlock::RpoNumber fblock =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
bool fallthru = IsNextInAssemblyOrder(fblock);
Label* tlabel = code()->GetLabel(tblock);
Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
Label* tlabel = GetLabel(tblock);
Label* flabel = fallthru ? &done : GetLabel(fblock);
switch (condition) {
case kUnorderedEqual:
__ b(vs, flabel);
......
......@@ -172,12 +172,12 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter {
} while (0)
#define ASSEMBLE_TEST_AND_BRANCH(asm_instr, width) \
do { \
bool fallthrough = IsNextInAssemblyOrder(i.InputRpo(3)); \
__ asm_instr(i.InputRegister##width(0), i.InputInt6(1), \
code_->GetLabel(i.InputRpo(2))); \
if (!fallthrough) __ B(code_->GetLabel(i.InputRpo(3))); \
#define ASSEMBLE_TEST_AND_BRANCH(asm_instr, width) \
do { \
bool fallthrough = IsNextInAssemblyOrder(i.InputRpo(3)); \
__ asm_instr(i.InputRegister##width(0), i.InputInt6(1), \
GetLabel(i.InputRpo(2))); \
if (!fallthrough) __ B(GetLabel(i.InputRpo(3))); \
} while (0)
......@@ -216,7 +216,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kArchJmp:
__ B(code_->GetLabel(i.InputRpo(0)));
__ B(GetLabel(i.InputRpo(0)));
break;
case kArchNop:
// don't emit code for nops.
......@@ -614,8 +614,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
BasicBlock::RpoNumber fblock =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
bool fallthru = IsNextInAssemblyOrder(fblock);
Label* tlabel = code()->GetLabel(tblock);
Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
Label* tlabel = GetLabel(tblock);
Label* flabel = fallthru ? &done : GetLabel(fblock);
switch (condition) {
case kUnorderedEqual:
__ B(vs, flabel);
......
......@@ -57,9 +57,7 @@ class InstructionOperandConverter {
return ToHeapObject(instr_->InputAt(index));
}
Label* InputLabel(int index) {
return gen_->code()->GetLabel(InputRpo(index));
}
Label* InputLabel(int index) { return gen_->GetLabel(InputRpo(index)); }
BasicBlock::RpoNumber InputRpo(int index) {
int rpo_number = InputInt32(index);
......
......@@ -18,6 +18,7 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
linkage_(linkage),
code_(code),
info_(info),
labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
current_block_(BasicBlock::RpoNumber::Invalid()),
current_source_position_(SourcePosition::Invalid()),
masm_(code->zone()->isolate(), NULL, 0),
......@@ -26,7 +27,11 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
deoptimization_states_(code->zone()),
deoptimization_literals_(code->zone()),
translations_(code->zone()),
last_lazy_deopt_pc_(0) {}
last_lazy_deopt_pc_(0) {
for (int i = 0; i < code->InstructionBlockCount(); ++i) {
new (&labels_[i]) Label;
}
}
Handle<Code> CodeGenerator::GenerateCode() {
......@@ -45,19 +50,24 @@ Handle<Code> CodeGenerator::GenerateCode() {
info->set_prologue_offset(masm()->pc_offset());
AssemblePrologue();
// Assemble all non-deferred instructions.
for (auto const block : code()->instruction_blocks()) {
if (block->IsDeferred()) continue;
for (int i = block->code_start(); i < block->code_end(); ++i) {
AssembleInstruction(code()->InstructionAt(i));
}
}
// Assemble all deferred instructions.
for (auto const block : code()->instruction_blocks()) {
if (!block->IsDeferred()) continue;
for (int i = block->code_start(); i < block->code_end(); ++i) {
AssembleInstruction(code()->InstructionAt(i));
// Assemble all non-deferred blocks, followed by deferred ones.
for (int deferred = 0; deferred < 2; ++deferred) {
for (auto const block : code()->instruction_blocks()) {
if (block->IsDeferred() == (deferred == 0)) {
continue;
}
// Bind a label for a block.
current_block_ = block->rpo_number();
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());
masm()->RecordComment(buffer.start());
}
masm()->bind(GetLabel(current_block_));
for (int i = block->code_start(); i < block->code_end(); ++i) {
AssembleInstruction(code()->InstructionAt(i));
}
}
}
......@@ -120,18 +130,6 @@ void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
void CodeGenerator::AssembleInstruction(Instruction* instr) {
if (instr->IsBlockStart()) {
// Bind a label for a block start and handle parallel moves.
BlockStartInstruction* block_start = BlockStartInstruction::cast(instr);
current_block_ = block_start->rpo_number();
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->id().ToInt());
masm()->RecordComment(buffer.start());
}
masm()->bind(block_start->label());
}
if (instr->IsGapMoves()) {
// Handle parallel moves associated with the gap instruction.
AssembleGap(GapInstruction::cast(instr));
......
......@@ -33,6 +33,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
Isolate* isolate() const { return zone()->isolate(); }
Linkage* linkage() const { return linkage_; }
Label* GetLabel(BasicBlock::RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
private:
MacroAssembler* masm() { return &masm_; }
GapResolver* resolver() { return &resolver_; }
......@@ -122,6 +124,7 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
Linkage* const linkage_;
InstructionSequence* const code_;
CompilationInfo* const info_;
Label* const labels_;
BasicBlock::RpoNumber current_block_;
SourcePosition current_source_position_;
MacroAssembler masm_;
......
......@@ -195,7 +195,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kArchJmp:
__ jmp(code()->GetLabel(i.InputRpo(0)));
__ jmp(GetLabel(i.InputRpo(0)));
break;
case kArchNop:
// don't emit code for nops.
......@@ -498,8 +498,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
BasicBlock::RpoNumber fblock =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
bool fallthru = IsNextInAssemblyOrder(fblock);
Label* tlabel = code()->GetLabel(tblock);
Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
Label* tlabel = GetLabel(tblock);
Label* flabel = fallthru ? &done : GetLabel(fblock);
Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
switch (condition) {
case kUnorderedEqual:
......
......@@ -420,6 +420,7 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
InstructionBlocks* instruction_blocks)
: zone_(instruction_zone),
instruction_blocks_(instruction_blocks),
block_starts_(zone()),
constants_(ConstantMap::key_compare(),
ConstantMap::allocator_type(zone())),
immediates_(zone()),
......@@ -428,29 +429,25 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
pointer_maps_(zone()),
doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
deoptimization_entries_(zone()) {}
Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) {
return GetBlockStart(rpo)->label();
deoptimization_entries_(zone()) {
block_starts_.reserve(instruction_blocks_->size());
}
BlockStartInstruction* InstructionSequence::GetBlockStart(
BasicBlock::RpoNumber rpo) {
InstructionBlock* block = InstructionBlockAt(rpo);
BlockStartInstruction* block_start =
BlockStartInstruction::cast(InstructionAt(block->code_start()));
DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt());
return block_start;
return BlockStartInstruction::cast(InstructionAt(block->code_start()));
}
void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
DCHECK(block_starts_.size() == rpo.ToSize());
InstructionBlock* block = InstructionBlockAt(rpo);
block->set_code_start(static_cast<int>(instructions_.size()));
BlockStartInstruction* block_start =
BlockStartInstruction::New(zone(), block->id(), rpo);
int code_start = static_cast<int>(instructions_.size());
block->set_code_start(code_start);
block_starts_.push_back(code_start);
BlockStartInstruction* block_start = BlockStartInstruction::New(zone());
AddInstruction(block_start);
}
......@@ -483,15 +480,15 @@ int InstructionSequence::AddInstruction(Instruction* instr) {
const InstructionBlock* InstructionSequence::GetInstructionBlock(
int instruction_index) const {
// TODO(turbofan): Optimize this.
for (;;) {
DCHECK_LE(0, instruction_index);
Instruction* instruction = InstructionAt(instruction_index--);
if (instruction->IsBlockStart()) {
return instruction_blocks_->at(
BlockStartInstruction::cast(instruction)->rpo_number().ToSize());
}
}
DCHECK(instruction_blocks_->size() == block_starts_.size());
auto begin = block_starts_.begin();
auto end = std::lower_bound(begin, block_starts_.end(), instruction_index,
std::less_equal<int>());
size_t index = std::distance(begin, end) - 1;
auto block = instruction_blocks_->at(index);
DCHECK(block->code_start() <= instruction_index &&
instruction_index < block->code_end());
return block;
}
......
......@@ -617,17 +617,11 @@ class GapInstruction : public Instruction {
// This special kind of gap move instruction represents the beginning of a
// block of code.
// TODO(titzer): move code_start and code_end from BasicBlock to here.
class BlockStartInstruction FINAL : public GapInstruction {
public:
Label* label() { return &label_; }
BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
BasicBlock::Id id() const { return id_; }
static BlockStartInstruction* New(Zone* zone, BasicBlock::Id id,
BasicBlock::RpoNumber rpo_number) {
static BlockStartInstruction* New(Zone* zone) {
void* buffer = zone->New(sizeof(BlockStartInstruction));
return new (buffer) BlockStartInstruction(id, rpo_number);
return new (buffer) BlockStartInstruction();
}
static BlockStartInstruction* cast(Instruction* instr) {
......@@ -636,14 +630,7 @@ class BlockStartInstruction FINAL : public GapInstruction {
}
private:
BlockStartInstruction(BasicBlock::Id id, BasicBlock::RpoNumber rpo_number)
: GapInstruction(kBlockStartInstruction),
id_(id),
rpo_number_(rpo_number) {}
BasicBlock::Id id_;
BasicBlock::RpoNumber rpo_number_;
Label label_;
BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {}
};
......@@ -925,7 +912,6 @@ class InstructionSequence FINAL {
void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
Label* GetLabel(BasicBlock::RpoNumber rpo);
BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo);
typedef InstructionDeque::const_iterator const_iterator;
......@@ -1000,6 +986,7 @@ class InstructionSequence FINAL {
Zone* const zone_;
InstructionBlocks* const instruction_blocks_;
IntVector block_starts_;
ConstantMap constants_;
ConstantDeque immediates_;
InstructionDeque instructions_;
......
......@@ -154,7 +154,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kArchJmp:
__ Branch(code_->GetLabel(i.InputRpo(0)));
__ Branch(GetLabel(i.InputRpo(0)));
break;
case kArchNop:
// don't emit code for nops.
......@@ -403,8 +403,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
BasicBlock::RpoNumber fblock =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
bool fallthru = IsNextInAssemblyOrder(fblock);
Label* tlabel = code()->GetLabel(tblock);
Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
Label* tlabel = GetLabel(tblock);
Label* flabel = fallthru ? &done : GetLabel(fblock);
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
......
......@@ -238,7 +238,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
break;
}
case kArchJmp:
__ jmp(code_->GetLabel(i.InputRpo(0)));
__ jmp(GetLabel(i.InputRpo(0)));
break;
case kArchNop:
// don't emit code for nops.
......@@ -620,8 +620,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
BasicBlock::RpoNumber fblock =
i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
bool fallthru = IsNextInAssemblyOrder(fblock);
Label* tlabel = code()->GetLabel(tblock);
Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
Label* tlabel = GetLabel(tblock);
Label* flabel = fallthru ? &done : GetLabel(fblock);
Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
switch (condition) {
case kUnorderedEqual:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment