Skip to content

Commit a9cff97

Browse files
[mlir][SCF] Generalize AffineMinSCFCanonicalization to min/max ops
* Add support for affine.max ops to SCF loop peeling pattern. * Add support for affine.max ops to `AffineMinSCFCanonicalizationPattern`. * Rename `AffineMinSCFCanonicalizationPattern` to `AffineOpSCFCanonicalizationPattern`. * Rename `AffineMinSCFCanonicalization` pass to `SCFAffineOpCanonicalization`. Differential Revision: https://reviews.llvm.org/D108009
1 parent 90e0c65 commit a9cff97

File tree

6 files changed

+220
-129
lines changed

6 files changed

+220
-129
lines changed

mlir/include/mlir/Dialect/SCF/Passes.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ std::unique_ptr<Pass> createForLoopSpecializationPass();
2828
/// better vectorization.
2929
std::unique_ptr<Pass> createForLoopPeelingPass();
3030

31-
/// Creates a pass that canonicalizes affine.min ops in scf.for loops with
32-
/// known lower and upper bounds.
33-
std::unique_ptr<Pass> createAffineMinSCFCanonicalizationPass();
31+
/// Creates a pass that canonicalizes affine.min and affine.max operations
32+
/// inside of scf.for loops with known lower and upper bounds.
33+
std::unique_ptr<Pass> createSCFAffineOpCanonicalizationPass();
3434

3535
/// Creates a loop fusion pass which fuses parallel loops.
3636
std::unique_ptr<Pass> createParallelLoopFusionPass();

mlir/include/mlir/Dialect/SCF/Passes.td

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ def SCFBufferize : FunctionPass<"scf-bufferize"> {
1919

2020
// Note: Making this a canonicalization pattern would require a dependency
2121
// of the SCF dialect on the Affine dialect or vice versa.
22-
def AffineMinSCFCanonicalization
23-
: FunctionPass<"canonicalize-scf-affine-min"> {
24-
let summary = "Canonicalize affine.min ops in the context of SCF loops with "
25-
"known bounds";
26-
let constructor = "mlir::createAffineMinSCFCanonicalizationPass()";
22+
def SCFAffineOpCanonicalization
23+
: FunctionPass<"canonicalize-scf-affine-op"> {
24+
let summary = "Canonicalize affine.min and affine.max ops in the context of "
25+
"SCF loops with known bounds";
26+
let constructor = "mlir::createSCFAffineOpCanonicalizationPass()";
2727
let dependentDialects = ["AffineDialect"];
2828
}
2929

mlir/include/mlir/Dialect/SCF/Transforms.h

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
namespace mlir {
2020

21-
class AffineMinOp;
21+
class AffineMap;
2222
class ConversionTarget;
2323
struct LogicalResult;
2424
class MLIRContext;
@@ -29,6 +29,7 @@ class RewritePatternSet;
2929
using OwningRewritePatternList = RewritePatternSet;
3030
class Operation;
3131
class Value;
32+
class ValueRange;
3233

3334
namespace scf {
3435

@@ -37,20 +38,28 @@ class ForOp;
3738
class ParallelOp;
3839
class ForOp;
3940

40-
/// Try to canonicalize an affine.min operation in the context of `for` loops
41-
/// with a known range.
41+
/// Match "for loop"-like operations: If the first parameter is an iteration
42+
/// variable, return lower/upper bounds via the second/third parameter and the
43+
/// step size via the last parameter. The function should return `success` in
44+
/// that case. If the first parameter is not an iteration variable, return
45+
/// `failure`.
46+
using LoopMatcherFn =
47+
function_ref<LogicalResult(Value, Value &, Value &, Value &)>;
48+
49+
/// Try to canonicalize an min/max operations in the context of for `loops` with
50+
/// a known range.
4251
///
43-
/// `loopMatcher` is used to retrieve loop bounds and step size for a given
44-
/// iteration variable: If the first parameter is an iteration variable, return
45-
/// lower/upper bounds via the second/third parameter and the step size via the
46-
/// last parameter. The function should return `success` in that case. If the
47-
/// first parameter is not an iteration variable, return `failure`.
52+
/// `map` is the body of the min/max operation and `operands` are the SSA values
53+
/// that the dimensions and symbols are bound to; dimensions are listed first.
54+
/// If `isMin`, the operation is a min operation; otherwise, a max operation.
55+
/// `loopMatcher` is used to retrieve loop bounds and the step size for a given
56+
/// iteration variable.
4857
///
4958
/// Note: `loopMatcher` allows this function to be used with any "for loop"-like
5059
/// operation (scf.for, scf.parallel and even ops defined in other dialects).
51-
LogicalResult canonicalizeAffineMinOpInLoop(
52-
AffineMinOp minOp, RewriterBase &rewriter,
53-
function_ref<LogicalResult(Value, Value &, Value &, Value &)> loopMatcher);
60+
LogicalResult canonicalizeMinMaxOpInLoop(RewriterBase &rewriter, Operation *op,
61+
AffineMap map, ValueRange operands,
62+
bool isMin, LoopMatcherFn loopMatcher);
5463

5564
/// Fuses all adjacent scf.parallel operations with identical bounds and step
5665
/// into one scf.parallel operations. Uses a naive aliasing and dependency
@@ -85,10 +94,10 @@ void naivelyFuseParallelOps(Region &region);
8594
/// ```
8695
///
8796
/// After loop peeling, this function tries to simplify/canonicalize affine.min
88-
/// operations in the body of the loop and the scf.if, taking advantage of the
89-
/// fact that every iteration of the peeled loop is a "full" iteration. This
90-
/// canonicalization is expected to enable further canonicalization
91-
/// opportunities through other patterns.
97+
/// and affine.max ops in the body of the loop and the scf.if, taking advantage
98+
/// of the fact that the peeled loop has only "full" iterations and the scf.if
99+
/// is always a partial iteration (if any). This canonicalization is expected to
100+
/// enable further canonicalization opportunities through other patterns.
92101
///
93102
/// The return value indicates whether the loop was rewritten or not. Loops are
94103
/// not rewritten if:
@@ -168,7 +177,7 @@ void populateSCFLoopPipeliningPatterns(RewritePatternSet &patterns,
168177
const PipeliningOption &options);
169178

170179
/// Populate patterns for canonicalizing operations inside SCF loop bodies.
171-
/// At the moment, only affine.min computations with iteration variables,
180+
/// At the moment, only affine.min/max computations with iteration variables,
172181
/// loop bounds and loop steps are canonicalized.
173182
void populateSCFLoopBodyCanonicalizationPatterns(RewritePatternSet &patterns);
174183

0 commit comments

Comments
 (0)