graph.h 4.59 KB
Newer Older
1 2 3 4 5 6 7
// 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_

8 9
#include "src/zone.h"
#include "src/zone-containers.h"
10 11 12 13 14

namespace v8 {
namespace internal {
namespace compiler {

15
// Forward declarations.
16
class GraphDecorator;
17 18 19 20 21 22 23 24 25 26 27 28
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.
29
typedef uint32_t NodeId;
30

31
class Graph final : public ZoneObject {
32 33 34
 public:
  explicit Graph(Zone* zone);

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
  // 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);
  };

55
  // Base implementation used by all factory methods.
56 57
  Node* NewNodeUnchecked(const Operator* op, int input_count,
                         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 68
  Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
  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 82
                Node* n5) {
    Node* nodes[] = {n1, n2, n3, n4, n5};
83
    return NewNode(op, arraysize(nodes), nodes);
84
  }
85 86
  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                Node* n5, Node* n6) {
87
    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
88
    return NewNode(op, arraysize(nodes), nodes);
89
  }
90 91 92 93 94
  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);
  }
95 96 97 98 99
  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);
  }
100 101 102 103 104
  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);
  }
105

106 107 108
  // Clone the {node}, and assign a new node id to the copy.
  Node* CloneNode(const Node* node);

109 110 111 112 113 114 115
  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; }

116
  size_t NodeCount() const { return next_node_id_; }
117

118
  void Decorate(Node* node);
119 120
  void AddDecorator(GraphDecorator* decorator);
  void RemoveDecorator(GraphDecorator* decorator);
121 122

 private:
123
  friend class NodeMarkerBase;
124

125 126 127
  inline NodeId NextNodeId();

  Zone* const zone_;
128 129
  Node* start_;
  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 139
// A graph decorator can be used to add behavior to the creation of nodes
// in a graph.
140 141 142
class GraphDecorator : public ZoneObject {
 public:
  virtual ~GraphDecorator() {}
143
  virtual void Decorate(Node* node) = 0;
144
};
145 146 147 148

}  // namespace compiler
}  // namespace internal
}  // namespace v8
149 150

#endif  // V8_COMPILER_GRAPH_H_