19#include "llvm/Support/Casting.h"
31struct MoveAccumulatorForContractLoop
33 using OpRewritePattern<vector::ContractionOp>::OpRewritePattern;
35 LogicalResult matchAndRewrite(vector::ContractionOp contractOp,
36 PatternRewriter &rewriter)
const override {
38 if (contractOp.getKind() != vector::CombiningKind::ADD)
40 "Expects add combining kind.");
42 Operation *accReadOp =
49 contractOp,
"Final acc write might have multiple users.");
51 Operation *resultUserOp = *contractValue.
getUsers().begin();
53 if (!accReadOp || !resultUserOp)
55 contractOp,
"Read from acc matrix is not by "
56 "transfer_read/load/constant_zero or multiple users of "
57 "contract operation.");
59 if (isa<arith::ConstantOp>(accReadOp))
62 "The input acc to contract is already a constant vector.");
64 if ((accReadOp->
getBlock() == contractOp->getBlock()) ||
65 (resultUserOp->
getBlock() == contractOp->getBlock()))
67 contractOp,
"Acc read/write should be in a separate block.");
73 contractOp,
"The input accumulator has multiple users.");
75 Operation *firstUser = *accValue.
getUsers().begin();
78 auto vecTy = dyn_cast<VectorType>(accValue.
getType());
82 Location loc = accReadOp->
getLoc();
83 Type elemTy = vecTy.getElementType();
85 Value zeroVec = arith::ConstantOp::create(
94 Location locUser = resultUserOp->
getLoc();
98 if (isa<FloatType>(elemTy)) {
100 arith::AddFOp::create(rewriter, locUser, contractValue, accValue);
101 }
else if (isa<IntegerType>(elemTy)) {
103 arith::AddIOp::create(rewriter, locUser, contractValue, accValue);
105 llvm_unreachable(
"expected floating-point or integer element type");
117 patterns.
add<MoveAccumulatorForContractLoop>(patterns.
getContext());
TypedAttr getZeroAttr(Type type)
static DenseElementsAttr get(ShapedType type, ArrayRef< Attribute > values)
Constructs a dense elements attribute from an array of element values.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void replaceUsesOfWith(Value from, Value to)
Replace any uses of 'from' with 'to' within this operation.
Block * getBlock()
Returns the operation block that contains this operation.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
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,...
Type getType() const
Return the type of this value.
void replaceAllUsesWith(Value newValue)
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
user_range getUsers() const
bool hasOneUse() const
Returns true if this value has exactly one use.
Value contractionUsersAfterYield(Value v)
Operation * traceToVectorReadLikeParentOperation(Value v)
void populateMoveAccumulatorForContractLoopPatterns(RewritePatternSet &patterns)
Include the generated interface declarations.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...