LLVM API Documentation

GenericDomTreeConstruction.h
Go to the documentation of this file.
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