Index: src/compiler/loop-analysis.h |
diff --git a/src/compiler/loop-analysis.h b/src/compiler/loop-analysis.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8c8d19ac690ebc30231fe662b11a4c8b149b70a2 |
--- /dev/null |
+++ b/src/compiler/loop-analysis.h |
@@ -0,0 +1,135 @@ |
+// Copyright 2014 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_LOOP_ANALYSIS_H_ |
+#define V8_COMPILER_LOOP_ANALYSIS_H_ |
+ |
+#include "src/base/iterator.h" |
+#include "src/compiler/graph.h" |
+#include "src/compiler/node.h" |
+#include "src/zone-containers.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+class LoopFinderImpl; |
+ |
+typedef base::iterator_range<Node**> NodeRange; |
+ |
+// Represents a tree of loops in a graph. |
+class LoopTree : public ZoneObject { |
+ public: |
+ LoopTree(size_t num_nodes, Zone* zone) |
+ : zone_(zone), |
+ outer_loops_(zone), |
+ all_loops_(zone), |
+ node_to_loop_num_(static_cast<int>(num_nodes), 0, zone), |
+ loop_nodes_(zone) {} |
+ |
+ // Represents a loop in the tree of loops, including the header nodes, |
+ // the body, and any nested loops. |
+ class Loop { |
+ public: |
+ Loop* parent() const { return parent_; } |
+ const ZoneVector<Loop*>& children() const { return children_; } |
+ size_t HeaderSize() const { return body_start_ - header_start_; } |
+ size_t BodySize() const { return body_end_ - body_start_; } |
+ size_t TotalSize() const { return body_end_ - header_start_; } |
+ |
+ private: |
+ friend class LoopTree; |
+ friend class LoopFinderImpl; |
+ |
+ explicit Loop(Zone* zone) |
+ : parent_(nullptr), |
+ depth_(0), |
+ children_(zone), |
+ header_start_(-1), |
+ body_start_(-1), |
+ body_end_(-1) {} |
+ Loop* parent_; |
+ int depth_; |
+ ZoneVector<Loop*> children_; |
+ int header_start_; |
+ int body_start_; |
+ int body_end_; |
+ }; |
+ |
+ // Return the innermost nested loop, if any, that contains {node}. |
+ Loop* ContainingLoop(Node* node) { |
+ if (node->id() >= static_cast<int>(node_to_loop_num_.size())) |
+ return nullptr; |
+ uint8_t num = node_to_loop_num_[node->id()]; |
+ return num > 0 ? &all_loops_[num - 1] : nullptr; |
+ } |
+ |
+ // Check if the {loop} contains the {node}, either directly or by containing |
+ // a nested loop that contains {node}. |
+ bool Contains(Loop* loop, Node* node) { |
+ for (Loop* c = ContainingLoop(node); c != nullptr; c = c->parent_) { |
+ if (c == loop) return true; |
+ } |
+ return false; |
+ } |
+ |
+ // Return the list of outer loops. |
+ const ZoneVector<Loop*>& outer_loops() const { return outer_loops_; } |
+ |
+ // Return the unique loop number for a given loop. Loop numbers start at {1}. |
+ int LoopNum(Loop* loop) const { |
+ return 1 + static_cast<int>(loop - &all_loops_[0]); |
+ } |
+ |
+ // Return a range which can iterate over the header nodes of {loop}. |
+ NodeRange HeaderNodes(Loop* loop) { |
+ return NodeRange(&loop_nodes_[0] + loop->header_start_, |
+ &loop_nodes_[0] + loop->body_start_); |
+ } |
+ |
+ // Return a range which can iterate over the body nodes of {loop}. |
+ NodeRange BodyNodes(Loop* loop) { |
+ return NodeRange(&loop_nodes_[0] + loop->body_start_, |
+ &loop_nodes_[0] + loop->body_end_); |
+ } |
+ |
+ private: |
+ friend class LoopFinderImpl; |
+ |
+ Loop* NewLoop() { |
+ all_loops_.push_back(Loop(zone_)); |
+ Loop* result = &all_loops_.back(); |
+ return result; |
+ } |
+ |
+ void SetParent(Loop* parent, Loop* child) { |
+ if (parent != nullptr) { |
+ parent->children_.push_back(child); |
+ child->parent_ = parent; |
+ child->depth_ = parent->depth_ + 1; |
+ } else { |
+ outer_loops_.push_back(child); |
+ } |
+ } |
+ |
+ Zone* zone_; |
+ ZoneVector<Loop*> outer_loops_; |
+ ZoneVector<Loop> all_loops_; |
+ // TODO(titzer): lift loop count restriction. |
+ ZoneVector<uint8_t> node_to_loop_num_; |
+ ZoneVector<Node*> loop_nodes_; |
+}; |
+ |
+ |
+class LoopFinder { |
+ public: |
+ // Build a loop tree for the entire graph. |
+ static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone); |
+}; |
+ |
+} // namespace compiler |
+} // namespace internal |
+} // namespace v8 |
+ |
+#endif // V8_COMPILER_LOOP_ANALYSIS_H_ |