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 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
639 return impl.ReduceIfTrue(node); | 637 return impl.ReduceIfTrue(node); |
640 case IrOpcode::kIfFalse: | 638 case IrOpcode::kIfFalse: |
641 return impl.ReduceIfFalse(node); | 639 return impl.ReduceIfFalse(node); |
642 default: | 640 default: |
643 return node; | 641 return node; |
644 } | 642 } |
645 } | 643 } |
646 } | 644 } |
647 } | 645 } |
648 } // namespace v8::internal::compiler | 646 } // namespace v8::internal::compiler |
OLD | NEW |