]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/Support/GenericDomTreeConstruction.h
Upgrade our copies of clang, llvm, lld, lldb, compiler-rt and libc++ to
[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/SmallPtrSet.h"
28 #include "llvm/Support/GenericDomTree.h"
29
30 namespace llvm {
31
32 template <class GraphT>
33 unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
34                  typename GraphT::NodeRef V, unsigned N) {
35   // This is more understandable as a recursive algorithm, but we can't use the
36   // recursive algorithm due to stack depth issues.  Keep it here for
37   // documentation purposes.
38 #if 0
39   InfoRec &VInfo = DT.Info[DT.Roots[i]];
40   VInfo.DFSNum = VInfo.Semi = ++N;
41   VInfo.Label = V;
42
43   Vertex.push_back(V);        // Vertex[n] = V;
44
45   for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E; ++SI) {
46     InfoRec &SuccVInfo = DT.Info[*SI];
47     if (SuccVInfo.Semi == 0) {
48       SuccVInfo.Parent = V;
49       N = DTDFSPass(DT, *SI, N);
50     }
51   }
52 #else
53   bool IsChildOfArtificialExit = (N != 0);
54
55   SmallVector<
56       std::pair<typename GraphT::NodeRef, typename GraphT::ChildIteratorType>,
57       32>
58       Worklist;
59   Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
60   while (!Worklist.empty()) {
61     typename GraphT::NodeRef BB = Worklist.back().first;
62     typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
63
64     auto &BBInfo = DT.Info[BB];
65
66     // First time we visited this BB?
67     if (NextSucc == GraphT::child_begin(BB)) {
68       BBInfo.DFSNum = BBInfo.Semi = ++N;
69       BBInfo.Label = BB;
70
71       DT.Vertex.push_back(BB);       // Vertex[n] = V;
72
73       if (IsChildOfArtificialExit)
74         BBInfo.Parent = 1;
75
76       IsChildOfArtificialExit = false;
77     }
78
79     // store the DFS number of the current BB - the reference to BBInfo might
80     // get invalidated when processing the successors.
81     unsigned BBDFSNum = BBInfo.DFSNum;
82
83     // If we are done with this block, remove it from the worklist.
84     if (NextSucc == GraphT::child_end(BB)) {
85       Worklist.pop_back();
86       continue;
87     }
88
89     // Increment the successor number for the next time we get to it.
90     ++Worklist.back().second;
91
92     // Visit the successor next, if it isn't already visited.
93     typename GraphT::NodeRef Succ = *NextSucc;
94
95     auto &SuccVInfo = DT.Info[Succ];
96     if (SuccVInfo.Semi == 0) {
97       SuccVInfo.Parent = BBDFSNum;
98       Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
99     }
100   }
101 #endif
102     return N;
103 }
104
105 template <class GraphT>
106 typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT,
107                               typename GraphT::NodeRef VIn,
108                               unsigned LastLinked) {
109   auto &VInInfo = DT.Info[VIn];
110   if (VInInfo.DFSNum < LastLinked)
111     return VIn;
112
113   SmallVector<typename GraphT::NodeRef, 32> Work;
114   SmallPtrSet<typename GraphT::NodeRef, 32> Visited;
115
116   if (VInInfo.Parent >= LastLinked)
117     Work.push_back(VIn);
118
119   while (!Work.empty()) {
120     typename GraphT::NodeRef V = Work.back();
121     auto &VInfo = DT.Info[V];
122     typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent];
123
124     // Process Ancestor first
125     if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
126       Work.push_back(VAncestor);
127       continue;
128     }
129     Work.pop_back();
130
131     // Update VInfo based on Ancestor info
132     if (VInfo.Parent < LastLinked)
133       continue;
134
135     auto &VAInfo = DT.Info[VAncestor];
136     typename GraphT::NodeRef VAncestorLabel = VAInfo.Label;
137     typename GraphT::NodeRef VLabel = VInfo.Label;
138     if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
139       VInfo.Label = VAncestorLabel;
140     VInfo.Parent = VAInfo.Parent;
141   }
142
143   return VInInfo.Label;
144 }
145
146 template <class FuncT, class NodeT>
147 void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
148                FuncT &F) {
149   typedef GraphTraits<NodeT> GraphT;
150   static_assert(std::is_pointer<typename GraphT::NodeRef>::value,
151                 "NodeRef should be pointer type");
152   typedef typename std::remove_pointer<typename GraphT::NodeRef>::type NodeType;
153
154   unsigned N = 0;
155   bool MultipleRoots = (DT.Roots.size() > 1);
156   if (MultipleRoots) {
157     auto &BBInfo = DT.Info[nullptr];
158     BBInfo.DFSNum = BBInfo.Semi = ++N;
159     BBInfo.Label = nullptr;
160
161     DT.Vertex.push_back(nullptr);       // Vertex[n] = V;
162   }
163
164   // Step #1: Number blocks in depth-first order and initialize variables used
165   // in later stages of the algorithm.
166   for (unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
167        i != e; ++i)
168     N = DFSPass<GraphT>(DT, DT.Roots[i], N);
169
170   // it might be that some blocks did not get a DFS number (e.g., blocks of
171   // infinite loops). In these cases an artificial exit node is required.
172   MultipleRoots |= (DT.isPostDominator() && N != GraphTraits<FuncT*>::size(&F));
173
174   // When naively implemented, the Lengauer-Tarjan algorithm requires a separate
175   // bucket for each vertex. However, this is unnecessary, because each vertex
176   // is only placed into a single bucket (that of its semidominator), and each
177   // vertex's bucket is processed before it is added to any bucket itself.
178   //
179   // Instead of using a bucket per vertex, we use a single array Buckets that
180   // has two purposes. Before the vertex V with preorder number i is processed,
181   // Buckets[i] stores the index of the first element in V's bucket. After V's
182   // bucket is processed, Buckets[i] stores the index of the next element in the
183   // bucket containing V, if any.
184   SmallVector<unsigned, 32> Buckets;
185   Buckets.resize(N + 1);
186   for (unsigned i = 1; i <= N; ++i)
187     Buckets[i] = i;
188
189   for (unsigned i = N; i >= 2; --i) {
190     typename GraphT::NodeRef W = DT.Vertex[i];
191     auto &WInfo = DT.Info[W];
192
193     // Step #2: Implicitly define the immediate dominator of vertices
194     for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
195       typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
196       typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1);
197       DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
198     }
199
200     // Step #3: Calculate the semidominators of all vertices
201
202     // initialize the semi dominator to point to the parent node
203     WInfo.Semi = WInfo.Parent;
204     typedef GraphTraits<Inverse<NodeT> > InvTraits;
205     for (typename InvTraits::ChildIteratorType CI =
206          InvTraits::child_begin(W),
207          E = InvTraits::child_end(W); CI != E; ++CI) {
208       typename InvTraits::NodeRef N = *CI;
209       if (DT.Info.count(N)) {  // Only if this predecessor is reachable!
210         unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
211         if (SemiU < WInfo.Semi)
212           WInfo.Semi = SemiU;
213       }
214     }
215
216     // If V is a non-root vertex and sdom(V) = parent(V), then idom(V) is
217     // necessarily parent(V). In this case, set idom(V) here and avoid placing
218     // V into a bucket.
219     if (WInfo.Semi == WInfo.Parent) {
220       DT.IDoms[W] = DT.Vertex[WInfo.Parent];
221     } else {
222       Buckets[i] = Buckets[WInfo.Semi];
223       Buckets[WInfo.Semi] = i;
224     }
225   }
226
227   if (N >= 1) {
228     typename GraphT::NodeRef Root = DT.Vertex[1];
229     for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
230       typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
231       DT.IDoms[V] = Root;
232     }
233   }
234
235   // Step #4: Explicitly define the immediate dominator of each vertex
236   for (unsigned i = 2; i <= N; ++i) {
237     typename GraphT::NodeRef W = DT.Vertex[i];
238     typename GraphT::NodeRef &WIDom = DT.IDoms[W];
239     if (WIDom != DT.Vertex[DT.Info[W].Semi])
240       WIDom = DT.IDoms[WIDom];
241   }
242
243   if (DT.Roots.empty()) return;
244
245   // Add a node for the root.  This node might be the actual root, if there is
246   // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
247   // which postdominates all real exits if there are multiple exit blocks, or
248   // an infinite loop.
249   typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr;
250
251   DT.RootNode =
252       (DT.DomTreeNodes[Root] =
253            llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr))
254           .get();
255
256   // Loop over all of the reachable blocks in the function...
257   for (unsigned i = 2; i <= N; ++i) {
258     typename GraphT::NodeRef W = DT.Vertex[i];
259
260     // Don't replace this with 'count', the insertion side effect is important
261     if (DT.DomTreeNodes[W])
262       continue; // Haven't calculated this node yet?
263
264     typename GraphT::NodeRef ImmDom = DT.getIDom(W);
265
266     assert(ImmDom || DT.DomTreeNodes[nullptr]);
267
268     // Get or calculate the node for the immediate dominator
269     DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom);
270
271     // Add a new tree node for this BasicBlock, and link it as a child of
272     // IDomNode
273     DT.DomTreeNodes[W] = IDomNode->addChild(
274         llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode));
275   }
276
277   // Free temporary memory used to construct idom's
278   DT.IDoms.clear();
279   DT.Info.clear();
280   DT.Vertex.clear();
281   DT.Vertex.shrink_to_fit();
282
283   DT.updateDFSNumbers();
284 }
285 }
286
287 #endif