| Index: src/compiler/control-reducer.cc
|
| diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc
|
| index 89b05d0c079c735cca34c10c9ceb5f4b09b911b2..1d8310316e7219bdc518fd465c9eab43052b7b43 100644
|
| --- a/src/compiler/control-reducer.cc
|
| +++ b/src/compiler/control-reducer.cc
|
| @@ -80,33 +80,41 @@ class ControlReducerImpl {
|
| Node* start = graph()->start();
|
| ZoneVector<byte> fw_reachability(graph()->NodeCount(), 0, zone_);
|
| fw_reachability[start->id()] = kFromStart | kOnStack;
|
| - stack_.push_back(start);
|
|
|
| - while (!stack_.empty()) {
|
| - Node* node = stack_.back();
|
| + // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal.
|
| + typedef std::pair<Node*, UseIter> FwIter;
|
| + ZoneDeque<FwIter> fw_stack(zone_);
|
| + fw_stack.push_back(FwIter(start, start->uses().begin()));
|
| +
|
| + while (!fw_stack.empty()) {
|
| + Node* node = fw_stack.back().first;
|
| TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic()));
|
| bool pop = true;
|
| - for (Node* const succ : node->uses()) {
|
| + while (fw_stack.back().second != node->uses().end()) {
|
| + Node* succ = *(fw_stack.back().second);
|
| byte reach = fw_reachability[succ->id()];
|
| if ((reach & kOnStack) != 0 && state_[succ->id()] != kVisited) {
|
| // {succ} is on stack and not reachable from end.
|
| ConnectNTL(nodes, succ);
|
| fw_reachability.resize(graph()->NodeCount(), 0);
|
| - pop = false; // continue traversing inputs to this node.
|
| + // The use list of {succ} might have changed.
|
| + fw_stack[fw_stack.size() - 1] = FwIter(succ, succ->uses().begin());
|
| + pop = false; // restart traversing successors of this node.
|
| break;
|
| }
|
| if ((reach & kFromStart) == 0 &&
|
| IrOpcode::IsControlOpcode(succ->opcode())) {
|
| // {succ} is a control node and not yet reached from start.
|
| fw_reachability[succ->id()] |= kFromStart | kOnStack;
|
| - stack_.push_back(succ);
|
| + fw_stack.push_back(FwIter(succ, succ->uses().begin()));
|
| pop = false; // "recurse" into successor control node.
|
| break;
|
| }
|
| + ++fw_stack.back().second;
|
| }
|
| if (pop) {
|
| fw_reachability[node->id()] &= ~kOnStack;
|
| - stack_.pop_back();
|
| + fw_stack.pop_back();
|
| }
|
| }
|
|
|
|
|