summaryrefslogtreecommitdiffstats
path: root/mlir/lib/Dialect
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/Dialect')
-rw-r--r--mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp9
-rw-r--r--mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp24
-rw-r--r--mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp6
-rw-r--r--mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp14
-rw-r--r--mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp21
-rw-r--r--mlir/lib/Dialect/Linalg/Utils/Utils.cpp7
-rw-r--r--mlir/lib/Dialect/StandardOps/Ops.cpp121
7 files changed, 152 insertions, 50 deletions
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
index 9a160f534fe..06563ff96cf 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp
@@ -376,10 +376,10 @@ void mlir::linalg::SubViewOp::build(Builder *b, OperationState &result,
result.addAttributes(attrs);
}
-static void print(OpAsmPrinter &p, SubViewOp op) {
+static void print(OpAsmPrinter &p, mlir::linalg::SubViewOp op) {
p << op.getOperationName() << " " << *op.getOperand(0) << "[";
auto ranges = op.getRanges();
- interleaveComma(ranges, p, [&p](const SubViewOp::Range &i) {
+ interleaveComma(ranges, p, [&p](const mlir::linalg::SubViewOp::Range &i) {
p << *i.min << ", " << *i.max << ", " << *i.step;
});
p << "]";
@@ -646,8 +646,9 @@ static LogicalResult verify(ConvOp op) {
return success();
}
-llvm::raw_ostream &mlir::linalg::operator<<(llvm::raw_ostream &os,
- SubViewOp::Range &range) {
+llvm::raw_ostream &
+mlir::linalg::operator<<(llvm::raw_ostream &os,
+ mlir::linalg::SubViewOp::Range &range) {
return os << "range " << *range.min << ":" << *range.max << ":"
<< *range.step;
}
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
index 82699545b3f..c6dffc3ab11 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Fusion.cpp
@@ -74,8 +74,9 @@ static llvm::cl::list<unsigned> clTileSizes(
// a subset of the original loop ranges of `op`.
// This is achieved by applying the `loopToOperandRangesMaps` permutation maps
// to the `loopRanges` in order to obtain view ranges.
-static LinalgOp cloneWithLoopRanges(OpBuilder &b, Location loc, LinalgOp op,
- ArrayRef<SubViewOp::Range> loopRanges) {
+static LinalgOp
+cloneWithLoopRanges(OpBuilder &b, Location loc, LinalgOp op,
+ ArrayRef<mlir::linalg::SubViewOp::Range> loopRanges) {
auto maps = loopToOperandRangesMaps(op);
SmallVector<Value *, 8> clonedViews;
clonedViews.reserve(op.getNumInputsAndOutputs());
@@ -87,7 +88,8 @@ static LinalgOp cloneWithLoopRanges(OpBuilder &b, Location loc, LinalgOp op,
auto map = maps[idx];
LLVM_DEBUG(dbgs() << "map: " << map << "\n");
Value *view = en.value();
- SmallVector<SubViewOp::Range, 8> viewRanges(map.getNumResults());
+ SmallVector<mlir::linalg::SubViewOp::Range, 8> viewRanges(
+ map.getNumResults());
for (auto en2 : llvm::enumerate(map.getResults())) {
unsigned d = en2.index();
// loopToOperandRangesMaps are permutations-only.
@@ -105,7 +107,8 @@ static LinalgOp cloneWithLoopRanges(OpBuilder &b, Location loc, LinalgOp op,
subViewOperands.push_back(r.max);
subViewOperands.push_back(r.step);
}
- clonedViews.push_back(b.create<SubViewOp>(loc, view, subViewOperands));
+ clonedViews.push_back(
+ b.create<mlir::linalg::SubViewOp>(loc, view, subViewOperands));
}
auto operands = getAssumedNonViewOperands(op);
clonedViews.append(operands.begin(), operands.end());
@@ -150,7 +153,7 @@ static ViewDimension getViewDefiningLoopRange(LinalgOp op, unsigned loopDepth) {
static LinalgOp fuse(Value *producedView, LinalgOp producer, LinalgOp consumer,
unsigned consumerIdx, unsigned producerIdx,
OperationFolder *folder) {
- auto subView = dyn_cast_or_null<SubViewOp>(
+ auto subView = dyn_cast_or_null<mlir::linalg::SubViewOp>(
consumer.getInput(consumerIdx)->getDefiningOp());
auto slice = dyn_cast_or_null<SliceOp>(
consumer.getInput(consumerIdx)->getDefiningOp());
@@ -169,7 +172,7 @@ static LinalgOp fuse(Value *producedView, LinalgOp producer, LinalgOp consumer,
unsigned nPar = producer.getNumParallelLoops();
unsigned nRed = producer.getNumReductionLoops();
unsigned nWin = producer.getNumWindowLoops();
- SmallVector<SubViewOp::Range, 8> loopRanges(nPar + nRed + nWin);
+ SmallVector<mlir::linalg::SubViewOp::Range, 8> loopRanges(nPar + nRed + nWin);
// Iterate over dimensions identified by the producer map for `producerIdx`.
// This defines a subset of the loop ranges that we need to complete later.
@@ -189,9 +192,9 @@ static LinalgOp fuse(Value *producedView, LinalgOp producer, LinalgOp consumer,
<< "existing LoopRange: " << loopRanges[i] << "\n");
else {
auto viewDim = getViewDefiningLoopRange(producer, i);
- loopRanges[i] = SubViewOp::Range{constant_index(folder, 0),
- dim(viewDim.view, viewDim.dimension),
- constant_index(folder, 1)};
+ loopRanges[i] = mlir::linalg::SubViewOp::Range{
+ constant_index(folder, 0), dim(viewDim.view, viewDim.dimension),
+ constant_index(folder, 1)};
LLVM_DEBUG(llvm::dbgs() << "new LoopRange: " << loopRanges[i] << "\n");
}
}
@@ -283,7 +286,8 @@ Optional<FusionInfo> mlir::linalg::fuseProducerOf(
// Must be a subview or a slice to guarantee there are loops we can fuse
// into.
- auto subView = dyn_cast_or_null<SubViewOp>(consumedView->getDefiningOp());
+ auto subView = dyn_cast_or_null<mlir::linalg::SubViewOp>(
+ consumedView->getDefiningOp());
auto slice = dyn_cast_or_null<SliceOp>(consumedView->getDefiningOp());
if (!subView && !slice) {
LLVM_DEBUG(dbgs() << "\nNot fusable (not a subview or slice)");
diff --git a/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp b/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp
index 6b51e039a5b..7a8bc7162af 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/LowerToLLVMDialect.cpp
@@ -487,11 +487,11 @@ public:
/// A non-conversion rewrite pattern kicks in to convert SubViewOp into RangeOps
/// and SliceOps.
-class SubViewOpConversion : public OpRewritePattern<SubViewOp> {
+class SubViewOpConversion : public OpRewritePattern<mlir::linalg::SubViewOp> {
public:
- using OpRewritePattern<SubViewOp>::OpRewritePattern;
+ using OpRewritePattern<mlir::linalg::SubViewOp>::OpRewritePattern;
- PatternMatchResult matchAndRewrite(SubViewOp op,
+ PatternMatchResult matchAndRewrite(mlir::linalg::SubViewOp op,
PatternRewriter &rewriter) const override {
auto *view = op.getView();
SmallVector<Value *, 8> ranges;
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
index a23e68dc8f3..3afee415405 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp
@@ -89,7 +89,7 @@ static Value *allocBuffer(Type elementType, Value *size, bool dynamicBuffers) {
// boundary tiles. For now this is done with an unconditional `fill` op followed
// by a partial `copy` op.
static PromotionInfo promoteFullTileBuffer(OpBuilder &b, Location loc,
- SubViewOp subView,
+ mlir::linalg::SubViewOp subView,
bool dynamicBuffers,
OperationFolder *folder) {
auto zero = constant_index(folder, 0);
@@ -135,7 +135,8 @@ mlir::linalg::promoteSubViews(OpBuilder &b, Location loc,
res.reserve(subViews.size());
DenseMap<Value *, PromotionInfo> promotionInfoMap;
for (auto *v : subViews) {
- SubViewOp subView = cast<SubViewOp>(v->getDefiningOp());
+ mlir::linalg::SubViewOp subView =
+ cast<mlir::linalg::SubViewOp>(v->getDefiningOp());
auto viewType = subView.getViewType();
// TODO(ntv): support more cases than just float.
if (!viewType.getElementType().isa<FloatType>())
@@ -147,7 +148,8 @@ mlir::linalg::promoteSubViews(OpBuilder &b, Location loc,
}
for (auto *v : subViews) {
- SubViewOp subView = cast<SubViewOp>(v->getDefiningOp());
+ mlir::linalg::SubViewOp subView =
+ cast<mlir::linalg::SubViewOp>(v->getDefiningOp());
auto info = promotionInfoMap.find(v);
if (info == promotionInfoMap.end())
continue;
@@ -165,7 +167,8 @@ mlir::linalg::promoteSubViews(OpBuilder &b, Location loc,
auto info = promotionInfoMap.find(v);
if (info == promotionInfoMap.end())
continue;
- copy(cast<SubViewOp>(v->getDefiningOp()), info->second.partialLocalView);
+ copy(cast<mlir::linalg::SubViewOp>(v->getDefiningOp()),
+ info->second.partialLocalView);
}
return res;
}
@@ -223,7 +226,8 @@ static void promoteSubViews(FuncOp f, bool dynamicBuffers) {
// nothing.
SetVector<Value *> subViews;
for (auto it : op.getInputsAndOutputs())
- if (auto sv = dyn_cast_or_null<SubViewOp>(it->getDefiningOp()))
+ if (auto sv =
+ dyn_cast_or_null<mlir::linalg::SubViewOp>(it->getDefiningOp()))
subViews.insert(sv);
if (!subViews.empty()) {
promoteSubViewOperands(op, subViews, dynamicBuffers, &folder);
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
index c1d9755f4df..b7a5740a387 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Tiling.cpp
@@ -65,7 +65,7 @@ static bool isZero(Value *v) {
// avoiding affine map manipulations.
// The returned ranges correspond to the loop ranges, in the proper order, that
// are tiled and for which new loops will be created.
-static SmallVector<SubViewOp::Range, 4>
+static SmallVector<mlir::linalg::SubViewOp::Range, 4>
makeTiledLoopRanges(OpBuilder &b, Location loc, AffineMap map,
ArrayRef<Value *> allViewSizes,
ArrayRef<Value *> allTileSizes, OperationFolder *folder) {
@@ -83,10 +83,10 @@ makeTiledLoopRanges(OpBuilder &b, Location loc, AffineMap map,
}
// Create a new range with the applied tile sizes.
- SmallVector<SubViewOp::Range, 4> res;
+ SmallVector<mlir::linalg::SubViewOp::Range, 4> res;
for (unsigned idx = 0, e = tileSizes.size(); idx < e; ++idx) {
- res.push_back(SubViewOp::Range{constant_index(folder, 0), viewSizes[idx],
- tileSizes[idx]});
+ res.push_back(mlir::linalg::SubViewOp::Range{
+ constant_index(folder, 0), viewSizes[idx], tileSizes[idx]});
}
return res;
}
@@ -182,13 +182,13 @@ makeTiledViews(OpBuilder &b, Location loc, LinalgOp linalgOp,
}
// Construct a new subview for the tile.
- SmallVector<SubViewOp::Range, 4> subViewRangeOperands;
+ SmallVector<mlir::linalg::SubViewOp::Range, 4> subViewRangeOperands;
subViewRangeOperands.reserve(rank * 3);
for (unsigned r = 0; r < rank; ++r) {
if (!isTiled(map.getSubMap({r}), tileSizes)) {
- subViewRangeOperands.push_back(
- SubViewOp::Range{constant_index(folder, 0), dim(view, r),
- constant_index(folder, 1)});
+ subViewRangeOperands.push_back(mlir::linalg::SubViewOp::Range{
+ constant_index(folder, 0), dim(view, r),
+ constant_index(folder, 1)});
continue;
}
@@ -198,7 +198,7 @@ makeTiledViews(OpBuilder &b, Location loc, LinalgOp linalgOp,
// Tiling creates a new slice at the proper index, the slice step is 1
// (i.e. the slice view does not subsample, stepping occurs in the loop).
subViewRangeOperands.push_back(
- SubViewOp::Range{min, max, constant_index(folder, 1)});
+ mlir::linalg::SubViewOp::Range{min, max, constant_index(folder, 1)});
}
SmallVector<Value *, 12> subViewOperands;
subViewOperands.reserve(subViewRangeOperands.size() * 3);
@@ -207,7 +207,8 @@ makeTiledViews(OpBuilder &b, Location loc, LinalgOp linalgOp,
subViewOperands.push_back(r.max);
subViewOperands.push_back(r.step);
}
- res.push_back(b.create<SubViewOp>(loc, view, subViewOperands));
+ res.push_back(
+ b.create<mlir::linalg::SubViewOp>(loc, view, subViewOperands));
}
// Traverse the mins/maxes and erase those that don't have uses left.
diff --git a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
index dcd2e56a1ee..20cf1834698 100644
--- a/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
+++ b/mlir/lib/Dialect/Linalg/Utils/Utils.cpp
@@ -56,8 +56,8 @@ mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
enter(body, /*prev=*/1);
}
-mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
- SubViewOp::Range range) {
+mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(
+ ValueHandle *iv, mlir::linalg::SubViewOp::Range range) {
auto forOp =
OperationHandle::createOp<ForOp>(range.min, range.max, range.step);
*iv = ValueHandle(forOp.getInductionVar());
@@ -74,7 +74,8 @@ mlir::edsc::LoopRangeBuilder::operator()(std::function<void(void)> fun) {
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
- ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
+ ArrayRef<ValueHandle *> ivs,
+ ArrayRef<mlir::linalg::SubViewOp::Range> ranges) {
loops.reserve(ranges.size());
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
loops.emplace_back(ivs[i], ranges[i]);
diff --git a/mlir/lib/Dialect/StandardOps/Ops.cpp b/mlir/lib/Dialect/StandardOps/Ops.cpp
index 9fc6f320e1d..12029248168 100644
--- a/mlir/lib/Dialect/StandardOps/Ops.cpp
+++ b/mlir/lib/Dialect/StandardOps/Ops.cpp
@@ -2380,6 +2380,23 @@ Value *ViewOp::getDynamicOffset() {
return nullptr;
}
+static LogicalResult verifyDynamicStrides(MemRefType memrefType,
+ ArrayRef<int64_t> strides) {
+ ArrayRef<int64_t> shape = memrefType.getShape();
+ unsigned rank = memrefType.getRank();
+ assert(rank == strides.size());
+ bool dynamicStrides = false;
+ for (int i = rank - 2; i >= 0; --i) {
+ // If size at dim 'i + 1' is dynamic, set the 'dynamicStrides' flag.
+ if (ShapedType::isDynamic(shape[i + 1]))
+ dynamicStrides = true;
+ // If stride at dim 'i' is not dynamic, return error.
+ if (dynamicStrides && strides[i] != MemRefType::getDynamicStrideOrOffset())
+ return failure();
+ }
+ return success();
+}
+
static LogicalResult verify(ViewOp op) {
auto baseType = op.getOperand(0)->getType().cast<MemRefType>();
auto viewType = op.getResult()->getType().cast<MemRefType>();
@@ -2396,7 +2413,7 @@ static LogicalResult verify(ViewOp op) {
"type ")
<< baseType << " and view memref type " << viewType;
- // Verify that the result memref type has a strided layout map. is strided
+ // Verify that the result memref type has a strided layout map.
int64_t offset;
llvm::SmallVector<int64_t, 4> strides;
if (failed(getStridesAndOffset(viewType, strides, offset)))
@@ -2413,20 +2430,9 @@ static LogicalResult verify(ViewOp op) {
// Verify dynamic strides symbols were added to correct dimensions based
// on dynamic sizes.
- ArrayRef<int64_t> viewShape = viewType.getShape();
- unsigned viewRank = viewType.getRank();
- assert(viewRank == strides.size());
- bool dynamicStrides = false;
- for (int i = viewRank - 2; i >= 0; --i) {
- // If size at dim 'i + 1' is dynamic, set the 'dynamicStrides' flag.
- if (ShapedType::isDynamic(viewShape[i + 1]))
- dynamicStrides = true;
- // If stride at dim 'i' is not dynamic, return error.
- if (dynamicStrides && strides[i] != MemRefType::getDynamicStrideOrOffset())
- return op.emitError("incorrect dynamic strides in view memref type ")
- << viewType;
- }
-
+ if (failed(verifyDynamicStrides(viewType, strides)))
+ return op.emitError("incorrect dynamic strides in view memref type ")
+ << viewType;
return success();
}
@@ -2544,6 +2550,91 @@ void ViewOp::getCanonicalizationPatterns(OwningRewritePatternList &results,
}
//===----------------------------------------------------------------------===//
+// SubViewOp
+//===----------------------------------------------------------------------===//
+
+static ParseResult parseSubViewOp(OpAsmParser &parser, OperationState &result) {
+ OpAsmParser::OperandType srcInfo;
+ SmallVector<OpAsmParser::OperandType, 4> offsetsInfo;
+ SmallVector<OpAsmParser::OperandType, 4> sizesInfo;
+ SmallVector<OpAsmParser::OperandType, 4> stridesInfo;
+ auto indexType = parser.getBuilder().getIndexType();
+ Type srcType, dstType;
+ return failure(
+ parser.parseOperand(srcInfo) ||
+ parser.parseOperandList(offsetsInfo, OpAsmParser::Delimiter::Square) ||
+ parser.parseOperandList(sizesInfo, OpAsmParser::Delimiter::Square) ||
+ parser.parseOperandList(stridesInfo, OpAsmParser::Delimiter::Square) ||
+ parser.parseOptionalAttrDict(result.attributes) ||
+ parser.parseColonType(srcType) ||
+ parser.resolveOperand(srcInfo, srcType, result.operands) ||
+ parser.resolveOperands(offsetsInfo, indexType, result.operands) ||
+ parser.resolveOperands(sizesInfo, indexType, result.operands) ||
+ parser.resolveOperands(stridesInfo, indexType, result.operands) ||
+ parser.parseKeywordType("to", dstType) ||
+ parser.addTypeToList(dstType, result.types));
+}
+
+static void print(OpAsmPrinter &p, SubViewOp op) {
+ p << op.getOperationName() << ' ' << *op.getOperand(0) << '[';
+ p.printOperands(op.getDynamicOffsets());
+ p << "][";
+ p.printOperands(op.getDynamicSizes());
+ p << "][";
+ p.printOperands(op.getDynamicStrides());
+ p << ']';
+ p.printOptionalAttrDict(op.getAttrs());
+ p << " : " << op.getOperand(0)->getType() << " to " << op.getType();
+}
+
+static LogicalResult verify(SubViewOp op) {
+ auto baseType = op.getOperand(0)->getType().cast<MemRefType>();
+ auto subViewType = op.getResult()->getType().cast<MemRefType>();
+
+ // The base memref and the view memref should be in the same memory space.
+ if (baseType.getMemorySpace() != subViewType.getMemorySpace())
+ return op.emitError("different memory spaces specified for base memref "
+ "type ")
+ << baseType << " and subview memref type " << subViewType;
+
+ // Verify that the base memref type has a strided layout map.
+ int64_t baseOffset;
+ llvm::SmallVector<int64_t, 4> baseStrides;
+ if (failed(getStridesAndOffset(baseType, baseStrides, baseOffset)))
+ return op.emitError("base type ") << subViewType << " is not strided";
+
+ // Verify that the result memref type has a strided layout map.
+ int64_t subViewOffset;
+ llvm::SmallVector<int64_t, 4> subViewStrides;
+ if (failed(getStridesAndOffset(subViewType, subViewStrides, subViewOffset)))
+ return op.emitError("result type ") << subViewType << " is not strided";
+
+ unsigned memrefOperandCount = 1;
+ unsigned numDynamicOffsets = llvm::size(op.getDynamicOffsets());
+ unsigned numDynamicSizes = llvm::size(op.getDynamicSizes());
+ unsigned numDynamicStrides = llvm::size(op.getDynamicStrides());
+
+ // Verify that we have the correct number of operands for the result type.
+ if (op.getNumOperands() != memrefOperandCount + numDynamicOffsets +
+ numDynamicSizes + numDynamicStrides)
+ return op.emitError("incorrect number of operands for type ")
+ << subViewType;
+
+ // Verify that the subview layout map has a dynamic offset.
+ if (subViewOffset != MemRefType::getDynamicStrideOrOffset())
+ return op.emitError("subview memref layout map must specify a dynamic "
+ "offset for type ")
+ << subViewType;
+
+ // Verify dynamic strides symbols were added to correct dimensions based
+ // on dynamic sizes.
+ if (failed(verifyDynamicStrides(subViewType, subViewStrides)))
+ return op.emitError("incorrect dynamic strides in view memref type ")
+ << subViewType;
+ return success();
+}
+
+//===----------------------------------------------------------------------===//
// ZeroExtendIOp
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud