OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 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 | 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 #include "src/compiler/loop-analysis.h" | 5 #include "src/compiler/loop-analysis.h" |
6 | 6 |
7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/node-marker.h" | 9 #include "src/compiler/node-marker.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 134 matching lines...) Loading... | |
145 // Propagate marks backward from loop headers. | 145 // Propagate marks backward from loop headers. |
146 void PropagateBackward() { | 146 void PropagateBackward() { |
147 PropagateBackward(end_, kVisited); | 147 PropagateBackward(end_, kVisited); |
148 | 148 |
149 while (!queue_.empty()) { | 149 while (!queue_.empty()) { |
150 Node* node = queue_.front(); | 150 Node* node = queue_.front(); |
151 queue_.pop_front(); | 151 queue_.pop_front(); |
152 queued_.Set(node, false); | 152 queued_.Set(node, false); |
153 | 153 |
154 // Setup loop headers first. | 154 // Setup loop headers first. |
155 NodeInfo& ni = info(node); | |
155 if (node->opcode() == IrOpcode::kLoop) { | 156 if (node->opcode() == IrOpcode::kLoop) { |
156 // found the loop node first. | 157 // found the loop node first. |
157 CreateLoopInfo(node); | 158 CreateLoopInfo(node, ni); |
158 } else if (node->opcode() == IrOpcode::kPhi || | 159 } else if (node->opcode() == IrOpcode::kPhi || |
159 node->opcode() == IrOpcode::kEffectPhi) { | 160 node->opcode() == IrOpcode::kEffectPhi) { |
160 // found a phi first. | 161 // found a phi first. |
161 Node* merge = node->InputAt(node->InputCount() - 1); | 162 Node* merge = node->InputAt(node->InputCount() - 1); |
162 if (merge->opcode() == IrOpcode::kLoop) CreateLoopInfo(merge); | 163 if (merge->opcode() == IrOpcode::kLoop) { |
164 ni.MarkBackward(CreateLoopInfo(merge, info(merge)).loop_mark); | |
165 } | |
163 } | 166 } |
164 | 167 |
165 // Propagate reachability marks backwards from this node. | 168 // Propagate reachability marks backwards from this node. |
166 NodeInfo& ni = info(node); | |
167 if (ni.IsLoopHeader()) { | 169 if (ni.IsLoopHeader()) { |
168 // Handle edges from loop header nodes specially. | 170 // Handle edges from loop header nodes specially. |
169 for (int i = 0; i < node->InputCount(); i++) { | 171 for (int i = 0; i < node->InputCount(); i++) { |
170 if (i == kAssumedLoopEntryIndex) { | 172 if (i == kAssumedLoopEntryIndex) { |
171 // Don't propagate the loop mark backwards on the entry edge. | 173 // Don't propagate the loop mark backwards on the entry edge. |
172 PropagateBackward(node->InputAt(0), | 174 PropagateBackward(node->InputAt(0), |
173 kVisited | (ni.backward & ~ni.loop_mark)); | 175 kVisited | (ni.backward & ~ni.loop_mark)); |
174 } else { | 176 } else { |
175 // Only propagate the loop mark on backedges. | 177 // Only propagate the loop mark on backedges. |
176 PropagateBackward(node->InputAt(i), ni.loop_mark); | 178 PropagateBackward(node->InputAt(i), ni.loop_mark); |
177 } | 179 } |
178 } | 180 } |
179 } else { | 181 } else { |
180 // Propagate all loop marks backwards for a normal node. | 182 // Propagate all loop marks backwards for a normal node. |
181 for (Node* const input : node->inputs()) { | 183 for (Node* const input : node->inputs()) { |
182 PropagateBackward(input, ni.backward); | 184 PropagateBackward(input, ni.backward); |
183 } | 185 } |
184 } | 186 } |
185 } | 187 } |
186 } | 188 } |
187 | 189 |
188 // Make a new loop header for the given node. | 190 // Make a new loop header for the given node. |
189 void CreateLoopInfo(Node* node) { | 191 NodeInfo& CreateLoopInfo(Node* node, NodeInfo& ni) { |
Michael Starzinger
2015/01/14 16:28:32
nit: Instead of returning the NodeInfo here, we co
| |
190 NodeInfo& ni = info(node); | 192 if (ni.IsLoopHeader()) return ni; // loop already set up. |
191 if (ni.IsLoopHeader()) return; // loop already set up. | |
192 | 193 |
193 loops_found_++; | 194 loops_found_++; |
194 size_t loop_num = loops_.size() + 1; | 195 size_t loop_num = loops_.size() + 1; |
195 CHECK(loops_found_ <= kMaxLoops); // TODO(titzer): don't crash. | 196 CHECK(loops_found_ <= kMaxLoops); // TODO(titzer): don't crash. |
196 // Create a new loop. | 197 // Create a new loop. |
197 loops_.push_back({node, nullptr, nullptr, nullptr}); | 198 loops_.push_back({node, nullptr, nullptr, nullptr}); |
198 loop_tree_->NewLoop(); | 199 loop_tree_->NewLoop(); |
199 LoopMarks loop_mark = kVisited | (1 << loop_num); | 200 LoopMarks loop_mark = kVisited | (1 << loop_num); |
200 ni.node = node; | |
201 ni.loop_mark = loop_mark; | 201 ni.loop_mark = loop_mark; |
202 | 202 |
203 // Setup loop mark for phis attached to loop header. | 203 // Setup loop mark for phis attached to loop header. |
204 for (Node* use : node->uses()) { | 204 for (Node* use : node->uses()) { |
205 if (use->opcode() == IrOpcode::kPhi || | 205 if (use->opcode() == IrOpcode::kPhi || |
206 use->opcode() == IrOpcode::kEffectPhi) { | 206 use->opcode() == IrOpcode::kEffectPhi) { |
207 info(use).loop_mark = loop_mark; | 207 info(use).loop_mark = loop_mark; |
208 } | 208 } |
209 } | 209 } |
210 return ni; | |
210 } | 211 } |
211 | 212 |
212 // Propagate marks forward from loops. | 213 // Propagate marks forward from loops. |
213 void PropagateForward() { | 214 void PropagateForward() { |
214 for (LoopInfo& li : loops_) { | 215 for (LoopInfo& li : loops_) { |
215 queued_.Set(li.header, true); | 216 queued_.Set(li.header, true); |
216 queue_.push_back(li.header); | 217 queue_.push_back(li.header); |
217 NodeInfo& ni = info(li.header); | 218 NodeInfo& ni = info(li.header); |
218 ni.forward = ni.loop_mark; | 219 ni.forward = ni.loop_mark; |
219 } | 220 } |
(...skipping 184 matching lines...) Loading... | |
404 finder.Run(); | 405 finder.Run(); |
405 if (FLAG_trace_turbo_graph) { | 406 if (FLAG_trace_turbo_graph) { |
406 finder.Print(); | 407 finder.Print(); |
407 } | 408 } |
408 return loop_tree; | 409 return loop_tree; |
409 } | 410 } |
410 | 411 |
411 } // namespace compiler | 412 } // namespace compiler |
412 } // namespace internal | 413 } // namespace internal |
413 } // namespace v8 | 414 } // namespace v8 |
OLD | NEW |