| 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-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
| 10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 // Gather all nodes backwards-reachable from end (through inputs). | 73 // Gather all nodes backwards-reachable from end (through inputs). |
| 74 state_.assign(graph()->NodeCount(), kUnvisited); | 74 state_.assign(graph()->NodeCount(), kUnvisited); |
| 75 NodeVector nodes(zone_); | 75 NodeVector nodes(zone_); |
| 76 AddNodesReachableFromEnd(nodes); | 76 AddNodesReachableFromEnd(nodes); |
| 77 | 77 |
| 78 // Walk forward through control nodes, looking for back edges to nodes | 78 // Walk forward through control nodes, looking for back edges to nodes |
| 79 // that are not connected to end. Those are non-terminating loops (NTLs). | 79 // that are not connected to end. Those are non-terminating loops (NTLs). |
| 80 Node* start = graph()->start(); | 80 Node* start = graph()->start(); |
| 81 ZoneVector<byte> fw_reachability(graph()->NodeCount(), 0, zone_); | 81 ZoneVector<byte> fw_reachability(graph()->NodeCount(), 0, zone_); |
| 82 fw_reachability[start->id()] = kFromStart | kOnStack; | 82 fw_reachability[start->id()] = kFromStart | kOnStack; |
| 83 stack_.push_back(start); | |
| 84 | 83 |
| 85 while (!stack_.empty()) { | 84 // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal. |
| 86 Node* node = stack_.back(); | 85 typedef std::pair<Node*, UseIter> FwIter; |
| 86 ZoneDeque<FwIter> fw_stack(zone_); |
| 87 fw_stack.push_back(FwIter(start, start->uses().begin())); |
| 88 |
| 89 while (!fw_stack.empty()) { |
| 90 Node* node = fw_stack.back().first; |
| 87 TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic())); | 91 TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic())); |
| 88 bool pop = true; | 92 bool pop = true; |
| 89 for (Node* const succ : node->uses()) { | 93 while (fw_stack.back().second != node->uses().end()) { |
| 94 Node* succ = *(fw_stack.back().second); |
| 90 byte reach = fw_reachability[succ->id()]; | 95 byte reach = fw_reachability[succ->id()]; |
| 91 if ((reach & kOnStack) != 0 && state_[succ->id()] != kVisited) { | 96 if ((reach & kOnStack) != 0 && state_[succ->id()] != kVisited) { |
| 92 // {succ} is on stack and not reachable from end. | 97 // {succ} is on stack and not reachable from end. |
| 93 ConnectNTL(nodes, succ); | 98 ConnectNTL(nodes, succ); |
| 94 fw_reachability.resize(graph()->NodeCount(), 0); | 99 fw_reachability.resize(graph()->NodeCount(), 0); |
| 95 pop = false; // continue traversing inputs to this node. | 100 // The use list of {succ} might have changed. |
| 101 fw_stack[fw_stack.size() - 1] = FwIter(succ, succ->uses().begin()); |
| 102 pop = false; // restart traversing successors of this node. |
| 96 break; | 103 break; |
| 97 } | 104 } |
| 98 if ((reach & kFromStart) == 0 && | 105 if ((reach & kFromStart) == 0 && |
| 99 IrOpcode::IsControlOpcode(succ->opcode())) { | 106 IrOpcode::IsControlOpcode(succ->opcode())) { |
| 100 // {succ} is a control node and not yet reached from start. | 107 // {succ} is a control node and not yet reached from start. |
| 101 fw_reachability[succ->id()] |= kFromStart | kOnStack; | 108 fw_reachability[succ->id()] |= kFromStart | kOnStack; |
| 102 stack_.push_back(succ); | 109 fw_stack.push_back(FwIter(succ, succ->uses().begin())); |
| 103 pop = false; // "recurse" into successor control node. | 110 pop = false; // "recurse" into successor control node. |
| 104 break; | 111 break; |
| 105 } | 112 } |
| 113 ++fw_stack.back().second; |
| 106 } | 114 } |
| 107 if (pop) { | 115 if (pop) { |
| 108 fw_reachability[node->id()] &= ~kOnStack; | 116 fw_reachability[node->id()] &= ~kOnStack; |
| 109 stack_.pop_back(); | 117 fw_stack.pop_back(); |
| 110 } | 118 } |
| 111 } | 119 } |
| 112 | 120 |
| 113 // Trim references from dead nodes to live nodes first. | 121 // Trim references from dead nodes to live nodes first. |
| 114 jsgraph_->GetCachedNodes(&nodes); | 122 jsgraph_->GetCachedNodes(&nodes); |
| 115 TrimNodes(nodes); | 123 TrimNodes(nodes); |
| 116 | 124 |
| 117 // Any control nodes not reachable from start are dead, even loops. | 125 // Any control nodes not reachable from start are dead, even loops. |
| 118 for (size_t i = 0; i < nodes.size(); i++) { | 126 for (size_t i = 0; i < nodes.size(); i++) { |
| 119 Node* node = nodes[i]; | 127 Node* node = nodes[i]; |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 Node* ControlReducer::ReduceBranchForTesting(JSGraph* jsgraph, | 565 Node* ControlReducer::ReduceBranchForTesting(JSGraph* jsgraph, |
| 558 CommonOperatorBuilder* common, | 566 CommonOperatorBuilder* common, |
| 559 Node* node) { | 567 Node* node) { |
| 560 Zone zone(jsgraph->graph()->zone()->isolate()); | 568 Zone zone(jsgraph->graph()->zone()->isolate()); |
| 561 ControlReducerImpl impl(&zone, jsgraph, common); | 569 ControlReducerImpl impl(&zone, jsgraph, common); |
| 562 return impl.ReduceBranch(node); | 570 return impl.ReduceBranch(node); |
| 563 } | 571 } |
| 564 } | 572 } |
| 565 } | 573 } |
| 566 } // namespace v8::internal::compiler | 574 } // namespace v8::internal::compiler |
| OLD | NEW |