blob: 6fb7cfa644ffc1ed51ceaf7f2caa353ab3cd2f3b [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 Murdoch62ed6312017-06-06 11:06:27 +0100107 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
108 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10) {
109 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10};
110 return NewNode(op, arraysize(nodes), nodes);
111 }
112 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
113 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
114 Node* n11) {
115 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11};
116 return NewNode(op, arraysize(nodes), nodes);
117 }
118 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
119 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
120 Node* n11, Node* n12) {
121 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12};
122 return NewNode(op, arraysize(nodes), nodes);
123 }
124 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
125 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
126 Node* n11, Node* n12, Node* n13) {
127 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13};
128 return NewNode(op, arraysize(nodes), nodes);
129 }
130 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
131 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
132 Node* n11, Node* n12, Node* n13, Node* n14) {
133 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7,
134 n8, n9, n10, n11, n12, n13, n14};
135 return NewNode(op, arraysize(nodes), nodes);
136 }
137 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
138 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
139 Node* n11, Node* n12, Node* n13, Node* n14, Node* n15) {
140 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8,
141 n9, n10, n11, n12, n13, n14, n15};
142 return NewNode(op, arraysize(nodes), nodes);
143 }
144 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
145 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
146 Node* n11, Node* n12, Node* n13, Node* n14, Node* n15,
147 Node* n16) {
148 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8,
149 n9, n10, n11, n12, n13, n14, n15, n16};
150 return NewNode(op, arraysize(nodes), nodes);
151 }
152 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
153 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9, Node* n10,
154 Node* n11, Node* n12, Node* n13, Node* n14, Node* n15,
155 Node* n16, Node* n17) {
156 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9,
157 n10, n11, n12, n13, n14, n15, n16, n17};
158 return NewNode(op, arraysize(nodes), nodes);
159 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000160
Ben Murdoch014dc512016-03-22 12:00:34 +0000161 // Clone the {node}, and assign a new node id to the copy.
162 Node* CloneNode(const Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163
Emily Bernier958fae72015-03-24 16:35:39 -0400164 Zone* zone() const { return zone_; }
165 Node* start() const { return start_; }
166 Node* end() const { return end_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167
Emily Bernier958fae72015-03-24 16:35:39 -0400168 void SetStart(Node* start) { start_ = start; }
169 void SetEnd(Node* end) { end_ = end; }
170
Ben Murdoch014dc512016-03-22 12:00:34 +0000171 size_t NodeCount() const { return next_node_id_; }
Emily Bernier958fae72015-03-24 16:35:39 -0400172
173 void Decorate(Node* node);
Ben Murdoch014dc512016-03-22 12:00:34 +0000174 void AddDecorator(GraphDecorator* decorator);
175 void RemoveDecorator(GraphDecorator* decorator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000177 // Very simple print API usable in a debugger.
178 void Print() const;
179
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 private:
Ben Murdoch014dc512016-03-22 12:00:34 +0000181 friend class NodeMarkerBase;
Emily Bernier958fae72015-03-24 16:35:39 -0400182
Ben Murdoch014dc512016-03-22 12:00:34 +0000183 inline NodeId NextNodeId();
184
185 Zone* const zone_;
Emily Bernier958fae72015-03-24 16:35:39 -0400186 Node* start_;
187 Node* end_;
188 Mark mark_max_;
189 NodeId next_node_id_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 ZoneVector<GraphDecorator*> decorators_;
Emily Bernier958fae72015-03-24 16:35:39 -0400191
192 DISALLOW_COPY_AND_ASSIGN(Graph);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000193};
194
195
Emily Bernier958fae72015-03-24 16:35:39 -0400196// A graph decorator can be used to add behavior to the creation of nodes
197// in a graph.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000198class GraphDecorator : public ZoneObject {
199 public:
200 virtual ~GraphDecorator() {}
201 virtual void Decorate(Node* node) = 0;
202};
203
204} // namespace compiler
205} // namespace internal
206} // namespace v8
207
208#endif // V8_COMPILER_GRAPH_H_