mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
SCCIterator: Merge MinVisitNumStack and VisitStack
This patch merges MinVisitNumStack with VisitStack using a StackElement struct. Patch by Mehdi Amini! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201353 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -47,6 +47,22 @@ class scc_iterator
|
|||||||
typedef typename super::reference reference;
|
typedef typename super::reference reference;
|
||||||
typedef typename super::pointer pointer;
|
typedef typename super::pointer pointer;
|
||||||
|
|
||||||
|
// Element of VisitStack during DFS.
|
||||||
|
struct StackElement {
|
||||||
|
NodeType *Node; ///< The current node pointer.
|
||||||
|
ChildItTy NextChild; ///< The next child, modified inplace during DFS.
|
||||||
|
unsigned MinVisited; ///< Minimum uplink value of all children of Node.
|
||||||
|
|
||||||
|
StackElement(NodeType *Node, const ChildItTy &Child, unsigned Min)
|
||||||
|
: Node(Node), NextChild(Child), MinVisited(Min) {}
|
||||||
|
|
||||||
|
bool operator==(const StackElement &Other) const {
|
||||||
|
return Node == Other.Node &&
|
||||||
|
NextChild == Other.NextChild &&
|
||||||
|
MinVisited == Other.MinVisited;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// The visit counters used to detect when a complete SCC is on the stack.
|
// The visit counters used to detect when a complete SCC is on the stack.
|
||||||
// visitNum is the global counter.
|
// visitNum is the global counter.
|
||||||
// nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
|
// nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
|
||||||
@@ -59,22 +75,17 @@ class scc_iterator
|
|||||||
// The current SCC, retrieved using operator*().
|
// The current SCC, retrieved using operator*().
|
||||||
SccTy CurrentSCC;
|
SccTy CurrentSCC;
|
||||||
|
|
||||||
// Used to maintain the ordering. The top is the current block, the first
|
|
||||||
// element is basic block pointer, second is the 'next child' to visit.
|
|
||||||
std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
|
|
||||||
|
|
||||||
// Stack holding the "min" values for each node in the DFS. This is used to
|
// DFS stack, Used to maintain the ordering. The top contains the current
|
||||||
// track the minimum uplink values for all children of the corresponding node
|
// node, the next child to visit, and the minimum uplink value of all child
|
||||||
// on the VisitStack.
|
std::vector<StackElement> VisitStack;
|
||||||
std::vector<unsigned> MinVisitNumStack;
|
|
||||||
|
|
||||||
// A single "visit" within the non-recursive DFS traversal.
|
// A single "visit" within the non-recursive DFS traversal.
|
||||||
void DFSVisitOne(NodeType *N) {
|
void DFSVisitOne(NodeType *N) {
|
||||||
++visitNum;
|
++visitNum;
|
||||||
nodeVisitNumbers[N] = visitNum;
|
nodeVisitNumbers[N] = visitNum;
|
||||||
SCCNodeStack.push_back(N);
|
SCCNodeStack.push_back(N);
|
||||||
MinVisitNumStack.push_back(visitNum);
|
VisitStack.push_back(StackElement(N, GT::child_begin(N), visitNum));
|
||||||
VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
|
|
||||||
#if 0 // Enable if needed when debugging.
|
#if 0 // Enable if needed when debugging.
|
||||||
dbgs() << "TarjanSCC: Node " << N <<
|
dbgs() << "TarjanSCC: Node " << N <<
|
||||||
" : visitNum = " << visitNum << "\n";
|
" : visitNum = " << visitNum << "\n";
|
||||||
@@ -84,35 +95,39 @@ class scc_iterator
|
|||||||
// The stack-based DFS traversal; defined below.
|
// The stack-based DFS traversal; defined below.
|
||||||
void DFSVisitChildren() {
|
void DFSVisitChildren() {
|
||||||
assert(!VisitStack.empty());
|
assert(!VisitStack.empty());
|
||||||
while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
|
while (VisitStack.back().NextChild !=
|
||||||
|
GT::child_end(VisitStack.back().Node)) {
|
||||||
// TOS has at least one more child so continue DFS
|
// TOS has at least one more child so continue DFS
|
||||||
NodeType *childN = *VisitStack.back().second++;
|
NodeType *childN = *VisitStack.back().NextChild++;
|
||||||
if (!nodeVisitNumbers.count(childN)) {
|
typename DenseMap<NodeType *, unsigned>::iterator Visited =
|
||||||
|
nodeVisitNumbers.find(childN);
|
||||||
|
if (Visited == nodeVisitNumbers.end()) {
|
||||||
// this node has never been seen.
|
// this node has never been seen.
|
||||||
DFSVisitOne(childN);
|
DFSVisitOne(childN);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned childNum = nodeVisitNumbers[childN];
|
unsigned childNum = Visited->second;
|
||||||
if (MinVisitNumStack.back() > childNum)
|
if (VisitStack.back().MinVisited > childNum)
|
||||||
MinVisitNumStack.back() = childNum;
|
VisitStack.back().MinVisited = childNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute the next SCC using the DFS traversal.
|
// Compute the next SCC using the DFS traversal.
|
||||||
void GetNextSCC() {
|
void GetNextSCC() {
|
||||||
assert(VisitStack.size() == MinVisitNumStack.size());
|
|
||||||
CurrentSCC.clear(); // Prepare to compute the next SCC
|
CurrentSCC.clear(); // Prepare to compute the next SCC
|
||||||
while (!VisitStack.empty()) {
|
while (!VisitStack.empty()) {
|
||||||
DFSVisitChildren();
|
DFSVisitChildren();
|
||||||
assert(VisitStack.back().second ==
|
|
||||||
GT::child_end(VisitStack.back().first));
|
// Pop the leaf on top of the VisitStack.
|
||||||
NodeType *visitingN = VisitStack.back().first;
|
NodeType *visitingN = VisitStack.back().Node;
|
||||||
unsigned minVisitNum = MinVisitNumStack.back();
|
unsigned minVisitNum = VisitStack.back().MinVisited;
|
||||||
|
assert(VisitStack.back().NextChild == GT::child_end(visitingN));
|
||||||
VisitStack.pop_back();
|
VisitStack.pop_back();
|
||||||
MinVisitNumStack.pop_back();
|
|
||||||
if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
|
// Propagate MinVisitNum to parent so we can detect the SCC starting node.
|
||||||
MinVisitNumStack.back() = minVisitNum;
|
if (!VisitStack.empty() && VisitStack.back().MinVisited > minVisitNum)
|
||||||
|
VisitStack.back().MinVisited = minVisitNum;
|
||||||
|
|
||||||
#if 0 // Enable if needed when debugging.
|
#if 0 // Enable if needed when debugging.
|
||||||
dbgs() << "TarjanSCC: Popped node " << visitingN <<
|
dbgs() << "TarjanSCC: Popped node " << visitingN <<
|
||||||
|
|||||||
Reference in New Issue
Block a user