X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FPostDominators.cpp;h=3f0deab9ea87656134a481b33ee65940d3a22dcf;hb=4b720718fbda1194f925e0a9d931bc220e8b0e3a;hp=68424400dbfb5f4bfddb711e25141e82f934780b;hpb=1997473cf72957d0e70322e2fe6fe2ab141c58a6;p=oota-llvm.git diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp index 68424400dbf..3f0deab9ea8 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,16 @@ // //===----------------------------------------------------------------------===// +#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/Assembly/Writer.h" +#include "llvm/Analysis/DominatorInternals.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -24,260 +29,40 @@ using namespace llvm; char PostDominatorTree::ID = 0; char PostDominanceFrontier::ID = 0; -char PostETForest::ID = 0; -static RegisterPass -F("postdomtree", "Post-Dominator Tree Construction", true); - -unsigned PostDominatorTree::DFSPass(BasicBlock *V, InfoRec &VInfo, - unsigned N) { - std::vector > workStack; - std::set visited; - workStack.push_back(std::make_pair(V, &VInfo)); - - do { - BasicBlock *currentBB = workStack.back().first; - InfoRec *currentVInfo = workStack.back().second; - - // Visit each block only once. - if (visited.count(currentBB) == 0) { - - visited.insert(currentBB); - currentVInfo->Semi = ++N; - currentVInfo->Label = currentBB; - - Vertex.push_back(currentBB); // Vertex[n] = current; - // Info[currentBB].Ancestor = 0; - // Ancestor[n] = 0 - // Child[currentBB] = 0; - currentVInfo->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) == 0) { - workStack.push_back(std::make_pair(*PI, &SuccVInfo)); - visitChild = 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()); +INITIALIZE_PASS(PostDominatorTree, "postdomtree", + "Post-Dominator Tree Construction", true, true) - return N; +bool PostDominatorTree::runOnFunction(Function &F) { + DT->recalculate(F); + 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::Link(BasicBlock *V, BasicBlock *W, - InfoRec &WInfo) { - // Higher-complexity but faster implementation - WInfo.Ancestor = V; +void PostDominatorTree::print(raw_ostream &OS, const Module *) const { + DT->print(OS); } -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) - if (succ_begin(I) == succ_end(I)) - Roots.push_back(I); - - 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], Info[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; - Nodes[Root] = RootNode = new Node(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. - Node *&BBNode = Nodes[I]; - if (!BBNode) { // Haven't calculated this node yet? - // Get or calculate the node for the immediate dominator - Node *IPDomNode = getNodeForBlock(ImmPostDom); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - BBNode = IPDomNode->addChild(new Node(I, IPDomNode)); - } - } - // Free temporary memory used to construct idom's - IDoms.clear(); - Info.clear(); - std::vector().swap(Vertex); -} - - -DominatorTreeBase::Node *PostDominatorTree::getNodeForBlock(BasicBlock *BB) { - Node *&BBNode = Nodes[BB]; - if (BBNode) return BBNode; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate postdominator. - BasicBlock *IPDom = getIDom(BB); - Node *IPDomNode = getNodeForBlock(IPDom); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - return BBNode = IPDomNode->addChild(new Node(BB, IPDomNode)); -} - -//===----------------------------------------------------------------------===// -// PostETForest Implementation -//===----------------------------------------------------------------------===// - -static RegisterPass -G("postetforest", "Post-ET-Forest Construction", true); - -ETNode *PostETForest::getNodeForBlock(BasicBlock *BB) { - ETNode *&BBNode = Nodes[BB]; - if (BBNode) return BBNode; - - // Haven't calculated this node yet? Get or calculate the node for the - // immediate dominator. - PostDominatorTree::Node *node = getAnalysis().getNode(BB); - - // If we are unreachable, we may not have an immediate dominator. - if (!node) - return 0; - else if (!node->getIDom()) - return BBNode = new ETNode(BB); - else { - ETNode *IDomNode = getNodeForBlock(node->getIDom()->getBlock()); - - // Add a new tree node for this BasicBlock, and link it as a child of - // IDomNode - BBNode = new ETNode(BB); - BBNode->setFather(IDomNode); - return BBNode; - } -} - -void PostETForest::calculate(const PostDominatorTree &DT) { - for (unsigned i = 0, e = Roots.size(); i != e; ++i) - Nodes[Roots[i]] = new ETNode(Roots[i]); // Add a node for the root - - // Iterate over all nodes in inverse 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) { - BasicBlock *BB = *I; - ETNode *&BBNode = Nodes[BB]; - if (!BBNode) { - ETNode *IDomNode = NULL; - PostDominatorTree::Node *node = DT.getNode(BB); - if (node && node->getIDom()) - IDomNode = getNodeForBlock(node->getIDom()->getBlock()); - - // Add a new ETNode for this BasicBlock, and set it's parent - // to it's immediate dominator. - BBNode = new ETNode(BB); - if (IDomNode) - BBNode->setFather(IDomNode); - } - } - - 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)->hasFather()) - getNodeForBlock(*I)->assignDFSNumber(dfsnum); - } - DFSInfoValid = true; +FunctionPass* llvm::createPostDomTree() { + return new PostDominatorTree(); } //===----------------------------------------------------------------------===// // PostDominanceFrontier Implementation //===----------------------------------------------------------------------===// -static RegisterPass -H("postdomfrontier", "Post-Dominance Frontier Construction", true); +INITIALIZE_PASS_BEGIN(PostDominanceFrontier, "postdomfrontier", + "Post-Dominance Frontier Construction", true, true) +INITIALIZE_PASS_DEPENDENCY(PostDominatorTree) +INITIALIZE_PASS_END(PostDominanceFrontier, "postdomfrontier", + "Post-Dominance Frontier Construction", true, true) const DominanceFrontier::DomSetType & PostDominanceFrontier::calculate(const PostDominatorTree &DT, - const DominatorTree::Node *Node) { + const DomTreeNode *Node) { // Loop over CFG successors to calculate DFlocal[Node] BasicBlock *BB = Node->getBlock(); DomSetType &S = Frontiers[BB]; // The new set to fill in... @@ -286,24 +71,25 @@ PostDominanceFrontier::calculate(const PostDominatorTree &DT, if (BB) for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); SI != SE; ++SI) { + BasicBlock *P = *SI; // Does Node immediately dominate this predecessor? - DominatorTree::Node *SINode = DT[*SI]; + DomTreeNode *SINode = DT[P]; if (SINode && SINode->getIDom() != Node) - S.insert(*SI); + S.insert(P); } // 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 (PostDominatorTree::Node::const_iterator + for (DomTreeNode::const_iterator NI = Node->begin(), NE = Node->end(); NI != NE; ++NI) { - DominatorTree::Node *IDominee = *NI; + DomTreeNode *IDominee = *NI; const DomSetType &ChildDF = calculate(DT, IDominee); DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); for (; CDFI != CDFE; ++CDFI) { - if (!Node->properlyDominates(DT[*CDFI])) + if (!DT.properlyDominates(Node, DT[*CDFI])) S.insert(*CDFI); } } @@ -311,5 +97,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(); +}