diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h index 2ee6efbae41..06a42dac38d 100644 --- a/include/llvm/Analysis/PostDominators.h +++ b/include/llvm/Analysis/PostDominators.h @@ -29,7 +29,7 @@ struct PostDominatorTree : public DominatorTreeBase { virtual bool runOnFunction(Function &F) { reset(); // Reset from the last time we were run... - calculate(F); + PDTcalculate(*this, F); return false; } @@ -37,11 +37,13 @@ struct PostDominatorTree : public DominatorTreeBase { AU.setPreservesAll(); } private: - void calculate(Function &F); unsigned DFSPass(BasicBlock *V, unsigned N); - void Compress(BasicBlock *V, InfoRec &VInfo); - BasicBlock *Eval(BasicBlock *V); - void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo); + friend void PDTcalculate(PostDominatorTree& PDT, Function &F); + friend void PDTCompress(PostDominatorTree& PDT, BasicBlock *V, + InfoRec &VInfo); + friend BasicBlock *PDTEval(PostDominatorTree& PDT, BasicBlock *V); + friend void PDTLink(PostDominatorTree& PDT,BasicBlock *V, + BasicBlock *W, InfoRec &WInfo); }; diff --git a/lib/Analysis/PostDominatorCalculation.h b/lib/Analysis/PostDominatorCalculation.h new file mode 100644 index 00000000000..0240c44d977 --- /dev/null +++ b/lib/Analysis/PostDominatorCalculation.h @@ -0,0 +1,148 @@ +//==- PostDominatorCalculation.h - Post-Dominator Calculation ----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Owen Anderson and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// PostDominatorTree calculation implementation. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_POST_DOMINATOR_CALCULATION_H +#define LLVM_ANALYSIS_POST_DOMINATOR_CALCULATION_H + +#include "llvm/Analysis/PostDominators.h" + +namespace llvm { + +void PDTCompress(PostDominatorTree& PDT, BasicBlock *V, + PostDominatorTree::InfoRec &VInfo) { + BasicBlock *VAncestor = VInfo.Ancestor; + PostDominatorTree::InfoRec &VAInfo = PDT.Info[VAncestor]; + if (VAInfo.Ancestor == 0) + return; + + PDTCompress(PDT, VAncestor, VAInfo); + + BasicBlock *VAncestorLabel = VAInfo.Label; + BasicBlock *VLabel = VInfo.Label; + if (PDT.Info[VAncestorLabel].Semi < PDT.Info[VLabel].Semi) + VInfo.Label = VAncestorLabel; + + VInfo.Ancestor = VAInfo.Ancestor; +} + +BasicBlock *PDTEval(PostDominatorTree& PDT, BasicBlock *V) { + PostDominatorTree::InfoRec &VInfo = PDT.Info[V]; + + // Higher-complexity but faster implementation + if (VInfo.Ancestor == 0) + return V; + PDTCompress(PDT, V, VInfo); + return VInfo.Label; +} + +void PDTLink(PostDominatorTree& PDT, BasicBlock *V, BasicBlock *W, + PostDominatorTree::InfoRec &WInfo) { + // Higher-complexity but faster implementation + WInfo.Ancestor = V; +} + +void PDTcalculate(PostDominatorTree& PDT, Function &F) { + // Step #0: Scan the function looking for the root nodes of the post-dominance + // relationships. These blocks, which have no successors, end with return and + // unwind instructions. + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { + TerminatorInst *Insn = I->getTerminator(); + if (Insn->getNumSuccessors() == 0) { + // Unreachable block is not a root node. + if (!isa(Insn)) + PDT.Roots.push_back(I); + } + + // Prepopulate maps so that we don't get iterator invalidation issues later. + PDT.IDoms[I] = 0; + PDT.DomTreeNodes[I] = 0; + } + + PDT.Vertex.push_back(0); + + // Step #1: Number blocks in depth-first order and initialize variables used + // in later stages of the algorithm. + unsigned N = 0; + for (unsigned i = 0, e = PDT.Roots.size(); i != e; ++i) + N = PDT.DFSPass(PDT.Roots[i], N); + + for (unsigned i = N; i >= 2; --i) { + BasicBlock *W = PDT.Vertex[i]; + PostDominatorTree::InfoRec &WInfo = PDT.Info[W]; + + // Step #2: Calculate the semidominators of all vertices + for (succ_iterator SI = succ_begin(W), SE = succ_end(W); SI != SE; ++SI) + if (PDT.Info.count(*SI)) { // Only if this predecessor is reachable! + unsigned SemiU = PDT.Info[PDTEval(PDT, *SI)].Semi; + if (SemiU < WInfo.Semi) + WInfo.Semi = SemiU; + } + + PDT.Info[PDT.Vertex[WInfo.Semi]].Bucket.push_back(W); + + BasicBlock *WParent = WInfo.Parent; + PDTLink(PDT, WParent, W, WInfo); + + // Step #3: Implicitly define the immediate dominator of vertices + std::vector &WParentBucket = PDT.Info[WParent].Bucket; + while (!WParentBucket.empty()) { + BasicBlock *V = WParentBucket.back(); + WParentBucket.pop_back(); + BasicBlock *U = PDTEval(PDT, V); + PDT.IDoms[V] = PDT.Info[U].Semi < PDT.Info[V].Semi ? U : WParent; + } + } + + // Step #4: Explicitly define the immediate dominator of each vertex + for (unsigned i = 2; i <= N; ++i) { + BasicBlock *W = PDT.Vertex[i]; + BasicBlock *&WIDom = PDT.IDoms[W]; + if (WIDom != PDT.Vertex[PDT.Info[W].Semi]) + WIDom = PDT.IDoms[WIDom]; + } + + if (PDT.Roots.empty()) return; + + // Add a node for the root. This node might be the actual root, if there is + // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) + // which postdominates all real exits if there are multiple exit blocks. + BasicBlock *Root = PDT.Roots.size() == 1 ? PDT.Roots[0] : 0; + PDT.DomTreeNodes[Root] = PDT.RootNode = new DomTreeNode(Root, 0); + + // Loop over all of the reachable blocks in the function... + for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) + if (BasicBlock *ImmPostDom = PDT.getIDom(I)) { // Reachable block. + DomTreeNode *&BBNode = PDT.DomTreeNodes[I]; + if (!BBNode) { // Haven't calculated this node yet? + // Get or calculate the node for the immediate dominator + DomTreeNode *IPDomNode = PDT.getNodeForBlock(ImmPostDom); + + // Add a new tree node for this BasicBlock, and link it as a child of + // IDomNode + DomTreeNode *C = new DomTreeNode(I, IPDomNode); + PDT.DomTreeNodes[I] = C; + BBNode = IPDomNode->addChild(C); + } + } + + // Free temporary memory used to construct idom's + PDT.IDoms.clear(); + PDT.Info.clear(); + std::vector().swap(PDT.Vertex); + + // Start out with the DFS numbers being invalid. Let them be computed if + // demanded. + PDT.DFSInfoValid = false; +} + +} +#endif \ No newline at end of file diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index 69e9cbe26b8..b8d833e23d7 100644 --- a/lib/Analysis/PostDominators.cpp +++ b/lib/Analysis/PostDominators.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/CFG.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SetOperations.h" +#include "PostDominatorCalculation.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -72,148 +73,6 @@ unsigned PostDominatorTree::DFSPass(BasicBlock *V, unsigned N) { return N; } -void PostDominatorTree::Compress(BasicBlock *V, InfoRec &VInfo) { - BasicBlock *VAncestor = VInfo.Ancestor; - InfoRec &VAInfo = Info[VAncestor]; - if (VAInfo.Ancestor == 0) - return; - - Compress(VAncestor, VAInfo); - - BasicBlock *VAncestorLabel = VAInfo.Label; - BasicBlock *VLabel = VInfo.Label; - if (Info[VAncestorLabel].Semi < Info[VLabel].Semi) - VInfo.Label = VAncestorLabel; - - VInfo.Ancestor = VAInfo.Ancestor; -} - -BasicBlock *PostDominatorTree::Eval(BasicBlock *V) { - InfoRec &VInfo = Info[V]; - - // Higher-complexity but faster implementation - if (VInfo.Ancestor == 0) - return V; - Compress(V, VInfo); - return VInfo.Label; -} - -void PostDominatorTree::Link(BasicBlock *V, BasicBlock *W, - InfoRec &WInfo) { - // Higher-complexity but faster implementation - WInfo.Ancestor = V; -} - -void PostDominatorTree::calculate(Function &F) { - // Step #0: Scan the function looking for the root nodes of the post-dominance - // relationships. These blocks, which have no successors, end with return and - // unwind instructions. - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) { - TerminatorInst *Insn = I->getTerminator(); - if (Insn->getNumSuccessors() == 0) { - // Unreachable block is not a root node. - if (!isa(Insn)) - Roots.push_back(I); - } - - // Prepopulate maps so that we don't get iterator invalidation issues later. - IDoms[I] = 0; - DomTreeNodes[I] = 0; - } - - Vertex.push_back(0); - - // Step #1: Number blocks in depth-first order and initialize variables used - // in later stages of the algorithm. - unsigned N = 0; - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - N = DFSPass(Roots[i], N); - - for (unsigned i = N; i >= 2; --i) { - BasicBlock *W = Vertex[i]; - InfoRec &WInfo = Info[W]; - - // Step #2: Calculate the semidominators of all vertices - for (succ_iterator SI = succ_begin(W), SE = succ_end(W); SI != SE; ++SI) - if (Info.count(*SI)) { // Only if this predecessor is reachable! - unsigned SemiU = Info[Eval(*SI)].Semi; - if (SemiU < WInfo.Semi) - WInfo.Semi = SemiU; - } - - Info[Vertex[WInfo.Semi]].Bucket.push_back(W); - - BasicBlock *WParent = WInfo.Parent; - Link(WParent, W, WInfo); - - // Step #3: Implicitly define the immediate dominator of vertices - std::vector &WParentBucket = Info[WParent].Bucket; - while (!WParentBucket.empty()) { - BasicBlock *V = WParentBucket.back(); - WParentBucket.pop_back(); - BasicBlock *U = Eval(V); - IDoms[V] = Info[U].Semi < Info[V].Semi ? U : WParent; - } - } - - // Step #4: Explicitly define the immediate dominator of each vertex - for (unsigned i = 2; i <= N; ++i) { - BasicBlock *W = Vertex[i]; - BasicBlock *&WIDom = IDoms[W]; - if (WIDom != Vertex[Info[W].Semi]) - WIDom = IDoms[WIDom]; - } - - if (Roots.empty()) return; - - // Add a node for the root. This node might be the actual root, if there is - // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) - // which postdominates all real exits if there are multiple exit blocks. - BasicBlock *Root = Roots.size() == 1 ? Roots[0] : 0; - DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0); - - // Loop over all of the reachable blocks in the function... - for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) - if (BasicBlock *ImmPostDom = getIDom(I)) { // Reachable block. - DomTreeNode *&BBNode = DomTreeNodes[I]; - if (!BBNode) { // Haven't calculated this node yet? - // Get or calculate the node for the immediate dominator - DomTreeNode *IPDomNode = getNodeForBlock(ImmPostDom); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - DomTreeNode *C = new DomTreeNode(I, IPDomNode); - DomTreeNodes[I] = C; - BBNode = IPDomNode->addChild(C); - } - } - - // Free temporary memory used to construct idom's - IDoms.clear(); - Info.clear(); - std::vector().swap(Vertex); - - // Start out with the DFS numbers being invalid. Let them be computed if - // demanded. - DFSInfoValid = false; -} - - -DomTreeNode *PostDominatorTree::getNodeForBlock(BasicBlock *BB) { - DomTreeNode *&BBNode = DomTreeNodes[BB]; - if (BBNode) return BBNode; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate postdominator. - BasicBlock *IPDom = getIDom(BB); - DomTreeNode *IPDomNode = getNodeForBlock(IPDom); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - DomTreeNode *C = new DomTreeNode(BB, IPDomNode); - return DomTreeNodes[BB] = IPDomNode->addChild(C); -} - //===----------------------------------------------------------------------===// // PostDominanceFrontier Implementation //===----------------------------------------------------------------------===//