X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FPostDominators.cpp;h=c38e0503f931d25bc9ae725f6a567f6ad2c214ee;hb=9b1061e2e3c3a463aa251e2e6631d5e4313a7ac6;hp=244f8cdff525c16649730bb714a82d59d4423760;hpb=e93e31198109b03b8c22296a1500839e95d59b5f;p=oota-llvm.git diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index 244f8cdff52..c38e0503f93 100644 --- a/lib/Analysis/PostDominators.cpp +++ b/lib/Analysis/PostDominators.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -11,11 +11,15 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "postdomtree" + #include "llvm/Analysis/PostDominators.h" #include "llvm/Instructions.h" #include "llvm/Support/CFG.h" +#include "llvm/Support/Debug.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/SetOperations.h" +#include "llvm/Analysis/DominatorInternals.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -25,200 +29,25 @@ using namespace llvm; char PostDominatorTree::ID = 0; char PostDominanceFrontier::ID = 0; static RegisterPass -F("postdomtree", "Post-Dominator Tree Construction", true); - -unsigned PostDominatorTree::DFSPass(BasicBlock *V, unsigned N) { - std::vector workStack; - std::set visited; - workStack.push_back(V); - - do { - BasicBlock *currentBB = workStack.back(); - InfoRec &CurVInfo = Info[currentBB]; - - // Visit each block only once. - if (visited.insert(currentBB).second) { - CurVInfo.Semi = ++N; - CurVInfo.Label = currentBB; - - Vertex.push_back(currentBB); // Vertex[n] = current; - // Info[currentBB].Ancestor = 0; - // Ancestor[n] = 0 - // Child[currentBB] = 0; - CurVInfo.Size = 1; // Size[currentBB] = 1 - } - - // Visit children - bool visitChild = false; - for (pred_iterator PI = pred_begin(currentBB), PE = pred_end(currentBB); - PI != PE && !visitChild; ++PI) { - InfoRec &SuccVInfo = Info[*PI]; - if (SuccVInfo.Semi == 0) { - SuccVInfo.Parent = currentBB; - if (!visited.count(*PI)) { - workStack.push_back(*PI); - visitChild = true; - } - } - } +F("postdomtree", "Post-Dominator Tree Construction", true, true); - // If all children are visited or if this block has no child then pop this - // block out of workStack. - if (!visitChild) - workStack.pop_back(); - - } while (!workStack.empty()); - - return N; +bool PostDominatorTree::runOnFunction(Function &F) { + DT->recalculate(F); + DEBUG(DT->print(dbgs())); + return false; } -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; +PostDominatorTree::~PostDominatorTree() { + delete DT; } -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::print(raw_ostream &OS, const Module *) const { + DT->print(OS); } -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); - - int dfsnum = 0; - // Iterate over all nodes in depth first order... - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - for (idf_iterator I = idf_begin(Roots[i]), - E = idf_end(Roots[i]); I != E; ++I) { - if (!getNodeForBlock(*I)->getIDom()) - getNodeForBlock(*I)->assignDFSNumber(dfsnum); - } - DFSInfoValid = true; -} - - -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); - DomTreeNodes[BB] = C; - return BBNode = IPDomNode->addChild(C); +FunctionPass* llvm::createPostDomTree() { + return new PostDominatorTree(); } //===----------------------------------------------------------------------===// @@ -226,7 +55,7 @@ DomTreeNode *PostDominatorTree::getNodeForBlock(BasicBlock *BB) { //===----------------------------------------------------------------------===// static RegisterPass -H("postdomfrontier", "Post-Dominance Frontier Construction", true); +H("postdomfrontier", "Post-Dominance Frontier Construction", true, true); const DominanceFrontier::DomSetType & PostDominanceFrontier::calculate(const PostDominatorTree &DT, @@ -264,5 +93,6 @@ PostDominanceFrontier::calculate(const PostDominatorTree &DT, return S; } -// Ensure that this .cpp file gets linked when PostDominators.h is used. -DEFINING_FILE_FOR(PostDominanceFrontier) +FunctionPass* llvm::createPostDomFrontier() { + return new PostDominanceFrontier(); +}