Skip to content

Commit 4c303e1

Browse files
[mlir][IR] DominanceInfo: Deduplicate properlyDominates implementation
The implementations of `DominanceInfo::properlyDominates` and `PostDominanceInfo::properlyPostDominates` are almost identical: only one line of code is different. Define the function in `DominanceInfoBase` to avoid the code duplication. Note: This commit is not marked as NFC because `PostDominanceInfo::properlyPostDominates` now also has an `enclosingOpOk` argument.
1 parent 01dcc41 commit 4c303e1

File tree

2 files changed

+48
-84
lines changed

2 files changed

+48
-84
lines changed

mlir/include/mlir/IR/Dominance.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,12 @@ class DominanceInfoBase {
113113
llvm::PointerIntPair<DomTree *, 1, bool>
114114
getDominanceInfo(Region *region, bool needsDomTree) const;
115115

116-
/// Return true if the specified block A properly dominates block B.
117-
bool properlyDominates(Block *a, Block *b) const;
116+
/// Return "true" if the specified block A properly (post)dominates block B.
117+
bool properlyDominatesImpl(Block *a, Block *b) const;
118+
119+
/// Return "true" if the specified op A properly (post)dominates op B.
120+
bool properlyDominatesImpl(Operation *a, Operation *b,
121+
bool enclosingOpOk = true) const;
118122

119123
/// A mapping of regions to their base dominator tree and a cached
120124
/// "hasSSADominance" bit. This map does not contain dominator trees for
@@ -147,7 +151,9 @@ class DominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/false> {
147151
/// The `enclosingOpOk` flag says whether we should return true if the B op
148152
/// is enclosed by a region on A.
149153
bool properlyDominates(Operation *a, Operation *b,
150-
bool enclosingOpOk = true) const;
154+
bool enclosingOpOk = true) const {
155+
return super::properlyDominatesImpl(a, b, enclosingOpOk);
156+
}
151157

152158
/// Return true if operation A dominates operation B, i.e. if A and B are the
153159
/// same operation or A properly dominates B.
@@ -183,7 +189,7 @@ class DominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/false> {
183189
/// dominance" of ops, the single block is considered to properly dominate
184190
/// itself in a graph region.
185191
bool properlyDominates(Block *a, Block *b) const {
186-
return super::properlyDominates(a, b);
192+
return super::properlyDominatesImpl(a, b);
187193
}
188194
};
189195

@@ -193,7 +199,10 @@ class PostDominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/true> {
193199
using super::super;
194200

195201
/// Return true if operation A properly postdominates operation B.
196-
bool properlyPostDominates(Operation *a, Operation *b) const;
202+
bool properlyPostDominates(Operation *a, Operation *b,
203+
bool enclosingOpOk = true) const {
204+
return super::properlyDominatesImpl(a, b, enclosingOpOk);
205+
}
197206

198207
/// Return true if operation A postdominates operation B.
199208
bool postDominates(Operation *a, Operation *b) const {
@@ -202,7 +211,7 @@ class PostDominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/true> {
202211

203212
/// Return true if the specified block A properly postdominates block B.
204213
bool properlyPostDominates(Block *a, Block *b) const {
205-
return super::properlyDominates(a, b);
214+
return super::properlyDominatesImpl(a, b);
206215
}
207216

208217
/// Return true if the specified block A postdominates block B.

mlir/lib/IR/Dominance.cpp

Lines changed: 33 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ DominanceInfoBase<IsPostDom>::findNearestCommonDominator(Block *a,
215215

216216
/// Return true if the specified block A properly dominates block B.
217217
template <bool IsPostDom>
218-
bool DominanceInfoBase<IsPostDom>::properlyDominates(Block *a, Block *b) const {
218+
bool DominanceInfoBase<IsPostDom>::properlyDominatesImpl(Block *a,
219+
Block *b) const {
219220
assert(a && b && "null blocks not allowed");
220221

221222
// A block dominates, but does not properly dominate, itself unless this
@@ -243,51 +244,29 @@ bool DominanceInfoBase<IsPostDom>::properlyDominates(Block *a, Block *b) const {
243244
return getDomTree(regionA).properlyDominates(a, b);
244245
}
245246

246-
/// Return true if the specified block is reachable from the entry block of
247-
/// its region.
248247
template <bool IsPostDom>
249-
bool DominanceInfoBase<IsPostDom>::isReachableFromEntry(Block *a) const {
250-
// If this is the first block in its region, then it is obviously reachable.
251-
Region *region = a->getParent();
252-
if (&region->front() == a)
253-
return true;
254-
255-
// Otherwise this is some block in a multi-block region. Check DomTree.
256-
return getDomTree(region).isReachableFromEntry(a);
257-
}
258-
259-
template class detail::DominanceInfoBase</*IsPostDom=*/true>;
260-
template class detail::DominanceInfoBase</*IsPostDom=*/false>;
261-
262-
//===----------------------------------------------------------------------===//
263-
// DominanceInfo
264-
//===----------------------------------------------------------------------===//
265-
266-
/// Return true if operation `a` properly dominates operation `b`. The
267-
/// 'enclosingOpOk' flag says whether we should return true if the `b` op is
268-
/// enclosed by a region on 'a'.
269-
bool DominanceInfo::properlyDominates(Operation *a, Operation *b,
270-
bool enclosingOpOk) const {
248+
bool DominanceInfoBase<IsPostDom>::properlyDominatesImpl(
249+
Operation *a, Operation *b, bool enclosingOpOk) const {
271250
Block *aBlock = a->getBlock(), *bBlock = b->getBlock();
272251
assert(aBlock && bBlock && "operations must be in a block");
273252

274-
// An operation dominates, but does not properly dominate, itself unless this
275-
// is a graph region.
253+
// An operation (pos)dominates, but does not properly (pos)dominate, itself
254+
// unless this is a graph region.
276255
if (a == b)
277256
return !hasSSADominance(aBlock);
278257

279258
// If these ops are in different regions, then normalize one into the other.
280259
Region *aRegion = aBlock->getParent();
281260
if (aRegion != bBlock->getParent()) {
282261
// Scoot up b's region tree until we find an operation in A's region that
283-
// encloses it. If this fails, then we know there is no post-dom relation.
262+
// encloses it. If this fails, then we know there is no (post)dom relation.
284263
b = aRegion ? aRegion->findAncestorOpInRegion(*b) : nullptr;
285264
if (!b)
286265
return false;
287266
bBlock = b->getBlock();
288267
assert(bBlock->getParent() == aRegion);
289268

290-
// If 'a' encloses 'b', then we consider it to dominate.
269+
// If 'a' encloses 'b', then we consider it to (post)dominate.
291270
if (a == b && enclosingOpOk)
292271
return true;
293272
}
@@ -297,17 +276,39 @@ bool DominanceInfo::properlyDominates(Operation *a, Operation *b,
297276
// Dominance changes based on the region type. In a region with SSA
298277
// dominance, uses inside the same block must follow defs. In other
299278
// regions kinds, uses and defs can come in any order inside a block.
300-
if (hasSSADominance(aBlock)) {
301-
// If the blocks are the same, then check if b is before a in the block.
279+
if (!hasSSADominance(aBlock))
280+
return true;
281+
if constexpr (IsPostDom) {
282+
return b->isBeforeInBlock(a);
283+
} else {
302284
return a->isBeforeInBlock(b);
303285
}
304-
return true;
305286
}
306287

307288
// If the blocks are different, use DomTree to resolve the query.
308289
return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
309290
}
310291

292+
/// Return true if the specified block is reachable from the entry block of
293+
/// its region.
294+
template <bool IsPostDom>
295+
bool DominanceInfoBase<IsPostDom>::isReachableFromEntry(Block *a) const {
296+
// If this is the first block in its region, then it is obviously reachable.
297+
Region *region = a->getParent();
298+
if (&region->front() == a)
299+
return true;
300+
301+
// Otherwise this is some block in a multi-block region. Check DomTree.
302+
return getDomTree(region).isReachableFromEntry(a);
303+
}
304+
305+
template class detail::DominanceInfoBase</*IsPostDom=*/true>;
306+
template class detail::DominanceInfoBase</*IsPostDom=*/false>;
307+
308+
//===----------------------------------------------------------------------===//
309+
// DominanceInfo
310+
//===----------------------------------------------------------------------===//
311+
311312
/// Return true if the `a` value properly dominates operation `b`, i.e if the
312313
/// operation that defines `a` properlyDominates `b` and the operation that
313314
/// defines `a` does not contain `b`.
@@ -321,49 +322,3 @@ bool DominanceInfo::properlyDominates(Value a, Operation *b) const {
321322
// `b`, but `a` does not itself enclose `b` in one of its regions.
322323
return properlyDominates(a.getDefiningOp(), b, /*enclosingOpOk=*/false);
323324
}
324-
325-
//===----------------------------------------------------------------------===//
326-
// PostDominanceInfo
327-
//===----------------------------------------------------------------------===//
328-
329-
/// Returns true if statement 'a' properly postdominates statement b.
330-
bool PostDominanceInfo::properlyPostDominates(Operation *a,
331-
Operation *b) const {
332-
auto *aBlock = a->getBlock(), *bBlock = b->getBlock();
333-
assert(aBlock && bBlock && "operations must be in a block");
334-
335-
// An instruction postDominates, but does not properlyPostDominate, itself
336-
// unless this is a graph region.
337-
if (a == b)
338-
return !hasSSADominance(aBlock);
339-
340-
// If these ops are in different regions, then normalize one into the other.
341-
Region *aRegion = aBlock->getParent();
342-
if (aRegion != bBlock->getParent()) {
343-
// Scoot up b's region tree until we find an operation in A's region that
344-
// encloses it. If this fails, then we know there is no post-dom relation.
345-
b = aRegion ? aRegion->findAncestorOpInRegion(*b) : nullptr;
346-
if (!b)
347-
return false;
348-
bBlock = b->getBlock();
349-
assert(bBlock->getParent() == aRegion);
350-
351-
// If 'a' encloses 'b', then we consider it to postdominate.
352-
if (a == b)
353-
return true;
354-
}
355-
356-
// Ok, they are in the same region. If they are in the same block, check if b
357-
// is before a in the block.
358-
if (aBlock == bBlock) {
359-
// Dominance changes based on the region type.
360-
if (hasSSADominance(aBlock)) {
361-
// If the blocks are the same, then check if b is before a in the block.
362-
return b->isBeforeInBlock(a);
363-
}
364-
return true;
365-
}
366-
367-
// If the blocks are different, check if a's block post dominates b's.
368-
return getDomTree(aRegion).properlyDominates(aBlock, bBlock);
369-
}

0 commit comments

Comments
 (0)