59 if (blockingUses.size() != 1)
61 Value blockingUse = (*blockingUses.begin())->get();
62 if (blockingUse != slot.
ptr || xferOp.getBase() != slot.
ptr)
66 if (!isa<MemRefType>(xferOp.getBase().getType()))
70 if (xferOp.getVectorType() != slot.
valueType)
76 if (!constIndex || *constIndex != 0)
81 if (!xferOp.getPermutationMap().isIdentity())
97struct TransferReadOpMemOpModel
98 :
public PromotableMemOpInterface::ExternalModel<TransferReadOpMemOpModel,
99 vector::TransferReadOp> {
100 bool loadsFrom(Operation *op,
const MemorySlot &slot)
const {
101 return cast<vector::TransferReadOp>(op).getBase() == slot.
ptr;
104 bool storesTo(Operation *op,
const MemorySlot &slot)
const {
return false; }
106 Value getStored(Operation *op,
const MemorySlot &slot, OpBuilder &builder,
107 Value reachingDef,
const DataLayout &dataLayout)
const {
108 llvm_unreachable(
"getStored should not be called on TransferReadOp");
111 bool canUsesBeRemoved(Operation *op,
const MemorySlot &slot,
112 const SmallPtrSetImpl<OpOperand *> &blockingUses,
113 SmallVectorImpl<OpOperand *> &newBlockingUses,
114 const DataLayout &dataLayout)
const {
126 removeBlockingUses(Operation *op,
const MemorySlot &slot,
127 const SmallPtrSetImpl<OpOperand *> &blockingUses,
128 OpBuilder &builder, Value reachingDefinition,
129 const DataLayout &dataLayout)
const {
130 auto readOp = cast<vector::TransferReadOp>(op);
131 Location loc = op->
getLoc();
133 if (Value opMask = readOp.getMask())
135 ? arith::AndIOp::create(builder, loc, mask, opMask).getResult()
138 Value
result = reachingDefinition;
140 Value padSplat = vector::BroadcastOp::create(
141 builder, loc, readOp.getVectorType(), readOp.getPadding());
142 result = arith::SelectOp::create(builder, loc, mask, reachingDefinition,
146 return DeletionKind::Delete;
151struct TransferWriteOpMemOpModel
152 :
public PromotableMemOpInterface::ExternalModel<TransferWriteOpMemOpModel,
153 vector::TransferWriteOp> {
154 bool loadsFrom(Operation *op,
const MemorySlot &slot)
const {
return false; }
156 bool storesTo(Operation *op,
const MemorySlot &slot)
const {
157 return cast<vector::TransferWriteOp>(op).getBase() == slot.
ptr;
162 Value getStored(Operation *op,
const MemorySlot &slot, OpBuilder &builder,
163 Value reachingDef,
const DataLayout &dataLayout)
const {
164 auto writeOp = cast<vector::TransferWriteOp>(op);
165 Value stored = writeOp.getValueToStore();
168 if (Value mask = writeOp.getMask())
169 stored = arith::SelectOp::create(builder, op->
getLoc(), mask, stored,
174 bool canUsesBeRemoved(Operation *op,
const MemorySlot &slot,
175 const SmallPtrSetImpl<OpOperand *> &blockingUses,
176 SmallVectorImpl<OpOperand *> &newBlockingUses,
177 const DataLayout &dataLayout)
const {
185 removeBlockingUses(Operation *op,
const MemorySlot &slot,
186 const SmallPtrSetImpl<OpOperand *> &blockingUses,
187 OpBuilder &builder, Value reachingDefinition,
188 const DataLayout &dataLayout)
const {
189 return DeletionKind::Delete;
194PromotableMemOpInterface getWrappedMemOp(
Operation *op) {
195 Operation *maskableOp = cast<vector::MaskOp>(op).getMaskableOp();
198 if (!isa<vector::TransferReadOp, vector::TransferWriteOp>(maskableOp))
200 return cast<PromotableMemOpInterface>(maskableOp);
206struct MaskOpMemOpModel
207 :
public PromotableMemOpInterface::ExternalModel<MaskOpMemOpModel,
209 bool ownsWrappedBlockingUses(Operation *op)
const {
210 return static_cast<bool>(getWrappedMemOp(op));
213 bool loadsFrom(Operation *op,
const MemorySlot &slot)
const {
214 PromotableMemOpInterface memOp = getWrappedMemOp(op);
215 return memOp && memOp.loadsFrom(slot);
218 bool storesTo(Operation *op,
const MemorySlot &slot)
const {
219 PromotableMemOpInterface memOp = getWrappedMemOp(op);
220 return memOp && memOp.storesTo(slot);
223 Value getStored(Operation *op,
const MemorySlot &slot, OpBuilder &builder,
224 Value reachingDef,
const DataLayout &dataLayout)
const {
226 getWrappedMemOp(op).getStored(slot, builder, reachingDef, dataLayout);
227 return arith::SelectOp::create(builder, op->
getLoc(),
228 cast<vector::MaskOp>(op).getMask(), stored,
232 bool canUsesBeRemoved(Operation *op,
const MemorySlot &slot,
233 const SmallPtrSetImpl<OpOperand *> &blockingUses,
234 SmallVectorImpl<OpOperand *> &newBlockingUses,
235 const DataLayout &dataLayout)
const {
236 PromotableMemOpInterface memOp = getWrappedMemOp(op);
238 if (!memOp || cast<VectorTransferOpInterface>(*memOp).getMask())
240 return memOp.canUsesBeRemoved(slot, blockingUses, newBlockingUses,
247 removeBlockingUses(Operation *op,
const MemorySlot &slot,
248 const SmallPtrSetImpl<OpOperand *> &blockingUses,
249 OpBuilder &builder, Value reachingDefinition,
250 const DataLayout &dataLayout)
const {
251 auto maskOp = cast<vector::MaskOp>(op);
252 PromotableMemOpInterface memOp = getWrappedMemOp(op);
253 memOp.removeBlockingUses(slot, blockingUses, builder, reachingDefinition,
255 auto readOp = dyn_cast<vector::TransferReadOp>(*memOp);
257 return DeletionKind::Delete;
259 Location loc = op->
getLoc();
260 Value enabled = maskOp.getMaskBlock()->getTerminator()->getOperand(0);
263 ? maskOp.getPassthru()
264 : vector::BroadcastOp::create(builder, loc, readOp.getVectorType(),
265 readOp.getPadding());
266 Value
result = arith::SelectOp::create(builder, loc, maskOp.getMask(),
268 maskOp->getResult(0).replaceAllUsesWith(
result);
269 return DeletionKind::Delete;
281 TransferReadOp::attachInterface<TransferReadOpMemOpModel>(*ctx);
282 TransferWriteOp::attachInterface<TransferWriteOpMemOpModel>(*ctx);
283 MaskOp::attachInterface<MaskOpMemOpModel>(*ctx);
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.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation is the basic unit of execution within MLIR.
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...
void replaceAllUsesWith(Value newValue)
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
Value buildDynamicSubViewMask(OpBuilder &builder, Location loc, Value slotPtr)
Builds a mask for the subview's valid region in the parent vector, or returns null if isDynamicSubVie...
bool isDynamicSubViewSlot(Value slotPtr)
Returns whether slotPtr is a dynamic memref.subview that can be promoted as an alias of the whole par...
void registerMemorySlotInterfacesExternalModels(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.
Type valueType
Type of the value contained in the slot.
Value ptr
Pointer to the memory slot, used by operations to refer to it.