• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/zone.h"
9 #include "src/zone-containers.h"
10 
11 namespace v8 {
12 namespace internal {
13 namespace compiler {
14 
15 // Forward declarations.
16 class GraphDecorator;
17 class Node;
18 class 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.
24 typedef 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.
29 typedef uint32_t NodeId;
30 
31 class Graph final : public ZoneObject {
32  public:
33   explicit Graph(Zone* zone);
34 
35   // 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:
SubgraphScope(Graph * graph)40     explicit SubgraphScope(Graph* graph)
41         : graph_(graph), start_(graph->start()), end_(graph->end()) {}
~SubgraphScope()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 
55   // Base implementation used by all factory methods.
56   Node* NewNodeUnchecked(const Operator* op, int input_count,
57                          Node* const* inputs, bool incomplete = false);
58 
59   // Factory that checks the input count.
60   Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
61                 bool incomplete = false);
62 
63   // Factories for nodes with static input counts.
NewNode(const Operator * op)64   Node* NewNode(const Operator* op) {
65     return NewNode(op, 0, static_cast<Node* const*>(nullptr));
66   }
NewNode(const Operator * op,Node * n1)67   Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
NewNode(const Operator * op,Node * n1,Node * n2)68   Node* NewNode(const Operator* op, Node* n1, Node* n2) {
69     Node* nodes[] = {n1, n2};
70     return NewNode(op, arraysize(nodes), nodes);
71   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3)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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4)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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5)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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5,Node * n6)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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5,Node * n6,Node * n7)90   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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5,Node * n6,Node * n7,Node * n8)95   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   }
NewNode(const Operator * op,Node * n1,Node * n2,Node * n3,Node * n4,Node * n5,Node * n6,Node * n7,Node * n8,Node * n9)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   }
105 
106   // Clone the {node}, and assign a new node id to the copy.
107   Node* CloneNode(const Node* node);
108 
zone()109   Zone* zone() const { return zone_; }
start()110   Node* start() const { return start_; }
end()111   Node* end() const { return end_; }
112 
SetStart(Node * start)113   void SetStart(Node* start) { start_ = start; }
SetEnd(Node * end)114   void SetEnd(Node* end) { end_ = end; }
115 
NodeCount()116   size_t NodeCount() const { return next_node_id_; }
117 
118   void Decorate(Node* node);
119   void AddDecorator(GraphDecorator* decorator);
120   void RemoveDecorator(GraphDecorator* decorator);
121 
122  private:
123   friend class NodeMarkerBase;
124 
125   inline NodeId NextNodeId();
126 
127   Zone* const zone_;
128   Node* start_;
129   Node* end_;
130   Mark mark_max_;
131   NodeId next_node_id_;
132   ZoneVector<GraphDecorator*> decorators_;
133 
134   DISALLOW_COPY_AND_ASSIGN(Graph);
135 };
136 
137 
138 // A graph decorator can be used to add behavior to the creation of nodes
139 // in a graph.
140 class GraphDecorator : public ZoneObject {
141  public:
~GraphDecorator()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_
151