From ee9de3307596eeb5ed4fb32c43d930f203b5dc05 Mon Sep 17 00:00:00 2001 From: "dcarney@chromium.org" Date: Thu, 30 Oct 2014 09:50:15 +0000 Subject: [PATCH] [turbofan] move Node to vreg mapping to InstructionSelector BUG= R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/683933004 Cr-Commit-Position: refs/heads/master@{#25010} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25010 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/instruction-selector-impl.h | 9 +++-- src/compiler/instruction-selector.cc | 38 +++++++++++++++++----- src/compiler/instruction-selector.h | 13 +++++++- src/compiler/instruction.cc | 10 ------ src/compiler/instruction.h | 15 ++------- src/compiler/pipeline.cc | 8 ++--- test/cctest/compiler/test-codegen-deopt.cc | 6 ++-- test/cctest/compiler/test-instruction.cc | 4 +-- .../compiler/instruction-selector-unittest.cc | 10 +++--- 9 files changed, 61 insertions(+), 52 deletions(-) diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index bc2ada7..53e288d 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -46,7 +46,8 @@ class OperandGenerator { InstructionOperand* DefineAsConstant(Node* node) { selector()->MarkAsDefined(node); - int virtual_register = sequence()->AddConstant(node, ToConstant(node)); + int virtual_register = selector_->GetVirtualRegister(node); + sequence()->AddConstant(virtual_register, ToConstant(node)); return ConstantOperand::Create(virtual_register, zone()); } @@ -172,8 +173,7 @@ class OperandGenerator { UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { DCHECK_NOT_NULL(node); DCHECK_NOT_NULL(operand); - operand->set_virtual_register( - selector_->sequence()->GetVirtualRegister(node)); + operand->set_virtual_register(selector_->GetVirtualRegister(node)); selector()->MarkAsDefined(node); return operand; } @@ -181,8 +181,7 @@ class OperandGenerator { UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { DCHECK_NOT_NULL(node); DCHECK_NOT_NULL(operand); - operand->set_virtual_register( - selector_->sequence()->GetVirtualRegister(node)); + operand->set_virtual_register(selector_->GetVirtualRegister(node)); selector()->MarkAsUsed(node); return operand; } diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 22da0b5..729f163 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -4,6 +4,7 @@ #include "src/compiler/instruction-selector.h" +#include "src/compiler/graph.h" #include "src/compiler/instruction-selector-impl.h" #include "src/compiler/node-matchers.h" #include "src/compiler/node-properties-inl.h" @@ -13,7 +14,8 @@ namespace v8 { namespace internal { namespace compiler { -InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage, +InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph, + Linkage* linkage, InstructionSequence* sequence, Schedule* schedule, SourcePositionTable* source_positions, @@ -24,10 +26,11 @@ InstructionSelector::InstructionSelector(Zone* local_zone, Linkage* linkage, source_positions_(source_positions), features_(features), schedule_(schedule), + node_map_(graph->NodeCount(), kNodeUnmapped, zone()), current_block_(NULL), instructions_(zone()), - defined_(sequence->node_count(), false, zone()), - used_(sequence->node_count(), false, zone()) {} + defined_(graph->NodeCount(), false, zone()), + used_(graph->NodeCount(), false, zone()) {} void InstructionSelector::SelectInstructions() { @@ -157,6 +160,19 @@ bool InstructionSelector::CanCover(Node* user, Node* node) const { } +int InstructionSelector::GetVirtualRegister(const Node* node) { + if (node_map_[node->id()] == kNodeUnmapped) { + node_map_[node->id()] = sequence()->NextVirtualRegister(); + } + return node_map_[node->id()]; +} + + +int InstructionSelector::GetMappedVirtualRegister(const Node* node) const { + return node_map_[node->id()]; +} + + bool InstructionSelector::IsDefined(Node* node) const { DCHECK_NOT_NULL(node); NodeId id = node->id(); @@ -195,27 +211,31 @@ void InstructionSelector::MarkAsUsed(Node* node) { bool InstructionSelector::IsDouble(const Node* node) const { DCHECK_NOT_NULL(node); - return sequence()->IsDouble(sequence()->GetVirtualRegister(node)); + int virtual_register = GetMappedVirtualRegister(node); + if (virtual_register == kNodeUnmapped) return false; + return sequence()->IsDouble(virtual_register); } void InstructionSelector::MarkAsDouble(Node* node) { DCHECK_NOT_NULL(node); DCHECK(!IsReference(node)); - sequence()->MarkAsDouble(sequence()->GetVirtualRegister(node)); + sequence()->MarkAsDouble(GetVirtualRegister(node)); } bool InstructionSelector::IsReference(const Node* node) const { DCHECK_NOT_NULL(node); - return sequence()->IsReference(sequence()->GetVirtualRegister(node)); + int virtual_register = GetMappedVirtualRegister(node); + if (virtual_register == kNodeUnmapped) return false; + return sequence()->IsReference(virtual_register); } void InstructionSelector::MarkAsReference(Node* node) { DCHECK_NOT_NULL(node); DCHECK(!IsDouble(node)); - sequence()->MarkAsReference(sequence()->GetVirtualRegister(node)); + sequence()->MarkAsReference(GetVirtualRegister(node)); } @@ -892,14 +912,14 @@ void InstructionSelector::VisitParameter(Node* node) { void InstructionSelector::VisitPhi(Node* node) { // TODO(bmeurer): Emit a PhiInstruction here. PhiInstruction* phi = new (instruction_zone()) - PhiInstruction(instruction_zone(), sequence()->GetVirtualRegister(node)); + PhiInstruction(instruction_zone(), GetVirtualRegister(node)); sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi); const int input_count = node->op()->InputCount(); phi->operands().reserve(static_cast(input_count)); for (int i = 0; i < input_count; ++i) { Node* const input = node->InputAt(i); MarkAsUsed(input); - phi->operands().push_back(sequence()->GetVirtualRegister(input)); + phi->operands().push_back(GetVirtualRegister(input)); } } diff --git a/src/compiler/instruction-selector.h b/src/compiler/instruction-selector.h index 59f8073..4e916be 100644 --- a/src/compiler/instruction-selector.h +++ b/src/compiler/instruction-selector.h @@ -21,12 +21,17 @@ struct CallBuffer; // TODO(bmeurer): Remove this. class FlagsContinuation; class Linkage; +typedef IntVector NodeToVregMap; + class InstructionSelector FINAL { public: + static const int kNodeUnmapped = -1; + // Forward declarations. class Features; - InstructionSelector(Zone* local_zone, Linkage* linkage, + // TODO(dcarney): pass in vreg mapping instead of graph. + InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage, InstructionSequence* sequence, Schedule* schedule, SourcePositionTable* source_positions, Features features = SupportedFeatures()); @@ -110,6 +115,11 @@ class InstructionSelector FINAL { // Checks if {node} is currently live. bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); } + int GetVirtualRegister(const Node* node); + // Gets the current mapping if it exists, kNodeUnmapped otherwise. + int GetMappedVirtualRegister(const Node* node) const; + const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; } + private: friend class OperandGenerator; @@ -206,6 +216,7 @@ class InstructionSelector FINAL { SourcePositionTable* const source_positions_; Features features_; Schedule* const schedule_; + NodeToVregMap node_map_; BasicBlock* current_block_; ZoneDeque instructions_; BoolVector defined_; diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc index 8ba4b0c..7ee5a69 100644 --- a/src/compiler/instruction.cc +++ b/src/compiler/instruction.cc @@ -387,10 +387,8 @@ static void InitializeInstructionBlocks(Zone* zone, const Schedule* schedule, InstructionSequence::InstructionSequence(Zone* instruction_zone, - const Graph* graph, const Schedule* schedule) : zone_(instruction_zone), - node_map_(graph->NodeCount(), kNodeUnmapped, zone()), instruction_blocks_(static_cast(schedule->rpo_order()->size()), NULL, zone()), constants_(ConstantMap::key_compare(), @@ -406,14 +404,6 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone, } -int InstructionSequence::GetVirtualRegister(const Node* node) { - if (node_map_[node->id()] == kNodeUnmapped) { - node_map_[node->id()] = NextVirtualRegister(); - } - return node_map_[node->id()]; -} - - Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) { return GetBlockStart(rpo)->label(); } diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h index 72453ed..6d37b9f 100644 --- a/src/compiler/instruction.h +++ b/src/compiler/instruction.h @@ -842,22 +842,17 @@ typedef ZoneDeque InstructionDeque; typedef ZoneDeque PointerMapDeque; typedef ZoneVector DeoptimizationVector; typedef ZoneVector InstructionBlocks; -typedef IntVector NodeToVregMap; // Represents architecture-specific generated code before, during, and after // register allocation. // TODO(titzer): s/IsDouble/IsFloat64/ class InstructionSequence FINAL { public: - static const int kNodeUnmapped = -1; - - InstructionSequence(Zone* zone, const Graph* graph, const Schedule* schedule); + InstructionSequence(Zone* zone, const Schedule* schedule); int NextVirtualRegister() { return next_virtual_register_++; } int VirtualRegisterCount() const { return next_virtual_register_; } - int node_count() const { return static_cast(node_map_.size()); } - const InstructionBlocks& instruction_blocks() const { return instruction_blocks_; } @@ -882,9 +877,6 @@ class InstructionSequence FINAL { const InstructionBlock* GetInstructionBlock(int instruction_index) const; - int GetVirtualRegister(const Node* node); - const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; } - bool IsReference(int virtual_register) const; bool IsDouble(int virtual_register) const; @@ -919,8 +911,8 @@ class InstructionSequence FINAL { void StartBlock(BasicBlock* block); void EndBlock(BasicBlock* block); - int AddConstant(Node* node, Constant constant) { - int virtual_register = GetVirtualRegister(node); + int AddConstant(int virtual_register, Constant constant) { + DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_); DCHECK(constants_.find(virtual_register) == constants_.end()); constants_.insert(std::make_pair(virtual_register, constant)); return virtual_register; @@ -967,7 +959,6 @@ class InstructionSequence FINAL { typedef std::set, ZoneIntAllocator> VirtualRegisterSet; Zone* const zone_; - NodeToVregMap node_map_; InstructionBlocks instruction_blocks_; ConstantMap constants_; ConstantDeque immediates_; diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index 0c79c08..0dcb408 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -538,15 +538,15 @@ Handle Pipeline::GenerateCode(Linkage* linkage, PipelineData* data) { data->schedule()); } - InstructionSequence sequence(data->instruction_zone(), data->graph(), - data->schedule()); + InstructionSequence sequence(data->instruction_zone(), data->schedule()); // Select and schedule instructions covering the scheduled graph. { PhaseScope phase_scope(data->pipeline_statistics(), "select instructions"); ZonePool::Scope zone_scope(data->zone_pool()); - InstructionSelector selector(zone_scope.zone(), linkage, &sequence, - data->schedule(), data->source_positions()); + InstructionSelector selector(zone_scope.zone(), data->graph(), linkage, + &sequence, data->schedule(), + data->source_positions()); selector.SelectInstructions(); } diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc index a11ac05..e299c3d 100644 --- a/test/cctest/compiler/test-codegen-deopt.cc +++ b/test/cctest/compiler/test-codegen-deopt.cc @@ -66,10 +66,10 @@ class DeoptCodegenTester { // Initialize the codegen and generate code. Linkage* linkage = new (scope_->main_zone()) Linkage(info.zone(), &info); code = new v8::internal::compiler::InstructionSequence(scope_->main_zone(), - graph, schedule); + schedule); SourcePositionTable source_positions(graph); - InstructionSelector selector(scope_->main_zone(), linkage, code, schedule, - &source_positions); + InstructionSelector selector(scope_->main_zone(), graph, linkage, code, + schedule, &source_positions); selector.SelectInstructions(); if (FLAG_trace_turbo) { diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc index d61f34c..2b41e40 100644 --- a/test/cctest/compiler/test-instruction.cc +++ b/test/cctest/compiler/test-instruction.cc @@ -55,7 +55,7 @@ class InstructionTester : public HandleAndZoneScope { Scheduler::ComputeSpecialRPO(&zone_pool, &schedule); DCHECK(schedule.rpo_order()->size() > 0); } - code = new TestInstrSeq(main_zone(), &graph, &schedule); + code = new TestInstrSeq(main_zone(), &schedule); } Node* Int32Constant(int32_t val) { @@ -128,8 +128,6 @@ TEST(InstructionBasic) { R.allocCode(); - CHECK_EQ(R.graph.NodeCount(), R.code->node_count()); - BasicBlockVector* blocks = R.schedule.rpo_order(); CHECK_EQ(static_cast(blocks->size()), R.code->InstructionBlockCount()); diff --git a/test/unittests/compiler/instruction-selector-unittest.cc b/test/unittests/compiler/instruction-selector-unittest.cc index 0c5cdc5..5c45632 100644 --- a/test/unittests/compiler/instruction-selector-unittest.cc +++ b/test/unittests/compiler/instruction-selector-unittest.cc @@ -37,10 +37,10 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build( EXPECT_NE(0, graph()->NodeCount()); int initial_node_count = graph()->NodeCount(); Linkage linkage(test_->zone(), call_descriptor()); - InstructionSequence sequence(test_->zone(), graph(), schedule); + InstructionSequence sequence(test_->zone(), schedule); SourcePositionTable source_position_table(graph()); - InstructionSelector selector(test_->zone(), &linkage, &sequence, schedule, - &source_position_table, features); + InstructionSelector selector(test_->zone(), graph(), &linkage, &sequence, + schedule, &source_position_table, features); selector.SelectInstructions(); if (FLAG_trace_turbo) { OFStream out(stdout); @@ -50,9 +50,9 @@ InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build( Stream s; // Map virtual registers. { - const NodeToVregMap& node_map = sequence.GetNodeMapForTesting(); + const NodeToVregMap& node_map = selector.GetNodeMapForTesting(); for (int i = 0; i < initial_node_count; ++i) { - if (node_map[i] != InstructionSequence::kNodeUnmapped) { + if (node_map[i] != InstructionSelector::kNodeUnmapped) { s.virtual_registers_.insert(std::make_pair(i, node_map[i])); } } -- 2.7.4