|
11 | 11 | #include "mlir/IR/AffineMap.h"
|
12 | 12 | #include "mlir/IR/BuiltinTypes.h"
|
13 | 13 | #include "mlir/IR/Dialect.h"
|
| 14 | +#include "mlir/IR/Dominance.h" |
14 | 15 | #include "mlir/IR/IRMapping.h"
|
15 | 16 | #include "mlir/IR/IntegerSet.h"
|
16 | 17 | #include "mlir/IR/Matchers.h"
|
@@ -641,3 +642,44 @@ void OpBuilder::cloneRegionBefore(Region ®ion, Region &parent,
|
641 | 642 | void OpBuilder::cloneRegionBefore(Region ®ion, Block *before) {
|
642 | 643 | cloneRegionBefore(region, *before->getParent(), before->getIterator());
|
643 | 644 | }
|
| 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