[turbofan] move Node to vreg mapping to InstructionSelector
authordcarney@chromium.org <dcarney@chromium.org>
Thu, 30 Oct 2014 09:50:15 +0000 (09:50 +0000)
committerdcarney@chromium.org <dcarney@chromium.org>
Thu, 30 Oct 2014 09:50:41 +0000 (09:50 +0000)
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
src/compiler/instruction-selector.cc
src/compiler/instruction-selector.h
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/pipeline.cc
test/cctest/compiler/test-codegen-deopt.cc
test/cctest/compiler/test-instruction.cc
test/unittests/compiler/instruction-selector-unittest.cc

index bc2ada7..53e288d 100644 (file)
@@ -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;
   }
index 22da0b5..729f163 100644 (file)
@@ -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<size_t>(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));
   }
 }
 
index 59f8073..4e916be 100644 (file)
@@ -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<Instruction*> instructions_;
   BoolVector defined_;
index 8ba4b0c..7ee5a69 100644 (file)
@@ -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<int>(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();
 }
index 72453ed..6d37b9f 100644 (file)
@@ -842,22 +842,17 @@ typedef ZoneDeque<Instruction*> InstructionDeque;
 typedef ZoneDeque<PointerMap*> PointerMapDeque;
 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
 typedef ZoneVector<InstructionBlock*> 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<int>(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<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
 
   Zone* const zone_;
-  NodeToVregMap node_map_;
   InstructionBlocks instruction_blocks_;
   ConstantMap constants_;
   ConstantDeque immediates_;
index 0c79c08..0dcb408 100644 (file)
@@ -538,15 +538,15 @@ Handle<Code> 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();
   }
 
index a11ac05..e299c3d 100644 (file)
@@ -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) {
index d61f34c..2b41e40 100644 (file)
@@ -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<int>(blocks->size()), R.code->InstructionBlockCount());
 
index 0c5cdc5..5c45632 100644 (file)
@@ -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]));
       }
     }