"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",
+++ /dev/null
-// 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_
+++ /dev/null
-// 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_
// 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"
#include "src/rewriter.h"
#include "src/scopes.h"
-
namespace v8 {
namespace internal {
namespace compiler {
};
-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
}
-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_;
};
return Reducer::Replace(value_output());
}
+} // namespace
+
void JSInliner::AddClosureToFrameState(Node* frame_state,
Handle<JSFunction> jsfunction) {
}
-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();
}
}
- return inlinee.InlineAtCall(jsgraph_, call_node);
+ return inlinee.InlineAtCall(jsgraph_, node);
}
} // namespace compiler
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_;
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_
#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"
// 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"
#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"
#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"
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());
#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"
'../../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',