forked from OSchip/llvm-project
[mlir][Linalg] Drop spurious usage of OperationFolder
Instead, use createOrFold builders which result in more static information available. Differential Revision: https://reviews.llvm.org/D102832
This commit is contained in:
parent
4cd1b66dff
commit
ef33c6e3ce
|
@ -19,45 +19,6 @@
|
|||
namespace mlir {
|
||||
namespace edsc {
|
||||
namespace intrinsics {
|
||||
|
||||
template <typename Op>
|
||||
struct FoldedValueBuilder {
|
||||
// Builder-based
|
||||
template <typename... Args>
|
||||
FoldedValueBuilder(OperationFolder *folder, Args... args) {
|
||||
value = folder ? folder->create<Op>(ScopedContext::getBuilderRef(),
|
||||
ScopedContext::getLocation(), args...)
|
||||
: ScopedContext::getBuilderRef().create<Op>(
|
||||
ScopedContext::getLocation(), args...);
|
||||
}
|
||||
|
||||
operator Value() { return value; }
|
||||
Value value;
|
||||
};
|
||||
|
||||
using folded_math_tanh = FoldedValueBuilder<math::TanhOp>;
|
||||
using folded_memref_alloc = FoldedValueBuilder<memref::AllocOp>;
|
||||
using folded_memref_cast = FoldedValueBuilder<memref::CastOp>;
|
||||
using folded_memref_dim = FoldedValueBuilder<memref::DimOp>;
|
||||
using folded_memref_load = FoldedValueBuilder<memref::LoadOp>;
|
||||
using folded_memref_sub_view = FoldedValueBuilder<memref::SubViewOp>;
|
||||
using folded_memref_tensor_load = FoldedValueBuilder<memref::TensorLoadOp>;
|
||||
using folded_memref_view = FoldedValueBuilder<memref::ViewOp>;
|
||||
using folded_std_muli = FoldedValueBuilder<MulIOp>;
|
||||
using folded_std_addi = FoldedValueBuilder<AddIOp>;
|
||||
using folded_std_addf = FoldedValueBuilder<AddFOp>;
|
||||
using folded_std_constant = FoldedValueBuilder<ConstantOp>;
|
||||
using folded_std_constant_float = FoldedValueBuilder<ConstantFloatOp>;
|
||||
using folded_std_constant_index = FoldedValueBuilder<ConstantIndexOp>;
|
||||
using folded_std_constant_int = FoldedValueBuilder<ConstantIntOp>;
|
||||
using folded_std_index_cast = FoldedValueBuilder<IndexCastOp>;
|
||||
using folded_std_muli = FoldedValueBuilder<MulIOp>;
|
||||
using folded_std_mulf = FoldedValueBuilder<MulFOp>;
|
||||
using folded_std_select = FoldedValueBuilder<SelectOp>;
|
||||
using folded_std_subi = FoldedValueBuilder<SubIOp>;
|
||||
using folded_std_zero_extendi = FoldedValueBuilder<ZeroExtendIOp>;
|
||||
using folded_std_sign_extendi = FoldedValueBuilder<SignExtendIOp>;
|
||||
using folded_tensor_extract = FoldedValueBuilder<tensor::ExtractOp>;
|
||||
} // namespace intrinsics
|
||||
} // namespace edsc
|
||||
} // namespace mlir
|
||||
|
|
|
@ -220,10 +220,9 @@ void interchangeGenericOp(PatternRewriter &rewriter, GenericOp genericOp,
|
|||
/// smallest constant value for the size of the buffer needed for each
|
||||
/// dimension. If that is not possible, contains the dynamic size of the
|
||||
/// subview. The call back should return the buffer to use.
|
||||
using AllocBufferCallbackFn =
|
||||
std::function<Optional<Value>(OpBuilder &b, memref::SubViewOp subView,
|
||||
ArrayRef<Value> boundingSubViewSize,
|
||||
DataLayout &layout, OperationFolder *folder)>;
|
||||
using AllocBufferCallbackFn = std::function<Optional<Value>(
|
||||
OpBuilder &b, memref::SubViewOp subView,
|
||||
ArrayRef<Value> boundingSubViewSize, DataLayout &layout)>;
|
||||
|
||||
/// Callback function type used to deallocate the buffers used to hold the
|
||||
/// promoted subview.
|
||||
|
@ -321,8 +320,7 @@ struct PromotionInfo {
|
|||
Optional<PromotionInfo>
|
||||
promoteSubviewAsNewBuffer(OpBuilder &b, Location loc, memref::SubViewOp subView,
|
||||
AllocBufferCallbackFn allocationFn,
|
||||
DataLayout &layout,
|
||||
OperationFolder *folder = nullptr);
|
||||
DataLayout &layout);
|
||||
|
||||
/// Promotes the `subViews` into a new buffer allocated at the insertion point
|
||||
/// `b`. Promotion occurs in 3 steps:
|
||||
|
@ -335,8 +333,7 @@ promoteSubviewAsNewBuffer(OpBuilder &b, Location loc, memref::SubViewOp subView,
|
|||
/// Returns the modified linalg op (the modification happens in place) as well
|
||||
/// as all the copy ops created.
|
||||
Optional<LinalgOp> promoteSubViews(OpBuilder &b, LinalgOp op,
|
||||
LinalgPromotionOptions options,
|
||||
OperationFolder *folder = nullptr);
|
||||
LinalgPromotionOptions options);
|
||||
|
||||
/// Emit a suitable vector form for a Linalg op with fully static shape.
|
||||
LogicalResult vectorizeLinalgOp(OpBuilder &builder, Operation *op,
|
||||
|
|
|
@ -24,7 +24,6 @@ namespace mlir {
|
|||
class AffineExpr;
|
||||
class AffineForOp;
|
||||
class AffineMap;
|
||||
class OperationFolder;
|
||||
class PatternRewriter;
|
||||
|
||||
namespace linalg {
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "mlir/IR/AffineExpr.h"
|
||||
#include "mlir/IR/AffineExprVisitor.h"
|
||||
#include "mlir/IR/AffineMap.h"
|
||||
#include "mlir/IR/ImplicitLocOpBuilder.h"
|
||||
#include "mlir/Support/LLVM.h"
|
||||
#include "mlir/Transforms/FoldUtils.h"
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
|
@ -38,75 +39,66 @@ using namespace mlir::scf;
|
|||
|
||||
using llvm::MapVector;
|
||||
|
||||
using folded_affine_min = FoldedValueBuilder<AffineMinOp>;
|
||||
using folded_linalg_range = FoldedValueBuilder<linalg::RangeOp>;
|
||||
using folded_memref_dim = FoldedValueBuilder<memref::DimOp>;
|
||||
using folded_memref_subview = FoldedValueBuilder<memref::SubViewOp>;
|
||||
using folded_memref_view = FoldedValueBuilder<memref::ViewOp>;
|
||||
|
||||
#define DEBUG_TYPE "linalg-promotion"
|
||||
|
||||
/// Alloc a new buffer of `size`. If `dynamicBuffers` is true allocate exactly
|
||||
/// the size needed, otherwise try to allocate a static bounding box.
|
||||
static Value allocBuffer(const LinalgPromotionOptions &options,
|
||||
Type elementType, Value size, bool dynamicBuffers,
|
||||
DataLayout &layout, OperationFolder *folder,
|
||||
/// Alloc a new buffer of `size` * `width` i8; where `width` is given by the
|
||||
/// data `layout` for `elementType`.
|
||||
/// Use AllocOp or AllocaOp depending on `options`.
|
||||
/// Take an optional alignment.
|
||||
static Value allocBuffer(ImplicitLocOpBuilder &b,
|
||||
const LinalgPromotionOptions &options,
|
||||
Type elementType, Value allocSize, DataLayout &layout,
|
||||
Optional<unsigned> alignment = None) {
|
||||
auto *ctx = size.getContext();
|
||||
auto width = layout.getTypeSize(elementType);
|
||||
IntegerAttr alignment_attr;
|
||||
|
||||
IntegerAttr alignmentAttr;
|
||||
if (alignment.hasValue())
|
||||
alignment_attr =
|
||||
IntegerAttr::get(IntegerType::get(ctx, 64), alignment.getValue());
|
||||
if (!dynamicBuffers)
|
||||
if (auto cst = size.getDefiningOp<ConstantIndexOp>())
|
||||
return options.useAlloca
|
||||
? memref_alloca(MemRefType::get(width * cst.getValue(),
|
||||
IntegerType::get(ctx, 8)),
|
||||
ValueRange{}, alignment_attr)
|
||||
.value
|
||||
: memref_alloc(MemRefType::get(width * cst.getValue(),
|
||||
IntegerType::get(ctx, 8)),
|
||||
ValueRange{}, alignment_attr)
|
||||
.value;
|
||||
alignmentAttr = b.getI64IntegerAttr(alignment.getValue());
|
||||
|
||||
// Static buffer.
|
||||
if (auto cst = allocSize.getDefiningOp<ConstantIndexOp>()) {
|
||||
auto staticBufferType =
|
||||
MemRefType::get(width * cst.getValue(), b.getIntegerType(8));
|
||||
if (options.useAlloca) {
|
||||
return b.createOrFold<memref::AllocaOp>(staticBufferType, ValueRange{},
|
||||
alignmentAttr);
|
||||
}
|
||||
return b.createOrFold<memref::AllocOp>(staticBufferType, ValueRange{},
|
||||
alignmentAttr);
|
||||
}
|
||||
|
||||
// Fallback dynamic buffer.
|
||||
auto dynamicBufferType = MemRefType::get(-1, b.getIntegerType(8));
|
||||
Value mul =
|
||||
folded_std_muli(folder, folded_std_constant_index(folder, width), size);
|
||||
return options.useAlloca
|
||||
? memref_alloca(MemRefType::get(-1, IntegerType::get(ctx, 8)), mul,
|
||||
alignment_attr)
|
||||
.value
|
||||
: memref_alloc(MemRefType::get(-1, IntegerType::get(ctx, 8)), mul,
|
||||
alignment_attr)
|
||||
.value;
|
||||
b.createOrFold<MulIOp>(b.create<ConstantIndexOp>(width), allocSize);
|
||||
if (options.useAlloca)
|
||||
return b.create<memref::AllocaOp>(dynamicBufferType, mul, alignmentAttr);
|
||||
return b.create<memref::AllocOp>(dynamicBufferType, mul, alignmentAttr);
|
||||
}
|
||||
|
||||
/// Default allocation callback function. This allocates a promoted buffer when
|
||||
/// no call back to do so is provided. The default is to allocate a
|
||||
/// memref<..xi8> and return a view to get a memref type of shape
|
||||
/// boundingSubViewSize.
|
||||
static Optional<Value>
|
||||
defaultAllocBufferCallBack(const LinalgPromotionOptions &options,
|
||||
OpBuilder &builder, memref::SubViewOp subView,
|
||||
ArrayRef<Value> boundingSubViewSize,
|
||||
bool dynamicBuffers, Optional<unsigned> alignment,
|
||||
DataLayout &layout, OperationFolder *folder) {
|
||||
static Optional<Value> defaultAllocBufferCallBack(
|
||||
const LinalgPromotionOptions &options, OpBuilder &builder,
|
||||
memref::SubViewOp subView, ArrayRef<Value> boundingSubViewSize,
|
||||
bool dynamicBuffers, Optional<unsigned> alignment, DataLayout &layout) {
|
||||
ShapedType viewType = subView.getType();
|
||||
int64_t rank = viewType.getRank();
|
||||
(void)rank;
|
||||
assert(rank > 0 && boundingSubViewSize.size() == static_cast<size_t>(rank));
|
||||
auto zero = folded_std_constant_index(folder, 0);
|
||||
auto one = folded_std_constant_index(folder, 1);
|
||||
ImplicitLocOpBuilder b(subView.getLoc(), builder);
|
||||
auto zero = b.createOrFold<ConstantIndexOp>(0);
|
||||
auto one = b.createOrFold<ConstantIndexOp>(1);
|
||||
|
||||
Value allocSize = one;
|
||||
for (auto size : llvm::enumerate(boundingSubViewSize))
|
||||
allocSize = folded_std_muli(folder, allocSize, size.value());
|
||||
Value buffer = allocBuffer(options, viewType.getElementType(), allocSize,
|
||||
dynamicBuffers, layout, folder, alignment);
|
||||
allocSize = b.createOrFold<MulIOp>(allocSize, size.value());
|
||||
Value buffer = allocBuffer(b, options, viewType.getElementType(), allocSize,
|
||||
layout, alignment);
|
||||
SmallVector<int64_t, 4> dynSizes(boundingSubViewSize.size(),
|
||||
ShapedType::kDynamicSize);
|
||||
Value view = folded_memref_view(
|
||||
folder, MemRefType::get(dynSizes, viewType.getElementType()), buffer,
|
||||
zero, boundingSubViewSize);
|
||||
Value view = b.createOrFold<memref::ViewOp>(
|
||||
MemRefType::get(dynSizes, viewType.getElementType()), buffer, zero,
|
||||
boundingSubViewSize);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
@ -171,16 +163,15 @@ LinalgOpInstancePromotionOptions::LinalgOpInstancePromotionOptions(
|
|||
}
|
||||
}
|
||||
|
||||
allocationFn =
|
||||
(options.allocationFn
|
||||
? *(options.allocationFn)
|
||||
: [&](OpBuilder &builder, memref::SubViewOp subViewOp,
|
||||
ArrayRef<Value> boundingSubViewSize, DataLayout &layout,
|
||||
OperationFolder *folder) -> Optional<Value> {
|
||||
return defaultAllocBufferCallBack(options, builder, subViewOp,
|
||||
boundingSubViewSize, dynamicBuffers,
|
||||
alignment, layout, folder);
|
||||
});
|
||||
allocationFn = (options.allocationFn
|
||||
? *(options.allocationFn)
|
||||
: [&](OpBuilder &builder, memref::SubViewOp subViewOp,
|
||||
ArrayRef<Value> boundingSubViewSize,
|
||||
DataLayout &layout) -> Optional<Value> {
|
||||
return defaultAllocBufferCallBack(options, builder, subViewOp,
|
||||
boundingSubViewSize, dynamicBuffers,
|
||||
alignment, layout);
|
||||
});
|
||||
deallocationFn =
|
||||
(options.deallocationFn
|
||||
? *(options.deallocationFn)
|
||||
|
@ -215,8 +206,7 @@ LinalgOpInstancePromotionOptions::LinalgOpInstancePromotionOptions(
|
|||
// by a partial `copy` op.
|
||||
Optional<PromotionInfo> mlir::linalg::promoteSubviewAsNewBuffer(
|
||||
OpBuilder &b, Location loc, memref::SubViewOp subView,
|
||||
AllocBufferCallbackFn allocationFn, DataLayout &layout,
|
||||
OperationFolder *folder) {
|
||||
AllocBufferCallbackFn allocationFn, DataLayout &layout) {
|
||||
ScopedContext scopedContext(b, loc);
|
||||
auto viewType = subView.getType();
|
||||
auto rank = viewType.getRank();
|
||||
|
@ -233,27 +223,24 @@ Optional<PromotionInfo> mlir::linalg::promoteSubviewAsNewBuffer(
|
|||
(!sizeAttr) ? rangeValue.size : b.create<ConstantOp>(loc, sizeAttr);
|
||||
LLVM_DEBUG(llvm::dbgs() << "Extracted tightest: " << size << "\n");
|
||||
fullSizes.push_back(size);
|
||||
partialSizes.push_back(
|
||||
folded_memref_dim(folder, subView, en.index()).value);
|
||||
partialSizes.push_back(memref_dim(subView, en.index()).value);
|
||||
}
|
||||
SmallVector<int64_t, 4> dynSizes(fullSizes.size(), -1);
|
||||
// If a callback is not specified, then use the default implementation for
|
||||
// allocating the promoted buffer.
|
||||
Optional<Value> fullLocalView =
|
||||
allocationFn(b, subView, fullSizes, layout, folder);
|
||||
Optional<Value> fullLocalView = allocationFn(b, subView, fullSizes, layout);
|
||||
if (!fullLocalView)
|
||||
return {};
|
||||
SmallVector<OpFoldResult, 4> zeros(fullSizes.size(), b.getIndexAttr(0));
|
||||
SmallVector<OpFoldResult, 4> ones(fullSizes.size(), b.getIndexAttr(1));
|
||||
auto partialLocalView =
|
||||
folded_memref_subview(folder, *fullLocalView, zeros, partialSizes, ones);
|
||||
auto partialLocalView = b.createOrFold<memref::SubViewOp>(
|
||||
loc, *fullLocalView, zeros, partialSizes, ones);
|
||||
return PromotionInfo{*fullLocalView, partialLocalView};
|
||||
}
|
||||
|
||||
static Optional<MapVector<unsigned, PromotionInfo>>
|
||||
promoteSubViews(OpBuilder &b, Location loc,
|
||||
LinalgOpInstancePromotionOptions options, DataLayout &layout,
|
||||
OperationFolder *folder) {
|
||||
LinalgOpInstancePromotionOptions options, DataLayout &layout) {
|
||||
if (options.subViews.empty())
|
||||
return {};
|
||||
|
||||
|
@ -264,7 +251,7 @@ promoteSubViews(OpBuilder &b, Location loc,
|
|||
memref::SubViewOp subView =
|
||||
cast<memref::SubViewOp>(v.second.getDefiningOp());
|
||||
Optional<PromotionInfo> promotionInfo = promoteSubviewAsNewBuffer(
|
||||
b, loc, subView, options.allocationFn, layout, folder);
|
||||
b, loc, subView, options.allocationFn, layout);
|
||||
if (!promotionInfo)
|
||||
return {};
|
||||
promotionInfoMap[v.first] = *promotionInfo;
|
||||
|
@ -274,16 +261,16 @@ promoteSubViews(OpBuilder &b, Location loc,
|
|||
continue;
|
||||
Value fillVal;
|
||||
if (auto t = subView.getType().getElementType().dyn_cast<FloatType>()) {
|
||||
fillVal = folded_std_constant(folder, FloatAttr::get(t, 0.0));
|
||||
fillVal = std_constant(FloatAttr::get(t, 0.0));
|
||||
} else if (auto t =
|
||||
subView.getType().getElementType().dyn_cast<IntegerType>()) {
|
||||
fillVal = folded_std_constant_int(folder, 0, t);
|
||||
fillVal = std_constant_int(0, t);
|
||||
} else if (auto t =
|
||||
subView.getType().getElementType().dyn_cast<ComplexType>()) {
|
||||
if (auto et = t.getElementType().dyn_cast<FloatType>())
|
||||
fillVal = folded_std_constant(folder, FloatAttr::get(et, 0.0));
|
||||
fillVal = std_constant(FloatAttr::get(et, 0.0));
|
||||
else if (auto et = t.getElementType().cast<IntegerType>())
|
||||
fillVal = folded_std_constant_int(folder, 0, et);
|
||||
fillVal = std_constant_int(0, et);
|
||||
fillVal = b.create<complex::CreateOp>(loc, t, fillVal, fillVal);
|
||||
} else {
|
||||
return {};
|
||||
|
@ -306,8 +293,7 @@ promoteSubViews(OpBuilder &b, Location loc,
|
|||
|
||||
static Optional<LinalgOp>
|
||||
promoteSubViews(OpBuilder &b, LinalgOp op,
|
||||
LinalgOpInstancePromotionOptions options, DataLayout &layout,
|
||||
OperationFolder *folder) {
|
||||
LinalgOpInstancePromotionOptions options, DataLayout &layout) {
|
||||
assert(op.hasBufferSemantics() && "expected linalg op with buffer semantics");
|
||||
|
||||
if (auto convOp = dyn_cast<linalg::ConvOp>(op.getOperation())) {
|
||||
|
@ -318,8 +304,7 @@ promoteSubViews(OpBuilder &b, LinalgOp op,
|
|||
|
||||
// 1. Promote the specified views and use them in the new op.
|
||||
auto loc = op.getLoc();
|
||||
auto promotedBuffersAndViews =
|
||||
promoteSubViews(b, loc, options, layout, folder);
|
||||
auto promotedBuffersAndViews = promoteSubViews(b, loc, options, layout);
|
||||
if (!promotedBuffersAndViews ||
|
||||
promotedBuffersAndViews->size() != options.subViews.size())
|
||||
return {};
|
||||
|
@ -386,13 +371,12 @@ mlir::linalg::promoteSubviewsPrecondition(Operation *op,
|
|||
return failure();
|
||||
}
|
||||
|
||||
Optional<LinalgOp> mlir::linalg::promoteSubViews(OpBuilder &b,
|
||||
LinalgOp linalgOp,
|
||||
LinalgPromotionOptions options,
|
||||
OperationFolder *folder) {
|
||||
Optional<LinalgOp>
|
||||
mlir::linalg::promoteSubViews(OpBuilder &b, LinalgOp linalgOp,
|
||||
LinalgPromotionOptions options) {
|
||||
LinalgOpInstancePromotionOptions linalgOptions(linalgOp, options);
|
||||
auto layout = DataLayout::closest(linalgOp);
|
||||
return ::promoteSubViews(b, linalgOp, linalgOptions, layout, folder);
|
||||
return ::promoteSubViews(b, linalgOp, linalgOptions, layout);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -404,8 +388,7 @@ struct LinalgPromotionPass : public LinalgPromotionBase<LinalgPromotionPass> {
|
|||
}
|
||||
|
||||
void runOnFunction() override {
|
||||
OperationFolder folder(&getContext());
|
||||
getFunction().walk([this, &folder](LinalgOp op) {
|
||||
getFunction().walk([this](LinalgOp op) {
|
||||
auto options = LinalgPromotionOptions()
|
||||
.setDynamicBuffers(dynamicBuffers)
|
||||
.setUseAlloca(useAlloca);
|
||||
|
@ -413,7 +396,7 @@ struct LinalgPromotionPass : public LinalgPromotionBase<LinalgPromotionPass> {
|
|||
return;
|
||||
LLVM_DEBUG(llvm::dbgs() << "Promote: " << *(op.getOperation()) << "\n");
|
||||
OpBuilder b(op);
|
||||
promoteSubViews(b, op, options, &folder);
|
||||
promoteSubViews(b, op, options);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -48,7 +48,7 @@ func @matvec(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
|||
// CHECK: scf.parallel {{.*}} step (%[[c5]])
|
||||
// CHECK: scf.for {{.*}} step %[[c6]]
|
||||
// CHECK: linalg.matvec
|
||||
// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
|
||||
func @matmul(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
||||
|
@ -87,7 +87,7 @@ func @matmul(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
|||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4]] {
|
||||
// CHECK: linalg.matmul
|
||||
// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
|
||||
#matmul_accesses = [
|
||||
|
@ -141,7 +141,7 @@ func @matvec_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
|||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c6]]
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c5]]
|
||||
// CHECK: linalg.matvec
|
||||
// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>)
|
||||
|
||||
func @matmul_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
||||
|
@ -174,7 +174,7 @@ func @matmul_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
|||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c30]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c40]] {
|
||||
// CHECK: linalg.matmul
|
||||
// CHECK: ins({{.*}}, {{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>)
|
||||
|
||||
func @promote_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
||||
|
@ -214,19 +214,19 @@ func @promote_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>,
|
|||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] {
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s1:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s2:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s1:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s2:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc() : memref<32000000xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1]
|
||||
// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK: %[[a1:.*]] = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK: %[[v1:.*]] = memref.view %[[a1]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[a1:.*]] = memref.alloc() : memref<48000000xi8>
|
||||
// CHECK: %[[v1:.*]] = memref.view %[[a1]]{{.*}} : memref<48000000xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[l1:.*]] = memref.subview %[[v1]][0, 0] [%{{.*}}, %{{.*}}] [1, 1]
|
||||
// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK: %[[a2:.*]] = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK: %[[v2:.*]] = memref.view %[[a2]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[a2:.*]] = memref.alloc() : memref<24000000xi8>
|
||||
// CHECK: %[[v2:.*]] = memref.view %[[a2]]{{.*}} : memref<24000000xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[l2:.*]] = memref.subview %[[v2]][0, 0] [%{{.*}}, %{{.*}}] [1, 1]
|
||||
// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>
|
||||
|
@ -273,21 +273,17 @@ func @promote_first_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?
|
|||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] {
|
||||
// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] {
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s1:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s2:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s1:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[s2:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc() : memref<32000000xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK-NOT: %{{.*}} = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK-NOT: %{{.*}} = memref.view %{{.*}}[{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK-NOT: %{{.*}} = memref.subview %{{.*}}[0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK-NOT: %{{.*}} = memref.alloc({{%.*}}) : memref<?xi8>
|
||||
// CHECK-NOT: %{{.*}} = memref.view %{{.*}}[{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK-NOT: %{{.*}} = memref.subview %{{.*}}[0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK-NOT: memref.alloc
|
||||
// CHECK-NOT: memref.view
|
||||
// CHECK-NOT: memref.subview
|
||||
// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK-NOT: linalg.copy(%[[s1]], %{{.*}}) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK-NOT: linalg.copy(%[[s2]], %{{.*}}) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>^
|
||||
// CHECK-NOT: linalg.copy
|
||||
// CHECK: linalg.matmul
|
||||
// CHECK-SAME: ins(%[[v0]], %[[s1]] : memref<?x?xf32>, memref<?x?xf32, #[[$STRIDED_2D]]>)
|
||||
// CHECK-SAME: outs(%[[s2]] : memref<?x?xf32, #[[$STRIDED_2D]]>)
|
||||
|
@ -306,11 +302,11 @@ func @aligned_promote_fill(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>) {
|
|||
}
|
||||
// CHECK-LABEL: func @aligned_promote_fill
|
||||
// CHECK: %[[cf:.*]] = constant {{.*}} : f32
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) {alignment = 32 : i64} : memref<?xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc() {alignment = 32 : i64} : memref<32000000xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32>
|
||||
// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK: linalg.fill(%[[v0]], {{%.*}}) : memref<?x?xf32>, f32
|
||||
// CHECK: linalg.fill(%[[v0]], {{.*}}) : memref<?x?xf32>, f32
|
||||
// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xf32, #map{{.*}}>, memref<?x?xf32, #map{{.*}}>
|
||||
// CHECK: linalg.fill(%[[v0]], %[[cf]]) : memref<?x?xf32>, f32
|
||||
|
||||
|
@ -329,11 +325,11 @@ func @aligned_promote_fill_complex(%arg0: memref<?x?xcomplex<f32>, offset: ?, st
|
|||
}
|
||||
// CHECK-LABEL: func @aligned_promote_fill_complex
|
||||
// CHECK: %[[cc:.*]] = complex.create {{.*}} : complex<f32>
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{%.*}}[{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] [{{%.*}}, {{%.*}}] : memref<?x?xcomplex<f32>, #map{{.*}}> to memref<?x?xcomplex<f32>, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc({{%.*}}) {alignment = 32 : i64} : memref<?xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]][{{.*}}][{{%.*}}, {{%.*}}] : memref<?xi8> to memref<?x?xcomplex<f32>>
|
||||
// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xcomplex<f32>, #map{{.*}}> to memref<?x?xcomplex<f32>, #map{{.*}}>
|
||||
// CHECK: %[[a0:.*]] = memref.alloc() {alignment = 32 : i64} : memref<64000000xi8>
|
||||
// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<64000000xi8> to memref<?x?xcomplex<f32>>
|
||||
// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xcomplex<f32>> to memref<?x?xcomplex<f32>, #[[$STRIDED_2D_u_1]]>
|
||||
// CHECK: linalg.fill(%[[v0]], {{%.*}}) : memref<?x?xcomplex<f32>>, complex<f32>
|
||||
// CHECK: linalg.fill(%[[v0]], {{.*}}) : memref<?x?xcomplex<f32>>, complex<f32>
|
||||
// CHECK: linalg.copy(%[[s0]], %[[l0]]) : memref<?x?xcomplex<f32>, #map{{.*}}>, memref<?x?xcomplex<f32>, #map{{.*}}>
|
||||
// CHECK: linalg.fill(%[[v0]], %[[cc]]) : memref<?x?xcomplex<f32>>, complex<f32>
|
||||
|
||||
|
|
|
@ -271,8 +271,7 @@ static void fillL1TilingAndMatmulToVectorPatterns(
|
|||
// Allocation call back
|
||||
static Optional<Value> allocCallBackFn(OpBuilder &b, memref::SubViewOp subView,
|
||||
ArrayRef<Value> boundingSubViewSize,
|
||||
DataLayout &layout,
|
||||
OperationFolder *folder) {
|
||||
DataLayout &layout) {
|
||||
SmallVector<int64_t, 4> shape(boundingSubViewSize.size(), -1);
|
||||
return b
|
||||
.create<memref::AllocOp>(
|
||||
|
|
Loading…
Reference in New Issue