22 if (isa<Attribute>(ofr))
34 memref::AllocaOp allocaOp,
45 newSizes.push_back(*ub);
49 if (llvm::equal(allocaOp.getMixedSizes(), newSizes))
50 return allocaOp.getResult();
54 AllocaOp::create(b, loc, newSizes, allocaOp.getType().getElementType());
59 return SubViewOp::create(b, loc, newAllocaOp, offsets,
60 allocaOp.getMixedSizes(), strides)
65 static UnrealizedConversionCastOp
67 UnrealizedConversionCastOp conversionOp, SubViewOp op) {
70 MemRefType newResultType = SubViewOp::inferRankReducedResultType(
71 op.getType().getShape(), op.getSourceType(), op.getMixedOffsets(),
72 op.getMixedSizes(), op.getMixedStrides());
73 Value newSubview = SubViewOp::create(
74 rewriter, op.getLoc(), newResultType, conversionOp.getOperand(0),
75 op.getMixedOffsets(), op.getMixedSizes(), op.getMixedStrides());
76 auto newConversionOp = UnrealizedConversionCastOp::create(
77 rewriter, op.getLoc(), op.
getType(), newSubview);
79 return newConversionOp;
99 "expected same number of results");
106 for (
const auto &it :
108 unrealizedConversions.push_back(UnrealizedConversionCastOp::create(
109 rewriter, to->
getLoc(), std::get<0>(it.value()).getType(),
110 std::get<1>(it.value())));
112 unrealizedConversions.back()->getResult(0));
117 for (
int i = 0; i < static_cast<int>(unrealizedConversions.size()); ++i) {
118 UnrealizedConversionCastOp conversion = unrealizedConversions[i];
119 assert(conversion->getNumOperands() == 1 &&
120 conversion->getNumResults() == 1 &&
121 "expected single operand and single result");
126 if (
auto subviewOp = dyn_cast<SubViewOp>(user)) {
127 unrealizedConversions.push_back(
137 if (llvm::any_of(user->getResultTypes(),
138 [](
Type t) { return isa<MemRefType>(t); }))
140 if (llvm::any_of(user->getRegions(), [](
Region &r) {
141 return llvm::any_of(r.getArguments(), [](BlockArgument bbArg) {
142 return isa<MemRefType>(bbArg.getType());
150 for (
OpOperand &operand : user->getOpOperands()) {
151 if ([[maybe_unused]]
auto castOp =
152 operand.get().getDefiningOp<UnrealizedConversionCastOp>()) {
154 user, [&]() { operand.set(conversion->getOperand(0)); });
161 for (
auto op : unrealizedConversions)
162 if (op->getUses().empty())
163 rewriter.eraseOp(op);
167 memref::AllocaOp allocaOp,
174 replacement->getDefiningOp());
180 function_ref<
bool(memref::AllocOp, memref::DeallocOp)> filter) {
181 memref::DeallocOp dealloc =
nullptr;
183 llvm::make_range(alloc->getIterator(), alloc->getBlock()->end())) {
184 dealloc = dyn_cast<memref::DeallocOp>(candidate);
185 if (dealloc && dealloc.getMemref() == alloc.getMemref() &&
186 (!filter || filter(alloc, dealloc))) {
197 alloc, alloc.getMemref().getType(), alloc.getOperands());
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
IntegerAttr getIndexAttr(int64_t value)
Ty getType(Args &&...args)
Get or construct an instance of the type Ty with provided arguments.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
RAII guard to reset the insertion point of the builder when destroyed.
This class helps build Operations.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
void setInsertionPointAfter(Operation *op)
Sets the insertion point to the node after the specified operation, which will cause subsequent inser...
This class represents a single result from folding an operation.
This class represents an operand of an operation.
Operation is the basic unit of execution within MLIR.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
result_range getResults()
unsigned getNumResults()
Return the number of results held by this operation.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
void replaceAllUsesWith(Value from, Value to)
Find uses of from and replace them with to.
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
void modifyOpInPlace(Operation *root, CallableT &&callable)
This method is a utility wrapper around an in-place modification of an operation.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
static LogicalResult computeIndependentBound(AffineMap &resultMap, ValueDimList &mapOperands, presburger::BoundType type, const Variable &var, ValueRange independencies, bool closedUB=false)
Compute a bound in that is independent of all values in independencies.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
OpFoldResult materializeComputedBound(OpBuilder &b, Location loc, AffineMap boundMap, ArrayRef< std::pair< Value, std::optional< int64_t >>> mapOperands)
Materialize an already computed bound with Affine dialect ops.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
FailureOr< Value > buildIndependentOp(OpBuilder &b, AllocaOp allocaOp, ValueRange independencies)
Build a new memref::AllocaOp whose dynamic sizes are independent of all given independencies.
FailureOr< Value > replaceWithIndependentOp(RewriterBase &rewriter, memref::AllocaOp allocaOp, ValueRange independencies)
Build a new memref::AllocaOp whose dynamic sizes are independent of all given independencies.
memref::AllocaOp allocToAlloca(RewriterBase &rewriter, memref::AllocOp alloc, function_ref< bool(memref::AllocOp, memref::DeallocOp)> filter=nullptr)
Replaces the given alloc with the corresponding alloca and returns it if the following conditions are...
Include the generated interface declarations.
SmallVector< std::pair< Value, std::optional< int64_t > >> ValueDimList