@@ -760,7 +760,8 @@ class IRRewrite {
760760 InlineBlock,
761761 MoveBlock,
762762 SplitBlock,
763- BlockTypeConversion
763+ BlockTypeConversion,
764+ MoveOperation
764765 };
765766
766767 virtual ~IRRewrite () = default ;
@@ -982,6 +983,54 @@ class BlockTypeConversionRewrite : public BlockRewrite {
982983 // `ArgConverter::applyRewrites`. This should be done in the "commit" method.
983984 void rollback () override ;
984985};
986+
987+ // / An operation rewrite.
988+ class OperationRewrite : public IRRewrite {
989+ public:
990+ // / Return the operation that this rewrite operates on.
991+ Operation *getOperation () const { return op; }
992+
993+ static bool classof (const IRRewrite *rewrite) {
994+ return rewrite->getKind () >= Kind::MoveOperation &&
995+ rewrite->getKind () <= Kind::MoveOperation;
996+ }
997+
998+ protected:
999+ OperationRewrite (Kind kind, ConversionPatternRewriterImpl &rewriterImpl,
1000+ Operation *op)
1001+ : IRRewrite(kind, rewriterImpl), op(op) {}
1002+
1003+ // The operation that this rewrite operates on.
1004+ Operation *op;
1005+ };
1006+
1007+ // / Moving of an operation. This rewrite is immediately reflected in the IR.
1008+ class MoveOperationRewrite : public OperationRewrite {
1009+ public:
1010+ MoveOperationRewrite (ConversionPatternRewriterImpl &rewriterImpl,
1011+ Operation *op, Block *block, Operation *insertBeforeOp)
1012+ : OperationRewrite(Kind::MoveOperation, rewriterImpl, op), block(block),
1013+ insertBeforeOp (insertBeforeOp) {}
1014+
1015+ static bool classof (const IRRewrite *rewrite) {
1016+ return rewrite->getKind () == Kind::MoveOperation;
1017+ }
1018+
1019+ void rollback () override {
1020+ // Move the operation back to its original position.
1021+ Block::iterator before =
1022+ insertBeforeOp ? Block::iterator (insertBeforeOp) : block->end ();
1023+ block->getOperations ().splice (before, op->getBlock ()->getOperations (), op);
1024+ }
1025+
1026+ private:
1027+ // The block in which this operation was previously contained.
1028+ Block *block;
1029+
1030+ // The original successor of this operation before it was moved. "nullptr" if
1031+ // this operation was the only operation in the region.
1032+ Operation *insertBeforeOp;
1033+ };
9851034} // namespace
9861035
9871036// ===----------------------------------------------------------------------===//
@@ -1478,12 +1527,19 @@ LogicalResult ConversionPatternRewriterImpl::convertNonEntryRegionTypes(
14781527
14791528void ConversionPatternRewriterImpl::notifyOperationInserted (
14801529 Operation *op, OpBuilder::InsertPoint previous) {
1481- assert (!previous.isSet () && " expected newly created op" );
14821530 LLVM_DEBUG ({
14831531 logger.startLine () << " ** Insert : '" << op->getName () << " '(" << op
14841532 << " )\n " ;
14851533 });
1486- createdOps.push_back (op);
1534+ if (!previous.isSet ()) {
1535+ // This is a newly created op.
1536+ createdOps.push_back (op);
1537+ return ;
1538+ }
1539+ Operation *prevOp = previous.getPoint () == previous.getBlock ()->end ()
1540+ ? nullptr
1541+ : &*previous.getPoint ();
1542+ appendRewrite<MoveOperationRewrite>(op, previous.getBlock (), prevOp);
14871543}
14881544
14891545void ConversionPatternRewriterImpl::notifyOpReplaced (Operation *op,
@@ -1722,18 +1778,6 @@ void ConversionPatternRewriter::cancelOpModification(Operation *op) {
17221778 rootUpdates.erase (rootUpdates.begin () + updateIdx);
17231779}
17241780
1725- void ConversionPatternRewriter::moveOpBefore (Operation *op, Block *block,
1726- Block::iterator iterator) {
1727- llvm_unreachable (
1728- " moving single ops is not supported in a dialect conversion" );
1729- }
1730-
1731- void ConversionPatternRewriter::moveOpAfter (Operation *op, Block *block,
1732- Block::iterator iterator) {
1733- llvm_unreachable (
1734- " moving single ops is not supported in a dialect conversion" );
1735- }
1736-
17371781detail::ConversionPatternRewriterImpl &ConversionPatternRewriter::getImpl () {
17381782 return *impl;
17391783}
0 commit comments