Skip to content

Commit 752df2b

Browse files
[mlir][IR] DominanceInfo: Add function to query dominator of a range of block (#77098)
Also improve the implementation of `findCommonDominator` (skip duplicate blocks) and extract it from `BufferPlacementTransformationBase` (so that `BufferPlacementTransformationBase` can be retired eventually).
1 parent dd450f0 commit 752df2b

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

mlir/include/mlir/Dialect/Bufferization/Transforms/BufferUtils.h

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,33 +73,36 @@ class BufferPlacementAllocs {
7373
AllocEntryList allocs;
7474
};
7575

76+
/// Finds a common dominator for the given value while taking the positions
77+
/// of the values in the value set into account. It supports dominator and
78+
/// post-dominator analyses via template arguments. If no common dominator
79+
/// can be found, this function will return "nullptr".
80+
template <typename DominatorT>
81+
Block *findCommonDominator(Value value,
82+
const BufferViewFlowAnalysis::ValueSetT &values,
83+
const DominatorT &doms) {
84+
// Store blocks in a set before querying `DominanceInfo` to filter out
85+
// duplicate blocks (for performance reasons).
86+
llvm::SmallPtrSet<Block *, 16> blocks;
87+
// Start with the current block the value is defined in.
88+
blocks.insert(value.getParentBlock());
89+
for (Value childValue : values) {
90+
for (Operation *user : childValue.getUsers()) {
91+
// Find an appropriate dominator block that takes the current use into
92+
// account.
93+
blocks.insert(user->getBlock());
94+
}
95+
// Take values without any users into account.
96+
blocks.insert(childValue.getParentBlock());
97+
}
98+
return doms.findNearestCommonDominator(blocks);
99+
}
100+
76101
/// The base class for all BufferPlacement transformations.
77102
class BufferPlacementTransformationBase {
78103
public:
79104
using ValueSetT = BufferViewFlowAnalysis::ValueSetT;
80105

81-
/// Finds a common dominator for the given value while taking the positions
82-
/// of the values in the value set into account. It supports dominator and
83-
/// post-dominator analyses via template arguments.
84-
template <typename DominatorT>
85-
static Block *findCommonDominator(Value value, const ValueSetT &values,
86-
const DominatorT &doms) {
87-
// Start with the current block the value is defined in.
88-
Block *dom = value.getParentBlock();
89-
// Iterate over all aliases and their uses to find a safe placement block
90-
// according to the given dominator information.
91-
for (Value childValue : values) {
92-
for (Operation *user : childValue.getUsers()) {
93-
// Move upwards in the dominator tree to find an appropriate
94-
// dominator block that takes the current use into account.
95-
dom = doms.findNearestCommonDominator(dom, user->getBlock());
96-
}
97-
// Take values without any users into account.
98-
dom = doms.findNearestCommonDominator(dom, childValue.getParentBlock());
99-
}
100-
return dom;
101-
}
102-
103106
/// Constructs a new operation base using the given root operation.
104107
BufferPlacementTransformationBase(Operation *op);
105108

mlir/include/mlir/IR/Dominance.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,21 @@ class DominanceInfoBase {
5454
/// nullptr.
5555
Block *findNearestCommonDominator(Block *a, Block *b) const;
5656

57+
/// Finds the nearest common dominator block for the given range of blocks.
58+
/// If no common dominator can be found, this function will return nullptr.
59+
template <typename BlockRangeT>
60+
Block *findNearestCommonDominator(BlockRangeT &&blocks) const {
61+
if (blocks.begin() == blocks.end())
62+
return nullptr;
63+
Block *dom = *blocks.begin();
64+
for (auto it = ++blocks.begin(); it != blocks.end(); ++it) {
65+
dom = findNearestCommonDominator(dom, *it);
66+
if (!dom)
67+
return nullptr;
68+
}
69+
return dom;
70+
}
71+
5772
/// Get the root dominance node of the given region. Note that this operation
5873
/// is only defined for multi-block regions!
5974
DominanceInfoNode *getRootNode(Region *region) {

0 commit comments

Comments
 (0)