36 memref::AllocaOp allocaOp,
47 newSizes.push_back(*ub);
51 if (llvm::equal(allocaOp.getMixedSizes(), newSizes))
52 return allocaOp.getResult();
56 b.
create<AllocaOp>(loc, newSizes, allocaOp.getType().getElementType());
62 .
create<SubViewOp>(loc, newAllocaOp, offsets, allocaOp.getMixedSizes(),
68 static UnrealizedConversionCastOp
70 UnrealizedConversionCastOp conversionOp, SubViewOp op) {
73 auto newResultType = cast<MemRefType>(SubViewOp::inferRankReducedResultType(
74 op.getType().getShape(), op.getSourceType(), op.getMixedOffsets(),
75 op.getMixedSizes(), op.getMixedStrides()));
77 op.getLoc(), newResultType, conversionOp.getOperand(0),
78 op.getMixedOffsets(), op.getMixedSizes(), op.getMixedStrides());
79 auto newConversionOp = rewriter.
create<UnrealizedConversionCastOp>(
80 op.getLoc(), op.getType(), newSubview);
82 return newConversionOp;
102 "expected same number of results");
109 for (
const auto &it :
111 unrealizedConversions.push_back(rewriter.
create<UnrealizedConversionCastOp>(
112 to->
getLoc(), std::get<0>(it.value()).getType(),
113 std::get<1>(it.value())));
115 unrealizedConversions.back()->getResult(0));
120 for (
int i = 0; i < static_cast<int>(unrealizedConversions.size()); ++i) {
121 UnrealizedConversionCastOp conversion = unrealizedConversions[i];
122 assert(conversion->getNumOperands() == 1 &&
123 conversion->getNumResults() == 1 &&
124 "expected single operand and single result");
129 if (
auto subviewOp = dyn_cast<SubViewOp>(user)) {
130 unrealizedConversions.push_back(
140 if (llvm::any_of(user->getResultTypes(),
141 [](
Type t) { return isa<MemRefType>(t); }))
143 if (llvm::any_of(user->getRegions(), [](
Region &r) {
144 return llvm::any_of(r.getArguments(), [](BlockArgument bbArg) {
145 return isa<MemRefType>(bbArg.getType());
153 for (
OpOperand &operand : user->getOpOperands()) {
154 if ([[maybe_unused]]
auto castOp =
155 operand.get().getDefiningOp<UnrealizedConversionCastOp>()) {
157 user, [&]() { operand.set(conversion->getOperand(0)); });
164 for (
auto op : unrealizedConversions)
165 if (op->getUses().empty())
166 rewriter.eraseOp(op);
170 memref::AllocaOp allocaOp,
174 if (failed(replacement))
177 replacement->getDefiningOp());
183 function_ref<
bool(memref::AllocOp, memref::DeallocOp)> filter) {
184 memref::DeallocOp dealloc =
nullptr;
186 llvm::make_range(alloc->getIterator(), alloc->getBlock()->end())) {
187 dealloc = dyn_cast<memref::DeallocOp>(candidate);
188 if (dealloc && dealloc.getMemref() == alloc.getMemref() &&
189 (!filter || filter(alloc, dealloc))) {
200 alloc, alloc.getMemref().getType(), alloc.getOperands());
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
Attributes are known-constant values of operations.
IntegerAttr getIndexAttr(int64_t value)
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.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
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