20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SmallVector.h"
24#define GEN_PASS_DEF_LINALGFOLDINTOELEMENTWISEPASS
25#include "mlir/Dialect/Linalg/Passes.h.inc"
31#define DEBUG_TYPE "linalg-fold-into-elementwise"
34template <
typename ProducerOpTy>
35struct ElementwiseOpFolder {
43 newIns.push_back(producerOp.getInput());
46 producerOp.getMatchingIndexingMap(producerOp.getDpsInputOperand(0))
52template <
typename... ProducerOps>
56 LogicalResult matchAndRewrite(LinalgOp op,
58 if (!isa<GenericOp, ElementwiseOp>(op.getOperation()) || !
isElementwise(op))
64 for (
OpOperand *operand : op.getDpsInputOperands()) {
65 AffineMap consumerMap = op.getMatchingIndexingMap(operand);
66 const bool folded = (ElementwiseOpFolder<ProducerOps>::fold(
67 operand, consumerMap, newIns, newMaps) ||
73 newIns.push_back(operand->get());
74 newMaps.push_back(consumerMap);
82 newMaps.append(originalMaps.begin() + op.getNumDpsInputs(),
94 for (
auto [
index, operand] : llvm::enumerate(op.getDpsInputOperands()))
95 op->setOperand(operand->getOperandNumber(), newIns[
index]);
102struct LinalgFoldIntoElementwisePass
104 LinalgFoldIntoElementwisePass> {
106 LinalgFoldIntoElementwisePass>::LinalgFoldIntoElementwisePassBase;
108 void runOnOperation()
override {
114 return signalPassFailure();
121 patterns.
add<FoldIntoElementwisePattern<TransposeOp, BroadcastOp>>(
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
bool isProjectedPermutation(bool allowZeroInResults=false) const
Returns true if the AffineMap represents a subset (i.e.
ArrayAttr getAffineMapArrayAttr(ArrayRef< AffineMap > values)
IRValueT get() const
Return the current value being used by this operand.
This class represents an operand of an operation.
Operation is the basic unit of execution within MLIR.
MLIRContext * getContext()
Return the context this operation is associated with.
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
void modifyOpInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around an in-place modification of an operation.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
void populateLinalgFoldIntoElementwisePatterns(RewritePatternSet &patterns)
Populates patterns with patterns that fold operations like linalg.transform into elementwise op map.
bool isElementwise(LinalgOp op)
Check if a LinalgOp is an element-wise operation.
Include the generated interface declarations.
AffineMap concatAffineMaps(ArrayRef< AffineMap > maps, MLIRContext *context)
Concatenates a list of maps into a single AffineMap, stepping over potentially empty maps.
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
AffineMap inversePermutation(AffineMap map)
Returns a map of codomain to domain dimensions such that the first codomain dimension for a particula...
OpInterfaceRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting a...