}
namespace {
+/// This is a pattern to fold trivially empty loops.
+struct AffineForEmptyLoopFolder : public OpRewritePattern<AffineForOp> {
+ using OpRewritePattern<AffineForOp>::OpRewritePattern;
+
+ PatternMatchResult matchAndRewrite(AffineForOp forOp,
+ PatternRewriter &rewriter) const override {
+ // Check that the body only contains a terminator.
+ auto *body = forOp.getBody();
+ if (std::next(body->begin()) != body->end())
+ return matchFailure();
+ rewriter.replaceOp(forOp, llvm::None);
+ return matchSuccess();
+ }
+};
+
/// This is a pattern to fold constant loop bounds.
struct AffineForLoopBoundFolder : public OpRewritePattern<AffineForOp> {
using OpRewritePattern<AffineForOp>::OpRewritePattern;
void AffineForOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
MLIRContext *context) {
- results.insert<AffineForLoopBoundFolder>(context);
+ results.insert<AffineForEmptyLoopFolder, AffineForLoopBoundFolder>(context);
}
AffineBound AffineForOp::getLowerBound() {
// CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
// CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %cst = constant 7.000000e+00 : f32
// CHECK-NEXT: %cst_0 = constant 8.000000e+00 : f32
// CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %3 = affine.load %1[%arg0] : memref<10xf32>
// CHECK-NEXT: %4 = addf %2, %3 : f32
// CHECK-NEXT: affine.store %4, %0[%arg0] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
-
func @invariant_code_inside_affine_if() {
%m = alloc() : memref<10xf32>
%cf8 = constant 8.0 : f32
// CHECK-NEXT: %2 = addf %cst, %cst : f32
// CHECK-NEXT: affine.store %2, %0[%arg0] : memref<10xf32>
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
// CHECK-NEXT: %2 = addf %cst, %cst : f32
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
-
+
// CHECK-NEXT: affine.for %arg1 = 0 to 10 {
// CHECK-NEXT: affine.store %2, %0[%arg1] : memref<10xf32>
// CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %2 = addf %cst, %cst : f32
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
// CHECK-NEXT: affine.for %arg1 = 0 to 10 {
- // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
+ // CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
// CHECK-NEXT: affine.store %2, %0[%arg1] : memref<10xf32>
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
// CHECK-NEXT: affine.for %arg1 = 0 to 10 {
// CHECK-NEXT: affine.store %1, %0[%arg1] : memref<10xf32>
- // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+ // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
+
return
}
// CHECK-NEXT: %1 = addf %cst, %cst_0 : f32
// CHECK-NEXT: %2 = addf %cst, %cst : f32
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
- // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
+ // CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
// CHECK-NEXT: affine.for %arg1 = 0 to 10 {
- // CHECK-NEXT: %4 = affine.load %0[%arg1] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+ // CHECK-NEXT: %4 = affine.load %0[%arg1] : memref<10xf32>
+
return
}
// CHECK-NEXT: %1 = addf %cst, %cst : f32
// CHECK-NEXT: affine.store %1, %0[%arg0] : memref<10xf32>
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: affine.store %1, %0[%arg1] : memref<10xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %4 = affine.load %0[%arg0] : memref<10xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %3 = affine.load %0[%arg0] : memref<10xf32>
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %2 = affine.load %1[%c0] : memref<100xf32>
// CHECK-NEXT: affine.for %arg0 = 0 to 5 {
// CHECK-NEXT: affine.store %2, %0[%arg0] : memref<100xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: %1 = affine.load %0[%c0] : memref<10xf32>
// CHECK-NEXT: affine.for %arg1 = 0 to 10 {
// CHECK-NEXT: affine.store %cst, %0[%arg1] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}
// CHECK-NEXT: affine.for %arg0 = 0 to 10 {
// CHECK-NEXT: affine.store %cst, %0[%c0] : memref<10xf32>
// CHECK-NEXT: %1 = affine.load %0[%arg0] : memref<10xf32>
- // CHECK-NEXT: }
- // CHECK-NEXT: return
+
return
}