diff options
| author | River Riddle <riverriddle@google.com> | 2019-11-05 11:57:03 -0800 |
|---|---|---|
| committer | A. Unique TensorFlower <gardener@tensorflow.org> | 2019-11-05 11:57:38 -0800 |
| commit | 2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd (patch) | |
| tree | cb79fed502c6e9d437b34cc1b89b5039952de79e /mlir/lib/Dialect/StandardOps/Ops.cpp | |
| parent | 6d2432561c7822235091d5c58df3b8abb8732610 (diff) | |
| download | bcm5719-llvm-2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd.tar.gz bcm5719-llvm-2366561a39d80c3c6f0f5b1257760b5a9ed2f7bd.zip | |
Add a PatternRewriter hook to merge blocks, and use it to support for folding branches.
A pattern rewriter hook, mergeBlock, is added that allows for merging the operations of one block into the end of another. This is used to support a canonicalization pattern for branch operations that folds the branch when the successor has a single predecessor(the branch block).
Example:
^bb0:
%c0_i32 = constant 0 : i32
br ^bb1(%c0_i32 : i32)
^bb1(%x : i32):
return %x : i32
becomes:
^bb0:
%c0_i32 = constant 0 : i32
return %c0_i32 : i32
PiperOrigin-RevId: 278677825
Diffstat (limited to 'mlir/lib/Dialect/StandardOps/Ops.cpp')
| -rw-r--r-- | mlir/lib/Dialect/StandardOps/Ops.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/mlir/lib/Dialect/StandardOps/Ops.cpp b/mlir/lib/Dialect/StandardOps/Ops.cpp index 3b52aafcb02..6fea2fae38c 100644 --- a/mlir/lib/Dialect/StandardOps/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/Ops.cpp @@ -473,6 +473,28 @@ void AllocOp::getCanonicalizationPatterns(OwningRewritePatternList &results, // BranchOp //===----------------------------------------------------------------------===// +namespace { +/// Simplify a branch to a block that has a single predecessor. This effectively +/// merges the two blocks. +struct SimplifyBrToBlockWithSinglePred : public OpRewritePattern<BranchOp> { + using OpRewritePattern<BranchOp>::OpRewritePattern; + + PatternMatchResult matchAndRewrite(BranchOp op, + PatternRewriter &rewriter) const override { + // Check that the successor block has a single predecessor. + Block *succ = op.getDest(); + Block *opParent = op.getOperation()->getBlock(); + if (succ == opParent || !has_single_element(succ->getPredecessors())) + return matchFailure(); + + // Merge the successor into the current block and erase the branch. + rewriter.mergeBlocks(succ, opParent, llvm::to_vector<1>(op.getOperands())); + rewriter.eraseOp(op); + return matchSuccess(); + } +}; +} // end anonymous namespace. + static ParseResult parseBranchOp(OpAsmParser &parser, OperationState &result) { Block *dest; SmallVector<Value *, 4> destOperands; @@ -495,6 +517,11 @@ void BranchOp::eraseOperand(unsigned index) { getOperation()->eraseSuccessorOperand(0, index); } +void BranchOp::getCanonicalizationPatterns(OwningRewritePatternList &results, + MLIRContext *context) { + results.insert<SimplifyBrToBlockWithSinglePred>(context); +} + //===----------------------------------------------------------------------===// // CallOp //===----------------------------------------------------------------------===// |

