Skip to content

Commit f716eaa

Browse files
[mlir][IR] Add OpBuilder::setInsertionPointAfterValues
1 parent e890126 commit f716eaa

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

mlir/include/mlir/IR/Builders.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
namespace mlir {
1717

1818
class AffineExpr;
19+
class PostDominanceInfo;
1920
class IRMapping;
2021
class UnknownLoc;
2122
class FileLineColLoc;
@@ -435,6 +436,19 @@ class OpBuilder : public Builder {
435436
}
436437
}
437438

439+
/// Sets the insertion point to a place that post-dominates the definitions
440+
/// of all given values. Returns "failure" and leaves the current insertion
441+
/// point unchanged if no such insertion point exists.
442+
///
443+
/// There may be multiple suitable insertion points. This function chooses an
444+
/// insertion right after one of the given values.
445+
///
446+
/// Note: Some of the given values may already have gone out of scope at the
447+
/// selected insertion point. (E.g., because they are defined in a nested
448+
/// region.)
449+
LogicalResult setInsertionPointAfterValues(ArrayRef<Value> values,
450+
const PostDominanceInfo &domInfo);
451+
438452
/// Sets the insertion point to the start of the specified block.
439453
void setInsertionPointToStart(Block *block) {
440454
setInsertionPoint(block, block->begin());

mlir/include/mlir/IR/Dominance.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,17 @@ class DominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/false> {
187187
/// dominance" of ops, the single block is considered to properly dominate
188188
/// itself in a graph region.
189189
bool properlyDominates(Block *a, Block *b) const;
190+
191+
bool properlyDominantes(Block *aBlock, Block::iterator aIt, Block *bBlock,
192+
Block::iterator bIt, bool enclosingOk = true) const {
193+
return super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk);
194+
}
195+
196+
bool dominantes(Block *aBlock, Block::iterator aIt, Block *bBlock,
197+
Block::iterator bIt, bool enclosingOk = true) const {
198+
return (aBlock == bBlock && aIt == bIt) ||
199+
super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk);
200+
}
190201
};
191202

192203
/// A class for computing basic postdominance information.
@@ -210,6 +221,18 @@ class PostDominanceInfo : public detail::DominanceInfoBase</*IsPostDom=*/true> {
210221
bool postDominates(Block *a, Block *b) const {
211222
return a == b || properlyPostDominates(a, b);
212223
}
224+
225+
bool properlyPostDominantes(Block *aBlock, Block::iterator aIt, Block *bBlock,
226+
Block::iterator bIt,
227+
bool enclosingOk = true) const {
228+
return super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk);
229+
}
230+
231+
bool postDominantes(Block *aBlock, Block::iterator aIt, Block *bBlock,
232+
Block::iterator bIt, bool enclosingOk = true) const {
233+
return (aBlock == bBlock && aIt == bIt) ||
234+
super::properlyDominatesImpl(aBlock, aIt, bBlock, bIt, enclosingOk);
235+
}
213236
};
214237

215238
} // namespace mlir

mlir/lib/IR/Builders.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "mlir/IR/AffineMap.h"
1212
#include "mlir/IR/BuiltinTypes.h"
1313
#include "mlir/IR/Dialect.h"
14+
#include "mlir/IR/Dominance.h"
1415
#include "mlir/IR/IRMapping.h"
1516
#include "mlir/IR/IntegerSet.h"
1617
#include "mlir/IR/Matchers.h"
@@ -641,3 +642,44 @@ void OpBuilder::cloneRegionBefore(Region &region, Region &parent,
641642
void OpBuilder::cloneRegionBefore(Region &region, Block *before) {
642643
cloneRegionBefore(region, *before->getParent(), before->getIterator());
643644
}
645+
646+
LogicalResult
647+
OpBuilder::setInsertionPointAfterValues(ArrayRef<Value> values,
648+
const PostDominanceInfo &domInfo) {
649+
// Helper function that computes the point after v's definition.
650+
auto computeAfterIp = [](Value v) -> std::pair<Block *, Block::iterator> {
651+
if (auto blockArg = dyn_cast<BlockArgument>(v))
652+
return std::make_pair(blockArg.getOwner(), blockArg.getOwner()->begin());
653+
Operation *op = v.getDefiningOp();
654+
return std::make_pair(op->getBlock(), op->getIterator());
655+
};
656+
657+
// Compute the insertion point after the first value is defined.
658+
assert(!values.empty() && "expected at least one Value");
659+
auto [block, blockIt] = computeAfterIp(values.front());
660+
661+
// Check the other values one-by-one and update the insertion point if
662+
// needed.
663+
for (Value v : values.drop_front()) {
664+
auto [candidateBlock, candidateBlockIt] = computeAfterIp(v);
665+
if (domInfo.postDominantes(candidateBlock, candidateBlockIt, block,
666+
blockIt)) {
667+
// The point after v's definition post-dominates the current (and all
668+
// previous) insertion points. Note: Post-dominance is transitive.
669+
block = candidateBlock;
670+
blockIt = candidateBlockIt;
671+
continue;
672+
}
673+
674+
if (!domInfo.postDominantes(block, blockIt, candidateBlock,
675+
candidateBlockIt)) {
676+
// The point after v's definition and the current insertion point do not
677+
// post-dominate each other. Therefore, there is no insertion point that
678+
// post-dominates all values.
679+
return failure();
680+
}
681+
}
682+
683+
setInsertionPoint(block, blockIt);
684+
return success();
685+
}

0 commit comments

Comments
 (0)