| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_COMPILER_LOOP_ANALYSIS_H_ | 5 #ifndef V8_COMPILER_LOOP_ANALYSIS_H_ |
| 6 #define V8_COMPILER_LOOP_ANALYSIS_H_ | 6 #define V8_COMPILER_LOOP_ANALYSIS_H_ |
| 7 | 7 |
| 8 #include "src/base/iterator.h" | 8 #include "src/base/iterator.h" |
| 9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
| 10 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 node_to_loop_num_(static_cast<int>(num_nodes), -1, zone), | 31 node_to_loop_num_(static_cast<int>(num_nodes), -1, zone), |
| 32 loop_nodes_(zone) {} | 32 loop_nodes_(zone) {} |
| 33 | 33 |
| 34 // Represents a loop in the tree of loops, including the header nodes, | 34 // Represents a loop in the tree of loops, including the header nodes, |
| 35 // the body, and any nested loops. | 35 // the body, and any nested loops. |
| 36 class Loop { | 36 class Loop { |
| 37 public: | 37 public: |
| 38 Loop* parent() const { return parent_; } | 38 Loop* parent() const { return parent_; } |
| 39 const ZoneVector<Loop*>& children() const { return children_; } | 39 const ZoneVector<Loop*>& children() const { return children_; } |
| 40 size_t HeaderSize() const { return body_start_ - header_start_; } | 40 size_t HeaderSize() const { return body_start_ - header_start_; } |
| 41 size_t BodySize() const { return body_end_ - body_start_; } | 41 size_t BodySize() const { return exits_start_ - body_start_; } |
| 42 size_t TotalSize() const { return body_end_ - header_start_; } | 42 size_t ExitsSize() const { return exits_end_ - exits_start_; } |
| 43 size_t TotalSize() const { return exits_end_ - header_start_; } |
| 43 size_t depth() const { return static_cast<size_t>(depth_); } | 44 size_t depth() const { return static_cast<size_t>(depth_); } |
| 44 | 45 |
| 45 private: | 46 private: |
| 46 friend class LoopTree; | 47 friend class LoopTree; |
| 47 friend class LoopFinderImpl; | 48 friend class LoopFinderImpl; |
| 48 | 49 |
| 49 explicit Loop(Zone* zone) | 50 explicit Loop(Zone* zone) |
| 50 : parent_(nullptr), | 51 : parent_(nullptr), |
| 51 depth_(0), | 52 depth_(0), |
| 52 children_(zone), | 53 children_(zone), |
| 53 header_start_(-1), | 54 header_start_(-1), |
| 54 body_start_(-1), | 55 body_start_(-1), |
| 55 body_end_(-1) {} | 56 exits_start_(-1), |
| 57 exits_end_(-1) {} |
| 56 Loop* parent_; | 58 Loop* parent_; |
| 57 int depth_; | 59 int depth_; |
| 58 ZoneVector<Loop*> children_; | 60 ZoneVector<Loop*> children_; |
| 59 int header_start_; | 61 int header_start_; |
| 60 int body_start_; | 62 int body_start_; |
| 61 int body_end_; | 63 int exits_start_; |
| 64 int exits_end_; |
| 62 }; | 65 }; |
| 63 | 66 |
| 64 // Return the innermost nested loop, if any, that contains {node}. | 67 // Return the innermost nested loop, if any, that contains {node}. |
| 65 Loop* ContainingLoop(Node* node) { | 68 Loop* ContainingLoop(Node* node) { |
| 66 if (node->id() >= node_to_loop_num_.size()) return nullptr; | 69 if (node->id() >= node_to_loop_num_.size()) return nullptr; |
| 67 int num = node_to_loop_num_[node->id()]; | 70 int num = node_to_loop_num_[node->id()]; |
| 68 return num > 0 ? &all_loops_[num - 1] : nullptr; | 71 return num > 0 ? &all_loops_[num - 1] : nullptr; |
| 69 } | 72 } |
| 70 | 73 |
| 71 // Check if the {loop} contains the {node}, either directly or by containing | 74 // Check if the {loop} contains the {node}, either directly or by containing |
| (...skipping 18 matching lines...) Expand all Loading... |
| 90 return NodeRange(&loop_nodes_[0] + loop->header_start_, | 93 return NodeRange(&loop_nodes_[0] + loop->header_start_, |
| 91 &loop_nodes_[0] + loop->body_start_); | 94 &loop_nodes_[0] + loop->body_start_); |
| 92 } | 95 } |
| 93 | 96 |
| 94 // Return the header control node for a loop. | 97 // Return the header control node for a loop. |
| 95 Node* HeaderNode(Loop* loop); | 98 Node* HeaderNode(Loop* loop); |
| 96 | 99 |
| 97 // Return a range which can iterate over the body nodes of {loop}. | 100 // Return a range which can iterate over the body nodes of {loop}. |
| 98 NodeRange BodyNodes(Loop* loop) { | 101 NodeRange BodyNodes(Loop* loop) { |
| 99 return NodeRange(&loop_nodes_[0] + loop->body_start_, | 102 return NodeRange(&loop_nodes_[0] + loop->body_start_, |
| 100 &loop_nodes_[0] + loop->body_end_); | 103 &loop_nodes_[0] + loop->exits_start_); |
| 104 } |
| 105 |
| 106 // Return a range which can iterate over the body nodes of {loop}. |
| 107 NodeRange ExitNodes(Loop* loop) { |
| 108 return NodeRange(&loop_nodes_[0] + loop->exits_start_, |
| 109 &loop_nodes_[0] + loop->exits_end_); |
| 101 } | 110 } |
| 102 | 111 |
| 103 // Return a range which can iterate over the nodes of {loop}. | 112 // Return a range which can iterate over the nodes of {loop}. |
| 104 NodeRange LoopNodes(Loop* loop) { | 113 NodeRange LoopNodes(Loop* loop) { |
| 105 return NodeRange(&loop_nodes_[0] + loop->header_start_, | 114 return NodeRange(&loop_nodes_[0] + loop->header_start_, |
| 106 &loop_nodes_[0] + loop->body_end_); | 115 &loop_nodes_[0] + loop->exits_end_); |
| 107 } | 116 } |
| 108 | 117 |
| 109 // Return the node that represents the control, i.e. the loop node itself. | 118 // Return the node that represents the control, i.e. the loop node itself. |
| 110 Node* GetLoopControl(Loop* loop) { | 119 Node* GetLoopControl(Loop* loop) { |
| 111 // TODO(turbofan): make the loop control node always first? | 120 // TODO(turbofan): make the loop control node always first? |
| 112 for (Node* node : HeaderNodes(loop)) { | 121 for (Node* node : HeaderNodes(loop)) { |
| 113 if (node->opcode() == IrOpcode::kLoop) return node; | 122 if (node->opcode() == IrOpcode::kLoop) return node; |
| 114 } | 123 } |
| 115 UNREACHABLE(); | 124 UNREACHABLE(); |
| 116 return nullptr; | 125 return nullptr; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 // Build a loop tree for the entire graph. | 158 // Build a loop tree for the entire graph. |
| 150 static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone); | 159 static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone); |
| 151 }; | 160 }; |
| 152 | 161 |
| 153 | 162 |
| 154 } // namespace compiler | 163 } // namespace compiler |
| 155 } // namespace internal | 164 } // namespace internal |
| 156 } // namespace v8 | 165 } // namespace v8 |
| 157 | 166 |
| 158 #endif // V8_COMPILER_LOOP_ANALYSIS_H_ | 167 #endif // V8_COMPILER_LOOP_ANALYSIS_H_ |
| OLD | NEW |