[turbofan] Finally get rid of the generic algorithm.
authorBenedikt Meurer <bmeurer@chromium.org>
Fri, 20 Feb 2015 08:42:29 +0000 (09:42 +0100)
committerBenedikt Meurer <bmeurer@chromium.org>
Fri, 20 Feb 2015 08:42:51 +0000 (08:42 +0000)
R=svenpanne@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26760}

BUILD.gn
src/compiler/generic-algorithm.h [deleted file]
src/compiler/graph-inl.h [deleted file]
src/compiler/js-inlining.cc
src/compiler/js-inlining.h
test/cctest/compiler/test-control-reducer.cc
test/cctest/compiler/test-js-typed-lowering.cc
test/cctest/compiler/test-machine-operator-reducer.cc
test/cctest/compiler/test-node-algorithm.cc
test/unittests/compiler/instruction-selector-unittest.cc
tools/gyp/v8.gyp

index 713ab6d..011c8eb 100644 (file)
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -535,9 +535,7 @@ source_set("v8_base") {
     "src/compiler/frame.h",
     "src/compiler/gap-resolver.cc",
     "src/compiler/gap-resolver.h",
-    "src/compiler/generic-algorithm.h",
     "src/compiler/graph-builder.h",
-    "src/compiler/graph-inl.h",
     "src/compiler/graph-reducer.cc",
     "src/compiler/graph-reducer.h",
     "src/compiler/graph-replay.cc",
diff --git a/src/compiler/generic-algorithm.h b/src/compiler/generic-algorithm.h
deleted file mode 100644 (file)
index 391757e..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GENERIC_ALGORITHM_H_
-#define V8_COMPILER_GENERIC_ALGORITHM_H_
-
-#include <stack>
-#include <vector>
-
-#include "src/compiler/graph.h"
-#include "src/compiler/node.h"
-#include "src/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class Graph;
-class Node;
-
-// GenericGraphVisit allows visitation of graphs of nodes and edges in pre- and
-// post-order. Visitation uses an explicitly allocated stack rather than the
-// execution stack to avoid stack overflow.
-class GenericGraphVisit {
- public:
-  // struct Visitor {
-  //   void Pre(Node* current);
-  //   void Post(Node* current);
-  //   void PreEdge(Node* from, int index, Node* to);
-  //   void PostEdge(Node* from, int index, Node* to);
-  // }
-  template <class Visitor>
-  static void Visit(Graph* graph, Zone* zone, Node** root_begin,
-                    Node** root_end, Visitor* visitor) {
-    typedef typename Node::InputEdges::iterator Iterator;
-    typedef std::pair<Iterator, Iterator> NodeState;
-    typedef std::stack<NodeState, ZoneDeque<NodeState> > NodeStateStack;
-    NodeStateStack stack((ZoneDeque<NodeState>(zone)));
-    BoolVector visited(graph->NodeCount(), false, zone);
-    Node* current = *root_begin;
-    while (true) {
-      DCHECK(current != NULL);
-      const int id = current->id();
-      DCHECK(id >= 0);
-      DCHECK(id < graph->NodeCount());  // Must be a valid id.
-      bool visit = !GetVisited(&visited, id);
-      if (visit) {
-        visitor->Pre(current);
-        SetVisited(&visited, id);
-      }
-      Iterator begin(visit ? current->input_edges().begin()
-                           : current->input_edges().end());
-      Iterator end(current->input_edges().end());
-      stack.push(NodeState(begin, end));
-      Node* post_order_node = current;
-      while (true) {
-        NodeState top = stack.top();
-        if (top.first == top.second) {
-          if (visit) {
-            visitor->Post(post_order_node);
-            SetVisited(&visited, post_order_node->id());
-          }
-          stack.pop();
-          if (stack.empty()) {
-            if (++root_begin == root_end) return;
-            current = *root_begin;
-            break;
-          }
-          post_order_node = (*stack.top().first).from();
-          visit = true;
-        } else {
-          visitor->PreEdge((*top.first).from(), (*top.first).index(),
-                           (*top.first).to());
-          current = (*top.first).to();
-          if (!GetVisited(&visited, current->id())) break;
-        }
-        top = stack.top();
-        visitor->PostEdge((*top.first).from(), (*top.first).index(),
-                          (*top.first).to());
-        ++stack.top().first;
-      }
-    }
-  }
-
-  template <class Visitor>
-  static void Visit(Graph* graph, Zone* zone, Node* current, Visitor* visitor) {
-    Node* array[] = {current};
-    Visit<Visitor>(graph, zone, &array[0], &array[1], visitor);
-  }
-
-  struct NullNodeVisitor {
-    void Pre(Node* node) {}
-    void Post(Node* node) {}
-    void PreEdge(Node* from, int index, Node* to) {}
-    void PostEdge(Node* from, int index, Node* to) {}
-  };
-
- private:
-  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) = true;
-  }
-
-  static bool GetVisited(BoolVector* visited, int id) {
-    if (id >= static_cast<int>(visited->size())) return false;
-    return visited->at(id);
-  }
-};
-
-typedef GenericGraphVisit::NullNodeVisitor NullNodeVisitor;
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_GENERIC_ALGORITHM_H_
diff --git a/src/compiler/graph-inl.h b/src/compiler/graph-inl.h
deleted file mode 100644 (file)
index 3a21737..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GRAPH_INL_H_
-#define V8_COMPILER_GRAPH_INL_H_
-
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/graph.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <class Visitor>
-void Graph::VisitNodeInputsFromEnd(Visitor* visitor) {
-  Zone tmp_zone;
-  GenericGraphVisit::Visit<Visitor>(this, &tmp_zone, end(), visitor);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_GRAPH_INL_H_
index 91d0823..0035b8d 100644 (file)
@@ -2,14 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/compiler/js-inlining.h"
+
 #include "src/ast.h"
 #include "src/ast-numbering.h"
 #include "src/compiler/access-builder.h"
+#include "src/compiler/all-nodes.h"
 #include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/graph-visualizer.h"
-#include "src/compiler/js-inlining.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties.h"
@@ -20,7 +21,6 @@
 #include "src/rewriter.h"
 #include "src/scopes.h"
 
-
 namespace v8 {
 namespace internal {
 namespace compiler {
@@ -56,28 +56,7 @@ class JSCallFunctionAccessor {
 };
 
 
-Reduction JSInliner::Reduce(Node* node) {
-  if (node->opcode() != IrOpcode::kJSCallFunction) return NoChange();
-
-  JSCallFunctionAccessor call(node);
-  HeapObjectMatcher<JSFunction> match(call.jsfunction());
-  if (!match.HasValue()) return NoChange();
-
-  Handle<JSFunction> jsfunction = match.Value().handle();
-
-  if (jsfunction->shared()->native()) {
-    if (FLAG_trace_turbo_inlining) {
-      SmartArrayPointer<char> name =
-          jsfunction->shared()->DebugName()->ToCString();
-      PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(),
-             info_->shared_info()->DebugName()->ToCString().get());
-    }
-    return NoChange();
-  }
-
-  return TryInlineJSCall(node, jsfunction);
-}
-
+namespace {
 
 // A facade on a JSFunction's graph to facilitate inlining. It assumes the
 // that the function graph has only one return statement, and provides
@@ -174,71 +153,59 @@ void Inlinee::UnifyReturn(JSGraph* jsgraph) {
 }
 
 
-class CopyVisitor : public NullNodeVisitor {
+class CopyVisitor {
  public:
   CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone)
-      : copies_(source_graph->NodeCount(), NULL, temp_zone),
-        sentinels_(source_graph->NodeCount(), NULL, temp_zone),
+      : sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "Sentinel", 0, 0,
+                     0, 0, 0, 0),
+        sentinel_(target_graph->NewNode(&sentinel_op_)),
+        copies_(source_graph->NodeCount(), sentinel_, temp_zone),
         source_graph_(source_graph),
         target_graph_(target_graph),
-        temp_zone_(temp_zone),
-        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
-                     0, 0, 0, 0) {}
+        temp_zone_(temp_zone) {}
+
+  Node* GetCopy(Node* orig) { return copies_[orig->id()]; }
 
-  void Post(Node* original) {
+  void CopyGraph() {
     NodeVector inputs(temp_zone_);
-    for (Node* const node : original->inputs()) {
-      inputs.push_back(GetCopy(node));
+    // TODO(bmeurer): AllNodes should be turned into something like
+    // Graph::CollectNodesReachableFromEnd() and the gray set stuff should be
+    // removed since it's only needed by the visualizer.
+    AllNodes all(temp_zone_, source_graph_);
+    // Copy all nodes reachable from end.
+    for (Node* orig : all.live) {
+      Node* copy = GetCopy(orig);
+      if (copy != sentinel_) {
+        // Mapping already exists.
+        continue;
+      }
+      // Copy the node.
+      inputs.clear();
+      for (Node* input : orig->inputs()) inputs.push_back(copies_[input->id()]);
+      copy = target_graph_->NewNode(orig->op(), orig->InputCount(), &inputs[0]);
+      copies_[orig->id()] = copy;
     }
-
-    // Reuse the operator in the copy. This assumes that op lives in a zone
-    // that lives longer than graph()'s zone.
-    Node* copy =
-        target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
-                               (inputs.empty() ? NULL : &inputs.front()));
-    copies_[original->id()] = copy;
-  }
-
-  Node* GetCopy(Node* original) {
-    Node* copy = copies_[original->id()];
-    if (copy == NULL) {
-      copy = GetSentinel(original);
+    // For missing inputs.
+    for (Node* orig : all.live) {
+      Node* copy = copies_[orig->id()];
+      for (int i = 0; i < copy->InputCount(); ++i) {
+        Node* input = copy->InputAt(i);
+        if (input == sentinel_) {
+          copy->ReplaceInput(i, GetCopy(orig->InputAt(i)));
+        }
+      }
     }
-    DCHECK(copy);
-    return copy;
   }
 
-  void CopyGraph() {
-    source_graph_->VisitNodeInputsFromEnd(this);
-    ReplaceSentinels();
-  }
-
-  const NodeVector& copies() { return copies_; }
+  const NodeVector& copies() const { return copies_; }
 
  private:
-  void ReplaceSentinels() {
-    for (NodeId id = 0; id < source_graph_->NodeCount(); ++id) {
-      Node* sentinel = sentinels_[id];
-      if (sentinel == NULL) continue;
-      Node* copy = copies_[id];
-      DCHECK(copy);
-      sentinel->ReplaceUses(copy);
-    }
-  }
-
-  Node* GetSentinel(Node* original) {
-    if (sentinels_[original->id()] == NULL) {
-      sentinels_[original->id()] = target_graph_->NewNode(&sentinel_op_);
-    }
-    return sentinels_[original->id()];
-  }
-
+  Operator const sentinel_op_;
+  Node* const sentinel_;
   NodeVector copies_;
-  NodeVector sentinels_;
-  Graph* source_graph_;
-  Graph* target_graph_;
-  Zone* temp_zone_;
-  Operator sentinel_op_;
+  Graph* const source_graph_;
+  Graph* const target_graph_;
+  Zone* const temp_zone_;
 };
 
 
@@ -299,6 +266,8 @@ Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
   return Reducer::Replace(value_output());
 }
 
+}  // namespace
+
 
 void JSInliner::AddClosureToFrameState(Node* frame_state,
                                        Handle<JSFunction> jsfunction) {
@@ -333,9 +302,25 @@ Node* JSInliner::CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
 }
 
 
-Reduction JSInliner::TryInlineJSCall(Node* call_node,
-                                     Handle<JSFunction> function) {
-  JSCallFunctionAccessor call(call_node);
+Reduction JSInliner::Reduce(Node* node) {
+  if (node->opcode() != IrOpcode::kJSCallFunction) return NoChange();
+
+  JSCallFunctionAccessor call(node);
+  HeapObjectMatcher<JSFunction> match(call.jsfunction());
+  if (!match.HasValue()) return NoChange();
+
+  Handle<JSFunction> function = match.Value().handle();
+
+  if (function->shared()->native()) {
+    if (FLAG_trace_turbo_inlining) {
+      SmartArrayPointer<char> name =
+          function->shared()->DebugName()->ToCString();
+      PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(),
+             info_->shared_info()->DebugName()->ToCString().get());
+    }
+    return NoChange();
+  }
+
   CompilationInfoWithZone info(function);
 
   if (!Compiler::ParseAndAnalyze(&info)) return NoChange();
@@ -388,7 +373,7 @@ Reduction JSInliner::TryInlineJSCall(Node* call_node,
     }
   }
 
-  return inlinee.InlineAtCall(jsgraph_, call_node);
+  return inlinee.InlineAtCall(jsgraph_, node);
 }
 
 }  // namespace compiler
