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