Line data Source code
1 : // 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 :
8 : #include "src/base/compiler-specific.h"
9 : #include "src/globals.h"
10 : #include "src/zone/zone-containers.h"
11 : #include "src/zone/zone.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 : namespace compiler {
16 :
17 : // Forward declarations.
18 : class GraphDecorator;
19 : class Node;
20 : class 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.
26 : typedef 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.
31 : typedef uint32_t NodeId;
32 :
33 : class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
34 : public:
35 : explicit Graph(Zone* zone);
36 :
37 : // 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 38030 : 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 :
57 : // Base implementation used by all factory methods.
58 : Node* NewNodeUnchecked(const Operator* op, int input_count,
59 : Node* const* inputs, bool incomplete = false);
60 :
61 : // Factory that checks the input count.
62 : Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
63 : bool incomplete = false);
64 :
65 : // Factories for nodes with static input counts.
66 : Node* NewNode(const Operator* op) {
67 26954086 : return NewNode(op, 0, static_cast<Node* const*>(nullptr));
68 : }
69 8432787 : Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
70 : Node* NewNode(const Operator* op, Node* n1, Node* n2) {
71 10991922 : Node* nodes[] = {n1, n2};
72 10991922 : return NewNode(op, arraysize(nodes), nodes);
73 : }
74 : Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
75 2476563 : Node* nodes[] = {n1, n2, n3};
76 2476563 : return NewNode(op, arraysize(nodes), nodes);
77 : }
78 : Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
79 2782932 : Node* nodes[] = {n1, n2, n3, n4};
80 2782932 : 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 479166 : Node* nodes[] = {n1, n2, n3, n4, n5};
85 479166 : 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 6020167 : Node* nodes[] = {n1, n2, n3, n4, n5, n6};
90 6020167 : return NewNode(op, arraysize(nodes), nodes);
91 : }
92 : Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
93 : Node* n5, Node* n6, Node* n7) {
94 4375 : Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
95 4375 : return NewNode(op, arraysize(nodes), nodes);
96 : }
97 : 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 : }
107 :
108 : // Clone the {node}, and assign a new node id to the copy.
109 : Node* CloneNode(const Node* node);
110 :
111 : Zone* zone() const { return zone_; }
112 : Node* start() const { return start_; }
113 : Node* end() const { return end_; }
114 :
115 962747 : void SetStart(Node* start) { start_ = start; }
116 962402 : void SetEnd(Node* end) { end_ = end; }
117 :
118 13992495 : size_t NodeCount() const { return next_node_id_; }
119 :
120 : void Decorate(Node* node);
121 : void AddDecorator(GraphDecorator* decorator);
122 : void RemoveDecorator(GraphDecorator* decorator);
123 :
124 : // Very simple print API usable in a debugger.
125 : void Print() const;
126 :
127 : private:
128 : friend class NodeMarkerBase;
129 :
130 : inline NodeId NextNodeId();
131 :
132 : Zone* const zone_;
133 : Node* start_;
134 : Node* end_;
135 : Mark mark_max_;
136 : NodeId next_node_id_;
137 : ZoneVector<GraphDecorator*> decorators_;
138 :
139 : DISALLOW_COPY_AND_ASSIGN(Graph);
140 : };
141 :
142 :
143 : // A graph decorator can be used to add behavior to the creation of nodes
144 : // in a graph.
145 791433 : class GraphDecorator : public ZoneObject {
146 : public:
147 0 : 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_
|