mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
[LCG] Hoist the logic for forming a new SCC from the top of the DFSStack
into a helper function. I plan to re-use it for doing incremental DFS-based updates to the SCCs when we mutate the call graph. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@206948 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b3112f6acc
commit
b001573515
@ -364,6 +364,11 @@ private:
|
||||
/// \brief Helper to update pointers back to the graph object during moves.
|
||||
void updateGraphPtrs();
|
||||
|
||||
/// \brief Helper to form a new SCC out of the top of a DFSStack-like
|
||||
/// structure.
|
||||
SCC *formSCCFromDFSStack(
|
||||
SmallVectorImpl<std::pair<Node *, Node::iterator>> &DFSStack);
|
||||
|
||||
/// \brief Retrieve the next node in the post-order SCC walk of the call graph.
|
||||
SCC *getNextSCCInPostOrder();
|
||||
};
|
||||
|
@ -151,6 +151,51 @@ void LazyCallGraph::updateGraphPtrs() {
|
||||
}
|
||||
}
|
||||
|
||||
LazyCallGraph::SCC *LazyCallGraph::formSCCFromDFSStack(
|
||||
SmallVectorImpl<std::pair<Node *, Node::iterator>> &DFSStack) {
|
||||
// The tail of the stack is the new SCC. Allocate the SCC and pop the stack
|
||||
// into it.
|
||||
SCC *NewSCC = new (SCCBPA.Allocate()) SCC();
|
||||
|
||||
// Because we don't follow the strict Tarjan recursive formulation, walk
|
||||
// from the top of the stack down, propagating the lowest link and stopping
|
||||
// when the DFS number is the lowest link.
|
||||
int LowestLink = DFSStack.back().first->LowLink;
|
||||
do {
|
||||
Node *SCCN = DFSStack.pop_back_val().first;
|
||||
SCCMap[&SCCN->getFunction()] = NewSCC;
|
||||
NewSCC->Nodes.push_back(SCCN);
|
||||
LowestLink = std::min(LowestLink, SCCN->LowLink);
|
||||
bool Inserted =
|
||||
NewSCC->NodeSet.insert(&SCCN->getFunction());
|
||||
(void)Inserted;
|
||||
assert(Inserted && "Cannot have duplicates in the DFSStack!");
|
||||
} while (!DFSStack.empty() && LowestLink <= DFSStack.back().first->DFSNumber);
|
||||
assert(LowestLink == NewSCC->Nodes.back()->DFSNumber &&
|
||||
"Cannot stop with a DFS number greater than the lowest link!");
|
||||
|
||||
// A final pass over all edges in the SCC (this remains linear as we only
|
||||
// do this once when we build the SCC) to connect it to the parent sets of
|
||||
// its children.
|
||||
bool IsLeafSCC = true;
|
||||
for (Node *SCCN : NewSCC->Nodes)
|
||||
for (Node *SCCChildN : *SCCN) {
|
||||
if (NewSCC->NodeSet.count(&SCCChildN->getFunction()))
|
||||
continue;
|
||||
SCC *ChildSCC = SCCMap.lookup(&SCCChildN->getFunction());
|
||||
assert(ChildSCC &&
|
||||
"Must have all child SCCs processed when building a new SCC!");
|
||||
ChildSCC->ParentSCCs.insert(NewSCC);
|
||||
IsLeafSCC = false;
|
||||
}
|
||||
|
||||
// For the SCCs where we fine no child SCCs, add them to the leaf list.
|
||||
if (IsLeafSCC)
|
||||
LeafSCCs.push_back(NewSCC);
|
||||
|
||||
return NewSCC;
|
||||
}
|
||||
|
||||
LazyCallGraph::SCC *LazyCallGraph::getNextSCCInPostOrder() {
|
||||
// When the stack is empty, there are no more SCCs to walk in this graph.
|
||||
if (DFSStack.empty()) {
|
||||
@ -190,47 +235,8 @@ LazyCallGraph::SCC *LazyCallGraph::getNextSCCInPostOrder() {
|
||||
N->LowLink = ChildN->LowLink;
|
||||
}
|
||||
|
||||
// The tail of the stack is the new SCC. Allocate the SCC and pop the stack
|
||||
// into it.
|
||||
SCC *NewSCC = new (SCCBPA.Allocate()) SCC();
|
||||
|
||||
// Because we don't follow the strict Tarjan recursive formulation, walk
|
||||
// from the top of the stack down, propagating the lowest link and stopping
|
||||
// when the DFS number is the lowest link.
|
||||
int LowestLink = N->LowLink;
|
||||
do {
|
||||
Node *SCCN = DFSStack.pop_back_val().first;
|
||||
SCCMap.insert(std::make_pair(&SCCN->getFunction(), NewSCC));
|
||||
NewSCC->Nodes.push_back(SCCN);
|
||||
LowestLink = std::min(LowestLink, SCCN->LowLink);
|
||||
bool Inserted =
|
||||
NewSCC->NodeSet.insert(&SCCN->getFunction());
|
||||
(void)Inserted;
|
||||
assert(Inserted && "Cannot have duplicates in the DFSStack!");
|
||||
} while (!DFSStack.empty() && LowestLink <= DFSStack.back().first->DFSNumber);
|
||||
assert(LowestLink == NewSCC->Nodes.back()->DFSNumber &&
|
||||
"Cannot stop with a DFS number greater than the lowest link!");
|
||||
|
||||
// A final pass over all edges in the SCC (this remains linear as we only
|
||||
// do this once when we build the SCC) to connect it to the parent sets of
|
||||
// its children.
|
||||
bool IsLeafSCC = true;
|
||||
for (Node *SCCN : NewSCC->Nodes)
|
||||
for (Node *SCCChildN : *SCCN) {
|
||||
if (NewSCC->NodeSet.count(&SCCChildN->getFunction()))
|
||||
continue;
|
||||
SCC *ChildSCC = SCCMap.lookup(&SCCChildN->getFunction());
|
||||
assert(ChildSCC &&
|
||||
"Must have all child SCCs processed when building a new SCC!");
|
||||
ChildSCC->ParentSCCs.insert(NewSCC);
|
||||
IsLeafSCC = false;
|
||||
}
|
||||
|
||||
// For the SCCs where we fine no child SCCs, add them to the leaf list.
|
||||
if (IsLeafSCC)
|
||||
LeafSCCs.push_back(NewSCC);
|
||||
|
||||
return NewSCC;
|
||||
// Form the new SCC out of the top of the DFS stack.
|
||||
return formSCCFromDFSStack(DFSStack);
|
||||
}
|
||||
|
||||
char LazyCallGraphAnalysis::PassID;
|
||||
|
Loading…
Reference in New Issue
Block a user