V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
loop-analysis.h
1 // Copyright 2014 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_LOOP_ANALYSIS_H_
6 #define V8_COMPILER_LOOP_ANALYSIS_H_
7 
8 #include "src/base/iterator.h"
9 #include "src/compiler/graph.h"
10 #include "src/compiler/node.h"
11 #include "src/globals.h"
12 #include "src/zone/zone-containers.h"
13 
14 namespace v8 {
15 namespace internal {
16 namespace compiler {
17 
18 // TODO(titzer): don't assume entry edges have a particular index.
19 static const int kAssumedLoopEntryIndex = 0; // assume loops are entered here.
20 
21 class LoopFinderImpl;
22 
23 typedef base::iterator_range<Node**> NodeRange;
24 
25 // Represents a tree of loops in a graph.
26 class LoopTree : public ZoneObject {
27  public:
28  LoopTree(size_t num_nodes, Zone* zone)
29  : zone_(zone),
30  outer_loops_(zone),
31  all_loops_(zone),
32  node_to_loop_num_(static_cast<int>(num_nodes), -1, zone),
33  loop_nodes_(zone) {}
34 
35  // Represents a loop in the tree of loops, including the header nodes,
36  // the body, and any nested loops.
37  class Loop {
38  public:
39  Loop* parent() const { return parent_; }
40  const ZoneVector<Loop*>& children() const { return children_; }
41  size_t HeaderSize() const { return body_start_ - header_start_; }
42  size_t BodySize() const { return exits_start_ - body_start_; }
43  size_t ExitsSize() const { return exits_end_ - exits_start_; }
44  size_t TotalSize() const { return exits_end_ - header_start_; }
45  size_t depth() const { return static_cast<size_t>(depth_); }
46 
47  private:
48  friend class LoopTree;
49  friend class LoopFinderImpl;
50 
51  explicit Loop(Zone* zone)
52  : parent_(nullptr),
53  depth_(0),
54  children_(zone),
55  header_start_(-1),
56  body_start_(-1),
57  exits_start_(-1),
58  exits_end_(-1) {}
59  Loop* parent_;
60  int depth_;
61  ZoneVector<Loop*> children_;
62  int header_start_;
63  int body_start_;
64  int exits_start_;
65  int exits_end_;
66  };
67 
68  // Return the innermost nested loop, if any, that contains {node}.
69  Loop* ContainingLoop(Node* node) {
70  if (node->id() >= node_to_loop_num_.size()) return nullptr;
71  int num = node_to_loop_num_[node->id()];
72  return num > 0 ? &all_loops_[num - 1] : nullptr;
73  }
74 
75  // Check if the {loop} contains the {node}, either directly or by containing
76  // a nested loop that contains {node}.
77  bool Contains(Loop* loop, Node* node) {
78  for (Loop* c = ContainingLoop(node); c != nullptr; c = c->parent_) {
79  if (c == loop) return true;
80  }
81  return false;
82  }
83 
84  // Return the list of outer loops.
85  const ZoneVector<Loop*>& outer_loops() const { return outer_loops_; }
86 
87  // Return the unique loop number for a given loop. Loop numbers start at {1}.
88  int LoopNum(Loop* loop) const {
89  return 1 + static_cast<int>(loop - &all_loops_[0]);
90  }
91 
92  // Return a range which can iterate over the header nodes of {loop}.
93  NodeRange HeaderNodes(Loop* loop) {
94  return NodeRange(&loop_nodes_[0] + loop->header_start_,
95  &loop_nodes_[0] + loop->body_start_);
96  }
97 
98  // Return the header control node for a loop.
99  Node* HeaderNode(Loop* loop);
100 
101  // Return a range which can iterate over the body nodes of {loop}.
102  NodeRange BodyNodes(Loop* loop) {
103  return NodeRange(&loop_nodes_[0] + loop->body_start_,
104  &loop_nodes_[0] + loop->exits_start_);
105  }
106 
107  // Return a range which can iterate over the body nodes of {loop}.
108  NodeRange ExitNodes(Loop* loop) {
109  return NodeRange(&loop_nodes_[0] + loop->exits_start_,
110  &loop_nodes_[0] + loop->exits_end_);
111  }
112 
113  // Return a range which can iterate over the nodes of {loop}.
114  NodeRange LoopNodes(Loop* loop) {
115  return NodeRange(&loop_nodes_[0] + loop->header_start_,
116  &loop_nodes_[0] + loop->exits_end_);
117  }
118 
119  // Return the node that represents the control, i.e. the loop node itself.
120  Node* GetLoopControl(Loop* loop) {
121  // TODO(turbofan): make the loop control node always first?
122  for (Node* node : HeaderNodes(loop)) {
123  if (node->opcode() == IrOpcode::kLoop) return node;
124  }
125  UNREACHABLE();
126  }
127 
128  Zone* zone() const { return zone_; }
129 
130  private:
131  friend class LoopFinderImpl;
132 
133  Loop* NewLoop() {
134  all_loops_.push_back(Loop(zone_));
135  Loop* result = &all_loops_.back();
136  return result;
137  }
138 
139  void SetParent(Loop* parent, Loop* child) {
140  if (parent != nullptr) {
141  parent->children_.push_back(child);
142  child->parent_ = parent;
143  child->depth_ = parent->depth_ + 1;
144  } else {
145  outer_loops_.push_back(child);
146  }
147  }
148 
149  Zone* zone_;
150  ZoneVector<Loop*> outer_loops_;
151  ZoneVector<Loop> all_loops_;
152  ZoneVector<int> node_to_loop_num_;
153  ZoneVector<Node*> loop_nodes_;
154 };
155 
156 class V8_EXPORT_PRIVATE LoopFinder {
157  public:
158  // Build a loop tree for the entire graph.
159  static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone);
160 };
161 
162 
163 } // namespace compiler
164 } // namespace internal
165 } // namespace v8
166 
167 #endif // V8_COMPILER_LOOP_ANALYSIS_H_
Definition: libplatform.h:13