mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-05 17:12:00 +00:00
[MLIR] Add PatternRewriter::mergeBlockBefore() to merge a block in the middle of another block.
- 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
This commit is contained in:
parent
724f570ad2
commit
9c7b0c4aa5
@ -207,7 +207,10 @@ public:
|
||||
}
|
||||
|
||||
/// 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.
|
||||
|
@ -326,6 +326,11 @@ public:
|
||||
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);
|
||||
|
@ -201,9 +201,6 @@ Operation *Block::getTerminator() {
|
||||
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();
|
||||
|
@ -128,6 +128,28 @@ void PatternRewriter::mergeBlocks(Block *source, Block *dest,
|
||||
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) {
|
||||
|
@ -893,16 +893,12 @@ struct TestMergeSingleBlockOps
|
||||
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();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user