23 #ifndef LLVM_ADT_SCCITERATOR_H 24 #define LLVM_ADT_SCCITERATOR_H 42 template <
class GraphT,
class GT = GraphTraits<GraphT>>
44 scc_iterator<GraphT, GT>, std::forward_iterator_tag,
45 const std::vector<typename GT::NodeRef>, ptrdiff_t> {
46 using NodeRef =
typename GT::NodeRef;
47 using ChildItTy =
typename GT::ChildIteratorType;
48 using SccTy = std::vector<NodeRef>;
49 using reference =
typename scc_iterator::reference;
57 StackElement(NodeRef Node,
const ChildItTy &Child,
unsigned Min)
58 : Node(Node), NextChild(Child), MinVisited(Min) {}
61 return Node == Other.Node &&
62 NextChild == Other.NextChild &&
63 MinVisited == Other.MinVisited;
75 std::vector<NodeRef> SCCNodeStack;
82 std::vector<StackElement> VisitStack;
85 void DFSVisitOne(NodeRef
N);
88 void DFSVisitChildren();
110 assert(!CurrentSCC.empty() || VisitStack.empty());
111 return CurrentSCC.empty();
115 return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
124 assert(!CurrentSCC.empty() &&
"Dereferencing END SCC iterator!");
137 assert(nodeVisitNumbers.
count(Old) &&
"Old not in scc_iterator?");
138 nodeVisitNumbers[New] = nodeVisitNumbers[Old];
139 nodeVisitNumbers.
erase(Old);
143 template <
class GraphT,
class GT>
146 nodeVisitNumbers[
N] = visitNum;
147 SCCNodeStack.push_back(N);
148 VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum));
149 #if 0 // Enable if needed when debugging. 150 dbgs() <<
"TarjanSCC: Node " << N <<
151 " : visitNum = " << visitNum <<
"\n";
155 template <
class GraphT,
class GT>
157 assert(!VisitStack.empty());
158 while (VisitStack.back().NextChild != GT::child_end(VisitStack.back().Node)) {
160 NodeRef childN = *VisitStack.back().NextChild++;
162 nodeVisitNumbers.
find(childN);
163 if (Visited == nodeVisitNumbers.
end()) {
169 unsigned childNum = Visited->second;
170 if (VisitStack.back().MinVisited > childNum)
171 VisitStack.back().MinVisited = childNum;
177 while (!VisitStack.empty()) {
181 NodeRef visitingN = VisitStack.back().Node;
182 unsigned minVisitNum = VisitStack.back().MinVisited;
183 assert(VisitStack.back().NextChild == GT::child_end(visitingN));
184 VisitStack.pop_back();
187 if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum)
188 VisitStack.back().MinVisited = minVisitNum;
190 #if 0 // Enable if needed when debugging. 191 dbgs() <<
"TarjanSCC: Popped node " << visitingN <<
192 " : minVisitNum = " << minVisitNum <<
"; Node visit num = " <<
193 nodeVisitNumbers[visitingN] <<
"\n";
196 if (minVisitNum != nodeVisitNumbers[visitingN])
204 CurrentSCC.push_back(SCCNodeStack.back());
205 SCCNodeStack.pop_back();
206 nodeVisitNumbers[CurrentSCC.back()] = ~0U;
207 }
while (CurrentSCC.back() != visitingN);
212 template <
class GraphT,
class GT>
214 assert(!CurrentSCC.empty() &&
"Dereferencing END SCC iterator!");
215 if (CurrentSCC.size() > 1)
217 NodeRef N = CurrentSCC.front();
218 for (ChildItTy CI = GT::child_begin(N), CE = GT::child_end(N); CI != CE;
237 #endif // LLVM_ADT_SCCITERATOR_H This class represents lattice values for constants.
void ReplaceNode(NodeRef Old, NodeRef New)
This informs the scc_iterator that the specified Old node has been deleted, and New is to be used in ...
scc_iterator & operator++()
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
reference operator*() const
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
scc_iterator< T > scc_end(const T &G)
Construct the end iterator for a deduced graph type T.
bool operator==(const scc_iterator &x) const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static scc_iterator end(const GraphT &)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasLoop() const
Test if the current SCC has a loop.
static scc_iterator begin(const GraphT &G)
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.