21#include "llvm/ADT/ArrayRef.h"
32LogicalResult SimplifyBoundedAffineOpsOp::verify() {
33 if (getLowerBounds().size() != getBoundedValues().size())
34 return emitOpError() <<
"incorrect number of lower bounds, expected "
35 << getBoundedValues().size() <<
" but found "
36 << getLowerBounds().size();
37 if (getUpperBounds().size() != getBoundedValues().size())
38 return emitOpError() <<
"incorrect number of upper bounds, expected "
39 << getBoundedValues().size() <<
" but found "
40 << getUpperBounds().size();
47template <
typename OpTy>
49 using OpRewritePattern<OpTy>::OpRewritePattern;
50 SimplifyAffineMinMaxOp(MLIRContext *ctx,
51 const FlatAffineValueConstraints &constraints,
52 PatternBenefit benefit = 1)
53 : OpRewritePattern<OpTy>(ctx, benefit), constraints(constraints) {}
55 LogicalResult matchAndRewrite(OpTy op,
56 PatternRewriter &rewriter)
const override {
57 FailureOr<AffineValueMap> simplified =
62 simplified->getOperands());
66 const FlatAffineValueConstraints &constraints;
79 for (
const auto &it : llvm::zip_equal(getBoundedValues(), getLowerBounds(),
81 Value handle = std::get<0>(it);
83 if (op->getNumResults() != 1 || !op->getResult(0).getType().isIndex()) {
86 <<
"expected bounded value handle to point to one or multiple "
87 "single-result index-typed ops";
88 diag.attachNote(op->getLoc()) <<
"multiple/non-index result";
91 boundedValues.push_back(op->getResult(0));
92 boundedOps.insert(op);
93 lbs.push_back(std::get<1>(it));
94 ubs.push_back(std::get<2>(it));
100 for (
const auto &it : llvm::zip(boundedValues, lbs, ubs)) {
102 if (!cstr.
findVar(std::get<0>(it), &pos))
112 if (!isa<AffineMinOp, AffineMaxOp>(
target)) {
114 <<
"target must be affine.min or affine.max";
115 diag.attachNote(
target->getLoc()) <<
"target op";
118 if (boundedOps.contains(
target)) {
120 <<
"target op result must not be constrained";
121 diag.attachNote(
target->getLoc()) <<
"target/constrained op";
124 targets.push_back(
target);
131 patterns.insert<SimplifyAffineMinMaxOp<AffineMinOp>,
132 SimplifyAffineMinMaxOp<AffineMaxOp>>(
getContext(), cstr);
136 targets, frozenPatterns,
142 <<
"affine.min/max simplification did not converge";
148void SimplifyBoundedAffineOpsOp::getEffects(
151 for (
OpOperand &operand : getBoundedValuesMutable())
160LogicalResult SuperVectorizeOp::verify() {
161 if (getFastestVaryingPattern().has_value()) {
162 if (getFastestVaryingPattern()->size() != getVectorSizes().size())
164 <<
"fastest varying pattern specified with different size than "
174 if (getFastestVaryingPattern().has_value())
175 fastestVaryingPattern = getFastestVaryingPattern().value();
178 if (!
target->getParentOfType<affine::AffineForOp>())
179 vectorizeChildAffineLoops(
target, getVectorizeReductions(),
180 getVectorSizes(), fastestVaryingPattern);
185void SuperVectorizeOp::getEffects(
200 if (!isa<AffineMinOp, AffineMaxOp>(
target)) {
202 <<
"target must be affine.min or affine.max";
203 diag.attachNote(
target->getLoc()) <<
"target op";
206 targets.push_back(
target);
208 bool modified =
false;
212 <<
"affine.min/max simplification did not converge";
215 return emitSilenceableError()
216 <<
"the transform failed to simplify any of the target operations";
221void SimplifyMinMaxAffineOpsOp::getEffects(
232class AffineTransformDialectExtension
234 AffineTransformDialectExtension> {
241 declareGeneratedDialect<AffineDialect>();
242 declareGeneratedDialect<vector::VectorDialect>();
244 registerTransformOps<
246#include "mlir/Dialect/Affine/TransformOps/AffineTransformOps.cpp.inc"
252#define GET_OP_CLASSES
253#include "mlir/Dialect/Affine/TransformOps/AffineTransformOps.cpp.inc"
p<< " : "<< getMemRefType()<< ", "<< getType();}static LogicalResult verifyVectorMemoryOp(Operation *op, MemRefType memrefType, VectorType vectorType) { if(memrefType.getElementType() !=vectorType.getElementType()) return op-> emitOpError("requires memref and vector types of the same elemental type")
Given a list of lists of parsed operands, populates uniqueOperands with unique operands.
static std::string diag(const llvm::Value &value)
#define MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(CLASS_NAME)
The result of a transform IR operation application.
static DiagnosedSilenceableFailure success()
Constructs a DiagnosedSilenceableFailure in the success state.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
void addExtensions()
Add the given extensions to the registry.
bool findVar(Value val, unsigned *pos, unsigned offset=0) const
Looks up the position of the variable with the specified Value starting with variables at offset offs...
unsigned appendSymbolVar(ValueRange vals)
This class represents a frozen set of patterns that can be processed by a pattern applicator.
This class allows control over how the GreedyPatternRewriteDriver works.
GreedyRewriteConfig & setStrictness(GreedyRewriteStrictness mode)
Listener * getListener() const
Returns the current listener of this builder, or nullptr if this builder doesn't have a listener.
This class represents an operand of an operation.
Operation is the basic unit of execution within MLIR.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
FlatAffineValueConstraints is an extension of FlatLinearValueConstraints with helper functions for Af...
LogicalResult addBound(presburger::BoundType type, unsigned pos, AffineMap boundMap, ValueRange operands)
Adds a bound for the variable at the specified position with constraints being drawn from the specifi...
Base class for extensions of the Transform dialect that supports injecting operations into the Transf...
void registerTransformDialectExtension(DialectRegistry ®istry)
LogicalResult simplifyAffineMinMaxOps(RewriterBase &rewriter, ArrayRef< Operation * > ops, bool *modified=nullptr)
This transform applies simplifyAffineMinOp and simplifyAffineMaxOp to all the affine....
FailureOr< AffineValueMap > simplifyConstrainedMinMaxOp(Operation *op, FlatAffineValueConstraints constraints)
Try to simplify the given affine.min or affine.max op to an affine map with a single result and opera...
Include the generated interface declarations.
llvm::DenseSet< ValueT, ValueInfoT > DenseSet
LogicalResult applyOpPatternsGreedily(ArrayRef< Operation * > ops, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr, bool *allErased=nullptr)
Rewrite the specified ops by repeatedly applying the highest benefit patterns in a greedy worklist dr...
DiagnosedDefiniteFailure emitDefiniteFailure(Location loc, const Twine &message={})
Emits a definite failure with the given message.
const FrozenRewritePatternSet & patterns
@ ExistingAndNewOps
Only pre-existing and newly created ops are processed.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...