Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit 1dca602

Browse files
committed
[GenericDomTree] Change GenericDomTree to use NodeRef in GraphTraits. NFC.
Summary: Looking at the implementation, GenericDomTree has more specific requirements on NodeRef, e.g. NodeRefObject->getParent() should compile, and NodeRef should be a pointer. We can remove the pointer requirement, but it seems to have little gain, given the limited use cases. Also changed GraphTraits<Inverse<Inverse<T>> to be more accurate. Reviewers: dblaikie, chandlerc Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23593 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278961 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6eaa7d5 commit 1dca602

File tree

5 files changed

+91
-87
lines changed

5 files changed

+91
-87
lines changed

include/llvm/ADT/GraphTraits.h

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,23 +88,7 @@ struct Inverse {
8888

8989
// Provide a partial specialization of GraphTraits so that the inverse of an
9090
// inverse falls back to the original graph.
91-
template<class T>
92-
struct GraphTraits<Inverse<Inverse<T> > > {
93-
typedef typename GraphTraits<T>::NodeType NodeType;
94-
typedef typename GraphTraits<T>::ChildIteratorType ChildIteratorType;
95-
96-
static NodeType *getEntryNode(Inverse<Inverse<T> > *G) {
97-
return GraphTraits<T>::getEntryNode(G->Graph.Graph);
98-
}
99-
100-
static ChildIteratorType child_begin(NodeType* N) {
101-
return GraphTraits<T>::child_begin(N);
102-
}
103-
104-
static ChildIteratorType child_end(NodeType* N) {
105-
return GraphTraits<T>::child_end(N);
106-
}
107-
};
91+
template <class T> struct GraphTraits<Inverse<Inverse<T>>> : GraphTraits<T> {};
10892

10993
} // End llvm namespace
11094

include/llvm/IR/Dominators.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ extern template class DomTreeNodeBase<BasicBlock>;
3333
extern template class DominatorTreeBase<BasicBlock>;
3434

3535
extern template void Calculate<Function, BasicBlock *>(
36-
DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
36+
DominatorTreeBaseByGraphTraits<GraphTraits<BasicBlock *>> &DT, Function &F);
3737
extern template void Calculate<Function, Inverse<BasicBlock *>>(
38-
DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
38+
DominatorTreeBaseByGraphTraits<GraphTraits<Inverse<BasicBlock *>>> &DT,
3939
Function &F);
4040

4141
typedef DomTreeNodeBase<BasicBlock> DomTreeNode;

include/llvm/Support/GenericDomTree.h

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
/// dominance queries on the CFG, but is fully generic w.r.t. the underlying
1414
/// graph types.
1515
///
16+
/// Unlike ADT/* graph algorithms, generic dominator tree has more reuiqrement
17+
/// on the graph's NodeRef. The NodeRef should be a pointer and, depending on
18+
/// the implementation, e.g. NodeRef->getParent() return the parent node.
19+
///
20+
/// FIXME: Maybe GenericDomTree needs a TreeTraits, instead of GraphTraits.
21+
///
1622
//===----------------------------------------------------------------------===//
1723

1824
#ifndef LLVM_SUPPORT_GENERICDOMTREE_H
@@ -30,6 +36,23 @@
3036

