[llvm-commits] CVS: llvm/lib/VMCore/Dominators.cpp
Devang Patel
dpatel at apple.com
Tue Mar 20 14:25:48 PDT 2007
Changes in directory llvm/lib/VMCore:
Dominators.cpp updated: 1.79 -> 1.80
---
Log message:
DominanceFrontier::calculate().
Avoid recursion, Use iterative algorithm.
---
Diffs of the changes: (+77 -22)
Dominators.cpp | 99 ++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 77 insertions(+), 22 deletions(-)
Index: llvm/lib/VMCore/Dominators.cpp
diff -u llvm/lib/VMCore/Dominators.cpp:1.79 llvm/lib/VMCore/Dominators.cpp:1.80
--- llvm/lib/VMCore/Dominators.cpp:1.79 Tue Mar 20 15:18:12 2007
+++ llvm/lib/VMCore/Dominators.cpp Tue Mar 20 16:25:31 2007
@@ -46,6 +46,19 @@
static RegisterPass<ImmediateDominators>
C("idom", "Immediate Dominators Construction", true);
+namespace {
+ class DFCalculateWorkObject {
+ public:
+ DFCalculateWorkObject(BasicBlock *B, BasicBlock *P,
+ const DominatorTree::Node *N,
+ const DominatorTree::Node *PN)
+ : currentBB(B), parentBB(P), Node(N), parentNode(PN) {}
+ BasicBlock *currentBB;
+ BasicBlock *parentBB;
+ const DominatorTree::Node *Node;
+ const DominatorTree::Node *parentNode;
+ };
+}
unsigned ImmediateDominators::DFSPass(BasicBlock *V, InfoRec &VInfo,
unsigned N) {
VInfo.Semi = ++N;
@@ -439,34 +452,76 @@
const DominanceFrontier::DomSetType &
DominanceFrontier::calculate(const DominatorTree &DT,
const DominatorTree::Node *Node) {
- // Loop over CFG successors to calculate DFlocal[Node]
BasicBlock *BB = Node->getBlock();
- DomSetType &S = Frontiers[BB]; // The new set to fill in...
+ DomSetType *Result = NULL;
- for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
- SI != SE; ++SI) {
- // Does Node immediately dominate this successor?
- if (DT[*SI]->getIDom() != Node)
- S.insert(*SI);
- }
+ std::vector<DFCalculateWorkObject *> workList;
+ std::set<BasicBlock *> visited;
- // At this point, S is DFlocal. Now we union in DFup's of our children...
- // Loop through and visit the nodes that Node immediately dominates (Node's
- // children in the IDomTree)
- //
- for (DominatorTree::Node::const_iterator NI = Node->begin(), NE = Node->end();
- NI != NE; ++NI) {
- DominatorTree::Node *IDominee = *NI;
- const DomSetType &ChildDF = calculate(DT, IDominee);
+ DFCalculateWorkObject *W = new DFCalculateWorkObject(BB, NULL, Node, NULL);
+ workList.push_back(W);
+ do {
+ DFCalculateWorkObject *currentW = workList.back();
+ assert (currentW && "Missing work object.");
+
+ BasicBlock *currentBB = currentW->currentBB;
+ BasicBlock *parentBB = currentW->parentBB;
+ const DominatorTree::Node *currentNode = currentW->Node;
+ const DominatorTree::Node *parentNode = currentW->parentNode;
+ assert (currentBB && "Invalid work object. Missing current Basic Block");
+ assert (currentNode && "Invalid work object. Missing current Node");
+ DomSetType &S = Frontiers[currentBB];
+
+ // Visit each block only once.
+ if (visited.count(currentBB) == 0) {
+ visited.insert(currentBB);
+
+ // Loop over CFG successors to calculate DFlocal[currentNode]
+ for (succ_iterator SI = succ_begin(currentBB), SE = succ_end(currentBB);
+ SI != SE; ++SI) {
+ // Does Node immediately dominate this successor?
+ if (DT[*SI]->getIDom() != currentNode)
+ S.insert(*SI);
+ }
+ }
- DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end();
- for (; CDFI != CDFE; ++CDFI) {
- if (!Node->properlyDominates(DT[*CDFI]))
- S.insert(*CDFI);
+ // At this point, S is DFlocal. Now we union in DFup's of our children...
+ // Loop through and visit the nodes that Node immediately dominates (Node's
+ // children in the IDomTree)
+ bool visitChild = false;
+ for (DominatorTree::Node::const_iterator NI = currentNode->begin(),
+ NE = currentNode->end(); NI != NE; ++NI) {
+ DominatorTree::Node *IDominee = *NI;
+ BasicBlock *childBB = IDominee->getBlock();
+ if (visited.count(childBB) == 0) {
+ DFCalculateWorkObject *newW =
+ new DFCalculateWorkObject(childBB, currentBB, IDominee, currentNode);
+ workList.push_back(newW);
+ visitChild = true;
+ }
}
- }
- return S;
+ // If all children are visited or there is any child then pop this block
+ // from the workList.
+ if (!visitChild) {
+
+ if (!parentBB) {
+ Result = &S;
+ break;
+ }
+
+ DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end();
+ DomSetType &parentSet = Frontiers[parentBB];
+ for (; CDFI != CDFE; ++CDFI) {
+ if (!parentNode->properlyDominates(DT[*CDFI]))
+ parentSet.insert(*CDFI);
+ }
+ workList.pop_back();
+ }
+
+ } while (!workList.empty());
+
+ return *Result;
}
void DominanceFrontierBase::print(std::ostream &o, const Module* ) const {
More information about the llvm-commits
mailing list