Home | History | Annotate | Download | only in compiler
      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/base/compiler-specific.h"
      9 #include "src/globals.h"
     10 #include "src/zone/zone-containers.h"
     11 #include "src/zone/zone.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 namespace compiler {
     16 
     17 // Forward declarations.
     18 class GraphDecorator;
     19 class Node;
     20 class Operator;
     21 
     22 
     23 // Marks are used during traversal of the graph to distinguish states of nodes.
     24 // Each node has a mark which is a monotonically increasing integer, and a
     25 // {NodeMarker} has a range of values that indicate states of a node.
     26 typedef uint32_t Mark;
     27 
     28 
     29 // NodeIds are identifying numbers for nodes that can be used to index auxiliary
     30 // 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  public:
     35   explicit Graph(Zone* zone);
     36 
     37   // Scope used when creating a subgraph for inlining. Automatically preserves
     38   // the original start and end nodes of the graph, and resets them when you
     39   // leave the scope.
     40   class SubgraphScope final {
     41    public:
     42     explicit SubgraphScope(Graph* graph)
     43         : graph_(graph), start_(graph->start()), end_(graph->end()) {}
     44     ~SubgraphScope() {
     45       graph_->SetStart(start_);
     46       graph_->SetEnd(end_);
     47     }
     48 
     49    private:
     50     Graph* const graph_;
     51     Node* const start_;
     52     Node* const end_;
     53 
     54     DISALLOW_COPY_AND_ASSIGN(SubgraphScope);
     55   };
     56 
     57   // Base implementation used by all factory methods.
     58   Node* NewNodeUnchecked(const Operator* op, int input_count,
     59                          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   Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
     70   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                 Node* n5) {
     84     Node* nodes[] = {n1, n2, n3, n4, n5};
     85     return NewNode(op, arraysize(nodes), nodes);
     86   }
     87   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
     88                 Node* n5, Node* n6) {
     89     Node* nodes[] = {n1, n2, n3, n4, n5, n6};
     90     return NewNode(op, arraysize(nodes), nodes);
     91   }
     92   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
     93                 Node* n5, Node* n6, Node* n7) {
     94     Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
     95     return NewNode(op, arraysize(nodes), nodes);
     96   }
     97   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
     98                 Node* n5, Node* n6, Node* n7, Node* n8) {
     99     Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8};
    100     return NewNode(op, arraysize(nodes), nodes);
    101   }
    102   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
    103                 Node* n5, Node* n6, Node* n7, Node* n8, Node* n9) {
    104     Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7, n8, n9};
    105     return NewNode(op, arraysize(nodes), nodes);
    106   }
    107 
    108   // Clone the {node}, and assign a new node id to the copy.
    109   Node* CloneNode(const Node* node);
    110 
    111   Zone* zone() const { return zone_; }
    112   Node* start() const { return start_; }
    113   Node* end() const { return end_; }
    114 
    115   void SetStart(Node* start) { start_ = start; }
    116   void SetEnd(Node* end) { end_ = end; }
    117 
    118   size_t NodeCount() const { return next_node_id_; }
    119 
    120   void Decorate(Node* node);
    121   void AddDecorator(GraphDecorator* decorator);
    122   void RemoveDecorator(GraphDecorator* decorator);
    123 
    124   // Very simple print API usable in a debugger.
    125   void Print() const;
    126 
    127  private:
    128   friend class NodeMarkerBase;
    129 
    130   inline NodeId NextNodeId();
    131 
    132   Zone* const zone_;
    133   Node* start_;
    134   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 // A graph decorator can be used to add behavior to the creation of nodes
    144 // in a graph.
    145 class GraphDecorator : public ZoneObject {
    146  public:
    147   virtual ~GraphDecorator() {}
    148   virtual void Decorate(Node* node) = 0;
    149 };
    150 
    151 }  // namespace compiler
    152 }  // namespace internal
    153 }  // namespace v8
    154 
    155 #endif  // V8_COMPILER_GRAPH_H_
    156