LLVM API Documentation
00001 //=== llvm/Analysis/DominatorInternals.h - Dominator Calculation -*- 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 #ifndef LLVM_ANALYSIS_DOMINATOR_INTERNALS_H 00011 #define LLVM_ANALYSIS_DOMINATOR_INTERNALS_H 00012 00013 #include "llvm/Analysis/Dominators.h" 00014 #include "llvm/ADT/SmallPtrSet.h" 00015 00016 //===----------------------------------------------------------------------===// 00017 // 00018 // DominatorTree construction - This pass constructs immediate dominator 00019 // information for a flow-graph based on the algorithm described in this 00020 // document: 00021 // 00022 // A Fast Algorithm for Finding Dominators in a Flowgraph 00023 // T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. 00024 // 00025 // This implements both the O(n*ack(n)) and the O(n*log(n)) versions of EVAL and 00026 // LINK, but it turns out that the theoretically slower O(n*log(n)) 00027 // implementation is actually faster than the "efficient" algorithm (even for 00028 // large CFGs) because the constant overheads are substantially smaller. The 00029 // lower-complexity version can be enabled with the following #define: 00030 // 00031 #define BALANCE_IDOM_TREE 0 00032 // 00033 //===----------------------------------------------------------------------===// 00034 00035 namespace llvm { 00036 00037 template<class GraphT> 00038 unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, 00039 typename GraphT::NodeType* V, unsigned N) { 00040 // This is more understandable as a recursive algorithm, but we can't use the 00041 // recursive algorithm due to stack depth issues. Keep it here for 00042 // documentation purposes. 00043 #if 0 00044 InfoRec &VInfo = DT.Info[DT.Roots[i]]; 00045 VInfo.DFSNum = VInfo.Semi = ++N; 00046 VInfo.Label = V; 00047 00048 Vertex.push_back(V); // Vertex[n] = V; 00049 //Info[V].Ancestor = 0; // Ancestor[n] = 0 00050 //Info[V].Child = 0; // Child[v] = 0 00051 VInfo.Size = 1; // Size[v] = 1 00052 00053 for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) { 00054 InfoRec &SuccVInfo = DT.Info[*SI]; 00055 if (SuccVInfo.Semi == 0) { 00056 SuccVInfo.Parent = V; 00057 N = DTDFSPass(DT, *SI, N); 00058 } 00059 } 00060 #else 00061 bool IsChilOfArtificialExit = (N != 0); 00062 00063 std::vector<std::pair<typename GraphT::NodeType*, 00064 typename GraphT::ChildIteratorType> > Worklist; 00065 Worklist.push_back(std::make_pair(V, GraphT::child_begin(V))); 00066 while (!Worklist.empty()) { 00067 typename GraphT::NodeType* BB = Worklist.back().first; 00068 typename GraphT::ChildIteratorType NextSucc = Worklist.back().second; 00069 00070 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = 00071 DT.Info[BB]; 00072 00073 // First time we visited this BB? 00074 if (NextSucc == GraphT::child_begin(BB)) { 00075 BBInfo.DFSNum = BBInfo.Semi = ++N; 00076 BBInfo.Label = BB; 00077 00078 DT.Vertex.push_back(BB); // Vertex[n] = V; 00079 //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0 00080 //BBInfo[V].Child = 0; // Child[v] = 0 00081 BBInfo.Size = 1; // Size[v] = 1 00082 00083 if (IsChilOfArtificialExit) 00084 BBInfo.Parent = 1; 00085 00086 IsChilOfArtificialExit = false; 00087 } 00088 00089 // store the DFS number of the current BB - the reference to BBInfo might 00090 // get invalidated when processing the successors. 00091 unsigned BBDFSNum = BBInfo.DFSNum; 00092 00093 // If we are done with this block, remove it from the worklist. 00094 if (NextSucc == GraphT::child_end(BB)) { 00095 Worklist.pop_back(); 00096 continue; 00097 } 00098 00099 // Increment the successor number for the next time we get to it. 00100 ++Worklist.back().second; 00101 00102 // Visit the successor next, if it isn't already visited. 00103 typename GraphT::NodeType* Succ = *NextSucc; 00104 00105 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo = 00106 DT.Info[Succ]; 00107 if (SuccVInfo.Semi == 0) { 00108 SuccVInfo.Parent = BBDFSNum; 00109 Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ))); 00110 } 00111 } 00112 #endif 00113 return N; 00114 } 00115 00116 template<class GraphT> 00117 void Compress(DominatorTreeBase<typename GraphT::NodeType>& DT, 00118 typename GraphT::NodeType *VIn) { 00119 std::vector<typename GraphT::NodeType*> Work; 00120 SmallPtrSet<typename GraphT::NodeType*, 32> Visited; 00121 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInVAInfo = 00122 DT.Info[DT.Vertex[DT.Info[VIn].Ancestor]]; 00123 00124 if (VInVAInfo.Ancestor != 0) 00125 Work.push_back(VIn); 00126 00127 while (!Work.empty()) { 00128 typename GraphT::NodeType* V = Work.back(); 00129 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo = 00130 DT.Info[V]; 00131 typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Ancestor]; 00132 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo = 00133 DT.Info[VAncestor]; 00134 00135 // Process Ancestor first 00136 if (Visited.insert(VAncestor) && 00137 VAInfo.Ancestor != 0) { 00138 Work.push_back(VAncestor); 00139 continue; 00140 } 00141 Work.pop_back(); 00142 00143 // Update VInfo based on Ancestor info 00144 if (VAInfo.Ancestor == 0) 00145 continue; 00146 typename GraphT::NodeType* VAncestorLabel = VAInfo.Label; 00147 typename GraphT::NodeType* VLabel = VInfo.Label; 00148 if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) 00149 VInfo.Label = VAncestorLabel; 00150 VInfo.Ancestor = VAInfo.Ancestor; 00151 } 00152 } 00153 00154 template<class GraphT> 00155 typename GraphT::NodeType* Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, 00156 typename GraphT::NodeType *V) { 00157 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo = 00158 DT.Info[V]; 00159 #if !BALANCE_IDOM_TREE 00160 // Higher-complexity but faster implementation 00161 if (VInfo.Ancestor == 0) 00162 return V; 00163 Compress<GraphT>(DT, V); 00164 return VInfo.Label; 00165 #else 00166 // Lower-complexity but slower implementation 00167 if (VInfo.Ancestor == 0) 00168 return VInfo.Label; 00169 Compress<GraphT>(DT, V); 00170 GraphT::NodeType* VLabel = VInfo.Label; 00171 00172 GraphT::NodeType* VAncestorLabel = DT.Info[VInfo.Ancestor].Label; 00173 if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi) 00174 return VLabel; 00175 else 00176 return VAncestorLabel; 00177 #endif 00178 } 00179 00180 template<class GraphT> 00181 void Link(DominatorTreeBase<typename GraphT::NodeType>& DT, 00182 unsigned DFSNumV, typename GraphT::NodeType* W, 00183 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo) { 00184 #if !BALANCE_IDOM_TREE 00185 // Higher-complexity but faster implementation 00186 WInfo.Ancestor = DFSNumV; 00187 #else 00188 // Lower-complexity but slower implementation 00189 GraphT::NodeType* WLabel = WInfo.Label; 00190 unsigned WLabelSemi = DT.Info[WLabel].Semi; 00191 GraphT::NodeType* S = W; 00192 InfoRec *SInfo = &DT.Info[S]; 00193 00194 GraphT::NodeType* SChild = SInfo->Child; 00195 InfoRec *SChildInfo = &DT.Info[SChild]; 00196 00197 while (WLabelSemi < DT.Info[SChildInfo->Label].Semi) { 00198 GraphT::NodeType* SChildChild = SChildInfo->Child; 00199 if (SInfo->Size+DT.Info[SChildChild].Size >= 2*SChildInfo->Size) { 00200 SChildInfo->Ancestor = S; 00201 SInfo->Child = SChild = SChildChild; 00202 SChildInfo = &DT.Info[SChild]; 00203 } else { 00204 SChildInfo->Size = SInfo->Size; 00205 S = SInfo->Ancestor = SChild; 00206 SInfo = SChildInfo; 00207 SChild = SChildChild; 00208 SChildInfo = &DT.Info[SChild]; 00209 } 00210 } 00211 00212 DominatorTreeBase::InfoRec &VInfo = DT.Info[V]; 00213 SInfo->Label = WLabel; 00214 00215 assert(V != W && "The optimization here will not work in this case!"); 00216 unsigned WSize = WInfo.Size; 00217 unsigned VSize = (VInfo.Size += WSize); 00218 00219 if (VSize < 2*WSize) 00220 std::swap(S, VInfo.Child); 00221 00222 while (S) { 00223 SInfo = &DT.Info[S]; 00224 SInfo->Ancestor = V; 00225 S = SInfo->Child; 00226 } 00227 #endif 00228 } 00229 00230 template<class FuncT, class NodeT> 00231 void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, 00232 FuncT& F) { 00233 typedef GraphTraits<NodeT> GraphT; 00234 00235 unsigned N = 0; 00236 bool MultipleRoots = (DT.Roots.size() > 1); 00237 if (MultipleRoots) { 00238 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = 00239 DT.Info[NULL]; 00240 BBInfo.DFSNum = BBInfo.Semi = ++N; 00241 BBInfo.Label = NULL; 00242 00243 DT.Vertex.push_back(NULL); // Vertex[n] = V; 00244 //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0 00245 //BBInfo[V].Child = 0; // Child[v] = 0 00246 BBInfo.Size = 1; // Size[v] = 1 00247 } 00248 00249 // Step #1: Number blocks in depth-first order and initialize variables used 00250 // in later stages of the algorithm. 00251 for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size()); 00252 i != e; ++i) 00253 N = DFSPass<GraphT>(DT, DT.Roots[i], N); 00254 00255 // it might be that some blocks did not get a DFS number (e.g., blocks of 00256 // infinite loops). In these cases an artificial exit node is required. 00257 MultipleRoots |= (DT.isPostDominator() && N != F.size()); 00258 00259 for (unsigned i = N; i >= 2; --i) { 00260 typename GraphT::NodeType* W = DT.Vertex[i]; 00261 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo = 00262 DT.Info[W]; 00263 00264 // Step #2: Calculate the semidominators of all vertices 00265 bool HasChildOutsideDFS = false; 00266 00267 // initialize the semi dominator to point to the parent node 00268 WInfo.Semi = WInfo.Parent; 00269 for (typename GraphTraits<Inverse<NodeT> >::ChildIteratorType CI = 00270 GraphTraits<Inverse<NodeT> >::child_begin(W), 00271 E = GraphTraits<Inverse<NodeT> >::child_end(W); CI != E; ++CI) { 00272 if (DT.Info.count(*CI)) { // Only if this predecessor is reachable! 00273 unsigned SemiU = DT.Info[Eval<GraphT>(DT, *CI)].Semi; 00274 if (SemiU < WInfo.Semi) 00275 WInfo.Semi = SemiU; 00276 } 00277 else { 00278 // if the child has no DFS number it is not post-dominated by any exit, 00279 // and so is the current block. 00280 HasChildOutsideDFS = true; 00281 } 00282 } 00283 00284 // if some child has no DFS number it is not post-dominated by any exit, 00285 // and so is the current block. 00286 if (DT.isPostDominator() && HasChildOutsideDFS) 00287 WInfo.Semi = 0; 00288 00289 DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W); 00290 00291 typename GraphT::NodeType* WParent = DT.Vertex[WInfo.Parent]; 00292 Link<GraphT>(DT, WInfo.Parent, W, WInfo); 00293 00294 // Step #3: Implicitly define the immediate dominator of vertices 00295 std::vector<typename GraphT::NodeType*> &WParentBucket = 00296 DT.Info[WParent].Bucket; 00297 while (!WParentBucket.empty()) { 00298 typename GraphT::NodeType* V = WParentBucket.back(); 00299 WParentBucket.pop_back(); 00300 typename GraphT::NodeType* U = Eval<GraphT>(DT, V); 00301 DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent; 00302 } 00303 } 00304 00305 // Step #4: Explicitly define the immediate dominator of each vertex 00306 for (unsigned i = 2; i <= N; ++i) { 00307 typename GraphT::NodeType* W = DT.Vertex[i]; 00308 typename GraphT::NodeType*& WIDom = DT.IDoms[W]; 00309 if (WIDom != DT.Vertex[DT.Info[W].Semi]) 00310 WIDom = DT.IDoms[WIDom]; 00311 } 00312 00313 if (DT.Roots.empty()) return; 00314 00315 // Add a node for the root. This node might be the actual root, if there is 00316 // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) 00317 // which postdominates all real exits if there are multiple exit blocks, or 00318 // an infinite loop. 00319 typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0; 00320 00321 DT.DomTreeNodes[Root] = DT.RootNode = 00322 new DomTreeNodeBase<typename GraphT::NodeType>(Root, 0); 00323 00324 // Loop over all of the reachable blocks in the function... 00325 for (unsigned i = 2; i <= N; ++i) { 00326 typename GraphT::NodeType* W = DT.Vertex[i]; 00327 00328 DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W]; 00329 if (BBNode) continue; // Haven't calculated this node yet? 00330 00331 typename GraphT::NodeType* ImmDom = DT.getIDom(W); 00332 00333 assert(ImmDom || DT.DomTreeNodes[NULL]); 00334 00335 // Get or calculate the node for the immediate dominator 00336 DomTreeNodeBase<typename GraphT::NodeType> *IDomNode = 00337 DT.getNodeForBlock(ImmDom); 00338 00339 // Add a new tree node for this BasicBlock, and link it as a child of 00340 // IDomNode 00341 DomTreeNodeBase<typename GraphT::NodeType> *C = 00342 new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode); 00343 DT.DomTreeNodes[W] = IDomNode->addChild(C); 00344 } 00345 00346 // Free temporary memory used to construct idom's 00347 DT.IDoms.clear(); 00348 DT.Info.clear(); 00349 std::vector<typename GraphT::NodeType*>().swap(DT.Vertex); 00350 00351 // FIXME: This does not work on PostDomTrees. It seems likely that this is 00352 // due to an error in the algorithm for post-dominators. This really should 00353 // be investigated and fixed at some point. 00354 // DT.updateDFSNumbers(); 00355 00356 // Start out with the DFS numbers being invalid. Let them be computed if 00357 // demanded. 00358 DT.DFSInfoValid = false; 00359 } 00360 00361 } 00362 00363 #endif