// Copyright 2013 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_COMPILER_GRAPH_H_
#define V8_COMPILER_GRAPH_H_
#include "src/base/compiler-specific.h"
#include "src/globals.h"
#include "src/zone/zone-containers.h"
#include "src/zone/zone.h"
namespace v8 {
namespace internal {
namespace compiler {
// Forward declarations.
class GraphDecorator;
class Node;
class Operator;
// Marks are used during traversal of the graph to distinguish states of nodes.
// Each node has a mark which is a monotonically increasing integer, and a
// {NodeMarker} has a range of values that indicate states of a node.
typedef uint32_t Mark;
// NodeIds are identifying numbers for nodes that can be used to index auxiliary
// out-of-line data associated with each node.
typedef uint32_t NodeId;
class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
public:
explicit Graph(Zone* zone);
// Scope used when creating a subgraph for inlining. Automatically preserves
// the original start and end nodes of the graph, and resets them when you
// leave the scope.
class SubgraphScope final {
public:
explicit SubgraphScope(Graph* graph)
: graph_(graph), start_(graph->start()), end_(graph->end()) {}
~SubgraphScope() {
graph_->SetStart(start_);
graph_->SetEnd(end_);
}
private:
Graph* const graph_;
Node* const start_;
Node* const end_;
DISALLOW_COPY_AND_ASSIGN(SubgraphScope);
};
// Base implementation used by all factory methods.
Node* NewNodeUnchecked(const Operator* op, int input_count,
Node* const* inputs, bool incomplete = false);
// Factory that checks the input count.
Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
bool incomplete = false);
// Factories for nodes with static input counts.
Node* NewNode(const Operator* op) {
return NewNode(op, 0, static_cast<Node* const*>(nullptr));
}
Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
Node* NewNode(const Operator* op, Node* n1, Node* n2) {
Node* nodes[] = {n1, n2};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
Node* nodes[] = {n1, n2, n3};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
Node* nodes[] = {n1, n2, n3, n4};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5) {
Node* nodes[] = {n1, n2, n3, n4, n5};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5, Node* n6) {
Node* nodes[] = {n1, n2, n3, n4, n5, n6};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5, Node* n6, Node* n7) {
Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5, Node* n6, Node* n7, Node* n8) {
Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8};
return NewNode(op, arraysize(nodes), nodes);
}
Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
Node* n5, Node* n6, Node* n7, Node* n8, Node* n9) {
Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9};
return NewNode(op, arraysize(nodes), nodes);
}
// Clone the {node}, and assign a new node id to the copy.
Node* CloneNode(const Node* node);
Zone* zone() const { return zone_; }
Node* start() const { return start_; }
Node* end() const { return end_; }
void SetStart(Node* start) { start_ = start; }
void SetEnd(Node* end) { end_ = end; }
size_t NodeCount() const { return next_node_id_; }
void Decorate(Node* node);
void AddDecorator(GraphDecorator* decorator);
void RemoveDecorator(GraphDecorator* decorator);
// Very simple print API usable in a debugger.
void Print() const;
private:
friend class NodeMarkerBase;
inline NodeId NextNodeId();
Zone* const zone_;
Node* start_;
Node* end_;
Mark mark_max_;
NodeId next_node_id_;
ZoneVector<GraphDecorator*> decorators_;
DISALLOW_COPY_AND_ASSIGN(Graph);
};
// A graph decorator can be used to add behavior to the creation of nodes
// in a graph.
class GraphDecorator : public ZoneObject {
public:
virtual ~GraphDecorator() {}
virtual void Decorate(Node* node) = 0;
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_GRAPH_H_