24 #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
25 #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
32 template <
class GraphT>
34 typename GraphT::NodeRef V,
unsigned N) {
39 InfoRec &VInfo = DT.Info[DT.Roots[
i]];
40 VInfo.DFSNum = VInfo.Semi = ++
N;
46 InfoRec &SuccVInfo = DT.Info[*
SI];
47 if (SuccVInfo.Semi == 0) {
49 N = DTDFSPass(DT, *
SI, N);
53 bool IsChildOfArtificialExit = (N != 0);
56 std::pair<typename GraphT::NodeRef, typename GraphT::ChildIteratorType>,
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;
64 auto &BBInfo = DT.Info[BB];
67 if (NextSucc == GraphT::child_begin(BB)) {
68 BBInfo.DFSNum = BBInfo.Semi = ++
N;
71 DT.Vertex.push_back(BB);
73 if (IsChildOfArtificialExit)
76 IsChildOfArtificialExit =
false;
81 unsigned BBDFSNum = BBInfo.DFSNum;
84 if (NextSucc == GraphT::child_end(BB)) {
90 ++Worklist.
back().second;
93 typename GraphT::NodeRef Succ = *NextSucc;
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)));
105 template <
class GraphT>
107 typename GraphT::NodeRef VIn,
108 unsigned LastLinked) {
109 auto &VInInfo = DT.Info[VIn];
110 if (VInInfo.DFSNum < LastLinked)
116 if (VInInfo.Parent >= LastLinked)
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];
125 if (Visited.
insert(VAncestor).second && VInfo.Parent >= LastLinked) {
132 if (VInfo.Parent < LastLinked)
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;
143 return VInInfo.Label;
146 template <
class FuncT,
class NodeT>
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;
155 bool MultipleRoots = (DT.Roots.size() > 1);
157 auto &BBInfo = DT.Info[
nullptr];
158 BBInfo.DFSNum = BBInfo.Semi = ++
N;
159 BBInfo.Label =
nullptr;
161 DT.Vertex.push_back(
nullptr);
166 for (
unsigned i = 0, e = static_cast<unsigned>(DT.Roots.size());
168 N = DFSPass<GraphT>(DT, DT.Roots[
i], N);
186 for (
unsigned i = 1;
i <=
N; ++
i)
189 for (
unsigned i = N;
i >= 2; --
i) {
190 typename GraphT::NodeRef W = DT.Vertex[
i];
191 auto &WInfo = DT.Info[W];
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;
203 WInfo.Semi = WInfo.Parent;
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)) {
210 unsigned SemiU = DT.Info[Eval<GraphT>(DT,
N,
i + 1)].Semi;
211 if (SemiU < WInfo.Semi)
219 if (WInfo.Semi == WInfo.Parent) {
220 DT.IDoms[W] = DT.Vertex[WInfo.Parent];
222 Buckets[
i] = Buckets[WInfo.Semi];
223 Buckets[WInfo.Semi] =
i;
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]];
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];
243 if (DT.Roots.empty())
return;
249 typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] :
nullptr;
252 (DT.DomTreeNodes[Root] =
253 llvm::make_unique<DomTreeNodeBase<NodeType>>(Root,
nullptr))
257 for (
unsigned i = 2;
i <=
N; ++
i) {
258 typename GraphT::NodeRef W = DT.Vertex[
i];
261 if (DT.DomTreeNodes[W])
264 typename GraphT::NodeRef ImmDom = DT.getIDom(W);
266 assert(ImmDom || DT.DomTreeNodes[
nullptr]);
273 DT.DomTreeNodes[W] = IDomNode->
addChild(
281 DT.Vertex.shrink_to_fit();
283 DT.updateDFSNumbers();
void push_back(const T &Elt)
std::unique_ptr< DomTreeNodeBase< NodeT > > addChild(std::unique_ptr< DomTreeNodeBase< NodeT >> C)
void Calculate(DominatorTreeBaseByGraphTraits< GraphTraits< N >> &DT, FuncT &F)
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
LLVM_NODISCARD bool empty() const
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits< GraphT > &DT, typename GraphT::NodeRef VIn, unsigned LastLinked)
Base class for the actual dominator tree node.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Interval::succ_iterator succ_end(Interval *I)
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&...args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
unsigned DFSPass(DominatorTreeBaseByGraphTraits< GraphT > &DT, typename GraphT::NodeRef V, unsigned N)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
typename detail::DominatorTreeBaseTraits< GT >::type DominatorTreeBaseByGraphTraits
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines a set of templates that efficiently compute a dominator tree over a generic graph...