1 //===- GreedyPatternRewriteDriver.h - Greedy Pattern Driver -----*- 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 // This file declares methods for applying a set of patterns greedily, choosing
10 // the patterns with the highest local benefit, until a fixed point is reached.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_TRANSFORMS_GREEDYPATTERNREWRITEDRIVER_H_
15 #define MLIR_TRANSFORMS_GREEDYPATTERNREWRITEDRIVER_H_
16 
17 #include "mlir/Rewrite/FrozenRewritePatternSet.h"
18 
19 namespace mlir {
20 
21 /// This class allows control over how the GreedyPatternRewriteDriver works.
22 class GreedyRewriteConfig {
23 public:
24   /// This specifies the order of initial traversal that populates the rewriters
25   /// worklist.  When set to true, it walks the operations top-down, which is
26   /// generally more efficient in compile time.  When set to false, its initial
27   /// traversal of the region tree is bottom up on each block, which may match
28   /// larger patterns when given an ambiguous pattern set.
29   bool useTopDownTraversal = false;
30 
31   // Perform control flow optimizations to the region tree after applying all
32   // patterns.
33   bool enableRegionSimplification = true;
34 
35   /// This specifies the maximum number of times the rewriter will iterate
36   /// between applying patterns and simplifying regions. Use `kNoIterationLimit`
37   /// to disable this iteration limit.
38   int64_t maxIterations = 10;
39 
40   static constexpr int64_t kNoIterationLimit = -1;
41 };
42 
43 //===----------------------------------------------------------------------===//
44 // applyPatternsGreedily
45 //===----------------------------------------------------------------------===//
46 
47 /// Rewrite the regions of the specified operation, which must be isolated from
48 /// above, by repeatedly applying the highest benefit patterns in a greedy
49 /// work-list driven manner.
50 ///
51 /// This variant may stop after a predefined number of iterations, see the
52 /// alternative below to provide a specific number of iterations before stopping
53 /// in absence of convergence.
54 ///
55 /// Return success if the iterative process converged and no more patterns can
56 /// be matched in the result operation regions.
57 ///
58 /// Note: This does not apply patterns to the top-level operation itself.
59 ///       These methods also perform folding and simple dead-code elimination
60 ///       before attempting to match any of the provided patterns.
61 ///
62 /// You may configure several aspects of this with GreedyRewriteConfig.
63 LogicalResult applyPatternsAndFoldGreedily(
64     MutableArrayRef<Region> regions, const FrozenRewritePatternSet &patterns,
65     GreedyRewriteConfig config = GreedyRewriteConfig());
66 
67 /// Rewrite the given regions, which must be isolated from above.
68 inline LogicalResult applyPatternsAndFoldGreedily(
69     Operation *op, const FrozenRewritePatternSet &patterns,
70     GreedyRewriteConfig config = GreedyRewriteConfig()) {
71   return applyPatternsAndFoldGreedily(op->getRegions(), patterns, config);
72 }
73 
74 /// Applies the specified patterns on `op` alone while also trying to fold it,
75 /// by selecting the highest benefits patterns in a greedy manner. Returns
76 /// success if no more patterns can be matched. `erased` is set to true if `op`
77 /// was folded away or erased as a result of becoming dead. Note: This does not
78 /// apply any patterns recursively to the regions of `op`.
79 LogicalResult applyOpPatternsAndFold(Operation *op,
80                                      const FrozenRewritePatternSet &patterns,
81                                      bool *erased = nullptr);
82 
83 /// Applies the specified rewrite patterns on `ops` while also trying to fold
84 /// these ops as well as any other ops that were in turn created due to such
85 /// rewrites. Furthermore, any pre-existing ops in the IR outside of `ops`
86 /// remain completely unmodified if `strict` is set to true. If `strict` is
87 /// false, other operations that use results of rewritten ops or supply operands
88 /// to such ops are in turn simplified; any other ops still remain unmodified
89 /// (i.e., regardless of `strict`). Note that ops in `ops` could be erased as a
90 /// result of folding, becoming dead, or via pattern rewrites. If more far
91 /// reaching simplification is desired, applyPatternsAndFoldGreedily should be
92 /// used. Returns true if at all any IR was rewritten.
93 bool applyOpPatternsAndFold(ArrayRef<Operation *> ops,
94                             const FrozenRewritePatternSet &patterns,
95                             bool strict);
96 
97 } // namespace mlir
98 
99 #endif // MLIR_TRANSFORMS_GREEDYPATTERNREWRITEDRIVER_H_
100