LLVM API Documentation
00001 //===- llvm/Analysis/DominanceFrontier.h - Dominator Frontiers --*- C++ -*-===// 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 // This is the generic implementation of the DominanceFrontier class, which 00011 // calculate and holds the dominance frontier for a function for. 00012 // 00013 // This should be considered deprecated, don't add any more uses of this data 00014 // structure. 00015 // 00016 //===----------------------------------------------------------------------===// 00017 00018 #ifndef LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H 00019 #define LLVM_ANALYSIS_DOMINANCEFRONTIERIMPL_H 00020 00021 #include "llvm/ADT/SmallPtrSet.h" 00022 #include "llvm/Support/Debug.h" 00023 00024 namespace llvm { 00025 00026 namespace { 00027 template <class BlockT> 00028 class DFCalculateWorkObject { 00029 public: 00030 typedef DomTreeNodeBase<BlockT> DomTreeNodeT; 00031 00032 DFCalculateWorkObject(BlockT *B, BlockT *P, const DomTreeNodeT *N, 00033 const DomTreeNodeT *PN) 00034 : currentBB(B), parentBB(P), Node(N), parentNode(PN) {} 00035 BlockT *currentBB; 00036 BlockT *parentBB; 00037 const DomTreeNodeT *Node; 00038 const DomTreeNodeT *parentNode; 00039 }; 00040 } 00041 00042 template <class BlockT> 00043 void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) { 00044 assert(find(BB) != end() && "Block is not in DominanceFrontier!"); 00045 for (iterator I = begin(), E = end(); I != E; ++I) 00046 I->second.erase(BB); 00047 Frontiers.erase(BB); 00048 } 00049 00050 template <class BlockT> 00051 void DominanceFrontierBase<BlockT>::addToFrontier(iterator I, 00052 BlockT *Node) { 00053 assert(I != end() && "BB is not in DominanceFrontier!"); 00054 assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); 00055 I->second.erase(Node); 00056 } 00057 00058 template <class BlockT> 00059 void DominanceFrontierBase<BlockT>::removeFromFrontier(iterator I, 00060 BlockT *Node) { 00061 assert(I != end() && "BB is not in DominanceFrontier!"); 00062 assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB"); 00063 I->second.erase(Node); 00064 } 00065 00066 template <class BlockT> 00067 bool DominanceFrontierBase<BlockT>::compareDomSet(DomSetType &DS1, 00068 const DomSetType &DS2) const { 00069 std::set<BlockT *> tmpSet; 00070 for (BlockT *BB : DS2) 00071 tmpSet.insert(BB); 00072 00073 for (typename DomSetType::const_iterator I = DS1.begin(), E = DS1.end(); 00074 I != E;) { 00075 BlockT *Node = *I++; 00076 00077 if (tmpSet.erase(Node) == 0) 00078 // Node is in DS1 but tnot in DS2. 00079 return true; 00080 } 00081 00082 if (!tmpSet.empty()) { 00083 // There are nodes that are in DS2 but not in DS1. 00084 return true; 00085 } 00086 00087 // DS1 and DS2 matches. 00088 return false; 00089 } 00090 00091 template <class BlockT> 00092 bool DominanceFrontierBase<BlockT>::compare( 00093 DominanceFrontierBase<BlockT> &Other) const { 00094 DomSetMapType tmpFrontiers; 00095 for (typename DomSetMapType::const_iterator I = Other.begin(), 00096 E = Other.end(); 00097 I != E; ++I) 00098 tmpFrontiers.insert(std::make_pair(I->first, I->second)); 00099 00100 for (typename DomSetMapType::iterator I = tmpFrontiers.begin(), 00101 E = tmpFrontiers.end(); 00102 I != E;) { 00103 BlockT *Node = I->first; 00104 const_iterator DFI = find(Node); 00105 if (DFI == end()) 00106 return true; 00107 00108 if (compareDomSet(I->second, DFI->second)) 00109 return true; 00110 00111 ++I; 00112 tmpFrontiers.erase(Node); 00113 } 00114 00115 if (!tmpFrontiers.empty()) 00116 return true; 00117 00118 return false; 00119 } 00120 00121 template <class BlockT> 00122 void DominanceFrontierBase<BlockT>::print(raw_ostream &OS) const { 00123 for (const_iterator I = begin(), E = end(); I != E; ++I) { 00124 OS << " DomFrontier for BB "; 00125 if (I->first) 00126 I->first->printAsOperand(OS, false); 00127 else 00128 OS << " <<exit node>>"; 00129 OS << " is:\t"; 00130 00131 const std::set<BlockT *> &BBs = I->second; 00132 00133 for (const BlockT *BB : BBs) { 00134 OS << ' '; 00135 if (BB) 00136 BB->printAsOperand(OS, false); 00137 else 00138 OS << "<<exit node>>"; 00139 } 00140 OS << '\n'; 00141 } 00142 } 00143 00144 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 00145 template <class BlockT> 00146 void DominanceFrontierBase<BlockT>::dump() const { 00147 print(dbgs()); 00148 } 00149 #endif 00150 00151 template <class BlockT> 00152 const typename ForwardDominanceFrontierBase<BlockT>::DomSetType & 00153 ForwardDominanceFrontierBase<BlockT>::calculate(const DomTreeT &DT, 00154 const DomTreeNodeT *Node) { 00155 BlockT *BB = Node->getBlock(); 00156 DomSetType *Result = nullptr; 00157 00158 std::vector<DFCalculateWorkObject<BlockT>> workList; 00159 SmallPtrSet<BlockT *, 32> visited; 00160 00161 workList.push_back(DFCalculateWorkObject<BlockT>(BB, nullptr, Node, nullptr)); 00162 do { 00163 DFCalculateWorkObject<BlockT> *currentW = &workList.back(); 00164 assert(currentW && "Missing work object."); 00165 00166 BlockT *currentBB = currentW->currentBB; 00167 BlockT *parentBB = currentW->parentBB; 00168 const DomTreeNodeT *currentNode = currentW->Node; 00169 const DomTreeNodeT *parentNode = currentW->parentNode; 00170 assert(currentBB && "Invalid work object. Missing current Basic Block"); 00171 assert(currentNode && "Invalid work object. Missing current Node"); 00172 DomSetType &S = this->Frontiers[currentBB]; 00173 00174 // Visit each block only once. 00175 if (visited.count(currentBB) == 0) { 00176 visited.insert(currentBB); 00177 00178 // Loop over CFG successors to calculate DFlocal[currentNode] 00179 for (auto SI = BlockTraits::child_begin(currentBB), 00180 SE = BlockTraits::child_end(currentBB); 00181 SI != SE; ++SI) { 00182 // Does Node immediately dominate this successor? 00183 if (DT[*SI]->getIDom() != currentNode) 00184 S.insert(*SI); 00185 } 00186 } 00187 00188 // At this point, S is DFlocal. Now we union in DFup's of our children... 00189 // Loop through and visit the nodes that Node immediately dominates (Node's 00190 // children in the IDomTree) 00191 bool visitChild = false; 00192 for (typename DomTreeNodeT::const_iterator NI = currentNode->begin(), 00193 NE = currentNode->end(); 00194 NI != NE; ++NI) { 00195 DomTreeNodeT *IDominee = *NI; 00196 BlockT *childBB = IDominee->getBlock(); 00197 if (visited.count(childBB) == 0) { 00198 workList.push_back(DFCalculateWorkObject<BlockT>( 00199 childBB, currentBB, IDominee, currentNode)); 00200 visitChild = true; 00201 } 00202 } 00203 00204 // If all children are visited or there is any child then pop this block 00205 // from the workList. 00206 if (!visitChild) { 00207 if (!parentBB) { 00208 Result = &S; 00209 break; 00210 } 00211 00212 typename DomSetType::const_iterator CDFI = S.begin(), CDFE = S.end(); 00213 DomSetType &parentSet = this->Frontiers[parentBB]; 00214 for (; CDFI != CDFE; ++CDFI) { 00215 if (!DT.properlyDominates(parentNode, DT[*CDFI])) 00216 parentSet.insert(*CDFI); 00217 } 00218 workList.pop_back(); 00219 } 00220 00221 } while (!workList.empty()); 00222 00223 return *Result; 00224 } 00225 00226 } // End llvm namespace 00227 00228 #endif