[Mlir-commits] [mlir] 3f9cdd4 - [MLIR] Add pattern rewriter util to erase block; remove dead else
Uday Bondhugula
llvmlistbot at llvm.org
Sun Apr 5 06:58:53 PDT 2020
Author: Uday Bondhugula
Date: 2020-04-05T19:24:43+05:30
New Revision: 3f9cdd44d740a49e2eabda284463a95d450fe72d
URL: https://github.com/llvm/llvm-project/commit/3f9cdd44d740a49e2eabda284463a95d450fe72d
DIFF: https://github.com/llvm/llvm-project/commit/3f9cdd44d740a49e2eabda284463a95d450fe72d.diff
LOG: [MLIR] Add pattern rewriter util to erase block; remove dead else
Add a pattern rewriter utility to erase blocks (while notifying the
pattern rewriting driver of the erased ops). Use this to remove trivial
else blocks in affine.if ops.
Differential Revision: https://reviews.llvm.org/D77083
Added:
Modified:
mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
mlir/include/mlir/IR/PatternMatch.h
mlir/include/mlir/Transforms/DialectConversion.h
mlir/lib/Dialect/Affine/IR/AffineOps.cpp
mlir/lib/IR/PatternMatch.cpp
mlir/lib/Transforms/DialectConversion.cpp
mlir/test/Transforms/canonicalize.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
index aedd21d3f6e7..d30e6b26ff2c 100644
--- a/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
+++ b/mlir/include/mlir/Dialect/Affine/IR/AffineOps.td
@@ -359,6 +359,7 @@ def AffineIfOp : Affine_Op<"if",
}
}];
+ let hasCanonicalizer = 1;
let hasFolder = 1;
}
diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h
index bab479bfbb61..ef3c9fa62aa8 100644
--- a/mlir/include/mlir/IR/PatternMatch.h
+++ b/mlir/include/mlir/IR/PatternMatch.h
@@ -280,6 +280,9 @@ class PatternRewriter : public OpBuilder {
/// This method erases an operation that is known to have no uses.
virtual void eraseOp(Operation *op);
+ /// This method erases all operations in a block.
+ virtual void eraseBlock(Block *block);
+
/// Merge the operations of block 'source' into the end of block 'dest'.
/// 'source's predecessors must either be empty or only contain 'dest`.
/// 'argValues' is used to replace the block arguments of 'source' after
diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h
index 9ab3a715e0ab..1c2fc74e570b 100644
--- a/mlir/include/mlir/Transforms/DialectConversion.h
+++ b/mlir/include/mlir/Transforms/DialectConversion.h
@@ -344,6 +344,10 @@ class ConversionPatternRewriter final : public PatternRewriter {
/// otherwise an assert will be issued.
void eraseOp(Operation *op) override;
+ /// PatternRewriter hook for erase all operations in a block. This is not yet
+ /// implemented for dialect conversion.
+ void eraseBlock(Block *block) override;
+
/// PatternRewriter hook for creating a new block with the given arguments.
Block *createBlock(Region *parent, Region::iterator insertPt = {},
TypeRange argTypes = llvm::None) override;
diff --git a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
index a92c621fa96e..6d0c4e9e93ad 100644
--- a/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
+++ b/mlir/lib/Dialect/Affine/IR/AffineOps.cpp
@@ -79,8 +79,8 @@ AffineDialect::AffineDialect(MLIRContext *context)
/// Materialize a single constant operation from a given attribute value with
/// the desired resultant type.
Operation *AffineDialect::materializeConstant(OpBuilder &builder,
- Attribute value, Type type,
- Location loc) {
+ Attribute value, Type type,
+ Location loc) {
return builder.create<ConstantOp>(loc, type, value);
}
@@ -1569,6 +1569,24 @@ void mlir::extractForInductionVars(ArrayRef<AffineForOp> forInsts,
// AffineIfOp
//===----------------------------------------------------------------------===//
+namespace {
+/// Remove else blocks that have nothing other than the terminator.
+struct SimplifyDeadElse : public OpRewritePattern<AffineIfOp> {
+ using OpRewritePattern<AffineIfOp>::OpRewritePattern;
+
+ LogicalResult matchAndRewrite(AffineIfOp ifOp,
+ PatternRewriter &rewriter) const override {
+ if (ifOp.elseRegion().empty() || !has_single_element(*ifOp.getElseBlock()))
+ return failure();
+
+ rewriter.startRootUpdate(ifOp);
+ rewriter.eraseBlock(ifOp.getElseBlock());
+ rewriter.finalizeRootUpdate(ifOp);
+ return success();
+ }
+};
+} // end anonymous namespace.
+
static LogicalResult verify(AffineIfOp op) {
// Verify that we have a condition attribute.
auto conditionAttr =
@@ -1713,6 +1731,11 @@ LogicalResult AffineIfOp::fold(ArrayRef<Attribute>,
return failure();
}
+void AffineIfOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
+ MLIRContext *context) {
+ results.insert<SimplifyDeadElse>(context);
+}
+
//===----------------------------------------------------------------------===//
// AffineLoadOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/IR/PatternMatch.cpp b/mlir/lib/IR/PatternMatch.cpp
index 7d9fd5dd3c87..faf30dca4cfe 100644
--- a/mlir/lib/IR/PatternMatch.cpp
+++ b/mlir/lib/IR/PatternMatch.cpp
@@ -89,6 +89,14 @@ void PatternRewriter::eraseOp(Operation *op) {
op->erase();
}
+void PatternRewriter::eraseBlock(Block *block) {
+ for (auto &op : llvm::make_early_inc_range(llvm::reverse(*block))) {
+ assert(op.use_empty() && "expected 'op' to have no uses");
+ eraseOp(&op);
+ }
+ block->erase();
+}
+
/// Merge the operations of block 'source' into the end of block 'dest'.
/// 'source's predecessors must be empty or only contain 'dest`.
/// 'argValues' is used to replace the block arguments of 'source' after
diff --git a/mlir/lib/Transforms/DialectConversion.cpp b/mlir/lib/Transforms/DialectConversion.cpp
index 725f5f4bb16e..ab6924f091ad 100644
--- a/mlir/lib/Transforms/DialectConversion.cpp
+++ b/mlir/lib/Transforms/DialectConversion.cpp
@@ -895,6 +895,10 @@ void ConversionPatternRewriter::eraseOp(Operation *op) {
impl->replaceOp(op, nullRepls);
}
+void ConversionPatternRewriter::eraseBlock(Block *block) {
+ llvm_unreachable("erasing blocks for dialect conversion not implemented");
+}
+
/// Apply a signature conversion to the entry block of the given region.
Block *ConversionPatternRewriter::applySignatureConversion(
Region *region, TypeConverter::SignatureConversion &conversion) {
diff --git a/mlir/test/Transforms/canonicalize.mlir b/mlir/test/Transforms/canonicalize.mlir
index 5e54c6262562..52f6c410f484 100644
--- a/mlir/test/Transforms/canonicalize.mlir
+++ b/mlir/test/Transforms/canonicalize.mlir
@@ -895,3 +895,25 @@ func @index_cast_fold() -> (i16, index) {
// CHECK: return %[[C4_I16]], %[[C4]] : i16, index
return %1, %2 : i16, index
}
+
+// CHECK-LABEL: func @remove_dead_else
+func @remove_dead_else(%M : memref<100 x i32>) {
+ affine.for %i = 0 to 100 {
+ affine.load %M[%i] : memref<100xi32>
+ affine.if affine_set<(d0) : (d0 - 2 >= 0)>(%i) {
+ affine.for %j = 0 to 100 {
+ affine.load %M[%j] : memref<100xi32>
+ }
+ } else {
+ // Nothing
+ }
+ affine.load %M[%i] : memref<100xi32>
+ }
+ return
+}
+// CHECK: affine.if
+// CHECK-NEXT: affine.for
+// CHECK-NEXT: affine.load
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: affine.load
More information about the Mlir-commits
mailing list