Chromium Code Reviews| 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...) Expand 10 before | Expand all | Expand 10 after 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...) Expand 10 before | Expand all | Expand 10 after 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 |