OLD | NEW |
1 //===- subzero/src/IceLoopAnalyzer.cpp - Loop Analysis --------------------===// | 1 //===- subzero/src/IceLoopAnalyzer.cpp - Loop Analysis --------------------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 16 matching lines...) Expand all Loading... |
27 } | 27 } |
28 | 28 |
29 NodeList::const_iterator LoopAnalyzer::LoopNode::successorsEnd() const { | 29 NodeList::const_iterator LoopAnalyzer::LoopNode::successorsEnd() const { |
30 return BB->getOutEdges().end(); | 30 return BB->getOutEdges().end(); |
31 } | 31 } |
32 | 32 |
33 void LoopAnalyzer::LoopNode::incrementLoopNestDepth() { | 33 void LoopAnalyzer::LoopNode::incrementLoopNestDepth() { |
34 BB->incrementLoopNestDepth(); | 34 BB->incrementLoopNestDepth(); |
35 } | 35 } |
36 | 36 |
| 37 bool LoopAnalyzer::LoopNode::hasSelfEdge() const { |
| 38 for (CfgNode *Succ : BB->getOutEdges()) { |
| 39 if (Succ == BB) |
| 40 return true; |
| 41 } |
| 42 return false; |
| 43 } |
| 44 |
37 LoopAnalyzer::LoopAnalyzer(Cfg *Fn) : Func(Fn) { | 45 LoopAnalyzer::LoopAnalyzer(Cfg *Fn) : Func(Fn) { |
38 const NodeList &Nodes = Func->getNodes(); | 46 const NodeList &Nodes = Func->getNodes(); |
39 | 47 |
40 // Allocate memory ahead of time. This is why a vector is used instead of a | 48 // 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). | 49 // stack which doesn't support reserving (or bulk erasure used below). |
42 AllNodes.reserve(Nodes.size()); | 50 AllNodes.reserve(Nodes.size()); |
43 WorkStack.reserve(Nodes.size()); | 51 WorkStack.reserve(Nodes.size()); |
44 LoopStack.reserve(Nodes.size()); | 52 LoopStack.reserve(Nodes.size()); |
45 | 53 |
46 // Create the LoopNodes from the function's CFG | 54 // Create the LoopNodes from the function's CFG |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 else if (Succ.isOnStack()) | 116 else if (Succ.isOnStack()) |
109 Node.tryLink(Succ.getIndex()); | 117 Node.tryLink(Succ.getIndex()); |
110 } | 118 } |
111 | 119 |
112 if (Node.getLowLink() != Node.getIndex()) | 120 if (Node.getLowLink() != Node.getIndex()) |
113 return nullptr; | 121 return nullptr; |
114 | 122 |
115 // Single node means no loop in the CFG | 123 // Single node means no loop in the CFG |
116 if (LoopStack.back() == &Node) { | 124 if (LoopStack.back() == &Node) { |
117 LoopStack.back()->setOnStack(false); | 125 LoopStack.back()->setOnStack(false); |
| 126 if (Node.hasSelfEdge()) |
| 127 LoopStack.back()->incrementLoopNestDepth(); |
118 LoopStack.back()->setDeleted(); | 128 LoopStack.back()->setDeleted(); |
119 ++NumDeletedNodes; | 129 ++NumDeletedNodes; |
120 LoopStack.pop_back(); | 130 LoopStack.pop_back(); |
121 return nullptr; | 131 return nullptr; |
122 } | 132 } |
123 | 133 |
124 // Reaching here means a loop has been found! It consists of the nodes on the | 134 // Reaching here means a loop has been found! It consists of the nodes on the |
125 // top of the stack, down until the current node being processed, Node, is | 135 // top of the stack, down until the current node being processed, Node, is |
126 // found. | 136 // found. |
127 for (auto It = LoopStack.rbegin(); It != LoopStack.rend(); ++It) { | 137 for (auto It = LoopStack.rbegin(); It != LoopStack.rend(); ++It) { |
128 (*It)->setOnStack(false); | 138 (*It)->setOnStack(false); |
129 (*It)->incrementLoopNestDepth(); | 139 (*It)->incrementLoopNestDepth(); |
130 // Remove the loop from the stack and delete the head node | 140 // Remove the loop from the stack and delete the head node |
131 if (*It == &Node) { | 141 if (*It == &Node) { |
132 (*It)->setDeleted(); | 142 (*It)->setDeleted(); |
133 ++NumDeletedNodes; | 143 ++NumDeletedNodes; |
134 LoopStack.erase(It.base() - 1, LoopStack.end()); | 144 LoopStack.erase(It.base() - 1, LoopStack.end()); |
135 break; | 145 break; |
136 } | 146 } |
137 } | 147 } |
138 | 148 |
139 return nullptr; | 149 return nullptr; |
140 } | 150 } |
141 | 151 |
142 } // end of namespace Ice | 152 } // end of namespace Ice |
OLD | NEW |