index 8a4e0c1..87e6cc9 100644 (file)
@@ -19,10 +19,9 @@ class JSInliner FINAL : public Reducer {
   JSInliner(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph)
       : local_zone_(local_zone), info_(info), jsgraph_(jsgraph) {}
 
-  Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) FINAL;
 
  private:
-  friend class InlinerVisitor;
   Zone* local_zone_;
   CompilationInfo* info_;
   JSGraph* jsgraph_;
@@ -31,11 +30,10 @@ class JSInliner FINAL : public Reducer {
                                          Handle<JSFunction> jsfunction,
                                          Zone* temp_zone);
   void AddClosureToFrameState(Node* frame_state, Handle<JSFunction> jsfunction);
-  Reduction TryInlineJSCall(Node* node, Handle<JSFunction> jsfunction);
-  static void UnifyReturn(Graph* graph);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_JS_INLINING_H_
index 827dcfd..f0efb7d 100644 (file)
@@ -8,7 +8,7 @@
 #include "src/base/bits.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/control-reducer.h"
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/graph.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties.h"
 
index f4531d3..15611f5 100644 (file)
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/js-typed-lowering.h"
 #include "src/compiler/machine-operator.h"
index 7ee5751..beedc45 100644 (file)
@@ -6,7 +6,6 @@
 
 #include "src/base/utils/random-number-generator.h"
 #include "src/codegen.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator-reducer.h"
 #include "src/compiler/operator-properties.h"
