graph.h 4.77 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/base/compiler-specific.h"
#include "src/globals.h"
10 11
#include "src/zone/zone-containers.h"
#include "src/zone/zone.h"
12 13 14 15 16

namespace v8 {
namespace internal {
namespace compiler {

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

33
class V8_EXPORT_PRIVATE Graph final : public NON_EXPORTED_BASE(ZoneObject) {
34 35 36
 public:
  explicit Graph(Zone* zone);

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

57
  // Base implementation used by all factory methods.
58 59
  Node* NewNodeUnchecked(const Operator* op, int input_count,
                         Node* const* inputs, bool incomplete = false);
60 61

  // Factory that checks the input count.
62
  Node* NewNode(const Operator* op, int input_count, Node* const* inputs,
63
                bool incomplete = false);
64 65

  // Factories for nodes with static input counts.
66
  Node* NewNode(const Operator* op) {
67
    return NewNode(op, 0, static_cast<Node* const*>(nullptr));
68
  }
69 70
  Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
  Node* NewNode(const Operator* op, Node* n1, Node* n2) {
71
    Node* nodes[] = {n1, n2};
72
    return NewNode(op, arraysize(nodes), nodes);
73
  }
74
  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
75
    Node* nodes[] = {n1, n2, n3};
76
    return NewNode(op, arraysize(nodes), nodes);
77
  }
78
  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
79
    Node* nodes[] = {n1, n2, n3, n4};
80
    return NewNode(op, arraysize(nodes), nodes);
81
  }
82
  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
83 84
                Node* n5) {
    Node* nodes[] = {n1, n2, n3, n4, n5};
85
    return NewNode(op, arraysize(nodes), nodes);
86
  }
87 88
  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                Node* n5, Node* n6) {
89
    Node* nodes[] = {n1, n2, n3, n4, n5, n6};
90
    return NewNode(op, arraysize(nodes), nodes);
91
  }
92 93 94 95 96
  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);
  }
97 98 99 100 101
  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);
  }
102 103 104 105 106
  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);
  }
107

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

111 112 113 114 115 116 117
  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; }

118
  size_t NodeCount() const { return next_node_id_; }
119

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

124 125 126
  // Very simple print API usable in a debugger.
  void Print() const;

127
 private:
128
  friend class NodeMarkerBase;
129

130 131 132
  inline NodeId NextNodeId();

  Zone* const zone_;
133 134
  Node* start_;
  Node* end_;
135
  Mark mark_max_;
136
  NodeId next_node_id_;
137
  ZoneVector<GraphDecorator*> decorators_;
138 139

  DISALLOW_COPY_AND_ASSIGN(Graph);
140 141 142
};


143 144
// A graph decorator can be used to add behavior to the creation of nodes
// in a graph.
145 146 147
class GraphDecorator : public ZoneObject {
 public:
  virtual ~GraphDecorator() {}
148
  virtual void Decorate(Node* node) = 0;
149
};
150 151 152 153

}  // namespace compiler
}  // namespace internal
}  // namespace v8
154 155

#endif  // V8_COMPILER_GRAPH_H_