[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:
Nicolas Vasilache 2021-05-20 09:07:21 +00:00
parent 4cd1b66dff
commit ef33c6e3ce
6 changed files with 107 additions and 172 deletions

View File

@ -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

View File

@ -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,

View File

@ -24,7 +24,6 @@ namespace mlir {
class AffineExpr;
class AffineForOp;
class AffineMap;
class OperationFolder;
class PatternRewriter;
namespace linalg {

View File

@ -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);
});
}
};

View File

@ -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>

View File

@ -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>(