blob: a694a0b414a578b24b9e0f4f2cc6edb29c8472c6 [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 Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/zone.h"
9#include "src/zone-containers.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010
11namespace v8 {
12namespace internal {
13namespace compiler {
14
Emily Bernierd0a1eb72015-03-24 16:35:39 -040015// Forward declarations.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016class GraphDecorator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000017class Node;
18class Operator;
19
20
21// Marks are used during traversal of the graph to distinguish states of nodes.
22// Each node has a mark which is a monotonically increasing integer, and a
23// {NodeMarker} has a range of values that indicate states of a node.
24typedef uint32_t Mark;
25
26
27// NodeIds are identifying numbers for nodes that can be used to index auxiliary
28// out-of-line data associated with each node.
29typedef uint32_t NodeId;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030
Ben Murdoch61f157c2016-09-16 13:49:30 +010031class Graph final : public ZoneObject {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 public:
33 explicit Graph(Zone* zone);
34
Ben Murdoch61f157c2016-09-16 13:49:30 +010035 // Scope used when creating a subgraph for inlining. Automatically preserves
36 // the original start and end nodes of the graph, and resets them when you
37 // leave the scope.
38 class SubgraphScope final {
39 public:
40 explicit SubgraphScope(Graph* graph)
41 : graph_(graph), start_(graph->start()), end_(graph->end()) {}
42 ~SubgraphScope() {
43 graph_->SetStart(start_);
44 graph_->SetEnd(end_);
45 }
46
47 private:
48 Graph* const graph_;
49 Node* const start_;
50 Node* const end_;
51
52 DISALLOW_COPY_AND_ASSIGN(SubgraphScope);
53 };
54
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055 // Base implementation used by all factory methods.
Ben Murdoch097c5b22016-05-18 11:27:45 +010056 Node* NewNodeUnchecked(const Operator* op, int input_count,
57 Node* const* inputs, bool incomplete = false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058
59 // Factory that checks the input count.
Ben Murdoch097c5b22016-05-18 11:27:45 +010060 Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
Emily Bernierd0a1eb72015-03-24 16:35:39 -040061 bool incomplete = false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062
63 // Factories for nodes with static input counts.
64 Node* NewNode(const Operator* op) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010065 return NewNode(op, 0, static_cast<Node* const*>(nullptr));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000066 }
67 Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
68 Node* NewNode(const Operator* op, Node* n1, Node* n2) {
69 Node* nodes[] = {n1, n2};
70 return NewNode(op, arraysize(nodes), nodes);
71 }
72 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
73 Node* nodes[] = {n1, n2, n3};
74 return NewNode(op, arraysize(nodes), nodes);
75 }
76 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
77 Node* nodes[] = {n1, n2, n3, n4};
78 return NewNode(op, arraysize(nodes), nodes);
79 }
80 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
81 Node* n5) {
82 Node* nodes[] = {n1, n2, n3, n4, n5};
83 return NewNode(op, arraysize(nodes), nodes);
84 }
85 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
86 Node* n5, Node* n6) {
87 Node* nodes[] = {n1, n2, n3, n4, n5, n6};
88 return NewNode(op, arraysize(nodes), nodes);
89 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040090 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
91 Node* n5, Node* n6, Node* n7) {
92 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
93 return NewNode(op, arraysize(nodes), nodes);
94 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
96 Node* n5, Node* n6, Node* n7, Node* n8) {
97 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8};
98 return NewNode(op, arraysize(nodes), nodes);
99 }
100 Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
101 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9) {
102 Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9};
103 return NewNode(op, arraysize(nodes), nodes);
104 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 // Clone the {node}, and assign a new node id to the copy.
107 Node* CloneNode(const Node* node);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109 Zone* zone() const { return zone_; }
110 Node* start() const { return start_; }
111 Node* end() const { return end_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400113 void SetStart(Node* start) { start_ = start; }
114 void SetEnd(Node* end) { end_ = end; }
115
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000116 size_t NodeCount() const { return next_node_id_; }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117
118 void Decorate(Node* node);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 void AddDecorator(GraphDecorator* decorator);
120 void RemoveDecorator(GraphDecorator* decorator);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121
122 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 friend class NodeMarkerBase;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400124
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125 inline NodeId NextNodeId();
126
127 Zone* const zone_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400128 Node* start_;
129 Node* end_;
130 Mark mark_max_;
131 NodeId next_node_id_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 ZoneVector<GraphDecorator*> decorators_;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400133
134 DISALLOW_COPY_AND_ASSIGN(Graph);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135};
136
137
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400138// A graph decorator can be used to add behavior to the creation of nodes
139// in a graph.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140class GraphDecorator : public ZoneObject {
141 public:
142 virtual ~GraphDecorator() {}
143 virtual void Decorate(Node* node) = 0;
144};
145
146} // namespace compiler
147} // namespace internal
148} // namespace v8
149
150#endif // V8_COMPILER_GRAPH_H_