diff --git a/mlir/include/mlir/Dialect/MemRef/IR/MemRef.h b/mlir/include/mlir/Dialect/MemRef/IR/MemRef.h --- a/mlir/include/mlir/Dialect/MemRef/IR/MemRef.h +++ b/mlir/include/mlir/Dialect/MemRef/IR/MemRef.h @@ -25,12 +25,6 @@ raw_ostream &operator<<(raw_ostream &os, Range &range); -/// Return the list of Range (i.e. offset, size, stride). Each Range -/// entry contains either the dynamic value or a ConstantIndexOp constructed -/// with `b` at location `loc`. -SmallVector getOrCreateRanges(OffsetSizeAndStrideOpInterface op, - OpBuilder &b, Location loc); - /// Given an operation, retrieves the value of each dynamic dimension through /// constructing the necessary DimOp operators. SmallVector getDynOperands(Location loc, Value val, OpBuilder &b); diff --git a/mlir/include/mlir/Dialect/Tensor/IR/Tensor.h b/mlir/include/mlir/Dialect/Tensor/IR/Tensor.h --- a/mlir/include/mlir/Dialect/Tensor/IR/Tensor.h +++ b/mlir/include/mlir/Dialect/Tensor/IR/Tensor.h @@ -18,20 +18,6 @@ #include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Interfaces/ViewLikeInterface.h" -//===----------------------------------------------------------------------===// -// Tensor Dialect Helpers -//===----------------------------------------------------------------------===// - -namespace mlir { - -/// Return the list of Range (i.e. offset, size, stride). Each Range -/// entry contains either the dynamic value or a ConstantIndexOp constructed -/// with `b` at location `loc`. -SmallVector getOrCreateRanges(OffsetSizeAndStrideOpInterface op, - OpBuilder &b, Location loc); - -} // namespace mlir - //===----------------------------------------------------------------------===// // Tensor Dialect //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h b/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h --- a/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h +++ b/mlir/include/mlir/Dialect/Utils/StaticValueUtils.h @@ -16,6 +16,7 @@ #define THIRD_PARTY_LLVM_LLVM_PROJECT_MLIR_INCLUDE_MLIR_DIALECT_UTILS_STATICVALUEUTILS_H_ #include "mlir/IR/OpDefinition.h" +#include "mlir/Interfaces/ViewLikeInterface.h" #include "llvm/ADT/SmallVector.h" @@ -48,6 +49,13 @@ /// IntegerAttr, return the integer. llvm::Optional getConstantIntValue(OpFoldResult ofr); +/// Return the list of Range (i.e. offset, size, stride). Each Range +/// entry contains either the dynamic value or a ConstantIndexOp constructed +/// with `b` at location `loc`. +llvm::SmallVector +getOrCreateRanges(OffsetSizeAndStrideOpInterface op, OpBuilder &b, + Location loc); + /// Return true if ofr and value are the same integer. /// Ignore integer bitwidth and type mismatch that come from the fact there is /// no IndexAttr and that IndexType has no bitwidth. diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -2229,13 +2229,6 @@ code extraBaseClassDeclaration = [{ /// Returns the dynamic sizes for this subview operation if specified. operand_range getDynamicSizes() { return sizes(); } - - /// Return the list of Range (i.e. offset, size, stride). Each - /// Range entry contains either the dynamic value or a ConstantIndexOp - /// constructed with `b` at location `loc`. - SmallVector getOrCreateRanges(OpBuilder &b, Location loc) { - return mlir::getOrCreateRanges(*this, b, loc); - } }]; } diff --git a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp @@ -20,6 +20,7 @@ #include "mlir/Dialect/Linalg/Utils/Utils.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/Dialect/Tensor/IR/Tensor.h" +#include "mlir/Dialect/Utils/StaticValueUtils.h" #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineMap.h" #include "mlir/IR/Dominance.h" @@ -258,9 +259,9 @@ Value shapedOperand, unsigned dim) { Operation *shapeProducingOp = shapedOperand.getDefiningOp(); if (auto subViewOp = dyn_cast(shapeProducingOp)) - return subViewOp.getOrCreateRanges(b, loc)[dim]; + return getOrCreateRanges(subViewOp, b, loc)[dim]; if (auto sliceOp = dyn_cast(shapeProducingOp)) - return sliceOp.getOrCreateRanges(b, loc)[dim]; + return getOrCreateRanges(sliceOp, b, loc)[dim]; llvm_unreachable("SubviewOp or ExtractSliceOp expected"); } diff --git a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp --- a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp +++ b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp @@ -18,6 +18,7 @@ #include "mlir/Dialect/Linalg/Transforms/Transforms.h" #include "mlir/Dialect/Linalg/Utils/Utils.h" #include "mlir/Dialect/SCF/SCF.h" +#include "mlir/Dialect/Utils/StaticValueUtils.h" #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineExprVisitor.h" #include "mlir/IR/AffineMap.h" @@ -218,7 +219,7 @@ SmallVector partialSizes; fullSizes.reserve(rank); partialSizes.reserve(rank); - for (auto en : llvm::enumerate(subView.getOrCreateRanges(b, loc))) { + for (auto en : llvm::enumerate(getOrCreateRanges(subView, b, loc))) { auto rangeValue = en.value(); // Try to extract a tight constant. LLVM_DEBUG(llvm::dbgs() << "Extract tightest: " << rangeValue.size << "\n"); diff --git a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp --- a/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp +++ b/mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp @@ -1794,34 +1794,6 @@ << range.stride; } -/// Return the list of Range (i.e. offset, size, stride). Each Range -/// entry contains either the dynamic value or a ConstantIndexOp constructed -/// with `b` at location `loc`. -SmallVector mlir::getOrCreateRanges(OffsetSizeAndStrideOpInterface op, - OpBuilder &b, Location loc) { - std::array ranks = op.getArrayAttrMaxRanks(); - assert(ranks[0] == ranks[1] && "expected offset and sizes of equal ranks"); - assert(ranks[1] == ranks[2] && "expected sizes and strides of equal ranks"); - SmallVector res; - unsigned rank = ranks[0]; - res.reserve(rank); - for (unsigned idx = 0; idx < rank; ++idx) { - Value offset = - op.isDynamicOffset(idx) - ? op.getDynamicOffset(idx) - : b.create(loc, op.getStaticOffset(idx)); - Value size = op.isDynamicSize(idx) - ? op.getDynamicSize(idx) - : b.create(loc, op.getStaticSize(idx)); - Value stride = - op.isDynamicStride(idx) - ? op.getDynamicStride(idx) - : b.create(loc, op.getStaticStride(idx)); - res.emplace_back(Range{offset, size, stride}); - } - return res; -} - /// Infer the canonical type of the result of a subview operation. Returns a /// type with rank `resultRank` that is either the rank of the rank-reduced /// type, or the non-rank-reduced type. diff --git a/mlir/lib/Dialect/Utils/CMakeLists.txt b/mlir/lib/Dialect/Utils/CMakeLists.txt --- a/mlir/lib/Dialect/Utils/CMakeLists.txt +++ b/mlir/lib/Dialect/Utils/CMakeLists.txt @@ -4,4 +4,5 @@ LINK_LIBS PUBLIC MLIRIR + MLIRViewLikeInterface ) diff --git a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp --- a/mlir/lib/Dialect/Utils/StaticValueUtils.cpp +++ b/mlir/lib/Dialect/Utils/StaticValueUtils.cpp @@ -9,6 +9,8 @@ #include "mlir/Dialect/Utils/StaticValueUtils.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" +using namespace mlir; + /// Helper function to dispatch an OpFoldResult into either the `dynamicVec` if /// it is a Value or into `staticVec` if it is an IntegerAttr. /// In the case of a Value, a copy of the `sentinel` value is also pushed to @@ -55,6 +57,35 @@ return llvm::None; } +/// Return the list of Range (i.e. offset, size, stride). Each Range +/// entry contains either the dynamic value or a ConstantIndexOp constructed +/// with `b` at location `loc`. +llvm::SmallVector +mlir::getOrCreateRanges(OffsetSizeAndStrideOpInterface op, OpBuilder &b, + Location loc) { + std::array ranks = op.getArrayAttrMaxRanks(); + assert(ranks[0] == ranks[1] && "expected offset and sizes of equal ranks"); + assert(ranks[1] == ranks[2] && "expected sizes and strides of equal ranks"); + SmallVector res; + unsigned rank = ranks[0]; + res.reserve(rank); + for (unsigned idx = 0; idx < rank; ++idx) { + Value offset = + op.isDynamicOffset(idx) + ? op.getDynamicOffset(idx) + : b.create(loc, op.getStaticOffset(idx)); + Value size = op.isDynamicSize(idx) + ? op.getDynamicSize(idx) + : b.create(loc, op.getStaticSize(idx)); + Value stride = + op.isDynamicStride(idx) + ? op.getDynamicStride(idx) + : b.create(loc, op.getStaticStride(idx)); + res.emplace_back(Range{offset, size, stride}); + } + return res; +} + /// Return true if ofr and value are the same integer. /// Ignore integer bitwidth and type mismatch that come from the fact there is /// no IndexAttr and that IndexType has no bitwidth. diff --git a/mlir/lib/Interfaces/CMakeLists.txt b/mlir/lib/Interfaces/CMakeLists.txt --- a/mlir/lib/Interfaces/CMakeLists.txt +++ b/mlir/lib/Interfaces/CMakeLists.txt @@ -39,4 +39,3 @@ add_mlir_interface_library(SideEffectInterfaces) add_mlir_interface_library(VectorInterfaces) add_mlir_interface_library(ViewLikeInterface) - diff --git a/mlir/lib/Interfaces/ViewLikeInterface.cpp b/mlir/lib/Interfaces/ViewLikeInterface.cpp --- a/mlir/lib/Interfaces/ViewLikeInterface.cpp +++ b/mlir/lib/Interfaces/ViewLikeInterface.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "mlir/Interfaces/ViewLikeInterface.h" +#include "mlir/Dialect/StandardOps/IR/Ops.h" using namespace mlir;