54 if (blockingUses.size() != 1)
56 Value blockingUse = (*blockingUses.begin())->get();
57 if (blockingUse != slot.
ptr || xferOp.getBase() != slot.
ptr)
61 if (!isa<MemRefType>(xferOp.getBase().getType()))
65 if (xferOp.getVectorType() != slot.
elemType)
71 if (!constIndex || *constIndex != 0)
76 if (!xferOp.getPermutationMap().isIdentity())
83 if (xferOp.hasOutOfBoundsDim())
99struct TransferReadOpMemOpModel
100 :
public PromotableMemOpInterface::ExternalModel<TransferReadOpMemOpModel,
101 vector::TransferReadOp> {
102 bool loadsFrom(Operation *op,
const MemorySlot &slot)
const {
103 return cast<vector::TransferReadOp>(op).getBase() == slot.
ptr;
106 bool storesTo(Operation *op,
const MemorySlot &slot)
const {
return false; }
108 Value getStored(Operation *op,
const MemorySlot &slot, OpBuilder &builder,
109 Value reachingDef,
const DataLayout &dataLayout)
const {
110 llvm_unreachable(
"getStored should not be called on TransferReadOp");
113 bool canUsesBeRemoved(Operation *op,
const MemorySlot &slot,
114 const SmallPtrSetImpl<OpOperand *> &blockingUses,
115 SmallVectorImpl<OpOperand *> &newBlockingUses,
116 const DataLayout &dataLayout)
const {
122 removeBlockingUses(Operation *op,
const MemorySlot &slot,
123 const SmallPtrSetImpl<OpOperand *> &blockingUses,
124 OpBuilder &builder, Value reachingDefinition,
125 const DataLayout &dataLayout)
const {
128 cast<vector::TransferReadOp>(op).getVector().replaceAllUsesWith(
130 return DeletionKind::Delete;
134struct TransferWriteOpMemOpModel
135 :
public PromotableMemOpInterface::ExternalModel<TransferWriteOpMemOpModel,
136 vector::TransferWriteOp> {
137 bool loadsFrom(Operation *op,
const MemorySlot &slot)
const {
return false; }
139 bool storesTo(Operation *op,
const MemorySlot &slot)
const {
140 return cast<vector::TransferWriteOp>(op).getBase() == slot.
ptr;
143 Value getStored(Operation *op,
const MemorySlot &slot, OpBuilder &builder,
144 Value reachingDef,
const DataLayout &dataLayout)
const {
145 return cast<vector::TransferWriteOp>(op).getValueToStore();
148 bool canUsesBeRemoved(Operation *op,
const MemorySlot &slot,
149 const SmallPtrSetImpl<OpOperand *> &blockingUses,
150 SmallVectorImpl<OpOperand *> &newBlockingUses,
151 const DataLayout &dataLayout)
const {
158 removeBlockingUses(Operation *op,
const MemorySlot &slot,
159 const SmallPtrSetImpl<OpOperand *> &blockingUses,
160 OpBuilder &builder, Value reachingDefinition,
161 const DataLayout &dataLayout)
const {
162 return DeletionKind::Delete;
180static std::optional<SmallVector<int64_t>>
182 auto srcType = dyn_cast<MemRefType>(subView.getSource().getType());
183 auto resType = dyn_cast<MemRefType>(subView.getResult().getType());
184 if (!srcType || !resType || !srcType.hasStaticShape() ||
185 !resType.hasStaticShape())
189 if (srcType.getRank() != resType.getRank())
205 offsets.push_back(*o);
210 for (
auto [size, dim] :
211 llvm::zip_equal(subView.getMixedSizes(), resType.getShape())) {
225struct SubViewOpAliasModel
226 :
public PromotableAliaserInterface::ExternalModel<SubViewOpAliasModel,
228 void getPromotableSlotAliases(Operation *op,
229 OpOperand &aliasedSlotPointerOperand,
230 const MemorySlot &parentSlot,
231 SmallVectorImpl<MemorySlot> &newSlots)
const {
232 auto subView = cast<memref::SubViewOp>(op);
233 if (aliasedSlotPointerOperand.
get() != subView.getSource())
238 auto parentVecType = dyn_cast<VectorType>(parentSlot.
elemType);
246 auto resType = cast<MemRefType>(subView.getResult().getType());
247 if (!VectorType::isValidElementType(resType.getElementType()))
249 VectorType aliasVecType =
250 VectorType::get(resType.getShape(), resType.getElementType());
251 newSlots.push_back(MemorySlot{subView.getResult(), aliasVecType});
254 Value projectSlotValueToAliasValue(Operation *op,
257 const MemorySlot &aliasSlot,
259 OpBuilder &builder)
const {
260 auto subView = cast<memref::SubViewOp>(op);
262 auto aliasVecType = cast<VectorType>(aliasSlot.
elemType);
263 SmallVector<int64_t> strides(offsets.size(), 1);
264 return vector::ExtractStridedSliceOp::create(
265 builder, op->
getLoc(), slotValue, offsets,
266 aliasVecType.getShape(), strides)
270 Value projectAliasValueToSlotValue(Operation *op,
274 Value aliasValue, Value reachingDef,
275 OpBuilder &builder)
const {
276 auto subView = cast<memref::SubViewOp>(op);
278 SmallVector<int64_t> strides(offsets.size(), 1);
279 return vector::InsertStridedSliceOp::create(
280 builder, op->
getLoc(), aliasValue, reachingDef, offsets, strides)
287struct SubViewOpPromotableModel
288 :
public PromotableOpInterface::ExternalModel<SubViewOpPromotableModel,
290 bool canUsesBeRemoved(Operation *op,
291 const SmallPtrSetImpl<OpOperand *> &blockingUses,
292 SmallVectorImpl<OpOperand *> &newBlockingUses,
293 const DataLayout &dataLayout)
const {
297 newBlockingUses.push_back(&use);
302 removeBlockingUses(Operation *op,
303 const SmallPtrSetImpl<OpOperand *> &blockingUses,
304 OpBuilder &builder)
const {
305 return DeletionKind::Delete;
318 TransferReadOp::attachInterface<TransferReadOpMemOpModel>(*ctx);
319 TransferWriteOp::attachInterface<TransferWriteOpMemOpModel>(*ctx);
324 memref::SubViewOp::attachInterface<SubViewOpAliasModel>(*ctx);
325 memref::SubViewOp::attachInterface<SubViewOpPromotableModel>(*ctx);
static std::optional< SmallVector< int64_t > > getPromotableSubViewOffsets(memref::SubViewOp subView)
Returns the offsets of subView as a static, contiguous, same-rank slice of its source,...
static bool isWholeBufferTransfer(VectorTransferOpInterface xferOp, const MemorySlot &slot, const SmallPtrSetImpl< OpOperand * > &blockingUses)
Returns whether xferOp accesses exactly the whole contents of slot, so it can act as a plain whole-bu...
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
IRValueT get() const
Return the current value being used by this operand.
MLIRContext is the top-level object for a collection of MLIR operations.
This class represents a single result from folding an 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.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
use_range getUses() const
Returns a range of all uses, which is useful for iterating over all uses.
void registerMemorySlotOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.
std::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
DeletionKind
Returned by operation promotion logic requesting the deletion of an operation.
Represents a slot in memory.
Value ptr
Pointer to the memory slot, used by operations to refer to it.
Type elemType
Type of the value contained in the slot.