LLVM API Documentation
00001 //===- DominanceFrontier.cpp - Dominance Frontier Calculation -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "llvm/Analysis/DominanceFrontier.h" 00011 #include "llvm/ADT/SmallPtrSet.h" 00012 #include "llvm/Assembly/Writer.h" 00013 #include "llvm/Support/Debug.h" 00014 #include "llvm/Support/raw_ostream.h" 00015 using namespace llvm; 00016 00017 char DominanceFrontier::ID = 0; 00018 INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier", 00019 "Dominance Frontier Construction", true, true) 00020 INITIALIZE_PASS_DEPENDENCY(DominatorTree) 00021 INITIALIZE_PASS_END(DominanceFrontier, "domfrontier", 00022 "Dominance Frontier Construction", true, true) 00023 00024 namespace { 00025 class DFCalculateWorkObject { 00026 public: 00027 DFCalculateWorkObject(BasicBlock *B, BasicBlock *P, 00028 const DomTreeNode *N, 00029 const DomTreeNode *PN) 00030 : currentBB(B), parentBB(P), Node(N), parentNode(PN) {} 00031 BasicBlock *currentBB; 00032 BasicBlock *parentBB; 00033 const DomTreeNode *Node; 00034 const DomTreeNode *parentNode; 00035 }; 00036 } 00037 00038 void DominanceFrontier::anchor() { } 00039 00040 const DominanceFrontier::DomSetType & 00041 DominanceFrontier::calculate(const DominatorTree &DT, 00042 const DomTreeNode *Node) { 00043 BasicBlock *BB = Node->getBlock(); 00044 DomSetType *Result = NULL; 00045 00046 std::vector<DFCalculateWorkObject> workList; 00047 SmallPtrSet<BasicBlock *, 32> visited; 00048 00049 workList.push_back(DFCalculateWorkObject(BB, NULL, Node, NULL)); 00050 do { 00051 DFCalculateWorkObject *currentW = &workList.back(); 00052 assert (currentW && "Missing work object."); 00053 00054 BasicBlock *currentBB = currentW->currentBB; 00055 BasicBlock *parentBB = currentW->parentBB; 00056 const DomTreeNode *currentNode = currentW->Node; 00057 const DomTreeNode *parentNode = currentW->parentNode; 00058 assert (currentBB && "Invalid work object. Missing current Basic Block"); 00059 assert (currentNode && "Invalid work object. Missing current Node"); 00060 DomSetType &S = Frontiers[currentBB]; 00061 00062 // Visit each block only once. 00063 if (visited.count(currentBB) == 0) { 00064 visited.insert(currentBB); 00065 00066 // Loop over CFG successors to calculate DFlocal[currentNode] 00067 for (succ_iterator SI = succ_begin(currentBB), SE = succ_end(currentBB); 00068 SI != SE; ++SI) { 00069 // Does Node immediately dominate this successor? 00070 if (DT[*SI]->getIDom() != currentNode) 00071 S.insert(*SI); 00072 } 00073 } 00074 00075 // At this point, S is DFlocal. Now we union in DFup's of our children... 00076 // Loop through and visit the nodes that Node immediately dominates (Node's 00077 // children in the IDomTree) 00078 bool visitChild = false; 00079 for (DomTreeNode::const_iterator NI = currentNode->begin(), 00080 NE = currentNode->end(); NI != NE; ++NI) { 00081 DomTreeNode *IDominee = *NI; 00082 BasicBlock *childBB = IDominee->getBlock(); 00083 if (visited.count(childBB) == 0) { 00084 workList.push_back(DFCalculateWorkObject(childBB, currentBB, 00085 IDominee, currentNode)); 00086 visitChild = true; 00087 } 00088 } 00089 00090 // If all children are visited or there is any child then pop this block 00091 // from the workList. 00092 if (!visitChild) { 00093 00094 if (!parentBB) { 00095 Result = &S; 00096 break; 00097 } 00098 00099 DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end(); 00100 DomSetType &parentSet = Frontiers[parentBB]; 00101 for (; CDFI != CDFE; ++CDFI) { 00102 if (!DT.properlyDominates(parentNode, DT[*CDFI])) 00103 parentSet.insert(*CDFI); 00104 } 00105 workList.pop_back(); 00106 } 00107 00108 } while (!workList.empty()); 00109 00110 return *Result; 00111 } 00112 00113 void DominanceFrontierBase::print(raw_ostream &OS, const Module* ) const { 00114 for (const_iterator I = begin(), E = end(); I != E; ++I) { 00115 OS << " DomFrontier for BB "; 00116 if (I->first) 00117 WriteAsOperand(OS, I->first, false); 00118 else 00119 OS << " <<exit node>>"; 00120 OS << " is:\t"; 00121 00122 const std::set<BasicBlock*> &BBs = I->second; 00123 00124 for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); 00125 I != E; ++I) { 00126 OS << ' '; 00127 if (*I) 00128 WriteAsOperand(OS, *I, false); 00129 else 00130 OS << "<<exit node>>"; 00131 } 00132 OS << "\n"; 00133 } 00134 } 00135 00136 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 00137 void DominanceFrontierBase::dump() const { 00138 print(dbgs()); 00139 } 00140 #endif 00141