| 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 #include "src/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 #include "src/compiler/control-reducer.h" | 6 #include "src/compiler/control-reducer.h" |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/node-marker.h" | 9 #include "src/compiler/node-marker.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1); | 124 AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1); |
| 125 | 125 |
| 126 // Reset the use iterators for the entire stack. | 126 // Reset the use iterators for the entire stack. |
| 127 for (size_t i = 0; i < fw_stack.size(); i++) { | 127 for (size_t i = 0; i < fw_stack.size(); i++) { |
| 128 FwIter& iter = fw_stack[i]; | 128 FwIter& iter = fw_stack[i]; |
| 129 fw_stack[i] = FwIter(iter.first, iter.first->uses().begin()); | 129 fw_stack[i] = FwIter(iter.first, iter.first->uses().begin()); |
| 130 } | 130 } |
| 131 pop = false; // restart traversing successors of this node. | 131 pop = false; // restart traversing successors of this node. |
| 132 break; | 132 break; |
| 133 } | 133 } |
| 134 if (NodeProperties::IsControl(succ) && | 134 if (succ->op()->ControlOutputCount() > 0 && |
| 135 !marked.IsReachableFromStart(succ)) { | 135 !marked.IsReachableFromStart(succ)) { |
| 136 // {succ} is a control node and not yet reached from start. | 136 // {succ} is a control node and not yet reached from start. |
| 137 marked.Push(succ); | 137 marked.Push(succ); |
| 138 marked.SetReachableFromStart(succ); | 138 marked.SetReachableFromStart(succ); |
| 139 fw_stack.push_back(FwIter(succ, succ->uses().begin())); | 139 fw_stack.push_back(FwIter(succ, succ->uses().begin())); |
| 140 pop = false; // "recurse" into successor control node. | 140 pop = false; // "recurse" into successor control node. |
| 141 break; | 141 break; |
| 142 } | 142 } |
| 143 ++fw_stack.back().second; | 143 ++fw_stack.back().second; |
| 144 } | 144 } |
| 145 if (pop) { | 145 if (pop) { |
| 146 marked.Pop(node); | 146 marked.Pop(node); |
| 147 fw_stack.pop_back(); | 147 fw_stack.pop_back(); |
| 148 } | 148 } |
| 149 } | 149 } |
| 150 | 150 |
| 151 // Trim references from dead nodes to live nodes first. | 151 // Trim references from dead nodes to live nodes first. |
| 152 jsgraph_->GetCachedNodes(&nodes); | 152 jsgraph_->GetCachedNodes(&nodes); |
| 153 TrimNodes(marked, nodes); | 153 TrimNodes(marked, nodes); |
| 154 | 154 |
| 155 // Any control nodes not reachable from start are dead, even loops. | 155 // Any control nodes not reachable from start are dead, even loops. |
| 156 for (size_t i = 0; i < nodes.size(); i++) { | 156 for (size_t i = 0; i < nodes.size(); i++) { |
| 157 Node* node = nodes[i]; | 157 Node* node = nodes[i]; |
| 158 if (NodeProperties::IsControl(node) && | 158 if (node->op()->ControlOutputCount() > 0 && |
| 159 !marked.IsReachableFromStart(node)) { | 159 !marked.IsReachableFromStart(node)) { |
| 160 ReplaceNode(node, dead()); // uses will be added to revisit queue. | 160 ReplaceNode(node, dead()); // uses will be added to revisit queue. |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 return TryRevisit(); // try to push a node onto the stack. | 163 return TryRevisit(); // try to push a node onto the stack. |
| 164 } | 164 } |
| 165 | 165 |
| 166 // Connect {loop}, the header of a non-terminating loop, to the end node. | 166 // Connect {loop}, the header of a non-terminating loop, to the end node. |
| 167 Node* ConnectNTL(Node* loop) { | 167 Node* ConnectNTL(Node* loop) { |
| 168 TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic())); | 168 TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic())); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 183 // Mark the node as visited so that we can revisit later. | 183 // Mark the node as visited so that we can revisit later. |
| 184 MarkAsVisited(if_false); | 184 MarkAsVisited(if_false); |
| 185 | 185 |
| 186 // Hook up the branch into the loop and collect all loop effects. | 186 // Hook up the branch into the loop and collect all loop effects. |
| 187 NodeVector effects(zone_); | 187 NodeVector effects(zone_); |
| 188 for (auto edge : loop->use_edges()) { | 188 for (auto edge : loop->use_edges()) { |
| 189 DCHECK_EQ(loop, edge.to()); | 189 DCHECK_EQ(loop, edge.to()); |
| 190 DCHECK(NodeProperties::IsControlEdge(edge)); | 190 DCHECK(NodeProperties::IsControlEdge(edge)); |
| 191 if (edge.from() == branch) continue; | 191 if (edge.from() == branch) continue; |
| 192 switch (edge.from()->opcode()) { | 192 switch (edge.from()->opcode()) { |
| 193 #define CASE(Opcode) case IrOpcode::k##Opcode: | 193 case IrOpcode::kPhi: |
| 194 CONTROL_OP_LIST(CASE) | |
| 195 #undef CASE | |
| 196 // Update all control nodes (except {branch}) pointing to the {loop}. | |
| 197 edge.UpdateTo(if_true); | |
| 198 break; | 194 break; |
| 199 case IrOpcode::kEffectPhi: | 195 case IrOpcode::kEffectPhi: |
| 200 effects.push_back(edge.from()); | 196 effects.push_back(edge.from()); |
| 201 break; | 197 break; |
| 202 default: | 198 default: |
| 199 // Update all control edges (except {branch}) pointing to the {loop}. |
| 200 edge.UpdateTo(if_true); |
| 203 break; | 201 break; |
| 204 } | 202 } |
| 205 } | 203 } |
| 206 | 204 |
| 207 // Compute effects for the Return. | 205 // Compute effects for the Return. |
| 208 Node* effect = graph()->start(); | 206 Node* effect = graph()->start(); |
| 209 int const effects_count = static_cast<int>(effects.size()); | 207 int const effects_count = static_cast<int>(effects.size()); |
| 210 if (effects_count == 1) { | 208 if (effects_count == 1) { |
| 211 effect = effects[0]; | 209 effect = effects[0]; |
| 212 } else if (effects_count > 1) { | 210 } else if (effects_count > 1) { |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 650 return impl.ReduceIfTrue(node); | 648 return impl.ReduceIfTrue(node); |
| 651 case IrOpcode::kIfFalse: | 649 case IrOpcode::kIfFalse: |
| 652 return impl.ReduceIfFalse(node); | 650 return impl.ReduceIfFalse(node); |
| 653 default: | 651 default: |
| 654 return node; | 652 return node; |
| 655 } | 653 } |
| 656 } | 654 } |
| 657 } | 655 } |
| 658 } | 656 } |
| 659 } // namespace v8::internal::compiler | 657 } // namespace v8::internal::compiler |
| OLD | NEW |