Make generic algorithm less generic.
authormstarzinger@chromium.org <mstarzinger@chromium.org>
Mon, 3 Nov 2014 10:30:34 +0000 (10:30 +0000)
committermstarzinger@chromium.org <mstarzinger@chromium.org>
Mon, 3 Nov 2014 10:31:11 +0000 (10:31 +0000)
R=jarin@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#25064}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25064 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

12 files changed:
src/compiler/generic-algorithm.h
src/compiler/graph-reducer.cc
src/compiler/graph-replay.cc
src/compiler/graph-replay.h
src/compiler/graph-visualizer.cc
src/compiler/js-context-specialization.cc
src/compiler/js-inlining.cc
src/compiler/scheduler.cc
src/compiler/typer.cc
src/compiler/typer.h
src/compiler/verifier.cc
test/cctest/compiler/test-node-algorithm.cc

index cd4984f..3442318 100644 (file)
@@ -23,16 +23,9 @@ namespace compiler {
 // by specifying custom traits.
 class GenericGraphVisit {
  public:
-  enum Control {
-    CONTINUE = 0x0,  // Continue depth-first normally
-    SKIP = 0x1,      // Skip this node and its successors
-    REENTER = 0x2,   // Allow reentering this node
-    DEFER = SKIP | REENTER
-  };
-
   // struct Visitor {
-  //   Control Pre(Traits::Node* current);
-  //   Control Post(Traits::Node* current);
+  //   void Pre(Traits::Node* current);
+  //   void Post(Traits::Node* current);
   //   void PreEdge(Traits::Node* from, int index, Traits::Node* to);
   //   void PostEdge(Traits::Node* from, int index, Traits::Node* to);
   // }
@@ -54,9 +47,8 @@ class GenericGraphVisit {
       DCHECK(id < Traits::max_id(graph));  // Must be a valid id.
       bool visit = !GetVisited(&visited, id);
       if (visit) {
-        Control control = visitor->Pre(current);
-        visit = !IsSkip(control);
-        if (!IsReenter(control)) SetVisited(&visited, id, true);
+        visitor->Pre(current);
+        SetVisited(&visited, id);
       }
       Iterator begin(visit ? Traits::begin(current) : Traits::end(current));
       Iterator end(Traits::end(current));
@@ -66,9 +58,8 @@ class GenericGraphVisit {
         NodeState top = stack.top();
         if (top.first == top.second) {
           if (visit) {
-            Control control = visitor->Post(post_order_node);
-            DCHECK(!IsSkip(control));
-            SetVisited(&visited, post_order_node->id(), !IsReenter(control));
+            visitor->Post(post_order_node);
+            SetVisited(&visited, post_order_node->id());
           }
           stack.pop();
           if (stack.empty()) {
@@ -101,23 +92,19 @@ class GenericGraphVisit {
 
   template <class B, class S>
   struct NullNodeVisitor {
-    Control Pre(GenericNode<B, S>* node) { return CONTINUE; }
-    Control Post(GenericNode<B, S>* node) { return CONTINUE; }
+    void Pre(GenericNode<B, S>* node) {}
+    void Post(GenericNode<B, S>* node) {}
     void PreEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
     void PostEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
   };
 
  private:
-  static bool IsSkip(Control c) { return c & SKIP; }
-  static bool IsReenter(Control c) { return c & REENTER; }
-
-  // TODO(turbofan): resizing could be optionally templatized away.
-  static void SetVisited(BoolVector* visited, int id, bool value) {
+  static void SetVisited(BoolVector* visited, int id) {
     if (id >= static_cast<int>(visited->size())) {
       // Resize and set all values to unvisited.
       visited->resize((3 * id) / 2, false);
     }
-    visited->at(id) = value;
+    visited->at(id) = true;
   }
 
   static bool GetVisited(BoolVector* visited, int id) {
index 07e8923..f716b2a 100644 (file)
@@ -72,10 +72,7 @@ void GraphReducer::ReduceNode(Node* node) {
 // A helper class to reuse the node traversal algorithm.
 struct GraphReducerVisitor FINAL : public NullNodeVisitor {
   explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {}
-  GenericGraphVisit::Control Post(Node* node) {
-    reducer_->ReduceNode(node);
-    return GenericGraphVisit::CONTINUE;
-  }
+  void Post(Node* node) { reducer_->ReduceNode(node); }
   GraphReducer* reducer_;
 };
 
index 0109adc..296ffe4 100644 (file)
@@ -24,14 +24,13 @@ void GraphReplayPrinter::PrintReplay(Graph* graph) {
 }
 
 
-GenericGraphVisit::Control GraphReplayPrinter::Pre(Node* node) {
+void GraphReplayPrinter::Pre(Node* node) {
   PrintReplayOpCreator(node->op());
   PrintF("  Node* n%d = graph.NewNode(op", node->id());
   for (int i = 0; i < node->InputCount(); ++i) {
     PrintF(", nil");
   }
   PrintF("); USE(n%d);\n", node->id());
-  return GenericGraphVisit::CONTINUE;
 }
 
 
index 53d5247..a66af22 100644 (file)
@@ -25,7 +25,7 @@ class GraphReplayPrinter FINAL : public NullNodeVisitor {
   static void PrintReplay(Graph* graph) {}
 #endif
 
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
   void PostEdge(Node* from, int index, Node* to);
 
  private:
index 19f533b..e0cf8f0 100644 (file)
@@ -66,7 +66,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
 
   void Print() { const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this); }
 
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
 
  private:
   std::ostream& os_;
@@ -77,7 +77,7 @@ class JSONGraphNodeWriter : public NullNodeVisitor {
 };
 
 
-GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) {
+void JSONGraphNodeWriter::Pre(Node* node) {
   if (first_node_) {
     first_node_ = false;
   } else {
@@ -105,7 +105,6 @@ GenericGraphVisit::Control JSONGraphNodeWriter::Pre(Node* node) {
   os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true"
                                                              : "false");
   os_ << "}";
-  return GenericGraphVisit::CONTINUE;
 }
 
 
@@ -172,7 +171,7 @@ class GraphVisualizer : public NullNodeVisitor {
 
   void Print();
 
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
 
  private:
   void AnnotateNode(Node* node);
@@ -202,7 +201,7 @@ static Node* GetControlCluster(Node* node) {
 }
 
 
-GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) {
+void GraphVisualizer::Pre(Node* node) {
   if (all_nodes_.count(node) == 0) {
     Node* control_cluster = GetControlCluster(node);
     if (control_cluster != NULL) {
@@ -215,7 +214,6 @@ GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) {
     all_nodes_.insert(node);
     if (use_to_def_) white_nodes_.insert(node);
   }
-  return GenericGraphVisit::CONTINUE;
 }
 
 
index ed76f11..8c4bb17 100644 (file)
@@ -20,7 +20,7 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
   explicit ContextSpecializationVisitor(JSContextSpecializer* spec)
       : spec_(spec) {}
 
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kJSLoadContext: {
         Reduction r = spec_->ReduceJSLoadContext(node);
@@ -41,7 +41,6 @@ class ContextSpecializationVisitor : public NullNodeVisitor {
       default:
         break;
     }
-    return GenericGraphVisit::CONTINUE;
   }
 
  private:
index 58fc858..e3c4427 100644 (file)
@@ -32,7 +32,7 @@ class InlinerVisitor : public NullNodeVisitor {
  public:
   explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
 
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kJSCallFunction:
         inliner_->TryInlineJSCall(node);
@@ -45,7 +45,6 @@ class InlinerVisitor : public NullNodeVisitor {
       default:
         break;
     }
-    return GenericGraphVisit::CONTINUE;
   }
 
  private:
@@ -167,7 +166,7 @@ class CopyVisitor : public NullNodeVisitor {
         sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
                      0, 0, 0, 0) {}
 
-  GenericGraphVisit::Control Post(Node* original) {
+  void Post(Node* original) {
     NodeVector inputs(temp_zone_);
     for (InputIter it = original->inputs().begin();
          it != original->inputs().end(); ++it) {
@@ -180,7 +179,6 @@ class CopyVisitor : public NullNodeVisitor {
         target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
                                (inputs.empty() ? NULL : &inputs.front()));
     copies_[original->id()] = copy;
-    return GenericGraphVisit::CONTINUE;
   }
 
   Node* GetCopy(Node* original) {
index 4bab8f5..1599152 100644 (file)
@@ -1012,7 +1012,7 @@ class PrepareUsesVisitor : public NullNodeVisitor {
   explicit PrepareUsesVisitor(Scheduler* scheduler)
       : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
 
-  GenericGraphVisit::Control Pre(Node* node) {
+  void Pre(Node* node) {
     if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
       // Fixed nodes are always roots for schedule late.
       scheduler_->schedule_root_nodes_.push_back(node);
@@ -1029,8 +1029,6 @@ class PrepareUsesVisitor : public NullNodeVisitor {
         schedule_->AddNode(block, node);
       }
     }
-
-    return GenericGraphVisit::CONTINUE;
   }
 
   void PostEdge(Node* from, int index, Node* to) {
index 1c169c2..3649f7d 100644 (file)
@@ -251,44 +251,19 @@ class Typer::RunVisitor : public Typer::Visitor {
       : Visitor(typer),
         redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
 
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     if (node->op()->ValueOutputCount() > 0) {
       Bounds bounds = TypeNode(node);
       NodeProperties::SetBounds(node, bounds);
       // Remember incompletely typed nodes for least fixpoint iteration.
       if (!NodeProperties::AllValueInputsAreTyped(node)) redo.insert(node);
     }
-    return GenericGraphVisit::CONTINUE;
   }
 
   NodeSet redo;
 };
 
 
-class Typer::NarrowVisitor : public Typer::Visitor {
- public:
-  explicit NarrowVisitor(Typer* typer) : Visitor(typer) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    if (node->op()->ValueOutputCount() > 0) {
-      Bounds previous = NodeProperties::GetBounds(node);
-      Bounds current = TypeNode(node);
-      NodeProperties::SetBounds(node, Bounds::Both(current, previous, zone()));
-      DCHECK(current.Narrows(previous));
-      // Stop when nothing changed (but allow re-entry in case it does later).
-      return previous.Narrows(current) ? GenericGraphVisit::DEFER
-                                       : GenericGraphVisit::REENTER;
-    } else {
-      return GenericGraphVisit::SKIP;
-    }
-  }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    return GenericGraphVisit::REENTER;
-  }
-};
-
-
 class Typer::WidenVisitor : public Typer::Visitor {
  public:
   explicit WidenVisitor(Typer* typer)
@@ -361,12 +336,6 @@ void Typer::Run() {
 }
 
 
-void Typer::Narrow(Node* start) {
-  NarrowVisitor typing(this);
-  graph_->VisitNodeUsesFrom(start, &typing);
-}
-
-
 void Typer::Decorator::Decorate(Node* node) {
   if (node->op()->ValueOutputCount() > 0) {
     // Only eagerly type-decorate nodes with known input types.
index 2cb0f51..8491d91 100644 (file)
@@ -21,7 +21,6 @@ class Typer {
   ~Typer();
 
   void Run();
-  void Narrow(Node* node);
 
   Graph* graph() { return graph_; }
   MaybeHandle<Context> context() { return context_; }
@@ -31,7 +30,6 @@ class Typer {
  private:
   class Visitor;
   class RunVisitor;
-  class NarrowVisitor;
   class WidenVisitor;
   class Decorator;
 
index 434b845..94d701a 100644 (file)
@@ -52,7 +52,7 @@ class Verifier::Visitor : public NullNodeVisitor {
   Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
 
   // Fulfills the PreNodeCallback interface.
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
 
   Zone* zone;
   Typing typing;
@@ -120,7 +120,7 @@ class Verifier::Visitor : public NullNodeVisitor {
 };
 
 
-GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
+void Verifier::Visitor::Pre(Node* node) {
   int value_count = node->op()->ValueInputCount();
   int context_count = OperatorProperties::GetContextInputCount(node->op());
   int frame_state_count =
@@ -728,8 +728,6 @@ GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
       // TODO(rossberg): Check.
       break;
   }
-
-  return GenericGraphVisit::CONTINUE;
 }
 
 
index c5e762d..e13baa8 100644 (file)
@@ -23,10 +23,9 @@ static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
 
 class PreNodeVisitor : public NullNodeVisitor {
  public:
-  GenericGraphVisit::Control Pre(Node* node) {
+  void Pre(Node* node) {
     printf("NODE ID: %d\n", node->id());
     nodes_.push_back(node);
-    return GenericGraphVisit::CONTINUE;
   }
   std::vector<Node*> nodes_;
 };
@@ -34,10 +33,9 @@ class PreNodeVisitor : public NullNodeVisitor {
 
 class PostNodeVisitor : public NullNodeVisitor {
  public:
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     printf("NODE ID: %d\n", node->id());
     nodes_.push_back(node);
-    return GenericGraphVisit::CONTINUE;
   }
   std::vector<Node*> nodes_;
 };
@@ -173,142 +171,6 @@ TEST(TestUseNodePreOrderVisitCycle) {
 }
 
 
-struct ReenterNodeVisitor : NullNodeVisitor {
-  GenericGraphVisit::Control Pre(Node* node) {
-    printf("[%d] PRE NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
-    nodes_.push_back(node->id());
-    int size = static_cast<int>(nodes_.size());
-    switch (node->id()) {
-      case 0:
-        return size < 6 ? GenericGraphVisit::REENTER : GenericGraphVisit::SKIP;
-      case 1:
-        return size < 4 ? GenericGraphVisit::DEFER
-                        : GenericGraphVisit::CONTINUE;
-      default:
-        return GenericGraphVisit::REENTER;
-    }
-  }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    printf("[%d] POST NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
-    nodes_.push_back(-node->id());
-    return node->id() == 4 ? GenericGraphVisit::REENTER
-                           : GenericGraphVisit::CONTINUE;
-  }
-
-  void PreEdge(Node* from, int index, Node* to) {
-    printf("[%d] PRE EDGE: %d-%d\n", static_cast<int>(edges_.size()),
-           from->id(), to->id());
-    edges_.push_back(std::make_pair(from->id(), to->id()));
-  }
-
-  void PostEdge(Node* from, int index, Node* to) {
-    printf("[%d] POST EDGE: %d-%d\n", static_cast<int>(edges_.size()),
-           from->id(), to->id());
-    edges_.push_back(std::make_pair(-from->id(), -to->id()));
-  }
-
-  std::vector<int> nodes_;
-  std::vector<std::pair<int, int> > edges_;
-};
-
-
-TEST(TestUseNodeReenterVisit) {
-  GraphWithStartNodeTester graph;
-  Node* n0 = graph.start_node();
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n0);
-  Node* n5 = graph.NewNode(&dummy_operator, n4);
-  n0->AppendInput(graph.main_zone(), n3);
-  graph.SetStart(n0);
-  graph.SetEnd(n5);
-
-  ReenterNodeVisitor visitor;
-  graph.VisitNodeUsesFromStart(&visitor);
-
-  CHECK_EQ(22, static_cast<int>(visitor.nodes_.size()));
-  CHECK_EQ(24, static_cast<int>(visitor.edges_.size()));
-
-  CHECK(n0->id() == visitor.nodes_[0]);
-  CHECK(n0->id() == visitor.edges_[0].first);
-  CHECK(n1->id() == visitor.edges_[0].second);
-  CHECK(n1->id() == visitor.nodes_[1]);
-  // N1 is deferred.
-  CHECK(-n1->id() == visitor.edges_[1].second);
-  CHECK(-n0->id() == visitor.edges_[1].first);
-  CHECK(n0->id() == visitor.edges_[2].first);
-  CHECK(n2->id() == visitor.edges_[2].second);
-  CHECK(n2->id() == visitor.nodes_[2]);
-  CHECK(n2->id() == visitor.edges_[3].first);
-  CHECK(n3->id() == visitor.edges_[3].second);
-  CHECK(n3->id() == visitor.nodes_[3]);
-  // Circle back to N0, which we may reenter for now.
-  CHECK(n3->id() == visitor.edges_[4].first);
-  CHECK(n0->id() == visitor.edges_[4].second);
-  CHECK(n0->id() == visitor.nodes_[4]);
-  CHECK(n0->id() == visitor.edges_[5].first);
-  CHECK(n1->id() == visitor.edges_[5].second);
-  CHECK(n1->id() == visitor.nodes_[5]);
-  // This time N1 is no longer deferred.
-  CHECK(-n1->id() == visitor.nodes_[6]);
-  CHECK(-n1->id() == visitor.edges_[6].second);
-  CHECK(-n0->id() == visitor.edges_[6].first);
-  CHECK(n0->id() == visitor.edges_[7].first);
-  CHECK(n2->id() == visitor.edges_[7].second);
-  CHECK(n2->id() == visitor.nodes_[7]);
-  CHECK(n2->id() == visitor.edges_[8].first);
-  CHECK(n3->id() == visitor.edges_[8].second);
-  CHECK(n3->id() == visitor.nodes_[8]);
-  CHECK(n3->id() == visitor.edges_[9].first);
-  CHECK(n0->id() == visitor.edges_[9].second);
-  CHECK(n0->id() == visitor.nodes_[9]);
-  // This time we break at N0 and skip it.
-  CHECK(-n0->id() == visitor.edges_[10].second);
-  CHECK(-n3->id() == visitor.edges_[10].first);
-  CHECK(-n3->id() == visitor.nodes_[10]);
-  CHECK(-n3->id() == visitor.edges_[11].second);
-  CHECK(-n2->id() == visitor.edges_[11].first);
-  CHECK(-n2->id() == visitor.nodes_[11]);
-  CHECK(-n2->id() == visitor.edges_[12].second);
-  CHECK(-n0->id() == visitor.edges_[12].first);
-  CHECK(n0->id() == visitor.edges_[13].first);
-  CHECK(n4->id() == visitor.edges_[13].second);
-  CHECK(n4->id() == visitor.nodes_[12]);
-  CHECK(n4->id() == visitor.edges_[14].first);
-  CHECK(n5->id() == visitor.edges_[14].second);
-  CHECK(n5->id() == visitor.nodes_[13]);
-  CHECK(-n5->id() == visitor.nodes_[14]);
-  CHECK(-n5->id() == visitor.edges_[15].second);
-  CHECK(-n4->id() == visitor.edges_[15].first);
-  CHECK(-n4->id() == visitor.nodes_[15]);
-  CHECK(-n4->id() == visitor.edges_[16].second);
-  CHECK(-n0->id() == visitor.edges_[16].first);
-  CHECK(-n0->id() == visitor.nodes_[16]);
-  CHECK(-n0->id() == visitor.edges_[17].second);
-  CHECK(-n3->id() == visitor.edges_[17].first);
-  CHECK(-n3->id() == visitor.nodes_[17]);
-  CHECK(-n3->id() == visitor.edges_[18].second);
-  CHECK(-n2->id() == visitor.edges_[18].first);
-  CHECK(-n2->id() == visitor.nodes_[18]);
-  CHECK(-n2->id() == visitor.edges_[19].second);
-  CHECK(-n0->id() == visitor.edges_[19].first);
-  // N4 may be reentered.
-  CHECK(n0->id() == visitor.edges_[20].first);
-  CHECK(n4->id() == visitor.edges_[20].second);
-  CHECK(n4->id() == visitor.nodes_[19]);
-  CHECK(n4->id() == visitor.edges_[21].first);
-  CHECK(n5->id() == visitor.edges_[21].second);
-  CHECK(-n5->id() == visitor.edges_[22].second);
-  CHECK(-n4->id() == visitor.edges_[22].first);
-  CHECK(-n4->id() == visitor.nodes_[20]);
-  CHECK(-n4->id() == visitor.edges_[23].second);
-  CHECK(-n0->id() == visitor.edges_[23].first);
-  CHECK(-n0->id() == visitor.nodes_[21]);
-}
-
-
 TEST(TestPrintNodeGraphToNodeGraphviz) {
   GraphWithStartNodeTester graph;
   Node* n2 = graph.NewNode(&dummy_operator, graph.start());