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 11namespace v8 { 12namespace internal { 13namespace compiler { 14 15// Forward declarations. 16class GraphDecorator; 17class 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; 30 31class 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: 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 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. 64 Node* NewNode(const Operator* op) { 65 return NewNode(op, 0, static_cast<Node* const*>(nullptr)); 66 } 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 } 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 } 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 } 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 109 Zone* zone() const { return zone_; } 110 Node* start() const { return start_; } 111 Node* end() const { return end_; } 112 113 void SetStart(Node* start) { start_ = start; } 114 void SetEnd(Node* end) { end_ = end; } 115 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. 140class 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_ 151