From: dcarney@chromium.org Date: Tue, 14 Oct 2014 08:51:22 +0000 (+0000) Subject: [turbofan] remove some of the dependency of Instruction on Schedule X-Git-Tag: upstream/4.7.83~6388 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=75d15894f6a04557e1672c83ebae9ca7c27ade22;p=platform%2Fupstream%2Fv8.git [turbofan] remove some of the dependency of Instruction on Schedule R=bmeurer@chromium.org BUG= Review URL: https://codereview.chromium.org/646393002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24584 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc index f278326cf..6f8859b10 100644 --- a/src/compiler/arm/code-generator-arm.cc +++ b/src/compiler/arm/code-generator-arm.cc @@ -193,7 +193,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ b(code_->GetLabel(i.InputBlock(0))); + __ b(code_->GetLabel(i.InputRpo(0))); DCHECK_EQ(LeaveCC, i.OutputSBit()); break; case kArchNop: @@ -485,8 +485,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2); - BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); Label* tlabel = code()->GetLabel(tblock); Label* flabel = fallthru ? &done : code()->GetLabel(fblock); diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc index da229d85d..fe62d5991 100644 --- a/src/compiler/arm64/code-generator-arm64.cc +++ b/src/compiler/arm64/code-generator-arm64.cc @@ -164,7 +164,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ B(code_->GetLabel(i.InputBlock(0))); + __ B(code_->GetLabel(i.InputRpo(0))); break; case kArchNop: // don't emit code for nops. @@ -526,8 +526,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2); - BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); Label* tlabel = code()->GetLabel(tblock); Label* flabel = fallthru ? &done : code()->GetLabel(fblock); diff --git a/src/compiler/code-generator-impl.h b/src/compiler/code-generator-impl.h index 318b7e96a..92d3b0523 100644 --- a/src/compiler/code-generator-impl.h +++ b/src/compiler/code-generator-impl.h @@ -6,14 +6,9 @@ #define V8_COMPILER_CODE_GENERATOR_IMPL_H_ #include "src/compiler/code-generator.h" -#include "src/compiler/common-operator.h" -#include "src/compiler/generic-graph.h" #include "src/compiler/instruction.h" #include "src/compiler/linkage.h" -#include "src/compiler/machine-operator.h" -#include "src/compiler/node.h" #include "src/compiler/opcodes.h" -#include "src/compiler/operator.h" namespace v8 { namespace internal { @@ -61,12 +56,12 @@ class InstructionOperandConverter { } Label* InputLabel(int index) { - return gen_->code()->GetLabel(InputBlock(index)); + return gen_->code()->GetLabel(InputRpo(index)); } - BasicBlock* InputBlock(int index) { - int block_id = InputInt32(index); - return gen_->schedule()->GetBlockById(BasicBlock::Id::FromInt(block_id)); + BasicBlock::RpoNumber InputRpo(int index) { + int rpo_number = InputInt32(index); + return BasicBlock::RpoNumber::FromInt(rpo_number); } Register OutputRegister(int index = 0) { diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc index fc62119cd..bb0ef1bc1 100644 --- a/src/compiler/code-generator.cc +++ b/src/compiler/code-generator.cc @@ -14,7 +14,7 @@ namespace compiler { CodeGenerator::CodeGenerator(InstructionSequence* code) : code_(code), - current_block_(NULL), + current_block_(BasicBlock::RpoNumber::Invalid()), current_source_position_(SourcePosition::Invalid()), masm_(code->zone()->isolate(), NULL, 0), resolver_(this), @@ -103,11 +103,12 @@ 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->block(); + current_block_ = block_start->rpo_number(); if (FLAG_code_comments) { // TODO(titzer): these code comments are a giant memory leak. Vector buffer = Vector::New(32); - SNPrintF(buffer, "-- B%d start --", block_start->block()->id().ToInt()); + // TODO(dcarney): should not be rpo number there + SNPrintF(buffer, "-- B%d (rpo) start --", current_block_.ToInt()); masm()->RecordComment(buffer.start()); } masm()->bind(block_start->label()); diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h index e740dd3a2..69d9f631f 100644 --- a/src/compiler/code-generator.h +++ b/src/compiler/code-generator.h @@ -39,9 +39,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler { // 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(); + bool IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const { + return current_block_.IsNext(block); } // Record a safepoint with the given pointer map. @@ -119,7 +118,7 @@ class CodeGenerator FINAL : public GapResolver::Assembler { }; InstructionSequence* code_; - BasicBlock* current_block_; + BasicBlock::RpoNumber current_block_; SourcePosition current_source_position_; MacroAssembler masm_; GapResolver resolver_; diff --git a/src/compiler/graph-visualizer.cc b/src/compiler/graph-visualizer.cc index 4340c250b..342ab544a 100644 --- a/src/compiler/graph-visualizer.cc +++ b/src/compiler/graph-visualizer.cc @@ -591,9 +591,9 @@ void GraphC1Visualizer::PrintSchedule(const char* phase, PrintIntProperty("loop_depth", current->loop_depth()); - if (current->code_start() >= 0) { - int first_index = current->first_instruction_index(); - int last_index = current->last_instruction_index(); + if (instructions->code_start(current) >= 0) { + int first_index = instructions->first_instruction_index(current); + int last_index = instructions->last_instruction_index(current); PrintIntProperty("first_lir_id", LifetimePosition::FromInstructionIndex( first_index).Value()); PrintIntProperty("last_lir_id", LifetimePosition::FromInstructionIndex( @@ -672,8 +672,8 @@ void GraphC1Visualizer::PrintSchedule(const char* phase, if (instructions != NULL) { Tag LIR_tag(this, "LIR"); - for (int j = current->first_instruction_index(); - j <= current->last_instruction_index(); j++) { + for (int j = instructions->first_instruction_index(current); + j <= instructions->last_instruction_index(current); j++) { PrintIndent(); os_ << j << " " << *instructions->InstructionAt(j) << " <|@\n"; } diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc index 454a02fa9..8543fd784 100644 --- a/src/compiler/ia32/code-generator-ia32.cc +++ b/src/compiler/ia32/code-generator-ia32.cc @@ -195,7 +195,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ jmp(code()->GetLabel(i.InputBlock(0))); + __ jmp(code()->GetLabel(i.InputRpo(0))); break; case kArchNop: // don't emit code for nops. @@ -470,8 +470,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2); - BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); Label* tlabel = code()->GetLabel(tblock); Label* flabel = fallthru ? &done : code()->GetLabel(fblock); diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index f6a437d00..b5459590f 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -130,7 +130,7 @@ class OperandGenerator { InstructionOperand* Label(BasicBlock* block) { // TODO(bmeurer): We misuse ImmediateOperand here. - return TempImmediate(block->id().ToInt()); + return TempImmediate(block->rpo_number()); } protected: diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index d62e253ab..0cfd950ac 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -55,11 +55,11 @@ void InstructionSelector::SelectInstructions() { // 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 = sequence()->code_end(block); + size_t start = sequence()->code_start(block); sequence()->StartBlock(block); while (start-- > end) { - sequence()->AddInstruction(instructions_[start], block); + sequence()->AddInstruction(instructions_[start]); } sequence()->EndBlock(block); } @@ -141,8 +141,7 @@ Instruction* InstructionSelector::Emit(Instruction* instr) { bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const { - return block->rpo_number() == (current_block_->rpo_number() + 1) && - block->deferred() == current_block_->deferred(); + return current_block_->GetRpoNumber().IsNext(block->GetRpoNumber()); } @@ -384,9 +383,8 @@ void InstructionSelector::VisitBlock(BasicBlock* block) { } // We're done with the block. - // TODO(bmeurer): We should not mutate the schedule. - block->set_code_start(static_cast(instructions_.size())); - block->set_code_end(current_block_end); + sequence()->set_code_start(block, static_cast(instructions_.size())); + sequence()->set_code_end(block, current_block_end); current_block_ = NULL; } diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc index 1a8276591..7f575741e 100644 --- a/src/compiler/instruction.cc +++ b/src/compiler/instruction.cc @@ -6,6 +6,7 @@ #include "src/compiler/common-operator.h" #include "src/compiler/generic-node-inl.h" +#include "src/compiler/graph.h" namespace v8 { namespace internal { @@ -321,6 +322,7 @@ InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph, : zone_(schedule->zone()), node_count_(graph->NodeCount()), node_map_(zone()->NewArray(node_count_)), + block_data_(schedule->BasicBlockCount(), zone()), linkage_(linkage), schedule_(schedule), constants_(ConstantMap::key_compare(), @@ -346,32 +348,36 @@ int InstructionSequence::GetVirtualRegister(const Node* node) { } -Label* InstructionSequence::GetLabel(BasicBlock* block) { - return GetBlockStart(block)->label(); +Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { + return GetBlockStart(rpo)->label(); } -BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) { - return BlockStartInstruction::cast(InstructionAt(block->code_start())); +BlockStartInstruction* InstructionSequence::GetBlockStart( + BasicBlock::RpoNumber rpo) { + BlockStartInstruction* block_start = + BlockStartInstruction::cast(InstructionAt(code_start(rpo))); + DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt()); + return block_start; } void InstructionSequence::StartBlock(BasicBlock* block) { - block->set_code_start(static_cast(instructions_.size())); + set_code_start(block, static_cast(instructions_.size())); BlockStartInstruction* block_start = BlockStartInstruction::New(zone(), block); - AddInstruction(block_start, block); + AddInstruction(block_start); } void InstructionSequence::EndBlock(BasicBlock* block) { int end = static_cast(instructions_.size()); - DCHECK(block->code_start() >= 0 && block->code_start() < end); - block->set_code_end(end); + DCHECK(code_start(block) >= 0 && code_start(block) < end); + set_code_end(block, end); } -int InstructionSequence::AddInstruction(Instruction* instr, BasicBlock* block) { +int InstructionSequence::AddInstruction(Instruction* instr) { // TODO(titzer): the order of these gaps is a holdover from Lithium. GapInstruction* gap = GapInstruction::New(zone()); if (instr->IsControl()) instructions_.push_back(gap); @@ -395,7 +401,8 @@ BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) { DCHECK_LE(0, instruction_index); Instruction* instruction = InstructionAt(instruction_index--); if (instruction->IsBlockStart()) { - return BlockStartInstruction::cast(instruction)->block(); + return schedule()->rpo_order()->at( + BlockStartInstruction::cast(instruction)->rpo_number().ToSize()); } } } @@ -537,8 +544,8 @@ std::ostream& operator<<(std::ostream& os, const InstructionSequence& code) { os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() << ")"; } - os << " instructions: [" << block->code_start() << ", " - << block->code_end() << ")\n predecessors:"; + os << " instructions: [" << code.code_start(block) << ", " + << code.code_end(block) << ")\n predecessors:"; for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin(); iter != block->predecessors_end(); ++iter) { @@ -560,8 +567,8 @@ std::ostream& operator<<(std::ostream& os, const InstructionSequence& code) { } ScopedVector buf(32); - for (int j = block->first_instruction_index(); - j <= block->last_instruction_index(); j++) { + for (int j = code.first_instruction_index(block); + j <= code.last_instruction_index(block); j++) { // TODO(svenpanne) Add some basic formatting to our streams. SNPrintF(buf, "%5d", j); os << " " << buf.start() << ": " << *code.InstructionAt(j) << "\n"; diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h index 2bb2b72c1..72ea0433d 100644 --- a/src/compiler/instruction.h +++ b/src/compiler/instruction.h @@ -12,10 +12,10 @@ #include "src/compiler/common-operator.h" #include "src/compiler/frame.h" -#include "src/compiler/graph.h" #include "src/compiler/instruction-codes.h" #include "src/compiler/opcodes.h" #include "src/compiler/schedule.h" +#include "src/compiler/source-position.h" // TODO(titzer): don't include the macro-assembler? #include "src/macro-assembler.h" #include "src/zone-allocator.h" @@ -596,8 +596,8 @@ class GapInstruction : public Instruction { // TODO(titzer): move code_start and code_end from BasicBlock to here. class BlockStartInstruction FINAL : public GapInstruction { public: - BasicBlock* block() const { return block_; } Label* label() { return &label_; } + BasicBlock::RpoNumber rpo_number() const { return rpo_number_; } static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { void* buffer = zone->New(sizeof(BlockStartInstruction)); @@ -611,9 +611,10 @@ class BlockStartInstruction FINAL : public GapInstruction { private: explicit BlockStartInstruction(BasicBlock* block) - : GapInstruction(kBlockStartInstruction), block_(block) {} + : GapInstruction(kBlockStartInstruction), + rpo_number_(block->GetRpoNumber()) {} - BasicBlock* block_; + BasicBlock::RpoNumber rpo_number_; Label label_; }; @@ -781,8 +782,6 @@ class InstructionSequence FINAL { return block->loop_header(); } - int GetLoopEnd(BasicBlock* block) const { return block->loop_end(); } - BasicBlock* GetBasicBlock(int instruction_index); int GetVirtualRegister(const Node* node); @@ -797,8 +796,8 @@ class InstructionSequence FINAL { void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); - Label* GetLabel(BasicBlock* block); - BlockStartInstruction* GetBlockStart(BasicBlock* block); + Label* GetLabel(BasicBlock::RpoNumber rpo); + BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo); typedef InstructionDeque::const_iterator const_iterator; const_iterator begin() const { return instructions_.begin(); } @@ -821,10 +820,32 @@ class InstructionSequence FINAL { const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } Zone* zone() const { return zone_; } - // Used by the code generator while adding instructions. - int AddInstruction(Instruction* instr, BasicBlock* block); + // Used by the instruction selector while adding instructions. + int AddInstruction(Instruction* instr); void StartBlock(BasicBlock* block); void EndBlock(BasicBlock* block); + void set_code_start(BasicBlock* block, int start) { + return GetBlockData(block->GetRpoNumber()).set_code_start(start); + } + void set_code_end(BasicBlock* block, int end) { + return GetBlockData(block->GetRpoNumber()).set_code_end(end); + } + // TODO(dcarney): use RpoNumber for all of the below. + int code_start(BasicBlock::RpoNumber rpo_number) const { + return GetBlockData(rpo_number).code_start(); + } + int code_start(BasicBlock* block) const { + return GetBlockData(block->GetRpoNumber()).code_start(); + } + int code_end(BasicBlock* block) const { + return GetBlockData(block->GetRpoNumber()).code_end(); + } + int first_instruction_index(BasicBlock* block) const { + return GetBlockData(block->GetRpoNumber()).first_instruction_index(); + } + int last_instruction_index(BasicBlock* block) const { + return GetBlockData(block->GetRpoNumber()).last_instruction_index(); + } int AddConstant(Node* node, Constant constant) { int virtual_register = GetVirtualRegister(node); @@ -868,14 +889,51 @@ class InstructionSequence FINAL { int GetFrameStateDescriptorCount(); private: + class BlockData { + public: + BlockData() : code_start_(-1), code_end_(-1) {} + // Instruction indexes (used by the register allocator). + int first_instruction_index() const { + DCHECK(code_start_ >= 0); + DCHECK(code_end_ > 0); + DCHECK(code_end_ >= code_start_); + return code_start_; + } + int last_instruction_index() const { + DCHECK(code_start_ >= 0); + DCHECK(code_end_ > 0); + DCHECK(code_end_ >= code_start_); + return code_end_ - 1; + } + + int32_t code_start() const { return code_start_; } + void set_code_start(int32_t start) { code_start_ = start; } + + int32_t code_end() const { return code_end_; } + void set_code_end(int32_t end) { code_end_ = end; } + + private: + int32_t code_start_; // start index of arch-specific code. + int32_t code_end_; // end index of arch-specific code. + }; + + const BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) const { + return block_data_[rpo_number.ToSize()]; + } + BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) { + return block_data_[rpo_number.ToSize()]; + } + friend std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); typedef std::set, ZoneIntAllocator> VirtualRegisterSet; + typedef ZoneVector BlockDataVector; Zone* zone_; int node_count_; int* node_map_; + BlockDataVector block_data_; Linkage* linkage_; Schedule* schedule_; ConstantMap constants_; diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc index 19d1b024e..8dcca2760 100644 --- a/src/compiler/mips/code-generator-mips.cc +++ b/src/compiler/mips/code-generator-mips.cc @@ -154,7 +154,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ Branch(code_->GetLabel(i.InputBlock(0))); + __ Branch(code_->GetLabel(i.InputRpo(0))); break; case kArchNop: // don't emit code for nops. @@ -393,8 +393,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2); - BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); Label* tlabel = code()->GetLabel(tblock); Label* flabel = fallthru ? &done : code()->GetLabel(fblock); diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc index fbaf4fa4e..c0ee02fb3 100644 --- a/src/compiler/register-allocator.cc +++ b/src/compiler/register-allocator.cc @@ -559,10 +559,11 @@ void RegisterAllocator::AddInitialIntervals(BasicBlock* block, BitVector* live_out) { // Add an interval that includes the entire block to the live range for // each live_out value. - LifetimePosition start = - LifetimePosition::FromInstructionIndex(block->first_instruction_index()); - LifetimePosition end = LifetimePosition::FromInstructionIndex( - block->last_instruction_index()).NextInstruction(); + LifetimePosition start = LifetimePosition::FromInstructionIndex( + code()->first_instruction_index(block)); + LifetimePosition end = + LifetimePosition::FromInstructionIndex( + code()->last_instruction_index(block)).NextInstruction(); BitVector::Iterator iterator(live_out); while (!iterator.Done()) { int operand_index = iterator.Current(); @@ -651,7 +652,7 @@ LiveRange* RegisterAllocator::LiveRangeFor(int index) { GapInstruction* RegisterAllocator::GetLastGap(BasicBlock* block) { - int last_instruction = block->last_instruction_index(); + int last_instruction = code()->last_instruction_index(block); return code()->GapAt(last_instruction - 1); } @@ -729,8 +730,8 @@ void RegisterAllocator::AddConstraintsGapMove(int index, void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) { - int start = block->first_instruction_index(); - int end = block->last_instruction_index(); + int start = code()->first_instruction_index(block); + int end = code()->last_instruction_index(block); DCHECK_NE(-1, start); for (int i = start; i <= end; ++i) { if (code()->IsGapAt(i)) { @@ -752,7 +753,7 @@ void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) { void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( BasicBlock* block) { - int end = block->last_instruction_index(); + int end = code()->last_instruction_index(block); Instruction* last_instruction = InstructionAt(end); for (size_t i = 0; i < last_instruction->OutputCount(); i++) { InstructionOperand* output_operand = last_instruction->OutputAt(i); @@ -773,7 +774,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( 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; + int gap_index = code()->first_instruction_index(*succ) + 1; DCHECK(code()->IsGapAt(gap_index)); // Create an unconstrained operand for the same virtual register @@ -790,7 +791,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( 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; + int gap_index = code()->first_instruction_index(*succ) + 1; range->SetSpillStartIndex(gap_index); // This move to spill operand is not a real use. Liveness analysis @@ -937,12 +938,12 @@ bool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr, void RegisterAllocator::ProcessInstructions(BasicBlock* block, BitVector* live) { - int block_start = block->first_instruction_index(); + int block_start = code()->first_instruction_index(block); LifetimePosition block_start_position = LifetimePosition::FromInstructionIndex(block_start); - for (int index = block->last_instruction_index(); index >= block_start; + for (int index = code()->last_instruction_index(block); index >= block_start; index--) { LifetimePosition curr_position = LifetimePosition::FromInstructionIndex(index); @@ -1081,19 +1082,21 @@ void RegisterAllocator::ResolvePhis(BasicBlock* block) { BasicBlock* cur_block = block->PredecessorAt(j); // The gap move must be added without any special processing as in // the AddConstraintsGapMove. - code()->AddGapMove(cur_block->last_instruction_index() - 1, operand, + code()->AddGapMove(code()->last_instruction_index(cur_block) - 1, operand, phi_operand); - Instruction* branch = InstructionAt(cur_block->last_instruction_index()); + Instruction* branch = + InstructionAt(code()->last_instruction_index(cur_block)); DCHECK(!branch->HasPointerMap()); USE(branch); } LiveRange* live_range = LiveRangeFor(phi_vreg); - BlockStartInstruction* block_start = code()->GetBlockStart(block); + BlockStartInstruction* block_start = + code()->GetBlockStart(block->GetRpoNumber()); block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone()) ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone()); - live_range->SetSpillStartIndex(block->first_instruction_index()); + live_range->SetSpillStartIndex(code()->first_instruction_index(block)); // We use the phi-ness of some nodes in some later heuristics. live_range->set_is_phi(true); @@ -1147,10 +1150,10 @@ void RegisterAllocator::ResolvePhis() { void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block, BasicBlock* pred) { - LifetimePosition pred_end = - LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); - LifetimePosition cur_start = - LifetimePosition::FromInstructionIndex(block->first_instruction_index()); + LifetimePosition pred_end = LifetimePosition::FromInstructionIndex( + code()->last_instruction_index(pred)); + LifetimePosition cur_start = LifetimePosition::FromInstructionIndex( + code()->first_instruction_index(block)); LiveRange* pred_cover = NULL; LiveRange* cur_cover = NULL; LiveRange* cur_range = range; @@ -1175,12 +1178,13 @@ void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block, if (!pred_op->Equals(cur_op)) { GapInstruction* gap = NULL; if (block->PredecessorCount() == 1) { - gap = code()->GapAt(block->first_instruction_index()); + gap = code()->GapAt(code()->first_instruction_index(block)); } else { DCHECK(pred->SuccessorCount() == 1); gap = GetLastGap(pred); - Instruction* branch = InstructionAt(pred->last_instruction_index()); + Instruction* branch = + InstructionAt(code()->last_instruction_index(pred)); DCHECK(!branch->HasPointerMap()); USE(branch); } @@ -1320,7 +1324,7 @@ void RegisterAllocator::BuildLiveRanges() { DCHECK(hint != NULL); LifetimePosition block_start = LifetimePosition::FromInstructionIndex( - block->first_instruction_index()); + code()->first_instruction_index(block)); Define(block_start, phi_operand, hint); } @@ -1333,9 +1337,9 @@ void RegisterAllocator::BuildLiveRanges() { // for each value live on entry to the header. BitVector::Iterator iterator(live); LifetimePosition start = LifetimePosition::FromInstructionIndex( - block->first_instruction_index()); + code()->first_instruction_index(block)); int end_index = - code()->BlockAt(block->loop_end())->last_instruction_index(); + code()->last_instruction_index(code()->BlockAt(block->loop_end())); LifetimePosition end = LifetimePosition::FromInstructionIndex(end_index).NextInstruction(); while (!iterator.Done()) { @@ -1967,7 +1971,7 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos( // If possible try to move spilling position backwards to loop header. // This will reduce number of memory moves on the back edge. LifetimePosition loop_start = LifetimePosition::FromInstructionIndex( - loop_header->first_instruction_index()); + code()->first_instruction_index(loop_header)); if (range->Covers(loop_start)) { if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) { @@ -2105,7 +2109,7 @@ LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start, if (block == end_block && !end_block->IsLoopHeader()) return end; return LifetimePosition::FromInstructionIndex( - block->first_instruction_index()); + code()->first_instruction_index(block)); } diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc index d641b4bfd..ac6b440d7 100644 --- a/src/compiler/schedule.cc +++ b/src/compiler/schedule.cc @@ -18,9 +18,6 @@ BasicBlock::BasicBlock(Zone* zone, Id id) loop_header_(NULL), loop_depth_(0), loop_end_(-1), - code_start_(-1), - code_end_(-1), - deferred_(false), control_(kNone), control_input_(NULL), nodes_(zone), @@ -86,14 +83,6 @@ void BasicBlock::set_rpo_number(int32_t 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; } diff --git a/src/compiler/schedule.h b/src/compiler/schedule.h index 68686b52f..acfc44768 100644 --- a/src/compiler/schedule.h +++ b/src/compiler/schedule.h @@ -50,24 +50,28 @@ class BasicBlock FINAL : public ZoneObject { size_t index_; }; + class RpoNumber FINAL { + public: + int ToInt() const { return static_cast(index_); } + size_t ToSize() const { return index_; } + static RpoNumber FromInt(int index) { + return RpoNumber(static_cast(index)); + } + static RpoNumber Invalid() { return RpoNumber(static_cast(-1)); } + + bool IsNext(const RpoNumber other) const { + return other.index_ == this->index_ + 1; + } + + private: + explicit RpoNumber(size_t index) : index_(index) {} + size_t index_; + }; + 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_start_; - } - int last_instruction_index() { - DCHECK(code_start_ >= 0); - DCHECK(code_end_ > 0); - DCHECK(code_end_ >= code_start_); - return code_end_ - 1; - } - // Predecessors and successors. typedef ZoneVector Predecessors; Predecessors::iterator predecessors_begin() { return predecessors_.begin(); } @@ -126,17 +130,10 @@ class BasicBlock FINAL : public ZoneObject { int32_t loop_end() const { return loop_end_; } void set_loop_end(int32_t loop_end); + RpoNumber GetRpoNumber() const { return RpoNumber::FromInt(rpo_number_); } 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; @@ -150,10 +147,7 @@ class BasicBlock FINAL : public ZoneObject { // 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. diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc index fa9f5117a..441187668 100644 --- a/src/compiler/x64/code-generator-x64.cc +++ b/src/compiler/x64/code-generator-x64.cc @@ -233,7 +233,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kArchJmp: - __ jmp(code_->GetLabel(i.InputBlock(0))); + __ jmp(code_->GetLabel(i.InputRpo(0))); break; case kArchNop: // don't emit code for nops. @@ -583,8 +583,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, // Emit a branch. The true and false targets are always the last two inputs // to the instruction. - BasicBlock* tblock = i.InputBlock(static_cast(instr->InputCount()) - 2); - BasicBlock* fblock = i.InputBlock(static_cast(instr->InputCount()) - 1); + BasicBlock::RpoNumber tblock = + i.InputRpo(static_cast(instr->InputCount()) - 2); + BasicBlock::RpoNumber fblock = + i.InputRpo(static_cast(instr->InputCount()) - 1); bool fallthru = IsNextInAssemblyOrder(fblock); Label* tlabel = code()->GetLabel(tblock); Label* flabel = fallthru ? &done : code()->GetLabel(fblock); diff --git a/src/zone-containers.h b/src/zone-containers.h index 2ee178029..4998cbf3f 100644 --- a/src/zone-containers.h +++ b/src/zone-containers.h @@ -23,6 +23,12 @@ class ZoneVector : public std::vector > { explicit ZoneVector(Zone* zone) : std::vector >(zone_allocator(zone)) {} + // Constructs a new vector and fills it with {size} elements, each + // constructed via the default constructor. + ZoneVector(int size, Zone* zone) + : std::vector >(size, T(), zone_allocator(zone)) { + } + // Constructs a new vector and fills it with {size} elements, each // having the value {def}. ZoneVector(int size, T def, Zone* zone) diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc index 073d58448..d0e4762f4 100644 --- a/test/cctest/compiler/test-instruction.cc +++ b/test/cctest/compiler/test-instruction.cc @@ -81,10 +81,10 @@ class InstructionTester : public HandleAndZoneScope { return node; } - int NewInstr(BasicBlock* block) { + int NewInstr() { InstructionCode opcode = static_cast(110); TestInstr* instr = TestInstr::New(zone(), opcode); - return code->AddInstruction(instr, block); + return code->AddInstruction(instr); } UnallocatedOperand* NewUnallocated(int vreg) { @@ -122,7 +122,7 @@ TEST(InstructionBasic) { i++, index++) { BasicBlock* block = *i; CHECK_EQ(block, R.code->BlockAt(index)); - CHECK_EQ(-1, R.code->GetLoopEnd(block)); + CHECK_EQ(-1, block->loop_end()); } } @@ -142,19 +142,19 @@ TEST(InstructionGetBasicBlock) { R.allocCode(); R.code->StartBlock(b0); - int i0 = R.NewInstr(b0); - int i1 = R.NewInstr(b0); + int i0 = R.NewInstr(); + int i1 = R.NewInstr(); R.code->EndBlock(b0); R.code->StartBlock(b1); - int i2 = R.NewInstr(b1); - int i3 = R.NewInstr(b1); - int i4 = R.NewInstr(b1); - int i5 = R.NewInstr(b1); + int i2 = R.NewInstr(); + int i3 = R.NewInstr(); + int i4 = R.NewInstr(); + int i5 = R.NewInstr(); R.code->EndBlock(b1); R.code->StartBlock(b2); - int i6 = R.NewInstr(b2); - int i7 = R.NewInstr(b2); - int i8 = R.NewInstr(b2); + int i6 = R.NewInstr(); + int i7 = R.NewInstr(); + int i8 = R.NewInstr(); R.code->EndBlock(b2); R.code->StartBlock(b3); R.code->EndBlock(b3); @@ -171,17 +171,17 @@ TEST(InstructionGetBasicBlock) { CHECK_EQ(b2, R.code->GetBasicBlock(i7)); CHECK_EQ(b2, R.code->GetBasicBlock(i8)); - CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index())); - CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index())); + CHECK_EQ(b0, R.code->GetBasicBlock(R.code->first_instruction_index(b0))); + CHECK_EQ(b0, R.code->GetBasicBlock(R.code->last_instruction_index(b0))); - CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index())); - CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index())); + CHECK_EQ(b1, R.code->GetBasicBlock(R.code->first_instruction_index(b1))); + CHECK_EQ(b1, R.code->GetBasicBlock(R.code->last_instruction_index(b1))); - CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index())); - CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index())); + CHECK_EQ(b2, R.code->GetBasicBlock(R.code->first_instruction_index(b2))); + CHECK_EQ(b2, R.code->GetBasicBlock(R.code->last_instruction_index(b2))); - CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index())); - CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index())); + CHECK_EQ(b3, R.code->GetBasicBlock(R.code->first_instruction_index(b3))); + CHECK_EQ(b3, R.code->GetBasicBlock(R.code->last_instruction_index(b3))); } @@ -195,8 +195,8 @@ TEST(InstructionIsGapAt) { TestInstr* i0 = TestInstr::New(R.zone(), 100); TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl(); R.code->StartBlock(b0); - R.code->AddInstruction(i0, b0); - R.code->AddInstruction(g, b0); + R.code->AddInstruction(i0); + R.code->AddInstruction(g); R.code->EndBlock(b0); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart()); @@ -222,15 +222,15 @@ TEST(InstructionIsGapAt2) { TestInstr* i0 = TestInstr::New(R.zone(), 100); TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl(); R.code->StartBlock(b0); - R.code->AddInstruction(i0, b0); - R.code->AddInstruction(g, b0); + R.code->AddInstruction(i0); + R.code->AddInstruction(g); R.code->EndBlock(b0); TestInstr* i1 = TestInstr::New(R.zone(), 102); TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl(); R.code->StartBlock(b1); - R.code->AddInstruction(i1, b1); - R.code->AddInstruction(g1, b1); + R.code->AddInstruction(i1); + R.code->AddInstruction(g1); R.code->EndBlock(b1); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart()); @@ -263,8 +263,8 @@ TEST(InstructionAddGapMove) { TestInstr* i0 = TestInstr::New(R.zone(), 100); TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl(); R.code->StartBlock(b0); - R.code->AddInstruction(i0, b0); - R.code->AddInstruction(g, b0); + R.code->AddInstruction(i0); + R.code->AddInstruction(g); R.code->EndBlock(b0); CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());