@@ -508,9 +508,11 @@ class InlineBlockRewrite : public BlockRewrite {
508508class MoveBlockRewrite : public BlockRewrite {
509509public:
510510 MoveBlockRewrite (ConversionPatternRewriterImpl &rewriterImpl, Block *block,
511- Region *region, Block *insertBeforeBlock)
512- : BlockRewrite(Kind::MoveBlock, rewriterImpl, block), region(region),
513- insertBeforeBlock (insertBeforeBlock) {}
511+ Region *previousRegion, Region::iterator previousIt)
512+ : BlockRewrite(Kind::MoveBlock, rewriterImpl, block),
513+ region (previousRegion),
514+ insertBeforeBlock(previousIt == previousRegion->end () ? nullptr
515+ : &*previousIt) {}
514516
515517 static bool classof (const IRRewrite *rewrite) {
516518 return rewrite->getKind () == Kind::MoveBlock;
@@ -617,9 +619,12 @@ class OperationRewrite : public IRRewrite {
617619class MoveOperationRewrite : public OperationRewrite {
618620public:
619621 MoveOperationRewrite (ConversionPatternRewriterImpl &rewriterImpl,
620- Operation *op, Block *block, Operation *insertBeforeOp)
621- : OperationRewrite(Kind::MoveOperation, rewriterImpl, op), block(block),
622- insertBeforeOp (insertBeforeOp) {}
622+ Operation *op, OpBuilder::InsertPoint previous)
623+ : OperationRewrite(Kind::MoveOperation, rewriterImpl, op),
624+ block (previous.getBlock()),
625+ insertBeforeOp(previous.getPoint() == previous.getBlock()->end()
626+ ? nullptr
627+ : &*previous.getPoint()) {}
623628
624629 static bool classof (const IRRewrite *rewrite) {
625630 return rewrite->getKind () == Kind::MoveOperation;
@@ -1588,23 +1593,30 @@ Value ConversionPatternRewriterImpl::findOrBuildReplacementValue(
15881593
15891594void ConversionPatternRewriterImpl::notifyOperationInserted (
15901595 Operation *op, OpBuilder::InsertPoint previous) {
1596+ // If no previous insertion point is provided, the op used to be detached.
1597+ bool wasDetached = !previous.isSet ();
15911598 LLVM_DEBUG ({
1592- logger.startLine () << " ** Insert : '" << op->getName () << " '(" << op
1593- << " )\n " ;
1599+ logger.startLine () << " ** Insert : '" << op->getName () << " ' (" << op
1600+ << " )" ;
1601+ if (wasDetached)
1602+ logger.getOStream () << " (was detached)" ;
1603+ logger.getOStream () << " \n " ;
15941604 });
15951605 assert (!wasOpReplaced (op->getParentOp ()) &&
15961606 " attempting to insert into a block within a replaced/erased op" );
15971607
1598- if (!previous.isSet ()) {
1599- // This is a newly created op.
1608+ if (wasDetached) {
1609+ // If the op was detached, it is most likely a newly created op.
1610+ // TODO: If the same op is inserted multiple times from a detached state,
1611+ // the rollback mechanism may erase the same op multiple times. This is a
1612+ // bug in the rollback-based dialect conversion driver.
16001613 appendRewrite<CreateOperationRewrite>(op);
16011614 patternNewOps.insert (op);
16021615 return ;
16031616 }
1604- Operation *prevOp = previous.getPoint () == previous.getBlock ()->end ()
1605- ? nullptr
1606- : &*previous.getPoint ();
1607- appendRewrite<MoveOperationRewrite>(op, previous.getBlock (), prevOp);
1617+
1618+ // The op was moved from one place to another.
1619+ appendRewrite<MoveOperationRewrite>(op, previous);
16081620}
16091621
16101622void ConversionPatternRewriterImpl::replaceOp (
@@ -1669,29 +1681,39 @@ void ConversionPatternRewriterImpl::eraseBlock(Block *block) {
16691681
16701682void ConversionPatternRewriterImpl::notifyBlockInserted (
16711683 Block *block, Region *previous, Region::iterator previousIt) {
1672- assert (!wasOpReplaced (block->getParentOp ()) &&
1673- " attempting to insert into a region within a replaced/erased op" );
1684+ // If no previous insertion point is provided, the block used to be detached.
1685+ bool wasDetached = !previous;
1686+ Operation *newParentOp = block->getParentOp ();
16741687 LLVM_DEBUG (
16751688 {
1676- Operation *parent = block-> getParentOp () ;
1689+ Operation *parent = newParentOp ;
16771690 if (parent) {
16781691 logger.startLine () << " ** Insert Block into : '" << parent->getName ()
1679- << " '(" << parent << " )\n " ;
1692+ << " ' (" << parent << " )" ;
16801693 } else {
16811694 logger.startLine ()
1682- << " ** Insert Block into detached Region (nullptr parent op)' \n " ;
1695+ << " ** Insert Block into detached Region (nullptr parent op)" ;
16831696 }
1697+ if (wasDetached)
1698+ logger.getOStream () << " (was detached)" ;
1699+ logger.getOStream () << " \n " ;
16841700 });
1701+ assert (!wasOpReplaced (newParentOp) &&
1702+ " attempting to insert into a region within a replaced/erased op" );
16851703
16861704 patternInsertedBlocks.insert (block);
16871705
1688- if (!previous) {
1689- // This is a newly created block.
1706+ if (wasDetached) {
1707+ // If the block was detached, it is most likely a newly created block.
1708+ // TODO: If the same block is inserted multiple times from a detached state,
1709+ // the rollback mechanism may erase the same block multiple times. This is a
1710+ // bug in the rollback-based dialect conversion driver.
16901711 appendRewrite<CreateBlockRewrite>(block);
16911712 return ;
16921713 }
1693- Block *prevBlock = previousIt == previous->end () ? nullptr : &*previousIt;
1694- appendRewrite<MoveBlockRewrite>(block, previous, prevBlock);
1714+
1715+ // The block was moved from one place to another.
1716+ appendRewrite<MoveBlockRewrite>(block, previous, previousIt);
16951717}
16961718
16971719void ConversionPatternRewriterImpl::inlineBlockBefore (Block *source,
0 commit comments