[LCG] During the incremental update of an SCC, switch to using the

SCCMap to test for nodes that have been re-added to the root SCC rather
than a set vector. We already have done the SCCMap lookup, we juts need
to test it in two different ways. In turn, do most of the processing of
these nodes as they go into the root SCC rather than lazily. This
simplifies the final loop to just stitch the root SCC into its
children's parent sets. No functionlatiy changed.

However, this makes a few things painfully obvious, which was my intent.
=] There is tons of repeated code introduced here and elsewhere. I'm
splitting the refactoring of that code into helpers from this change so
its clear that this is the change which switches the datastructures used
around, and the other is a pure factoring & deduplication of code
change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207217 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chandler Carruth 2014-04-25 09:52:44 +00:00
parent 435b9bd9fb
commit 09d1d3d588

View File

@ -203,8 +203,9 @@ LazyCallGraph::SCC::removeInternalEdge(LazyCallGraph &G, Node &Caller,
// incrementally add any chain of nodes which reaches something in the new
// node set to the new node set. This short circuits one side of the Tarjan's
// walk.
SmallSetVector<Node *, 1> NewNodes;
NewNodes.insert(&Callee);
Nodes.push_back(&Callee);
G.SCCMap.insert(std::make_pair(&Callee, this));
Callee.DFSNumber = Callee.LowLink = -1;
for (;;) {
if (DFSStack.empty()) {
@ -229,24 +230,31 @@ LazyCallGraph::SCC::removeInternalEdge(LazyCallGraph &G, Node &Caller,
bool Recurse = false;
for (auto I = DFSStack.back().second, E = N->end(); I != E; ++I) {
Node &ChildN = *I;
// If this child isn't currently in this SCC, no need to process it.
// However, we do need to remove this SCC from its SCC's parent set.
if (SCC *ChildSCC = G.SCCMap.lookup(&ChildN)) {
// Check if we have reached a node in the new (known connected) set of
// this SCC. If so, the entire stack is necessarily in that set and we
// can re-start.
if (ChildSCC == this) {
while (!PendingSCCStack.empty()) {
Nodes.push_back(PendingSCCStack.pop_back_val());
G.SCCMap.insert(std::make_pair(Nodes.back(), this));
Nodes.back()->DFSNumber = Nodes.back()->LowLink = -1;
}
while (!DFSStack.empty()) {
Nodes.push_back(DFSStack.pop_back_val().first);
G.SCCMap.insert(std::make_pair(Nodes.back(), this));
Nodes.back()->DFSNumber = Nodes.back()->LowLink = -1;
}
Recurse = true;
break;
}
// If this child isn't currently in this SCC, no need to process it.
// However, we do need to remove this SCC from its SCC's parent set.
ChildSCC->ParentSCCs.erase(this);
continue;
}
// Check if we have reached a node in the new (known connected) set. If
// so, the entire stack is necessarily in that set and we can re-start.
if (NewNodes.count(&ChildN)) {
while (!PendingSCCStack.empty())
NewNodes.insert(PendingSCCStack.pop_back_val());
while (!DFSStack.empty())
NewNodes.insert(DFSStack.pop_back_val().first);
Recurse = true;
break;
}
if (ChildN.DFSNumber == 0) {
// Mark that we should start at this child when next this node is the
// top of the stack. We don't start at the next child to ensure this
@ -288,21 +296,13 @@ LazyCallGraph::SCC::removeInternalEdge(LazyCallGraph &G, Node &Caller,
PendingSCCStack.push_back(N);
}
// Replace this SCC with the NewNodes we collected above.
// FIXME: Simplify this when the SCC's datastructure is just a list.
Nodes.clear();
// Now we need to reconnect the current SCC to the graph.
bool IsLeafSCC = true;
for (Node *N : NewNodes) {
N->DFSNumber = -1;
N->LowLink = -1;
Nodes.push_back(N);
G.SCCMap.insert(std::make_pair(N, this));
for (Node *N : Nodes) {
for (Node &ChildN : *N) {
if (NewNodes.count(&ChildN))
continue;
SCC &ChildSCC = *G.SCCMap.lookup(&ChildN);
if (&ChildSCC == this)
continue;
ChildSCC.ParentSCCs.insert(this);
IsLeafSCC = false;
}