index 842d182..0cb7701 100644 (file)
@@ -9,7 +9,6 @@
 #include "graph-tester.h"
 #include "src/compiler/common-operator.h"
 #include "src/compiler/graph.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
@@ -20,45 +19,6 @@ using namespace v8::internal::compiler;
 static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 0, 0, 0, 1, 0, 0);
 
-class PreNodeVisitor : public NullNodeVisitor {
- public:
-  void Pre(Node* node) {
-    printf("NODE ID: %d\n", node->id());
-    nodes_.push_back(node);
-  }
-  std::vector<Node*> nodes_;
-};
-
-
-class PostNodeVisitor : public NullNodeVisitor {
- public:
-  void Post(Node* node) {
-    printf("NODE ID: %d\n", node->id());
-    nodes_.push_back(node);
-  }
-  std::vector<Node*> nodes_;
-};
-
-
-TEST(TestInputNodePreOrderVisitSimple) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n2, n3);
-  Node* n5 = graph.NewNode(&dummy_operator, n4, n2);
-  graph.SetEnd(n5);
-
-  PreNodeVisitor node_visitor;
-  graph.VisitNodeInputsFromEnd(&node_visitor);
-  CHECK_EQ(5, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(n5->id() == node_visitor.nodes_[0]->id());
-  CHECK(n4->id() == node_visitor.nodes_[1]->id());
-  CHECK(n2->id() == node_visitor.nodes_[2]->id());
-  CHECK(graph.start()->id() == node_visitor.nodes_[3]->id());
-  CHECK(n3->id() == node_visitor.nodes_[4]->id());
-}
-
-
 TEST(TestPrintNodeGraphToNodeGraphviz) {
   GraphWithStartNodeTester graph;
   Node* n2 = graph.NewNode(&dummy_operator, graph.start());
index d3e00c6..f1506b8 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "test/unittests/compiler/instruction-selector-unittest.h"
 
-#include "src/compiler/graph-inl.h"
+#include "src/compiler/graph.h"
 #include "src/flags.h"
 #include "test/unittests/compiler/compiler-test-utils.h"
 
index 7f08ee2..36e0dfe 100644 (file)
         '../../src/compiler/frame.h',
         '../../src/compiler/gap-resolver.cc',
         '../../src/compiler/gap-resolver.h',
-        '../../src/compiler/generic-algorithm.h',
         '../../src/compiler/graph-builder.h',
-        '../../src/compiler/graph-inl.h',
         '../../src/compiler/graph-reducer.cc',
         '../../src/compiler/graph-reducer.h',
         '../../src/compiler/graph-replay.cc',