32 .Case<linalg::FillOp, linalg::CopyOp>([&](
auto op) {
33 return op.getInputs().size() == 1 &&
isDefinedAsZero(op.getInputs()[0]);
35 .Default([&](
auto) {
return false; });
65 if (addOp.getKind() != linalg::ElementwiseKind::add)
69 if (!addOp.hasPureTensorSemantics())
72 Value dominatingOperand =
nullptr;
73 linalg::LinalgOp dominatedOp =
nullptr;
75 Value lhs = addOp.getInputs()[0];
76 Value rhs = addOp.getInputs()[1];
82 if (
auto rhsOp = rhs.getDefiningOp<linalg::LinalgOp>()) {
85 dominatingOperand = lhs;
89 if (
auto lhsOp = lhs.getDefiningOp<linalg::LinalgOp>()) {
92 dominatingOperand = rhs;
96 if (!dominatingOperand || !dominatedOp)
107 auto dominatedDestOp =
108 dyn_cast<DestinationStyleOpInterface>((
Operation *)dominatedOp);
109 if (dominatedOp->getNumResults() != 1 ||
111 (!dominatedDestOp || dominatedDestOp.getNumDpsInits() != 1))
113 dominatedOp,
"expected dominated op to be single-result "
114 "destination-passing contraction");
117 if (!dominatedOp->getResult(0).hasOneUse())
120 "expected elementwise add to be single user of contraction's result");
124 auto *destOperand = dominatedDestOp.getDpsInitOperand(0);
127 dominatedOp,
"expected dominated op's dest to be additive zero");
137 for (
auto expr : indexMaps[destOperand->getOperandNumber()].getResults()) {
138 auto dim = dyn_cast<AffineDimExpr>(expr);
139 if (!dim || prevDimPos >
static_cast<int>(dim.getPosition()))
141 dominatedOp,
"expected index_map for contraction's dest to be an "
142 "ordered projection");
143 prevDimPos = dim.getPosition();
150 dominatedOp, [&]() { dominatedOp->setOperand(2, dominatingOperand); });
static bool isDefinedAsZero(Value val)
A class for computing basic dominance information.
bool properlyDominates(Operation *a, Operation *b, bool enclosingOpOk=true) const
Return true if operation A properly dominates operation B, i.e.
Operation is the basic unit of execution within MLIR.
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.
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the listener that the IR failed to be rewritten because of a match failure,...
void modifyOpInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around an in-place modification of an operation.
void replaceAllOpUsesWith(Operation *from, ValueRange to)
Find uses of from and replace them with to.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
bool isaContractionOpInterface(LinalgOp linalgOp)
Checks whether linalgOp conforms to ContractionOpInterface.
void populateFoldAddIntoDestPatterns(RewritePatternSet &patterns)
Pattern to replace linalg.add when destination passing on a contraction op suffices for achieving the...
Include the generated interface declarations.
bool isZeroIntegerOrFloat(OpFoldResult v)
Return "true" if v is an integer/float value/attribute with constant value zero.
llvm::TypeSwitch< T, ResultT > TypeSwitch
Replace a linalg.elementwise kind=add with one operand the single user of a contraction,...
LogicalResult matchAndRewrite(linalg::ElementwiseOp addOp, PatternRewriter &rewriter) const override
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})