- This utility to merge a block anywhere into another one can help inline single
block regions into other blocks.
- Modified patterns test to use the new function.
Differential Revision: https://reviews.llvm.org/D86251
}
/// Return true if this block has no predecessors.
- bool hasNoPredecessors();
+ bool hasNoPredecessors() { return pred_begin() == pred_end(); }
+
+ /// Returns true if this blocks has no successors.
+ bool hasNoSuccessors() { return succ_begin() == succ_end(); }
/// If this block has exactly one predecessor, return it. Otherwise, return
/// null.
virtual void mergeBlocks(Block *source, Block *dest,
ValueRange argValues = llvm::None);
+ // Merge the operations of block 'source' before the operation 'op'. Source
+ // block should not have existing predecessors or successors.
+ void mergeBlockBefore(Block *source, Operation *op,
+ ValueRange argValues = llvm::None);
+
/// Split the operations starting at "before" (inclusive) out of the given
/// block into a new block, and return it.
virtual Block *splitBlock(Block *block, Block::iterator before);
return &back();
}
-/// Return true if this block has no predecessors.
-bool Block::hasNoPredecessors() { return pred_begin() == pred_end(); }
-
// Indexed successor access.
unsigned Block::getNumSuccessors() {
return empty() ? 0 : back().getNumSuccessors();
source->erase();
}
+// Merge the operations of block 'source' before the operation 'op'. Source
+// block should not have existing predecessors or successors.
+void PatternRewriter::mergeBlockBefore(Block *source, Operation *op,
+ ValueRange argValues) {
+ assert(source->hasNoPredecessors() &&
+ "expected 'source' to have no predecessors");
+ assert(source->hasNoSuccessors() &&
+ "expected 'source' to have no successors");
+
+ // Split the block containing 'op' into two, one containg all operations
+ // before 'op' (prologue) and another (epilogue) containing 'op' and all
+ // operations after it.
+ Block *prologue = op->getBlock();
+ Block *epilogue = splitBlock(prologue, op->getIterator());
+
+ // Merge the source block at the end of the prologue.
+ mergeBlocks(source, prologue, argValues);
+
+ // Merge the epilogue at the end the prologue.
+ mergeBlocks(epilogue, prologue);
+}
+
/// Split the operations starting at "before" (inclusive) out of the given
/// block into a new block, and return it.
Block *PatternRewriter::splitBlock(Block *block, Block::iterator before) {
op.getParentOfType<SingleBlockImplicitTerminatorOp>();
if (!parentOp)
return failure();
- Block &parentBlock = parentOp.region().front();
Block &innerBlock = op.region().front();
TerminatorOp innerTerminator =
cast<TerminatorOp>(innerBlock.getTerminator());
- Block *parentPrologue =
- rewriter.splitBlock(&parentBlock, Block::iterator(op));
+ rewriter.mergeBlockBefore(&innerBlock, op);
rewriter.eraseOp(innerTerminator);
- rewriter.mergeBlocks(&innerBlock, &parentBlock, {});
rewriter.eraseOp(op);
- rewriter.mergeBlocks(parentPrologue, &parentBlock, {});
rewriter.updateRootInPlace(op, [] {});
return success();
}