LLVM API Documentation
00001 //===- GenericDomTreeConstruction.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 /// \file 00010 /// 00011 /// Generic dominator tree construction - This file provides routines to 00012 /// construct immediate dominator information for a flow-graph based on the 00013 /// algorithm described in this document: 00014 /// 00015 /// A Fast Algorithm for Finding Dominators in a Flowgraph 00016 /// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141. 00017 /// 00018 /// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns 00019 /// out that the theoretically slower O(n*log(n)) implementation is actually 00020 /// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs. 00021 /// 00022 //===----------------------------------------------------------------------===// 00023 00024 00025 #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H 00026 #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H 00027 00028 #include "llvm/ADT/SmallPtrSet.h" 00029 #include "llvm/Support/GenericDomTree.h" 00030 00031 namespace llvm { 00032 00033 template<class GraphT> 00034 unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT, 00035 typename GraphT::NodeType* V, unsigned N) { 00036 // This is more understandable as a recursive algorithm, but we can't use the 00037 // recursive algorithm due to stack depth issues. Keep it here for 00038 // documentation purposes. 00039 #if 0 00040 InfoRec &VInfo = DT.Info[DT.Roots[i]]; 00041 VInfo.DFSNum = VInfo.Semi = ++N; 00042 VInfo.Label = V; 00043 00044 Vertex.push_back(V); // Vertex[n] = V; 00045 00046 for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) { 00047 InfoRec &SuccVInfo = DT.Info[*SI]; 00048 if (SuccVInfo.Semi == 0) { 00049 SuccVInfo.Parent = V; 00050 N = DTDFSPass(DT, *SI, N); 00051 } 00052 } 00053 #else 00054 bool IsChildOfArtificialExit = (N != 0); 00055 00056 SmallVector<std::pair<typename GraphT::NodeType*, 00057 typename GraphT::ChildIteratorType>, 32> Worklist; 00058 Worklist.push_back(std::make_pair(V, GraphT::child_begin(V))); 00059 while (!Worklist.empty()) { 00060 typename GraphT::NodeType* BB = Worklist.back().first; 00061 typename GraphT::ChildIteratorType NextSucc = Worklist.back().second; 00062 00063 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = 00064 DT.Info[BB]; 00065 00066 // First time we visited this BB? 00067 if (NextSucc == GraphT::child_begin(BB)) { 00068 BBInfo.DFSNum = BBInfo.Semi = ++N; 00069 BBInfo.Label = BB; 00070 00071 DT.Vertex.push_back(BB); // Vertex[n] = V; 00072 00073 if (IsChildOfArtificialExit) 00074 BBInfo.Parent = 1; 00075 00076 IsChildOfArtificialExit = false; 00077 } 00078 00079 // store the DFS number of the current BB - the reference to BBInfo might 00080 // get invalidated when processing the successors. 00081 unsigned BBDFSNum = BBInfo.DFSNum; 00082 00083 // If we are done with this block, remove it from the worklist. 00084 if (NextSucc == GraphT::child_end(BB)) { 00085 Worklist.pop_back(); 00086 continue; 00087 } 00088 00089 // Increment the successor number for the next time we get to it. 00090 ++Worklist.back().second; 00091 00092 // Visit the successor next, if it isn't already visited. 00093 typename GraphT::NodeType* Succ = *NextSucc; 00094 00095 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo = 00096 DT.Info[Succ]; 00097 if (SuccVInfo.Semi == 0) { 00098 SuccVInfo.Parent = BBDFSNum; 00099 Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ))); 00100 } 00101 } 00102 #endif 00103 return N; 00104 } 00105 00106 template<class GraphT> 00107 typename GraphT::NodeType* 00108 Eval(DominatorTreeBase<typename GraphT::NodeType>& DT, 00109 typename GraphT::NodeType *VIn, unsigned LastLinked) { 00110 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo = 00111 DT.Info[VIn]; 00112 if (VInInfo.DFSNum < LastLinked) 00113 return VIn; 00114 00115 SmallVector<typename GraphT::NodeType*, 32> Work; 00116 SmallPtrSet<typename GraphT::NodeType*, 32> Visited; 00117 00118 if (VInInfo.Parent >= LastLinked) 00119 Work.push_back(VIn); 00120 00121 while (!Work.empty()) { 00122 typename GraphT::NodeType* V = Work.back(); 00123 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo = 00124 DT.Info[V]; 00125 typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent]; 00126 00127 // Process Ancestor first 00128 if (Visited.insert(VAncestor) && VInfo.Parent >= LastLinked) { 00129 Work.push_back(VAncestor); 00130 continue; 00131 } 00132 Work.pop_back(); 00133 00134 // Update VInfo based on Ancestor info 00135 if (VInfo.Parent < LastLinked) 00136 continue; 00137 00138 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo = 00139 DT.Info[VAncestor]; 00140 typename GraphT::NodeType* VAncestorLabel = VAInfo.Label; 00141 typename GraphT::NodeType* VLabel = VInfo.Label; 00142 if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi) 00143 VInfo.Label = VAncestorLabel; 00144 VInfo.Parent = VAInfo.Parent; 00145 } 00146 00147 return VInInfo.Label; 00148 } 00149 00150 template<class FuncT, class NodeT> 00151 void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT, 00152 FuncT& F) { 00153 typedef GraphTraits<NodeT> GraphT; 00154 00155 unsigned N = 0; 00156 bool MultipleRoots = (DT.Roots.size() > 1); 00157 if (MultipleRoots) { 00158 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo = 00159 DT.Info[nullptr]; 00160 BBInfo.DFSNum = BBInfo.Semi = ++N; 00161 BBInfo.Label = nullptr; 00162 00163 DT.Vertex.push_back(nullptr); // Vertex[n] = V; 00164 } 00165 00166 // Step #1: Number blocks in depth-first order and initialize variables used 00167 // in later stages of the algorithm. 00168 for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size()); 00169 i != e; ++i) 00170 N = DFSPass<GraphT>(DT, DT.Roots[i], N); 00171 00172 // it might be that some blocks did not get a DFS number (e.g., blocks of 00173 // infinite loops). In these cases an artificial exit node is required. 00174 MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F)); 00175 00176 // When naively implemented, the Lengauer-Tarjan algorithm requires a separate 00177 // bucket for each vertex. However, this is unnecessary, because each vertex 00178 // is only placed into a single bucket (that of its semidominator), and each 00179 // vertex's bucket is processed before it is added to any bucket itself. 00180 // 00181 // Instead of using a bucket per vertex, we use a single array Buckets that 00182 // has two purposes. Before the vertex V with preorder number i is processed, 00183 // Buckets[i] stores the index of the first element in V's bucket. After V's 00184 // bucket is processed, Buckets[i] stores the index of the next element in the 00185 // bucket containing V, if any. 00186 SmallVector<unsigned, 32> Buckets; 00187 Buckets.resize(N + 1); 00188 for (unsigned i = 1; i <= N; ++i) 00189 Buckets[i] = i; 00190 00191 for (unsigned i = N; i >= 2; --i) { 00192 typename GraphT::NodeType* W = DT.Vertex[i]; 00193 typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo = 00194 DT.Info[W]; 00195 00196 // Step #2: Implicitly define the immediate dominator of vertices 00197 for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) { 00198 typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; 00199 typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1); 00200 DT.IDoms[V] = DT.Info[U].Semi < i ? U : W; 00201 } 00202 00203 // Step #3: Calculate the semidominators of all vertices 00204 00205 // initialize the semi dominator to point to the parent node 00206 WInfo.Semi = WInfo.Parent; 00207 typedef GraphTraits<Inverse<NodeT> > InvTraits; 00208 for (typename InvTraits::ChildIteratorType CI = 00209 InvTraits::child_begin(W), 00210 E = InvTraits::child_end(W); CI != E; ++CI) { 00211 typename InvTraits::NodeType *N = *CI; 00212 if (DT.Info.count(N)) { // Only if this predecessor is reachable! 00213 unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi; 00214 if (SemiU < WInfo.Semi) 00215 WInfo.Semi = SemiU; 00216 } 00217 } 00218 00219 // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is 00220 // necessarily parent(V). In this case, set idom(V) here and avoid placing 00221 // V into a bucket. 00222 if (WInfo.Semi == WInfo.Parent) { 00223 DT.IDoms[W] = DT.Vertex[WInfo.Parent]; 00224 } else { 00225 Buckets[i] = Buckets[WInfo.Semi]; 00226 Buckets[WInfo.Semi] = i; 00227 } 00228 } 00229 00230 if (N >= 1) { 00231 typename GraphT::NodeType* Root = DT.Vertex[1]; 00232 for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) { 00233 typename GraphT::NodeType* V = DT.Vertex[Buckets[j]]; 00234 DT.IDoms[V] = Root; 00235 } 00236 } 00237 00238 // Step #4: Explicitly define the immediate dominator of each vertex 00239 for (unsigned i = 2; i <= N; ++i) { 00240 typename GraphT::NodeType* W = DT.Vertex[i]; 00241 typename GraphT::NodeType*& WIDom = DT.IDoms[W]; 00242 if (WIDom != DT.Vertex[DT.Info[W].Semi]) 00243 WIDom = DT.IDoms[WIDom]; 00244 } 00245 00246 if (DT.Roots.empty()) return; 00247 00248 // Add a node for the root. This node might be the actual root, if there is 00249 // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0) 00250 // which postdominates all real exits if there are multiple exit blocks, or 00251 // an infinite loop. 00252 typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr; 00253 00254 DT.DomTreeNodes[Root] = DT.RootNode = 00255 new DomTreeNodeBase<typename GraphT::NodeType>(Root, nullptr); 00256 00257 // Loop over all of the reachable blocks in the function... 00258 for (unsigned i = 2; i <= N; ++i) { 00259 typename GraphT::NodeType* W = DT.Vertex[i]; 00260 00261 DomTreeNodeBase<typename GraphT::NodeType> *BBNode = DT.DomTreeNodes[W]; 00262 if (BBNode) continue; // Haven't calculated this node yet? 00263 00264 typename GraphT::NodeType* ImmDom = DT.getIDom(W); 00265 00266 assert(ImmDom || DT.DomTreeNodes[nullptr]); 00267 00268 // Get or calculate the node for the immediate dominator 00269 DomTreeNodeBase<typename GraphT::NodeType> *IDomNode = 00270 DT.getNodeForBlock(ImmDom); 00271 00272 // Add a new tree node for this BasicBlock, and link it as a child of 00273 // IDomNode 00274 DomTreeNodeBase<typename GraphT::NodeType> *C = 00275 new DomTreeNodeBase<typename GraphT::NodeType>(W, IDomNode); 00276 DT.DomTreeNodes[W] = IDomNode->addChild(C); 00277 } 00278 00279 // Free temporary memory used to construct idom's 00280 DT.IDoms.clear(); 00281 DT.Info.clear(); 00282 std::vector<typename GraphT::NodeType*>().swap(DT.Vertex); 00283 00284 DT.updateDFSNumbers(); 00285 } 00286 00287 } 00288 00289 #endif