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 <array>
9
10 #include "src/base/compiler-specific.h"
11 #include "src/globals.h"
12 #include "src/zone/zone-containers.h"
13 #include "src/zone/zone.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
19 // Forward declarations.
20 class GraphDecorator;
21 class Node;
22 class Operator;
23
24
25 // Marks are used during traversal of the graph to distinguish states of nodes.
26 // Each node has a mark which is a monotonically increasing integer, and a
27 // {NodeMarker} has a range of values that indicate states of a node.
28 typedef uint32_t Mark;
29
30
31 // NodeIds are identifying numbers for nodes that can be used to index auxiliary
32 // out-of-line data associated with each node.
33 typedef uint32_t NodeId;
34
NON_EXPORTED_BASE(ZoneObject)35 class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
36 public:
37 explicit Graph(Zone* zone);
38
39 // Scope used when creating a subgraph for inlining. Automatically preserves
40 // the original start and end nodes of the graph, and resets them when you
41 // leave the scope.
42 class SubgraphScope final {
43 public:
44 explicit SubgraphScope(Graph* graph)
45 : graph_(graph), start_(graph->start()), end_(graph->end()) {}
46 ~SubgraphScope() {
47 graph_->SetStart(start_);
48 graph_->SetEnd(end_);
49 }
50
51 private:
52 Graph* const graph_;
53 Node* const start_;
54 Node* const end_;
55
56 DISALLOW_COPY_AND_ASSIGN(SubgraphScope);
57 };
58
59 // Base implementation used by all factory methods.
60 Node* NewNodeUnchecked(const Operator* op, int input_count,
61 Node* const* inputs, bool incomplete = false);
62
63 // Factory that checks the input count.
64 Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
65 bool incomplete = false);
66
67 // Factory template for nodes with static input counts.
68 template <typename... Nodes>
69 Node* NewNode(const Operator* op, Nodes*... nodes) {
70 std::array<Node*, sizeof...(nodes)> nodes_arr{{nodes...}};
71 return NewNode(op, nodes_arr.size(), nodes_arr.data());
72 }
73
74 // Clone the {node}, and assign a new node id to the copy.
75 Node* CloneNode(const Node* node);
76
77 Zone* zone() const { return zone_; }
78 Node* start() const { return start_; }
79 Node* end() const { return end_; }
80
81 void SetStart(Node* start) { start_ = start; }
82 void SetEnd(Node* end) { end_ = end; }
83
84 size_t NodeCount() const { return next_node_id_; }
85
86 void Decorate(Node* node);
87 void AddDecorator(GraphDecorator* decorator);
88 void RemoveDecorator(GraphDecorator* decorator);
89
90 // Very simple print API usable in a debugger.
91 void Print() const;
92
93 private:
94 friend class NodeMarkerBase;
95
96 inline NodeId NextNodeId();
97
98 Zone* const zone_;
99 Node* start_;
100 Node* end_;
101 Mark mark_max_;
102 NodeId next_node_id_;
103 ZoneVector<GraphDecorator*> decorators_;
104
105 DISALLOW_COPY_AND_ASSIGN(Graph);
106 };
107
108
109 // A graph decorator can be used to add behavior to the creation of nodes
110 // in a graph.
111 class GraphDecorator : public ZoneObject {
112 public:
~GraphDecorator()113 virtual ~GraphDecorator() {}
114 virtual void Decorate(Node* node) = 0;
115 };
116
117 } // namespace compiler
118 } // namespace internal
119 } // namespace v8
120
121 #endif // V8_COMPILER_GRAPH_H_
122