PostDominators.cpp revision 04fa56932052f416ea911fe65615ebecbf154f6d
1//===- PostDominators.cpp - Post-Dominator Calculation --------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the post-dominator construction algorithms. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Analysis/PostDominators.h" 15#include "llvm/Instructions.h" 16#include "llvm/Support/CFG.h" 17#include "llvm/ADT/DepthFirstIterator.h" 18#include "llvm/ADT/SetOperations.h" 19#include "PostDominatorCalculation.h" 20using namespace llvm; 21 22//===----------------------------------------------------------------------===// 23// PostDominatorTree Implementation 24//===----------------------------------------------------------------------===// 25 26char PostDominatorTree::ID = 0; 27char PostDominanceFrontier::ID = 0; 28static RegisterPass<PostDominatorTree> 29F("postdomtree", "Post-Dominator Tree Construction", true); 30 31unsigned PostDominatorTree::DFSPass(BasicBlock *V, unsigned N) { 32 std::vector<BasicBlock *> workStack; 33 SmallPtrSet<BasicBlock *, 32> Visited; 34 workStack.push_back(V); 35 36 do { 37 BasicBlock *currentBB = workStack.back(); 38 InfoRec &CurVInfo = Info[currentBB]; 39 40 // Visit each block only once. 41 if (Visited.insert(currentBB)) { 42 CurVInfo.Semi = ++N; 43 CurVInfo.Label = currentBB; 44 45 Vertex.push_back(currentBB); // Vertex[n] = current; 46 // Info[currentBB].Ancestor = 0; 47 // Ancestor[n] = 0 48 // Child[currentBB] = 0; 49 CurVInfo.Size = 1; // Size[currentBB] = 1 50 } 51 52 // Visit children 53 bool visitChild = false; 54 for (pred_iterator PI = pred_begin(currentBB), PE = pred_end(currentBB); 55 PI != PE && !visitChild; ++PI) { 56 InfoRec &SuccVInfo = Info[*PI]; 57 if (SuccVInfo.Semi == 0) { 58 SuccVInfo.Parent = currentBB; 59 if (!Visited.count(*PI)) { 60 workStack.push_back(*PI); 61 visitChild = true; 62 } 63 } 64 } 65 66 // If all children are visited or if this block has no child then pop this 67 // block out of workStack. 68 if (!visitChild) 69 workStack.pop_back(); 70 71 } while (!workStack.empty()); 72 73 return N; 74} 75 76//===----------------------------------------------------------------------===// 77// PostDominanceFrontier Implementation 78//===----------------------------------------------------------------------===// 79 80static RegisterPass<PostDominanceFrontier> 81H("postdomfrontier", "Post-Dominance Frontier Construction", true); 82 83const DominanceFrontier::DomSetType & 84PostDominanceFrontier::calculate(const PostDominatorTree &DT, 85 const DomTreeNode *Node) { 86 // Loop over CFG successors to calculate DFlocal[Node] 87 BasicBlock *BB = Node->getBlock(); 88 DomSetType &S = Frontiers[BB]; // The new set to fill in... 89 if (getRoots().empty()) return S; 90 91 if (BB) 92 for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB); 93 SI != SE; ++SI) { 94 // Does Node immediately dominate this predecessor? 95 DomTreeNode *SINode = DT[*SI]; 96 if (SINode && SINode->getIDom() != Node) 97 S.insert(*SI); 98 } 99 100 // At this point, S is DFlocal. Now we union in DFup's of our children... 101 // Loop through and visit the nodes that Node immediately dominates (Node's 102 // children in the IDomTree) 103 // 104 for (DomTreeNode::const_iterator 105 NI = Node->begin(), NE = Node->end(); NI != NE; ++NI) { 106 DomTreeNode *IDominee = *NI; 107 const DomSetType &ChildDF = calculate(DT, IDominee); 108 109 DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); 110 for (; CDFI != CDFE; ++CDFI) { 111 if (!DT.properlyDominates(Node, DT[*CDFI])) 112 S.insert(*CDFI); 113 } 114 } 115 116 return S; 117} 118 119// Ensure that this .cpp file gets linked when PostDominators.h is used. 120DEFINING_FILE_FOR(PostDominanceFrontier) 121