blob: c8af078895fb65653cbc44348540ac553427b7cb [file] [log] [blame]
// 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.
#include <array>
#include "src/base/compiler-specific.h"
#include "src/common/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.
using Mark = uint32_t;
// NodeIds are identifying numbers for nodes that can be used to index auxiliary
// out-of-line data associated with each node.
using NodeId = uint32_t;
class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
explicit Graph(Zone* zone);
Graph(const Graph&) = delete;
Graph& operator=(const Graph&) = delete;
// 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 {
explicit SubgraphScope(Graph* graph)
: graph_(graph), start_(graph->start()), end_(graph->end()) {}
~SubgraphScope() {
SubgraphScope(const SubgraphScope&) = delete;
SubgraphScope& operator=(const SubgraphScope&) = delete;
Graph* const graph_;
Node* const start_;
Node* const end_;
// 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);
// Factory template for nodes with static input counts.
// Note: Template magic below is used to ensure this method is only considered
// for argument types convertible to Node* during overload resoluation.
template <typename... Nodes,
typename = typename std::enable_if_t<
base::all(std::is_convertible<Nodes, Node*>::value...)>>
Node* NewNode(const Operator* op, Nodes... nodes) {
std::array<Node*, sizeof...(nodes)> nodes_arr{
return NewNode(op, nodes_arr.size(),;
// 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;
friend class NodeMarkerBase;
inline NodeId NextNodeId();
Zone* const zone_;
Node* start_;
Node* end_;
Mark mark_max_;
NodeId next_node_id_;
ZoneVector<GraphDecorator*> decorators_;
// A graph decorator can be used to add behavior to the creation of nodes
// in a graph.
class GraphDecorator : public ZoneObject {
virtual ~GraphDecorator() = default;
virtual void Decorate(Node* node) = 0;
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_COMPILER_GRAPH_H_