Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 //===- subzero/src/IceLoopAnalyzer.cpp - Loop Anaysis =====-----------------==// | |
|
Jim Stichnoth
2015/09/03 21:35:09
Analysis --------===//
(misspelling plus dash/equ
ascull
2015/09/03 22:47:13
Done.
| |
| 2 // | |
| 3 // The Subzero Code Generator | |
| 4 // | |
| 5 // This file is distributed under the University of Illinois Open Source | |
| 6 // License. See LICENSE.TXT for details. | |
| 7 // | |
| 8 //===----------------------------------------------------------------------===// | |
| 9 /// | |
| 10 /// \file | |
| 11 /// This file implements the loop analysis on the CFG. | |
| 12 /// | |
| 13 //===----------------------------------------------------------------------===// | |
| 14 #include "IceLoopAnalyzer.h" | |
| 15 | |
| 16 #include "IceCfg.h" | |
| 17 #include "IceCfgNode.h" | |
| 18 | |
| 19 namespace Ice { | |
| 20 | |
| 21 void LoopAnalyzer::LoopNode::reset() { | |
| 22 if (Deleted) | |
| 23 return; | |
| 24 Succ = BB->getOutEdges().begin(); | |
| 25 Index = LowLink = UndefinedIndex; | |
| 26 OnStack = false; | |
| 27 } | |
| 28 | |
| 29 NodeList::const_iterator LoopAnalyzer::LoopNode::successorsEnd() const { | |
| 30 return BB->getOutEdges().end(); | |
| 31 } | |
| 32 | |
| 33 void LoopAnalyzer::LoopNode::incrementLoopNestDepth() { | |
| 34 BB->incrementLoopNestDepth(); | |
| 35 } | |
| 36 | |
| 37 LoopAnalyzer::LoopAnalyzer(Cfg *Func) : Func(Func), NumDeletedNodes(0) { | |
|
Jim Stichnoth
2015/09/03 21:35:09
You can put "... NumDeletedNodes = 0;" in the memb
ascull
2015/09/03 22:47:12
Done.
| |
| 38 const NodeList &Nodes = Func->getNodes(); | |
| 39 | |
| 40 // Allocate memory ahead of time. This is why a vector is used instead of a | |
| 41 // stack which doesn't support reserving (or bulk erasure used below). | |
| 42 AllNodes.reserve(Nodes.size()); | |
| 43 WorkStack.reserve(Nodes.size()); | |
| 44 LoopStack.reserve(Nodes.size()); | |
| 45 | |
| 46 // Create the LoopNodes from the function's CFG | |
| 47 for (CfgNode *Node : Nodes) | |
| 48 AllNodes.emplace_back(Node); | |
| 49 } | |
| 50 | |
| 51 void LoopAnalyzer::computeLoopNestDepth() { | |
| 52 assert(AllNodes.size() == Func->getNodes().size()); | |
| 53 | |
| 54 while (NumDeletedNodes < AllNodes.size()) { | |
| 55 // Prepare to run Tarjan's | |
| 56 NextIndex = FirstDefinedIndex; | |
| 57 for (LoopNode &Node : AllNodes) | |
| 58 Node.reset(); | |
| 59 | |
| 60 assert(WorkStack.empty()); | |
| 61 assert(LoopStack.empty()); | |
| 62 | |
| 63 for (LoopNode &Node : AllNodes) { | |
| 64 if (Node.isDeleted() || Node.isVisited()) | |
| 65 continue; | |
| 66 | |
| 67 WorkStack.push_back(&Node); | |
| 68 | |
| 69 while (!WorkStack.empty()) { | |
| 70 LoopNode &WorkNode = *WorkStack.back(); | |
| 71 if (LoopNode *Succ = processNode(WorkNode)) | |
| 72 WorkStack.push_back(Succ); | |
| 73 else | |
| 74 WorkStack.pop_back(); | |
| 75 } | |
| 76 } | |
| 77 } | |
| 78 } | |
| 79 | |
| 80 LoopAnalyzer::LoopNode * | |
| 81 LoopAnalyzer::processNode(LoopAnalyzer::LoopNode &Node) { | |
| 82 if (!Node.isVisited()) { | |
| 83 Node.visit(NextIndex++); | |
| 84 LoopStack.push_back(&Node); | |
| 85 Node.setOnStack(); | |
| 86 } else { | |
| 87 // Returning to a node after having recursed into Succ so continue | |
| 88 // iterating through successors after using the Succ.LowLink value that was | |
| 89 // computed in the recursion. | |
| 90 LoopNode &Succ = AllNodes[(*Node.currentSuccessor())->getIndex()]; | |
| 91 Node.tryLink(Succ.getLowLink()); | |
| 92 Node.nextSuccessor(); | |
| 93 } | |
| 94 | |
| 95 // Visit the successors and recurse into unvisited nodes. The recursion could | |
| 96 // cause the iteration to be suspended but it will resume as the stack is | |
| 97 // unwound. | |
| 98 auto SuccEnd = Node.successorsEnd(); | |
| 99 for (; Node.currentSuccessor() != SuccEnd; Node.nextSuccessor()) { | |
| 100 LoopNode &Succ = AllNodes[(*Node.currentSuccessor())->getIndex()]; | |
| 101 | |
| 102 if (Succ.isDeleted()) | |
| 103 continue; | |
| 104 | |
| 105 if (!Succ.isVisited()) | |
| 106 return &Succ; | |
| 107 else if (Succ.isOnStack()) | |
| 108 Node.tryLink(Succ.getIndex()); | |
| 109 } | |
| 110 | |
| 111 if (Node.getLowLink() != Node.getIndex()) | |
| 112 return nullptr; | |
| 113 | |
| 114 // Single node means no loop in the CFG | |
| 115 if (LoopStack.back() == &Node) { | |
| 116 LoopStack.back()->setOnStack(false); | |
| 117 LoopStack.back()->setDeleted(); | |
| 118 ++NumDeletedNodes; | |
| 119 LoopStack.pop_back(); | |
| 120 return nullptr; | |
| 121 } | |
| 122 | |
| 123 // Reaching here means a loop has been found! It consists of the nodes on | |
| 124 // the top of the stack, down until the current node being processed, Node, | |
| 125 // is found. | |
| 126 for (auto It = LoopStack.rbegin(); It != LoopStack.rend(); ++It) { | |
| 127 (*It)->setOnStack(false); | |
| 128 (*It)->incrementLoopNestDepth(); | |
| 129 // Remove the loop from the stack and delete the head node | |
| 130 if (*It == &Node) { | |
| 131 (*It)->setDeleted(); | |
| 132 ++NumDeletedNodes; | |
| 133 LoopStack.erase(It.base() - 1, LoopStack.end()); | |
| 134 break; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 return nullptr; | |
| 139 } | |
| 140 | |
| 141 } // end of namespace Ice | |
| OLD | NEW |