3137
namespace llvm {
3238

39+
template <class NodeT> class DominatorTreeBase;
40+
41+
namespace detail {
42+
43+
template <typename GT> struct DominatorTreeBaseTraits {
44+
static_assert(std::is_pointer<typename GT::NodeRef>::value,
45+
"Currently NodeRef must be a pointer type.");
46+
using type = DominatorTreeBase<
47+
typename std::remove_pointer<typename GT::NodeRef>::type>;
48+
};
49+
50+
} // End namespace detail
51+
52+
template <typename GT>
53+
using DominatorTreeBaseByGraphTraits =
54+
typename detail::DominatorTreeBaseTraits<GT>::type;
55+
3356
/// \brief Base class that other, more interesting dominator analyses
3457
/// inherit from.
3558
template <class NodeT> class DominatorBase {
@@ -62,7 +85,6 @@ template <class NodeT> class DominatorBase {
6285
bool isPostDominator() const { return IsPostDominators; }
6386
};
6487

65-
template <class NodeT> class DominatorTreeBase;
6688
struct PostDominatorTree;
6789

6890
/// \brief Base class for the actual dominator tree node.
@@ -177,8 +199,7 @@ void PrintDomTree(const DomTreeNodeBase<NodeT> *N, raw_ostream &o,
177199

178200
// The calculate routine is provided in a separate header but referenced here.
179201
template <class FuncT, class N>
180-
void Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT,
181-
FuncT &F);
202+
void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT, FuncT &F);
182203

183204
/// \brief Core dominator tree base class.
184205
///
@@ -251,14 +272,14 @@ template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
251272
// NewBB is split and now it has one successor. Update dominator tree to
252273
// reflect this change.
253274
template <class N, class GraphT>
254-
void Split(DominatorTreeBase<typename GraphT::NodeType> &DT,
255-
typename GraphT::NodeType *NewBB) {
275+
void Split(DominatorTreeBaseByGraphTraits<GraphT> &DT,
276+
typename GraphT::NodeRef NewBB) {
256277
assert(std::distance(GraphT::child_begin(NewBB),
257278
GraphT::child_end(NewBB)) == 1 &&
258279
"NewBB should have a single successor!");
259-
typename GraphT::NodeType *NewBBSucc = *GraphT::child_begin(NewBB);
280+
typename GraphT::NodeRef NewBBSucc = *GraphT::child_begin(NewBB);
260281

261-
std::vector<typename GraphT::NodeType *> PredBlocks;
282+
std::vector<typename GraphT::NodeRef> PredBlocks;
262283
typedef GraphTraits<Inverse<N>> InvTraits;
263284
for (typename InvTraits::ChildIteratorType
264285
PI = InvTraits::child_begin(NewBB),
@@ -273,7 +294,7 @@ template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
273294
PI = InvTraits::child_begin(NewBBSucc),
274295
E = InvTraits::child_end(NewBBSucc);
275296
PI != E; ++PI) {
276-
typename InvTraits::NodeType *ND = *PI;
297+
typename InvTraits::NodeRef ND = *PI;
277298
if (ND != NewBB && !DT.dominates(NewBBSucc, ND) &&
278299
DT.isReachableFromEntry(ND)) {
279300
NewBBDominatesNewBBSucc = false;
@@ -627,18 +648,17 @@ template <class NodeT> class DominatorTreeBase : public DominatorBase<NodeT> {
627648

628649
protected:
629650
template <class GraphT>
630-
friend typename GraphT::NodeType *
631-
Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
632-
typename GraphT::NodeType *V, unsigned LastLinked);
651+
friend typename GraphT::NodeRef
652+
Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT, typename GraphT::NodeRef V,
653+
unsigned LastLinked);
633654

634655
template <class GraphT>
635-
friend unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType> &DT,
636-
typename GraphT::NodeType *V, unsigned N);
656+
friend unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
657+
typename GraphT::NodeRef V, unsigned N);
637658

638659
template <class FuncT, class N>
639-
friend void
640-
Calculate(DominatorTreeBase<typename GraphTraits<N>::NodeType> &DT, FuncT &F);
641-
660+
friend void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<N>> &DT,
661+
FuncT &F);
642662

643663
DomTreeNodeBase<NodeT> *getNodeForBlock(NodeT *BB) {
644664
if (DomTreeNodeBase<NodeT> *Node = getNode(BB))

include/llvm/Support/GenericDomTreeConstruction.h

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929

3030
namespace llvm {
3131

32-
template<class GraphT>
33-
unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
34-
typename GraphT::NodeType* V, unsigned N) {
32+
template <class GraphT>
33+
unsigned DFSPass(DominatorTreeBaseByGraphTraits<GraphT> &DT,
34+
typename GraphT::NodeRef V, unsigned N) {
3535
// This is more understandable as a recursive algorithm, but we can't use the
3636
// recursive algorithm due to stack depth issues. Keep it here for
3737
// documentation purposes.
@@ -52,15 +52,16 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
5252
#else
5353
bool IsChildOfArtificialExit = (N != 0);
5454

55-
SmallVector<std::pair<typename GraphT::NodeType*,
56-
typename GraphT::ChildIteratorType>, 32> Worklist;
55+
SmallVector<
56+
std::pair<typename GraphT::NodeRef, typename GraphT::ChildIteratorType>,
57+
32>
58+
Worklist;
5759
Worklist.push_back(std::make_pair(V, GraphT::child_begin(V)));
5860
while (!Worklist.empty()) {
59-
typename GraphT::NodeType* BB = Worklist.back().first;
61+
typename GraphT::NodeRef BB = Worklist.back().first;
6062
typename GraphT::ChildIteratorType NextSucc = Worklist.back().second;
6163

62-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
63-
DT.Info[BB];
64+
auto &BBInfo = DT.Info[BB];
6465

6566
// First time we visited this BB?
6667
if (NextSucc == GraphT::child_begin(BB)) {
@@ -89,10 +90,9 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
8990
++Worklist.back().second;
9091

9192
// Visit the successor next, if it isn't already visited.
92-
typename GraphT::NodeType* Succ = *NextSucc;
93+
typename GraphT::NodeRef Succ = *NextSucc;
9394

94-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &SuccVInfo =
95-
DT.Info[Succ];
95+
auto &SuccVInfo = DT.Info[Succ];
9696
if (SuccVInfo.Semi == 0) {
9797
SuccVInfo.Parent = BBDFSNum;
9898
Worklist.push_back(std::make_pair(Succ, GraphT::child_begin(Succ)));
@@ -103,25 +103,23 @@ unsigned DFSPass(DominatorTreeBase<typename GraphT::NodeType>& DT,
103103
}
104104

105105
template <class GraphT>
106-
typename GraphT::NodeType *
107-
Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
108-
typename GraphT::NodeType *VIn, unsigned LastLinked) {
109-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInInfo =
110-
DT.Info[VIn];
106+
typename GraphT::NodeRef Eval(DominatorTreeBaseByGraphTraits<GraphT> &DT,
107+
typename GraphT::NodeRef VIn,
108+
unsigned LastLinked) {
109+
auto &VInInfo = DT.Info[VIn];
111110
if (VInInfo.DFSNum < LastLinked)
112111
return VIn;
113112

114-
SmallVector<typename GraphT::NodeType*, 32> Work;
115-
SmallPtrSet<typename GraphT::NodeType*, 32> Visited;
113+
SmallVector<typename GraphT::NodeRef, 32> Work;
114+
SmallPtrSet<typename GraphT::NodeRef, 32> Visited;
116115

117116
if (VInInfo.Parent >= LastLinked)
118117
Work.push_back(VIn);
119118

120119
while (!Work.empty()) {
121-
typename GraphT::NodeType* V = Work.back();
122-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VInfo =
123-
DT.Info[V];
124-
typename GraphT::NodeType* VAncestor = DT.Vertex[VInfo.Parent];
120+
typename GraphT::NodeRef V = Work.back();
121+
auto &VInfo = DT.Info[V];
122+
typename GraphT::NodeRef VAncestor = DT.Vertex[VInfo.Parent];
125123

126124
// Process Ancestor first
127125
if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
@@ -134,10 +132,9 @@ Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
134132
if (VInfo.Parent < LastLinked)
135133
continue;
136134

137-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &VAInfo =
138-
DT.Info[VAncestor];
139-
typename GraphT::NodeType* VAncestorLabel = VAInfo.Label;
140-
typename GraphT::NodeType* VLabel = VInfo.Label;
135+
auto &VAInfo = DT.Info[VAncestor];
136+
typename GraphT::NodeRef VAncestorLabel = VAInfo.Label;
137+
typename GraphT::NodeRef VLabel = VInfo.Label;
141138
if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
142139
VInfo.Label = VAncestorLabel;
143140
VInfo.Parent = VAInfo.Parent;
@@ -146,16 +143,18 @@ Eval(DominatorTreeBase<typename GraphT::NodeType> &DT,
146143
return VInInfo.Label;
147144
}
148145

149-
template<class FuncT, class NodeT>
150-
void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
151-
FuncT& F) {
146+
template <class FuncT, class NodeT>
147+
void Calculate(DominatorTreeBaseByGraphTraits<GraphTraits<NodeT>> &DT,
148+
FuncT &F) {
152149
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;
153153

154154
unsigned N = 0;
155155
bool MultipleRoots = (DT.Roots.size() > 1);
156156
if (MultipleRoots) {
157-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &BBInfo =
158-
DT.Info[nullptr];
157+
auto &BBInfo = DT.Info[nullptr];
159158
BBInfo.DFSNum = BBInfo.Semi = ++N;
160159
BBInfo.Label = nullptr;
161160

@@ -188,14 +187,13 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
188187
Buckets[i] = i;
189188

190189
for (unsigned i = N; i >= 2; --i) {
191-
typename GraphT::NodeType* W = DT.Vertex[i];
192-
typename DominatorTreeBase<typename GraphT::NodeType>::InfoRec &WInfo =
193-
DT.Info[W];
190+
typename GraphT::NodeRef W = DT.Vertex[i];
191+
auto &WInfo = DT.Info[W];
194192

195193
// Step #2: Implicitly define the immediate dominator of vertices
196194
for (unsigned j = i; Buckets[j] != i; j = Buckets[j]) {
197-
typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
198-
typename GraphT::NodeType* U = Eval<GraphT>(DT, V, i + 1);
195+
typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
196+
typename GraphT::NodeRef U = Eval<GraphT>(DT, V, i + 1);
199197
DT.IDoms[V] = DT.Info[U].Semi < i ? U : W;
200198
}
201199

@@ -207,7 +205,7 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
207205
for (typename InvTraits::ChildIteratorType CI =
208206
InvTraits::child_begin(W),
209207
E = InvTraits::child_end(W); CI != E; ++CI) {
210-
typename InvTraits::NodeType *N = *CI;
208+
typename InvTraits::NodeRef N = *CI;
211209
if (DT.Info.count(N)) { // Only if this predecessor is reachable!
212210
unsigned SemiU = DT.Info[Eval<GraphT>(DT, N, i + 1)].Semi;
213211
if (SemiU < WInfo.Semi)
@@ -227,17 +225,17 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
227225
}
228226

229227
if (N >= 1) {
230-
typename GraphT::NodeType* Root = DT.Vertex[1];
228+
typename GraphT::NodeRef Root = DT.Vertex[1];
231229
for (unsigned j = 1; Buckets[j] != 1; j = Buckets[j]) {
232-
typename GraphT::NodeType* V = DT.Vertex[Buckets[j]];
230+
typename GraphT::NodeRef V = DT.Vertex[Buckets[j]];
233231
DT.IDoms[V] = Root;
234232
}
235233
}
236234

237235
// Step #4: Explicitly define the immediate dominator of each vertex
238236
for (unsigned i = 2; i <= N; ++i) {
239-
typename GraphT::NodeType* W = DT.Vertex[i];
240-
typename GraphT::NodeType*& WIDom = DT.IDoms[W];
237+
typename GraphT::NodeRef W = DT.Vertex[i];
238+
typename GraphT::NodeRef &WIDom = DT.IDoms[W];
241239
if (WIDom != DT.Vertex[DT.Info[W].Semi])
242240
WIDom = DT.IDoms[WIDom];
243241
}
@@ -248,34 +246,32 @@ void Calculate(DominatorTreeBase<typename GraphTraits<NodeT>::NodeType>& DT,
248246
// one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
249247
// which postdominates all real exits if there are multiple exit blocks, or
250248
// an infinite loop.
251-
typename GraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : nullptr;
249+
typename GraphT::NodeRef Root = !MultipleRoots ? DT.Roots[0] : nullptr;
252250

253251
DT.RootNode =
254252
(DT.DomTreeNodes[Root] =
255-
llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
256-
Root, nullptr)).get();
253+
llvm::make_unique<DomTreeNodeBase<NodeType>>(Root, nullptr))
254+
.get();
257255

258256
// Loop over all of the reachable blocks in the function...
259257
for (unsigned i = 2; i <= N; ++i) {
260-
typename GraphT::NodeType* W = DT.Vertex[i];
258+
typename GraphT::NodeRef W = DT.Vertex[i];
261259

262260
// Don't replace this with 'count', the insertion side effect is important
263261
if (DT.DomTreeNodes[W])
264262
continue; // Haven't calculated this node yet?
265263

266-
typename GraphT::NodeType* ImmDom = DT.getIDom(W);
264+
typename GraphT::NodeRef ImmDom = DT.getIDom(W);
267265

268266
assert(ImmDom || DT.DomTreeNodes[nullptr]);
269267

270268
// Get or calculate the node for the immediate dominator
271-
DomTreeNodeBase<typename GraphT::NodeType> *IDomNode =
272-
DT.getNodeForBlock(ImmDom);
269+
DomTreeNodeBase<NodeType> *IDomNode = DT.getNodeForBlock(ImmDom);
273270

274271
// Add a new tree node for this BasicBlock, and link it as a child of
275272
// IDomNode
276273
DT.DomTreeNodes[W] = IDomNode->addChild(
277-
llvm::make_unique<DomTreeNodeBase<typename GraphT::NodeType>>(
278-
W, IDomNode));
274+
llvm::make_unique<DomTreeNodeBase<NodeType>>(W, IDomNode));
279275
}
280276

281277
// Free temporary memory used to construct idom's

lib/IR/Dominators.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,13 @@ template class llvm::DomTreeNodeBase<BasicBlock>;
6464
template class llvm::DominatorTreeBase<BasicBlock>;
6565

6666
template void llvm::Calculate<Function, BasicBlock *>(
67-
DominatorTreeBase<GraphTraits<BasicBlock *>::NodeType> &DT, Function &F);
67+
DominatorTreeBase<
68+
typename std::remove_pointer<GraphTraits<BasicBlock *>::NodeRef>::type>
69+
&DT,
70+
Function &F);
6871
template void llvm::Calculate<Function, Inverse<BasicBlock *>>(
69-
DominatorTreeBase<GraphTraits<Inverse<BasicBlock *>>::NodeType> &DT,
72+
DominatorTreeBase<typename std::remove_pointer<
73+
GraphTraits<Inverse<BasicBlock *>>::NodeRef>::type> &DT,
7074
Function &F);
7175

7276
// dominates - Return true if Def dominates a use in User. This performs

0 commit comments

Comments
 (0)