MLIR: lib/IR/Dominance.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/Support/GenericDomTreeConstruction.h"
19
20 using namespace mlir;
22
23 template class llvm::DominatorTreeBase<Block, false>;
24 template class llvm::DominatorTreeBase<Block, true>;
25 template class llvm::DomTreeNodeBase;
26
27
28
29
30
31 template
33 for (auto entry : dominanceInfos)
34 delete entry.second.getPointer();
35 }
36
37 template
39 for (auto entry : dominanceInfos)
40 delete entry.second.getPointer();
41 dominanceInfos.clear();
43
44 template
46 auto it = dominanceInfos.find(region);
47 if (it != dominanceInfos.end()) {
48 delete it->second.getPointer();
49 dominanceInfos.erase(it);
51 }
52
53
54
56 template
58 bool needsDomTree) const
59 -> llvm::PointerIntPair<DomTree *, 1, bool> {
60
61 auto itAndInserted = dominanceInfos.insert({region, {nullptr, true}});
62 auto &entry = itAndInserted.first->second;
63
64
65
66
67 if (!itAndInserted.second) {
68
69
70 if (needsDomTree && !entry.getPointer() && !region->hasOneBlock()) {
71 auto *domTree = new DomTree();
72 domTree->recalculate(*region);
73 entry.setPointer(domTree);
74 }
75 return entry;
76 }
77
78
79
81 auto *domTree = new DomTree();
82 domTree->recalculate(*region);
83 entry.setPointer(domTree);
84
85 return entry;
86 }
87
90 if (!parentOp->isRegistered()) {
91 entry.setInt(false);
92 } else if (auto regionKindItf = dyn_cast(parentOp)) {
93
94
95 entry.setInt(regionKindItf.hasSSADominance(region->getRegionNumber()));
96 }
97 }
98
99 return entry;
100 }
101
102
103
106 return ancestorOp->getBlock();
107 return nullptr;
108 }
109
110
111
112
113
115 template
117 do {
118
119 if (func(block))
120 return block;
122 return nullptr;
123 }
124
125
126
128
129
132 if (aRegion == bRegion)
133 return true;
134
135
136
137
138 size_t aRegionDepth = 0;
140 ++aRegionDepth;
141 return block->getParent() == bRegion;
142 })) {
143 a = aResult;
144 return true;
145 }
146
147
148
149
150 size_t bRegionDepth = 0;
152 ++bRegionDepth;
153 return block->getParent() == aRegion;
154 })) {
155 b = bResult;
156 return true;
157 }
158
159
160
161 while (true) {
162 if (aRegionDepth > bRegionDepth) {
164 --aRegionDepth;
165 } else if (aRegionDepth < bRegionDepth) {
167 --bRegionDepth;
168 } else {
169 break;
170 }
171 }
172
173
174
175 while (a) {
176
177
179 return true;
180
183 }
184
185
186
187 return false;
188 }
189
190 template
193 Block *b) const {
194
195 if (!a || !b)
196 return nullptr;
197
198
199 if (a == b)
200 return a;
201
202
204 return nullptr;
205
206
207
208 if (a == b)
209 return a;
210
211
212
213 return getDomTree(a->getParent()).findNearestCommonDominator(a, b);
214 }
215
216
217
218
219
220
221
222
223 static std::pair<Block *, Block::iterator>
225
227 return std::make_pair(b, it);
228
229
231 if (!parentOp)
233 Operation *op = r->findAncestorOpInRegion(*parentOp);
234 if (!op)
236 return std::make_pair(op->getBlock(), op->getIterator());
237 }
238
239
240
241
244 if (a == b)
245 return false;
246 if (a == block->end())
247 return false;
248 if (b == block->end())
249 return true;
250 return a->isBeforeInBlock(&*b);
251 }
252
253 template
256 bool enclosingOk) const {
257 assert(aBlock && bBlock && "expected non-null blocks");
258
259
260
261 if (aBlock == bBlock && aIt == bIt)
262 return !hasSSADominance(aBlock);
263
264
265
267 if (aRegion != bBlock->getParent()) {
268
269
270 if (!aRegion) {
271 bBlock = nullptr;
273 } else {
274 std::tie(bBlock, bIt) =
276 }
277 if (!bBlock)
278 return false;
279 assert(bBlock->getParent() == aRegion && "expected block in regionA");
280
281
282 if (aBlock == bBlock && aIt == bIt && enclosingOk)
283 return true;
284 }
285
286
287 if (aBlock == bBlock) {
288
289
290
291 if (!hasSSADominance(aBlock))
292 return true;
293 if constexpr (IsPostDom) {
295 } else {
297 }
298 }
299
300
301 return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
302 }
303
304
305
306 template
308
310 if (®ion->front() == a)
311 return true;
312
313
314 return getDomTree(region).isReachableFromEntry(a);
315 }
316
319
320
321
322
323
325 bool enclosingOpOk) const {
326 return super::properlyDominatesImpl(a->getBlock(), a->getIterator(),
327 b->getBlock(), b->getIterator(),
328 enclosingOpOk);
329 }
330
332 return super::properlyDominatesImpl(a, a->begin(), b, b->begin(),
333 true);
334 }
335
336
337
338
340
341
342 if (auto blockArg = dyn_cast(a))
343 return dominates(blockArg.getOwner(), b->getBlock());
344
345
346
347 return properlyDominates(a.getDefiningOp(), b, false);
348 }
349
350
351
352
353
355 bool enclosingOpOk) const {
356 return super::properlyDominatesImpl(a->getBlock(), a->getIterator(),
357 b->getBlock(), b->getIterator(),
358 enclosingOpOk);
359 }
360
362 return super::properlyDominatesImpl(a, a->end(), b, b->end(),
363 true);
364 }
static Block * traverseAncestors(Block *block, const FuncT &func)
Walks up the list of containers of the given block and calls the user-defined traversal function for ...
static bool isBeforeInBlock(Block *block, Block::iterator a, Block::iterator b)
Given two iterators into the same block, return "true" if a is before `b.
static std::pair< Block *, Block::iterator > findAncestorIteratorInRegion(Region *r, Block *b, Block::iterator it)
Returns the given block iterator if it lies within the region region.
static bool tryGetBlocksInSameRegion(Block *&a, Block *&b)
Tries to update the given block references to live in the same region by exploring the relationship o...
static Block * getAncestorBlock(Block *block)
Return the ancestor block enclosing the specified block.
Block represents an ordered list of Operations.
OpListType::iterator iterator
Region * getParent() const
Provide a 'getParent' method for ilist_node_with_parent methods.
Operation * getParentOp()
Returns the closest surrounding operation that contains this block.
bool properlyDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly dominates operation B, i.e.
Operation is the basic unit of execution within MLIR.
Block * getBlock()
Returns the operation block that contains this operation.
bool properlyPostDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly postdominates operation B.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
unsigned getRegionNumber()
Return the number of this region in the parent operation.
Operation * getParentOp()
Return the parent operation this region is attached to.
bool hasOneBlock()
Return true if this region has exactly one block.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
llvm::PointerIntPair< DomTree *, 1, bool > getDominanceInfo(Region *region, bool needsDomTree) const
Return the dom tree and "hasSSADominance" bit for the given region.
bool isReachableFromEntry(Block *a) const
Return true if the specified block is reachable from the entry block of its region.
bool properlyDominatesImpl(Block *aBlock, Block::iterator aIt, Block *bBlock, Block::iterator bIt, bool enclosingOk=true) const
Return "true" if block iterator A properly (post)dominates block iterator B.
Block * findNearestCommonDominator(Block *a, Block *b) const
Finds the nearest common dominator block for the two given blocks a and b.
void invalidate()
Invalidate dominance info.
Include the generated interface declarations.