Home | History | Annotate | Download | only in Support
      1 //===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 ///
     11 /// Generic dominator tree construction - This file provides routines to
     12 /// construct immediate dominator information for a flow-graph based on the
     13 /// algorithm described in this document:
     14 ///
     15 ///   A Fast Algorithm for Finding Dominators in a Flowgraph
     16 ///   T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
     17 ///
     18 /// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns
     19 /// out that the theoretically slower O(n*log(n)) implementation is actually
     20 /// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs.
     21 ///
     22 //===----------------------------------------------------------------------===//
     23 
     24 #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
     25 #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
     26 
     27 #include "llvm/ADT/DepthFirstIterator.h"
     28 #include "llvm/ADT/SmallPtrSet.h"
     29 #include "llvm/Support/GenericDomTree.h"
     30 
     31 namespace llvm {
     32 
     33 // External storage for depth first iterator that reuses the info lookup map
     34 // domtree already has.  We don't have a set, but a map instead, so we are
     35 // converting the one argument insert calls.
     36 template <class NodeRef, class InfoType> struct df_iterator_dom_storage {
     37 public:
     38   typedef DenseMap<NodeRef, InfoType> BaseSet;
     39   df_iterator_dom_storage(BaseSet &Storage) : Storage(Storage) {}
     40 
     41   typedef typename BaseSet::iterator iterator;
     42   std::pair<iterator, bool> insert(NodeRef N) {
     43     return Storage.insert({N, InfoType()});
     44   }
     45   void completed(NodeRef) {}
     46 
     47 private:
     48   BaseSet &Storage;
     49 };
     50 
     51 template <class GraphT>
     52 unsigned ReverseDFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
     53                         typename GraphT::NodeRef V, unsigned N) {
     54   df_iterator_dom_storage<
     55       typename GraphT::NodeRef,
     56       typename DominatorTreeBaseByGraphTraits<GraphT>::InfoRec>
     57       DFStorage(DT.Info);
     58   bool IsChildOfArtificialExit = (N != 0);
     59   for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage);
     60        I != E; ++I) {
     61     typename GraphT::NodeRef BB = *I;
     62     auto &BBInfo = DT.Info[BB];
     63     BBInfo.DFSNum = BBInfo.Semi = ++N;
     64     BBInfo.Label = BB;
     65     // Set the parent to the top of the visited stack.  The stack includes us,
     66     // and is 1 based, so we subtract to account for both of these.
     67     if (I.getPathLength() > 1)
     68       BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum;
     69     DT.Vertex.push_back(BB); // Vertex[n] = V;
     70 
     71     if (IsChildOfArtificialExit)
     72       BBInfo.Parent = 1;
     73 
     74     IsChildOfArtificialExit = false;
     75   }
     76   return N;
     77 }
     78 template <class GraphT>
     79 unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
     80                  typename GraphT::NodeRef V, unsigned N) {
     81   df_iterator_dom_storage<
     82       typename GraphT::NodeRef,
     83       typename DominatorTreeBaseByGraphTraits<GraphT>::InfoRec>
     84       DFStorage(DT.Info);
     85   for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage);
     86        I != E; ++I) {
     87     typename GraphT::NodeRef BB = *I;
     88     auto &BBInfo = DT.Info[BB];
     89     BBInfo.DFSNum = BBInfo.Semi = ++N;
     90     BBInfo.Label = BB;
     91     // Set the parent to the top of the visited stack.  The stack includes us,
     92     // and is 1 based, so we subtract to account for both of these.
     93     if (I.getPathLength() > 1)
     94       BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum;
     95     DT.Vertex.push_back(BB); // Vertex[n] = V;
     96   }
     97   return N;
     98 }
     99 
    100 template <class GraphT>
    101 typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT,
    102                               typename GraphT::NodeRef VIn,
    103                               unsigned LastLinked) {
    104   auto &VInInfo = DT.Info[VIn];
    105   if (VInInfo.DFSNum < LastLinked)
    106     return VIn;
    107 
    108   SmallVector<typename GraphT::NodeRef, 32> Work;
    109   SmallPtrSet<typename GraphT::NodeRef, 32> Visited;
    110 
    111   if (VInInfo.Parent >= LastLinked)
    112     Work.push_back(VIn);
    113 
    114   while (!Work.empty()) {
    115     typename GraphT::NodeRef V = Work.back();
    116     auto &VInfo = DT.Info[V];
    117     typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent];
    118 
    119     // Process Ancestor first
    120     if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
    121       Work.push_back(VAncestor);
    122       continue;
    123     }
    124     Work.pop_back();
    125 
    126     // Update VInfo based on Ancestor info
    127     if (VInfo.Parent < LastLinked)
    128       continue;
    129 
    130     auto &VAInfo = DT.Info[VAncestor];
    131     typename GraphT::NodeRef VAncestorLabel = VAInfo.Label;
    132     typename GraphT::NodeRef VLabel = VInfo.Label;
    133     if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
    134       VInfo.Label = VAncestorLabel;
    135     VInfo.Parent = VAInfo.Parent;
    136   }
    137 
    138   return VInInfo.Label;
    139 }
    140 
    141 template <class FuncT, class NodeT>
    142 void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
    143                FuncT &F) {
    144   typedef GraphTraits<NodeT> GraphT;
    145   static_assert(std::is_pointer<typename GraphT::NodeRef>::value,
    146                 "NodeRef should be pointer type");
    147   typedef typename std::remove_pointer<typename GraphT::NodeRef>::type NodeType;
    148 
    149   unsigned N = 0;
    150   bool MultipleRoots = (DT.Roots.size() > 1);
    151   if (MultipleRoots) {
    152     auto &BBInfo = DT.Info[nullptr];
    153     BBInfo.DFSNum = BBInfo.Semi = ++N;
    154     BBInfo.Label = nullptr;
    155 
    156     DT.Vertex.push_back(nullptr);       // Vertex[n] = V;
    157   }
    158 
    159   // Step #1: Number blocks in depth-first order and initialize variables used
    160   // in later stages of the algorithm.
    161   if (DT.isPostDominator()){
    162     for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
    163          i != e; ++i)
    164       N = ReverseDFSPass<GraphT>(DT, DT.Roots[i], N);
    165   } else {
    166     N = DFSPass<GraphT>(DT, DT.Roots[0], N);
    167   }
    168 
    169   // it might be that some blocks did not get a DFS number (e.g., blocks of
    170   // infinite loops). In these cases an artificial exit node is required.
    171   MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
    172 
    173   // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
    174   // bucket for each vertex. However, this is unnecessary, because each vertex
    175   // is only placed into a single bucket (that of its semidominator), and each
    176   // vertex's bucket is processed before it is added to any bucket itself.
    177   //
    178   // Instead of using a bucket per vertex, we use a single array Buckets that
    179   // has two purposes. Before the vertex V with preorder number i is processed,
    180   // Buckets[i] stores the index of the first element in V's bucket. After V's
    181   // bucket is processed, Buckets[i] stores the index of the next element in the
    182   // bucket containing V, if any.
    183   SmallVector<unsigned, 32> Buckets;
    184   Buckets.resize(N + 1);
    185   for (unsigned i = 1; i <= N; ++i)
    186     Buckets[i] = i;
    187 
    188   for (unsigned i = N; i >= 2; --i) {
    189     typename GraphT::NodeRef W = DT.Vertex[i];
    190     auto &WInfo = DT.Info[W];
    191 
    192     // Step #2: Implicitly define the immediate dominator of vertices
    193     for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
    194       typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
    195       typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1);
    196       DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
    197     }
    198 
    199     // Step #3: Calculate the semidominators of all vertices
    200 
    201     // initialize the semi dominator to point to the parent node
    202     WInfo.Semi = WInfo.Parent;
    203     for (const auto &N : inverse_children<NodeT>(W))
    204       if (DT.Info.count(N)) { // Only if this predecessor is reachable!
    205         unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
    206         if (SemiU < WInfo.Semi)
    207           WInfo.Semi = SemiU;
    208       }
    209 
    210     // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
    211     // necessarily parent(V). In this case, set idom(V) here and avoid placing
    212     // V into a bucket.
    213     if (WInfo.Semi == WInfo.Parent) {
    214       DT.IDoms[W] = DT.Vertex[WInfo.Parent];
    215     } else {
    216       Buckets[i] = Buckets[WInfo.Semi];
    217       Buckets[WInfo.Semi] = i;
    218     }
    219   }
    220 
    221   if (N >= 1) {
    222     typename GraphT::NodeRef Root = DT.Vertex[1];
    223     for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
    224       typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
    225       DT.IDoms[V] = Root;
    226     }
    227   }
    228 
    229   // Step #4: Explicitly define the immediate dominator of each vertex
    230   for (unsigned i = 2; i <= N; ++i) {
    231     typename GraphT::NodeRef W = DT.Vertex[i];
    232     typename GraphT::NodeRef &WIDom = DT.IDoms[W];
    233     if (WIDom != DT.Vertex[DT.Info[W].Semi])
    234       WIDom = DT.IDoms[WIDom];
    235   }
    236 
    237   if (DT.Roots.empty()) return;
    238 
    239   // Add a node for the root.  This node might be the actual root, if there is
    240   // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
    241   // which postdominates all real exits if there are multiple exit blocks, or
    242   // an infinite loop.
    243   typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr;
    244 
    245   DT.RootNode =
    246       (DT.DomTreeNodes[Root] =
    247            llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr))
    248           .get();
    249 
    250   // Loop over all of the reachable blocks in the function...
    251   for (unsigned i = 2; i <= N; ++i) {
    252     typename GraphT::NodeRef W = DT.Vertex[i];
    253 
    254     // Don't replace this with 'count', the insertion side effect is important
    255     if (DT.DomTreeNodes[W])
    256       continue; // Haven't calculated this node yet?
    257 
    258     typename GraphT::NodeRef ImmDom = DT.getIDom(W);
    259 
    260     assert(ImmDom || DT.DomTreeNodes[nullptr]);
    261 
    262     // Get or calculate the node for the immediate dominator
    263     DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom);
    264 
    265     // Add a new tree node for this BasicBlock, and link it as a child of
    266     // IDomNode
    267     DT.DomTreeNodes[W] = IDomNode->addChild(
    268         llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode));
    269   }
    270 
    271   // Free temporary memory used to construct idom's
    272   DT.IDoms.clear();
    273   DT.Info.clear();
    274   DT.Vertex.clear();
    275   DT.Vertex.shrink_to_fit();
    276 
    277   DT.updateDFSNumbers();
    278 }
    279 }
    280 
    281 #endif
    282