xref: /llvm-project/mlir/include/mlir/Dialect/SCF/Transforms/Patterns.h (revision 4751f47c7af63315565891a1d112376b52e6b826)
1 //===- Patterns.h - SCF dialect rewrite patterns ----------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef MLIR_DIALECT_SCF_TRANSFORMS_PATTERNS_H
10 #define MLIR_DIALECT_SCF_TRANSFORMS_PATTERNS_H
11 
12 #include "mlir/Dialect/SCF/IR/SCF.h"
13 #include "mlir/Dialect/SCF/Transforms/Transforms.h"
14 #include "mlir/IR/PatternMatch.h"
15 
16 namespace mlir {
17 
18 class ConversionTarget;
19 class TypeConverter;
20 
21 namespace scf {
22 
23 // TODO: such patterns should be auto-generated.
24 class ForLoopPipeliningPattern : public OpRewritePattern<ForOp> {
25 public:
26   ForLoopPipeliningPattern(const PipeliningOption &options,
27                            MLIRContext *context)
28       : OpRewritePattern<ForOp>(context), options(options) {}
29   LogicalResult matchAndRewrite(ForOp forOp,
30                                 PatternRewriter &rewriter) const override {
31     return returningMatchAndRewrite(forOp, rewriter);
32   }
33 
34   FailureOr<ForOp> returningMatchAndRewrite(ForOp forOp,
35                                             PatternRewriter &rewriter) const {
36     return pipelineForLoop(rewriter, forOp, options);
37   }
38 
39 protected:
40   PipeliningOption options;
41 };
42 
43 /// Populates patterns for SCF structural type conversions and sets up the
44 /// provided ConversionTarget with the appropriate legality configuration for
45 /// the ops to get converted properly.
46 ///
47 /// A "structural" type conversion is one where the underlying ops are
48 /// completely agnostic to the actual types involved and simply need to update
49 /// their types. An example of this is scf.if -- the scf.if op and the
50 /// corresponding scf.yield ops need to update their types accordingly to the
51 /// TypeConverter, but otherwise don't care what type conversions are happening.
52 void populateSCFStructuralTypeConversionsAndLegality(
53     const TypeConverter &typeConverter, RewritePatternSet &patterns,
54     ConversionTarget &target);
55 
56 /// Similar to `populateSCFStructuralTypeConversionsAndLegality` but does not
57 /// populate the conversion target.
58 void populateSCFStructuralTypeConversions(const TypeConverter &typeConverter,
59                                           RewritePatternSet &patterns);
60 
61 /// Updates the ConversionTarget with dynamic legality of SCF operations based
62 /// on the provided type converter.
63 void populateSCFStructuralTypeConversionTarget(
64     const TypeConverter &typeConverter, ConversionTarget &target);
65 
66 /// Populates the provided pattern set with patterns that do 1:N type
67 /// conversions on (some) SCF ops. This is intended to be used with
68 /// applyPartialOneToNConversion.
69 /// FIXME: The 1:N dialect conversion is deprecated and will be removed soon.
70 /// 1:N support has been added to the regular dialect conversion driver.
71 /// Use populateSCFStructuralTypeConversions() instead.
72 void populateSCFStructuralOneToNTypeConversions(
73     const TypeConverter &typeConverter, RewritePatternSet &patterns);
74 
75 /// Populate patterns for SCF software pipelining transformation. See the
76 /// ForLoopPipeliningPattern for the transformation details.
77 void populateSCFLoopPipeliningPatterns(RewritePatternSet &patterns,
78                                        const PipeliningOption &options);
79 
80 /// Populate patterns for canonicalizing operations inside SCF loop bodies.
81 /// At the moment, only affine.min/max computations with iteration variables,
82 /// loop bounds and loop steps are canonicalized.
83 void populateSCFForLoopCanonicalizationPatterns(RewritePatternSet &patterns);
84 
85 /// Populate patterns to uplift `scf.while` ops to `scf.for`.
86 /// Uplifitng expects a specific ops pattern:
87 ///  * `before` block consisting of single arith.cmp op
88 ///  * `after` block containing arith.addi
89 void populateUpliftWhileToForPatterns(RewritePatternSet &patterns);
90 
91 /// Populate patterns to rotate `scf.while` ops, constructing `do-while` loops
92 /// from `while` loops.
93 void populateSCFRotateWhileLoopPatterns(RewritePatternSet &patterns);
94 } // namespace scf
95 } // namespace mlir
96 
97 #endif // MLIR_DIALECT_SCF_TRANSFORMS_PATTERNS_H
98