blob: 1e861c7b151e1bc6c18d8caddb455f599006d154 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2013 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_GRAPH_H_
6#define V8_COMPILER_GRAPH_H_
7
Ben Murdochc8c1d9e2017-03-08 14:04:23 +00008#include "src/base/compiler-specific.h"
9#include "src/globals.h"
Ben Murdochf3b273f2017-01-17 12:11:28 +000010#include "src/zone/zone-containers.h"
11#include "src/zone/zone.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000012
13namespace v8 {
14namespace internal {
15namespace compiler {
16
Emily Bernier958fae72015-03-24 16:35:39 -040017// Forward declarations.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018class GraphDecorator;
Ben Murdoch014dc512016-03-22 12:00:34 +000019class Node;
20class Operator;
21
22
23// Marks are used during traversal of the graph to distinguish states of nodes.
24// Each node has a mark which is a monotonically increasing integer, and a
25// {NodeMarker} has a range of values that indicate states of a node.
26typedef uint32_t Mark;
27
28
29// NodeIds are identifying numbers for nodes that can be used to index auxiliary
30// out-of-line data associated with each node.
31typedef uint32_t NodeId;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000033class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034 public:
35 explicit Graph(Zone* zone);
36
Ben Murdoch13e2dad2016-09-16 13:49:30 +010037 // Scope used when creating a subgraph for inlining. Automatically preserves
38 // the original start and end nodes of the graph, and resets them when you
39 // leave the scope.
40 class SubgraphScope final {
41 public:
42 explicit SubgraphScope(Graph* graph)
43 : graph_(graph), start_(graph->start()), end_(graph->end()) {}
44 ~SubgraphScope() {
45 graph_->SetStart(start_);
46 graph_->SetEnd(end_);
47 }
48
49 private:
50 Graph* const graph_;
51 Node* const start_;
52 Node* const end_;
53
54 DISALLOW_COPY_AND_ASSIGN(SubgraphScope);
55 };
56
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 // Base implementation used by all factory methods.
Ben Murdoch109988c2016-05-18 11:27:45 +010058 Node* NewNodeUnchecked(const Operator* op, int input_count,
59 Node* const* inputs, bool incomplete = false);
Ben Murdoch014dc512016-03-22 12:00:34 +000060
61 // Factory that checks the input count.
Ben Murdoch109988c2016-05-18 11:27:45 +010062 Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
Emily Bernier958fae72015-03-24 16:35:39 -040063 bool incomplete = false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064
65 // Factories for nodes with static input counts.
66 Node* NewNode(const Operator* op) {
Ben Murdoch109988c2016-05-18 11:27:45 +010067 return NewNode(op, 0, static_cast<Node* const*>(nullptr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 }
69 Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
70 Node* NewNode(const Operator* op, Node* n1, Node* n2) {
71 Node* nodes[] = {n1, n2};
72 return NewNode(op, arraysize(nodes), nodes);
73 }
74 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
75 Node* nodes[] = {n1, n2, n3};
76 return NewNode(op, arraysize(nodes), nodes);
77 }
78 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
79 Node* nodes[] = {n1, n2, n3, n4};
80 return NewNode(op, arraysize(nodes), nodes);
81 }
82 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
83 Node* n5) {
84 Node* nodes[] = {n1, n2, n3, n4, n5};
85 return NewNode(op, arraysize(nodes), nodes);
86 }
87 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
88 Node* n5, Node* n6) {
89 Node* nodes[] = {n1, n2, n3, n4, n5, n6};
90 return NewNode(op, arraysize(nodes), nodes);
91 }
Emily Bernier958fae72015-03-24 16:35:39 -040092 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
93 Node* n5, Node* n6, Node* n7) {
94 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
95 return NewNode(op, arraysize(nodes), nodes);
96 }
Ben Murdoch014dc512016-03-22 12:00:34 +000097 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
98 Node* n5, Node* n6, Node* n7, Node* n8) {
99 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8};
100 return NewNode(op, arraysize(nodes), nodes);
101 }
102 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
103 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9) {
104 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9};
105 return NewNode(op, arraysize(nodes), nodes);
106 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107
Ben Murdoch014dc512016-03-22 12:00:34 +0000108 // Clone the {node}, and assign a new node id to the copy.
109 Node* CloneNode(const Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110
Emily Bernier958fae72015-03-24 16:35:39 -0400111 Zone* zone() const { return zone_; }
112 Node* start() const { return start_; }
113 Node* end() const { return end_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000114
Emily Bernier958fae72015-03-24 16:35:39 -0400115 void SetStart(Node* start) { start_ = start; }
116 void SetEnd(Node* end) { end_ = end; }
117
Ben Murdoch014dc512016-03-22 12:00:34 +0000118 size_t NodeCount() const { return next_node_id_; }
Emily Bernier958fae72015-03-24 16:35:39 -0400119
120 void Decorate(Node* node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000121 void AddDecorator(GraphDecorator* decorator);
122 void RemoveDecorator(GraphDecorator* decorator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000124 // Very simple print API usable in a debugger.
125 void Print() const;
126
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 private:
Ben Murdoch014dc512016-03-22 12:00:34 +0000128 friend class NodeMarkerBase;
Emily Bernier958fae72015-03-24 16:35:39 -0400129
Ben Murdoch014dc512016-03-22 12:00:34 +0000130 inline NodeId NextNodeId();
131
132 Zone* const zone_;
Emily Bernier958fae72015-03-24 16:35:39 -0400133 Node* start_;
134 Node* end_;
135 Mark mark_max_;
136 NodeId next_node_id_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 ZoneVector<GraphDecorator*> decorators_;
Emily Bernier958fae72015-03-24 16:35:39 -0400138
139 DISALLOW_COPY_AND_ASSIGN(Graph);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140};
141
142
Emily Bernier958fae72015-03-24 16:35:39 -0400143// A graph decorator can be used to add behavior to the creation of nodes
144// in a graph.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145class GraphDecorator : public ZoneObject {
146 public:
147 virtual ~GraphDecorator() {}
148 virtual void Decorate(Node* node) = 0;
149};
150
151} // namespace compiler
152} // namespace internal
153} // namespace v8
154
155#endif // V8_COMPILER_GRAPH_H_