24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/Debug.h"
29 #define GEN_PASS_DEF_RAISEMEMREFDIALECT
30 #include "mlir/Dialect/Affine/Passes.h.inc"
34 #define DEBUG_TYPE "raise-memref-to-affine"
47 static std::optional<size_t>
51 Value *loopIV = llvm::find(dims, value);
52 if (loopIV != dims.end()) {
54 return {std::distance(dims.begin(), loopIV)};
56 if (isValidElement(value)) {
59 size_t idx = dims.size();
60 dims.push_back(value);
71 using namespace matchers;
72 IntegerAttr::ValueType cst;
78 if (llvm::isa_and_nonnull<arith::AddIOp>(definingOp) ||
79 llvm::isa_and_nonnull<arith::MulIOp>(definingOp)) {
87 toAffineExpr(definingOp->
getOperand(0), affineDims, affineSymbols);
89 toAffineExpr(definingOp->
getOperand(1), affineDims, affineSymbols);
93 if (isa<arith::AddIOp>(definingOp)) {
108 if (
auto dimIx = findInListOrAdd(value, affineSymbols, [](
Value v) {
114 if (
auto dimIx = findInListOrAdd(
130 for (
Value indexExpr : indices) {
131 AffineExpr res = toAffineExpr(indexExpr, dims, symbols);
135 results.push_back(res);
140 dims.append(symbols);
145 struct RaiseMemrefDialect
146 :
public affine::impl::RaiseMemrefDialectBase<RaiseMemrefDialect> {
148 void runOnOperation()
override {
156 if (
auto store = llvm::dyn_cast_or_null<memref::StoreOp>(op)) {
158 if (succeeded(computeAffineMapAndArgs(ctx, store.getIndices(), map,
160 rewriter.replaceOpWithNewOp<AffineStoreOp>(
161 op, store.getValueToStore(), store.getMemRef(), map, mapArgs);
165 LLVM_DEBUG(llvm::dbgs()
166 <<
"[affine] Cannot raise memref op: " << op <<
"\n");
168 }
else if (
auto load = llvm::dyn_cast_or_null<memref::LoadOp>(op)) {
169 if (succeeded(computeAffineMapAndArgs(ctx, load.getIndices(), map,
171 rewriter.replaceOpWithNewOp<AffineLoadOp>(op, load.getMemRef(), map,
175 LLVM_DEBUG(llvm::dbgs()
176 <<
"[affine] Cannot raise memref op: " << op <<
"\n");
184 std::unique_ptr<OperationPass<func::FuncOp>>
186 return std::make_unique<RaiseMemrefDialect>();
static MLIRContext * getContext(OpFoldResult val)
union mlir::linalg::@1194::ArityGroupAndKind::Kind kind
Base type for affine expression.
bool isSymbolicOrConstant() const
Returns true if this expression is made out of only symbols and constants, i.e., it does not involve ...
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
This class coordinates rewriting a piece of IR outside of a pattern rewrite, providing a way to keep ...
MLIRContext is the top-level object for a collection of MLIR operations.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Operation is the basic unit of execution within MLIR.
Value getOperand(unsigned idx)
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
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...
MLIRContext * getContext() const
Utility to get the associated MLIRContext that this value is defined in.
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
bool isValidDim(Value value)
Returns true if the given Value can be used as a dimension id in the region of the closest surroundin...
std::unique_ptr< OperationPass< func::FuncOp > > createRaiseMemrefToAffine()
Creates a pass that converts some memref operators to affine operators.
bool isValidSymbol(Value value)
Returns true if the given value can be used as a symbol in the region of the closest surrounding op t...
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
detail::constant_int_value_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
@ Mul
RHS of mul is always a constant or a symbolic expression.
AffineExpr getAffineBinaryOpExpr(AffineExprKind kind, AffineExpr lhs, AffineExpr rhs)
AffineExpr getAffineConstantExpr(int64_t constant, MLIRContext *context)
AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context)
These free functions allow clients of the API to not use classes in detail.
AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context)