]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h
Merge ^/head r317216 through r317280.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / Support / GenericDomTreeConstruction.h
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