1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
//===- llvm/Analysis/Dominators.h - Dominator Info Calculation ---*- C++ -*--=//
//
// This file defines the following classes:
// 1. DominatorSet: Calculates the [reverse] dominator set for a function
// 2. ImmediateDominators: Calculates and holds a mapping between BasicBlocks
// and their immediate dominator.
// 3. DominatorTree: Represent the ImmediateDominator as an explicit tree
// structure.
// 4. DominanceFrontier: Calculate and hold the dominance frontier for a
// function.
//
// These data structures are listed in increasing order of complexity. It
// takes longer to calculate the dominator frontier, for example, than the
// ImmediateDominator mapping.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DOMINATORS_H
#define LLVM_DOMINATORS_H
#include "llvm/Pass.h"
#include <set>
namespace cfg {
//===----------------------------------------------------------------------===//
//
// DominatorBase - Base class that other, more interesting dominator analyses
// inherit from.
//
class DominatorBase : public FunctionPass {
protected:
BasicBlock *Root;
const bool IsPostDominators;
inline DominatorBase(bool isPostDom) : Root(0), IsPostDominators(isPostDom) {}
public:
inline BasicBlock *getRoot() const { return Root; }
// Returns true if analysis based of postdoms
bool isPostDominator() const { return IsPostDominators; }
};
//===----------------------------------------------------------------------===//
//
// DominatorSet - Maintain a set<BasicBlock*> for every basic block in a
// function, that represents the blocks that dominate the block.
//
class DominatorSet : public DominatorBase {
public:
typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
// Map of dom sets
typedef std::map<BasicBlock*, DomSetType> DomSetMapType;
private:
DomSetMapType Doms;
void calcForwardDominatorSet(Function *F);
void calcPostDominatorSet(Function *F);
public:
// DominatorSet ctor - Build either the dominator set or the post-dominator
// set for a function...
//
static AnalysisID ID; // Build dominator set
static AnalysisID PostDomID; // Build postdominator set
DominatorSet(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnFunction(Function *F);
// Accessor interface:
typedef DomSetMapType::const_iterator const_iterator;
typedef DomSetMapType::iterator iterator;
inline const_iterator begin() const { return Doms.begin(); }
inline iterator begin() { return Doms.begin(); }
inline const_iterator end() const { return Doms.end(); }
inline iterator end() { return Doms.end(); }
inline const_iterator find(BasicBlock* B) const { return Doms.find(B); }
inline iterator find(BasicBlock* B) { return Doms.find(B); }
// getDominators - Return the set of basic blocks that dominate the specified
// block.
//
inline const DomSetType &getDominators(BasicBlock *BB) const {
const_iterator I = find(BB);
assert(I != end() && "BB not in function!");
return I->second;
}
// dominates - Return true if A dominates B.
//
inline bool dominates(BasicBlock *A, BasicBlock *B) const {
return getDominators(B).count(A) != 0;
}
// getAnalysisUsage - This obviously provides a dominator set, but it also
// uses the UnifyFunctionExitNode pass if building post-dominators
//
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
};
//===----------------------------------------------------------------------===//
//
// ImmediateDominators - Calculate the immediate dominator for each node in a
// function.
//
class ImmediateDominators : public DominatorBase {
std::map<BasicBlock*, BasicBlock*> IDoms;
void calcIDoms(const DominatorSet &DS);
public:
// ImmediateDominators ctor - Calculate the idom or post-idom mapping,
// for a function...
//
static AnalysisID ID; // Build immediate dominators
static AnalysisID PostDomID; // Build immediate postdominators
ImmediateDominators(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnFunction(Function *F) {
IDoms.clear(); // Reset from the last time we were run...
DominatorSet *DS;
if (isPostDominator())
DS = &getAnalysis<DominatorSet>(DominatorSet::PostDomID);
else
DS = &getAnalysis<DominatorSet>();
Root = DS->getRoot();
calcIDoms(*DS); // Can be used to make rev-idoms
return false;
}
// Accessor interface:
typedef std::map<BasicBlock*, BasicBlock*> IDomMapType;
typedef IDomMapType::const_iterator const_iterator;
inline const_iterator begin() const { return IDoms.begin(); }
inline const_iterator end() const { return IDoms.end(); }
inline const_iterator find(BasicBlock* B) const { return IDoms.find(B);}
// operator[] - Return the idom for the specified basic block. The start
// node returns null, because it does not have an immediate dominator.
//
inline BasicBlock *operator[](BasicBlock *BB) const {
std::map<BasicBlock*, BasicBlock*>::const_iterator I = IDoms.find(BB);
return I != IDoms.end() ? I->second : 0;
}
// getAnalysisUsage - This obviously provides a dominator tree, but it
// can only do so with the input of dominator sets
//
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
if (isPostDominator()) {
AU.addRequired(DominatorSet::PostDomID);
AU.addProvided(PostDomID);
} else {
AU.addRequired(DominatorSet::ID);
AU.addProvided(ID);
}
}
};
//===----------------------------------------------------------------------===//
//
// DominatorTree - Calculate the immediate dominator tree for a function.
//
class DominatorTree : public DominatorBase {
class Node2;
public:
typedef Node2 Node;
private:
std::map<BasicBlock*, Node*> Nodes;
void calculate(const DominatorSet &DS);
void reset();
typedef std::map<BasicBlock*, Node*> NodeMapType;
public:
class Node2 : public std::vector<Node*> {
friend class DominatorTree;
BasicBlock *TheNode;
Node2 *IDom;
public:
inline BasicBlock *getNode() const { return TheNode; }
inline Node2 *getIDom() const { return IDom; }
inline const std::vector<Node*> &getChildren() const { return *this; }
// dominates - Returns true iff this dominates N. Note that this is not a
// constant time operation!
inline bool dominates(const Node2 *N) const {
const Node2 *IDom;
while ((IDom = N->getIDom()) != 0 && IDom != this)
N = IDom; // Walk up the tree
return IDom != 0;
}
private:
inline Node2(BasicBlock *node, Node *iDom)
: TheNode(node), IDom(iDom) {}
inline Node2 *addChild(Node *C) { push_back(C); return C; }
};
public:
// DominatorTree ctor - Compute a dominator tree, given various amounts of
// previous knowledge...
static AnalysisID ID; // Build dominator tree
static AnalysisID PostDomID; // Build postdominator tree
DominatorTree(AnalysisID id) : DominatorBase(id == PostDomID) {}
~DominatorTree() { reset(); }
virtual bool runOnFunction(Function *F) {
reset();
DominatorSet *DS;
if (isPostDominator())
DS = &getAnalysis<DominatorSet>(DominatorSet::PostDomID);
else
DS = &getAnalysis<DominatorSet>();
Root = DS->getRoot();
calculate(*DS); // Can be used to make rev-idoms
return false;
}
inline Node *operator[](BasicBlock *BB) const {
NodeMapType::const_iterator i = Nodes.find(BB);
return (i != Nodes.end()) ? i->second : 0;
}
// getAnalysisUsage - This obviously provides a dominator tree, but it
// uses dominator sets
//
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
if (isPostDominator()) {
AU.addRequired(DominatorSet::PostDomID);
AU.addProvided(PostDomID);
} else {
AU.addRequired(DominatorSet::ID);
AU.addProvided(ID);
}
}
};
//===----------------------------------------------------------------------===//
//
// DominanceFrontier - Calculate the dominance frontiers for a function.
//
class DominanceFrontier : public DominatorBase {
public:
typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
private:
DomSetMapType Frontiers;
const DomSetType &calcDomFrontier(const DominatorTree &DT,
const DominatorTree::Node *Node);
const DomSetType &calcPostDomFrontier(const DominatorTree &DT,
const DominatorTree::Node *Node);
public:
// DominatorFrontier ctor - Compute dominator frontiers for a function
//
static AnalysisID ID; // Build dominator frontier
static AnalysisID PostDomID; // Build postdominator frontier
DominanceFrontier(AnalysisID id) : DominatorBase(id == PostDomID) {}
virtual bool runOnFunction(Function *) {
Frontiers.clear();
DominatorTree *DT;
if (isPostDominator())
DT = &getAnalysis<DominatorTree>(DominatorTree::PostDomID);
else
DT = &getAnalysis<DominatorTree>();
Root = DT->getRoot();
if (isPostDominator())
calcPostDomFrontier(*DT, (*DT)[Root]);
else
calcDomFrontier(*DT, (*DT)[Root]);
return false;
}
// Accessor interface:
typedef DomSetMapType::const_iterator const_iterator;
inline const_iterator begin() const { return Frontiers.begin(); }
inline const_iterator end() const { return Frontiers.end(); }
inline const_iterator find(BasicBlock* B) const { return Frontiers.find(B); }
// getAnalysisUsage - This obviously provides the dominance frontier, but it
// uses dominator sets
//
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
if (isPostDominator()) {
AU.addRequired(DominatorTree::PostDomID);
AU.addProvided(PostDomID);
} else {
AU.addRequired(DominatorTree::ID);
AU.addProvided(ID);
}
}
};
} // End namespace cfg
#endif
|