1 //===- PatternMatch.cpp - Base classes for pattern match ------------------===//
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 #include "mlir/IR/PatternMatch.h"
10 #include "mlir/IR/BlockAndValueMapping.h"
11 #include "mlir/IR/Operation.h"
12 #include "mlir/IR/Value.h"
13 
14 using namespace mlir;
15 
16 PatternBenefit::PatternBenefit(unsigned benefit) : representation(benefit) {
17   assert(representation == benefit && benefit != ImpossibleToMatchSentinel &&
18          "This pattern match benefit is too large to represent");
19 }
20 
21 unsigned short PatternBenefit::getBenefit() const {
22   assert(!isImpossibleToMatch() && "Pattern doesn't match");
23   return representation;
24 }
25 
26 //===----------------------------------------------------------------------===//
27 // Pattern implementation
28 //===----------------------------------------------------------------------===//
29 
30 Pattern::Pattern(StringRef rootName, PatternBenefit benefit,
31                  MLIRContext *context)
32     : rootKind(OperationName(rootName, context)), benefit(benefit) {}
33 Pattern::Pattern(PatternBenefit benefit, MatchAnyOpTypeTag)
34     : benefit(benefit) {}
35 
36 // Out-of-line vtable anchor.
37 void Pattern::anchor() {}
38 
39 //===----------------------------------------------------------------------===//
40 // RewritePattern and PatternRewriter implementation
41 //===----------------------------------------------------------------------===//
42 
43 void RewritePattern::rewrite(Operation *op, PatternRewriter &rewriter) const {
44   llvm_unreachable("need to implement either matchAndRewrite or one of the "
45                    "rewrite functions!");
46 }
47 
48 LogicalResult RewritePattern::match(Operation *op) const {
49   llvm_unreachable("need to implement either match or matchAndRewrite!");
50 }
51 
52 RewritePattern::RewritePattern(StringRef rootName,
53                                ArrayRef<StringRef> generatedNames,
54                                PatternBenefit benefit, MLIRContext *context)
55     : Pattern(rootName, benefit, context) {
56   generatedOps.reserve(generatedNames.size());
57   std::transform(generatedNames.begin(), generatedNames.end(),
58                  std::back_inserter(generatedOps), [context](StringRef name) {
59                    return OperationName(name, context);
60                  });
61 }
62 RewritePattern::RewritePattern(ArrayRef<StringRef> generatedNames,
63                                PatternBenefit benefit, MLIRContext *context,
64                                MatchAnyOpTypeTag tag)
65     : Pattern(benefit, tag) {
66   generatedOps.reserve(generatedNames.size());
67   std::transform(generatedNames.begin(), generatedNames.end(),
68                  std::back_inserter(generatedOps), [context](StringRef name) {
69                    return OperationName(name, context);
70                  });
71 }
72 
73 PatternRewriter::~PatternRewriter() {
74   // Out of line to provide a vtable anchor for the class.
75 }
76 
77 /// This method performs the final replacement for a pattern, where the
78 /// results of the operation are updated to use the specified list of SSA
79 /// values.
80 void PatternRewriter::replaceOp(Operation *op, ValueRange newValues) {
81   // Notify the rewriter subclass that we're about to replace this root.
82   notifyRootReplaced(op);
83 
84   assert(op->getNumResults() == newValues.size() &&
85          "incorrect # of replacement values");
86   op->replaceAllUsesWith(newValues);
87 
88   notifyOperationRemoved(op);
89   op->erase();
90 }
91 
92 /// This method erases an operation that is known to have no uses. The uses of
93 /// the given operation *must* be known to be dead.
94 void PatternRewriter::eraseOp(Operation *op) {
95   assert(op->use_empty() && "expected 'op' to have no uses");
96   notifyOperationRemoved(op);
97   op->erase();
98 }
99 
100 void PatternRewriter::eraseBlock(Block *block) {
101   for (auto &op : llvm::make_early_inc_range(llvm::reverse(*block))) {
102     assert(op.use_empty() && "expected 'op' to have no uses");
103     eraseOp(&op);
104   }
105   block->erase();
106 }
107 
108 /// Merge the operations of block 'source' into the end of block 'dest'.
109 /// 'source's predecessors must be empty or only contain 'dest`.
110 /// 'argValues' is used to replace the block arguments of 'source' after
111 /// merging.
112 void PatternRewriter::mergeBlocks(Block *source, Block *dest,
113                                   ValueRange argValues) {
114   assert(llvm::all_of(source->getPredecessors(),
115                       [dest](Block *succ) { return succ == dest; }) &&
116          "expected 'source' to have no predecessors or only 'dest'");
117   assert(argValues.size() == source->getNumArguments() &&
118          "incorrect # of argument replacement values");
119 
120   // Replace all of the successor arguments with the provided values.
121   for (auto it : llvm::zip(source->getArguments(), argValues))
122     std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
123 
124   // Splice the operations of the 'source' block into the 'dest' block and erase
125   // it.
126   dest->getOperations().splice(dest->end(), source->getOperations());
127   source->dropAllUses();
128   source->erase();
129 }
130 
131 // Merge the operations of block 'source' before the operation 'op'. Source
132 // block should not have existing predecessors or successors.
133 void PatternRewriter::mergeBlockBefore(Block *source, Operation *op,
134                                        ValueRange argValues) {
135   assert(source->hasNoPredecessors() &&
136          "expected 'source' to have no predecessors");
137   assert(source->hasNoSuccessors() &&
138          "expected 'source' to have no successors");
139 
140   // Split the block containing 'op' into two, one containg all operations
141   // before 'op' (prologue) and another (epilogue) containing 'op' and all
142   // operations after it.
143   Block *prologue = op->getBlock();
144   Block *epilogue = splitBlock(prologue, op->getIterator());
145 
146   // Merge the source block at the end of the prologue.
147   mergeBlocks(source, prologue, argValues);
148 
149   // Merge the epilogue at the end the prologue.
150   mergeBlocks(epilogue, prologue);
151 }
152 
153 /// Split the operations starting at "before" (inclusive) out of the given
154 /// block into a new block, and return it.
155 Block *PatternRewriter::splitBlock(Block *block, Block::iterator before) {
156   return block->splitBlock(before);
157 }
158 
159 /// 'op' and 'newOp' are known to have the same number of results, replace the
160 /// uses of op with uses of newOp
161 void PatternRewriter::replaceOpWithResultsOfAnotherOp(Operation *op,
162                                                       Operation *newOp) {
163   assert(op->getNumResults() == newOp->getNumResults() &&
164          "replacement op doesn't match results of original op");
165   if (op->getNumResults() == 1)
166     return replaceOp(op, newOp->getResult(0));
167   return replaceOp(op, newOp->getResults());
168 }
169 
170 /// Move the blocks that belong to "region" before the given position in
171 /// another region.  The two regions must be different.  The caller is in
172 /// charge to update create the operation transferring the control flow to the
173 /// region and pass it the correct block arguments.
174 void PatternRewriter::inlineRegionBefore(Region &region, Region &parent,
175                                          Region::iterator before) {
176   parent.getBlocks().splice(before, region.getBlocks());
177 }
178 void PatternRewriter::inlineRegionBefore(Region &region, Block *before) {
179   inlineRegionBefore(region, *before->getParent(), before->getIterator());
180 }
181 
182 /// Clone the blocks that belong to "region" before the given position in
183 /// another region "parent". The two regions must be different. The caller is
184 /// responsible for creating or updating the operation transferring flow of
185 /// control to the region and passing it the correct block arguments.
186 void PatternRewriter::cloneRegionBefore(Region &region, Region &parent,
187                                         Region::iterator before,
188                                         BlockAndValueMapping &mapping) {
189   region.cloneInto(&parent, before, mapping);
190 }
191 void PatternRewriter::cloneRegionBefore(Region &region, Region &parent,
192                                         Region::iterator before) {
193   BlockAndValueMapping mapping;
194   cloneRegionBefore(region, parent, before, mapping);
195 }
196 void PatternRewriter::cloneRegionBefore(Region &region, Block *before) {
197   cloneRegionBefore(region, *before->getParent(), before->getIterator());
198 }
199 
200 //===----------------------------------------------------------------------===//
201 // PatternMatcher implementation
202 //===----------------------------------------------------------------------===//
203 
204 void PatternApplicator::applyCostModel(CostModel model) {
205   // Separate patterns by root kind to simplify lookup later on.
206   patterns.clear();
207   anyOpPatterns.clear();
208   for (const auto &pat : owningPatternList) {
209     // If the pattern is always impossible to match, just ignore it.
210     if (pat->getBenefit().isImpossibleToMatch())
211       continue;
212     if (Optional<OperationName> opName = pat->getRootKind())
213       patterns[*opName].push_back(pat.get());
214     else
215       anyOpPatterns.push_back(pat.get());
216   }
217 
218   // Sort the patterns using the provided cost model.
219   llvm::SmallDenseMap<RewritePattern *, PatternBenefit> benefits;
220   auto cmp = [&benefits](RewritePattern *lhs, RewritePattern *rhs) {
221     return benefits[lhs] > benefits[rhs];
222   };
223   auto processPatternList = [&](SmallVectorImpl<RewritePattern *> &list) {
224     // Special case for one pattern in the list, which is the most common case.
225     if (list.size() == 1) {
226       if (model(*list.front()).isImpossibleToMatch())
227         list.clear();
228       return;
229     }
230 
231     // Collect the dynamic benefits for the current pattern list.
232     benefits.clear();
233     for (RewritePattern *pat : list)
234       benefits.try_emplace(pat, model(*pat));
235 
236     // Sort patterns with highest benefit first, and remove those that are
237     // impossible to match.
238     std::stable_sort(list.begin(), list.end(), cmp);
239     while (!list.empty() && benefits[list.back()].isImpossibleToMatch())
240       list.pop_back();
241   };
242   for (auto &it : patterns)
243     processPatternList(it.second);
244   processPatternList(anyOpPatterns);
245 }
246 
247 void PatternApplicator::walkAllPatterns(
248     function_ref<void(const RewritePattern &)> walk) {
249   for (auto &it : owningPatternList)
250     walk(*it);
251 }
252 
253 LogicalResult PatternApplicator::matchAndRewrite(
254     Operation *op, PatternRewriter &rewriter,
255     function_ref<bool(const RewritePattern &)> canApply,
256     function_ref<void(const RewritePattern &)> onFailure,
257     function_ref<LogicalResult(const RewritePattern &)> onSuccess) {
258   // Check to see if there are patterns matching this specific operation type.
259   MutableArrayRef<RewritePattern *> opPatterns;
260   auto patternIt = patterns.find(op->getName());
261   if (patternIt != patterns.end())
262     opPatterns = patternIt->second;
263 
264   // Process the patterns for that match the specific operation type, and any
265   // operation type in an interleaved fashion.
266   // FIXME: It'd be nice to just write an llvm::make_merge_range utility
267   // and pass in a comparison function. That would make this code trivial.
268   auto opIt = opPatterns.begin(), opE = opPatterns.end();
269   auto anyIt = anyOpPatterns.begin(), anyE = anyOpPatterns.end();
270   while (opIt != opE && anyIt != anyE) {
271     // Try to match the pattern providing the most benefit.
272     RewritePattern *pattern;
273     if ((*opIt)->getBenefit() >= (*anyIt)->getBenefit())
274       pattern = *(opIt++);
275     else
276       pattern = *(anyIt++);
277 
278     // Otherwise, try to match the generic pattern.
279     if (succeeded(matchAndRewrite(op, *pattern, rewriter, canApply, onFailure,
280                                   onSuccess)))
281       return success();
282   }
283   // If we break from the loop, then only one of the ranges can still have
284   // elements. Loop over both without checking given that we don't need to
285   // interleave anymore.
286   for (RewritePattern *pattern : llvm::concat<RewritePattern *>(
287            llvm::make_range(opIt, opE), llvm::make_range(anyIt, anyE))) {
288     if (succeeded(matchAndRewrite(op, *pattern, rewriter, canApply, onFailure,
289                                   onSuccess)))
290       return success();
291   }
292   return failure();
293 }
294 
295 LogicalResult PatternApplicator::matchAndRewrite(
296     Operation *op, const RewritePattern &pattern, PatternRewriter &rewriter,
297     function_ref<bool(const RewritePattern &)> canApply,
298     function_ref<void(const RewritePattern &)> onFailure,
299     function_ref<LogicalResult(const RewritePattern &)> onSuccess) {
300   // Check that the pattern can be applied.
301   if (canApply && !canApply(pattern))
302     return failure();
303 
304   // Try to match and rewrite this pattern. The patterns are sorted by
305   // benefit, so if we match we can immediately rewrite.
306   rewriter.setInsertionPoint(op);
307   if (succeeded(pattern.matchAndRewrite(op, rewriter)))
308     return success(!onSuccess || succeeded(onSuccess(pattern)));
309 
310   if (onFailure)
311     onFailure(pattern);
312   return failure();
313 }
314