diff options
| author | Nicolas Vasilache <ntv@google.com> | 2019-11-14 08:10:36 -0800 |
|---|---|---|
| committer | A. Unique TensorFlower <gardener@tensorflow.org> | 2019-11-14 08:15:23 -0800 |
| commit | f2b6ae99913d0049c7929160aed5f213b1081abb (patch) | |
| tree | 41ccb1f9a181eaada07f21cbc7da75ef2d229575 /mlir/lib/Transforms | |
| parent | 7c28de4aef6da3ab2f53118ecf717e56c68352e7 (diff) | |
| download | bcm5719-llvm-f2b6ae99913d0049c7929160aed5f213b1081abb.tar.gz bcm5719-llvm-f2b6ae99913d0049c7929160aed5f213b1081abb.zip | |
Move VectorOps to Tablegen - (almost) NFC
This CL moves VectorOps to Tablegen and cleans up the implementation.
This is almost NFC but 2 changes occur:
1. an interface change occurs in the padding value specification in vector_transfer_read:
the value becomes non-optional. As a shortcut we currently use %f0 for all paddings.
This should become an OpInterface for vectorization in the future.
2. the return type of vector.type_cast is trivial and simplified to `memref<vector<...>>`
Relevant roundtrip and invalid tests that used to sit in core are moved to the vector dialect.
The op documentation is moved to the .td file.
PiperOrigin-RevId: 280430869
Diffstat (limited to 'mlir/lib/Transforms')
| -rw-r--r-- | mlir/lib/Transforms/LowerVectorTransfers.cpp | 34 | ||||
| -rw-r--r-- | mlir/lib/Transforms/MaterializeVectors.cpp | 18 | ||||
| -rw-r--r-- | mlir/lib/Transforms/Vectorize.cpp | 14 |
3 files changed, 35 insertions, 31 deletions
diff --git a/mlir/lib/Transforms/LowerVectorTransfers.cpp b/mlir/lib/Transforms/LowerVectorTransfers.cpp index c517d74f221..57dd18dac0f 100644 --- a/mlir/lib/Transforms/LowerVectorTransfers.cpp +++ b/mlir/lib/Transforms/LowerVectorTransfers.cpp @@ -113,12 +113,6 @@ struct VectorTransferRewriter : public RewritePattern { {}, 0); } - /// View of tmpMemRefType as one vector, used in vector load/store to tmp - /// buffer. - MemRefType vectorMemRefType(VectorTransferOpTy transfer) const { - return MemRefType::get({1}, transfer.getVectorType(), {}, 0); - } - /// Performs the rewrite. PatternMatchResult matchAndRewrite(Operation *op, PatternRewriter &rewriter) const override; @@ -139,7 +133,7 @@ void coalesceCopy(VectorTransferOpTy transfer, // the loop order for creating pointwise copies between remote and local // memories. int coalescedIdx = -1; - auto exprs = transfer.getPermutationMap().getResults(); + auto exprs = transfer.permutation_map().getResults(); for (auto en : llvm::enumerate(exprs)) { auto dim = en.value().template dyn_cast<AffineDimExpr>(); if (!dim) { @@ -170,7 +164,7 @@ llvm::SmallVector<edsc::ValueHandle, 8> clip(VectorTransferOpTy transfer, using edsc::intrinsics::select; IndexHandle zero(index_t(0)), one(index_t(1)); - llvm::SmallVector<edsc::ValueHandle, 8> memRefAccess(transfer.getIndices()); + llvm::SmallVector<edsc::ValueHandle, 8> memRefAccess(transfer.indices()); llvm::SmallVector<edsc::ValueHandle, 8> clippedScalarAccessExprs( memRefAccess.size(), edsc::IndexHandle()); @@ -180,7 +174,7 @@ llvm::SmallVector<edsc::ValueHandle, 8> clip(VectorTransferOpTy transfer, ++memRefDim) { // Linear search on a small number of entries. int loopIndex = -1; - auto exprs = transfer.getPermutationMap().getResults(); + auto exprs = transfer.permutation_map().getResults(); for (auto en : llvm::enumerate(exprs)) { auto expr = en.value(); auto dim = expr.template dyn_cast<AffineDimExpr>(); @@ -273,9 +267,9 @@ VectorTransferRewriter<VectorTransferReadOp>::matchAndRewrite( // 1. Setup all the captures. ScopedContext scope(rewriter, transfer.getLoc()); - IndexedValue remote(transfer.getMemRef()); - MemRefView view(transfer.getMemRef()); - VectorView vectorView(transfer.getVector()); + IndexedValue remote(transfer.memref()); + MemRefView view(transfer.memref()); + VectorView vectorView(transfer.vector()); SmallVector<IndexHandle, 8> ivs = makeIndexHandles(vectorView.rank()); SmallVector<ValueHandle *, 8> pivs = makeIndexHandlePointers(MutableArrayRef<IndexHandle>(ivs)); @@ -291,12 +285,12 @@ VectorTransferRewriter<VectorTransferReadOp>::matchAndRewrite( // 2. Emit alloc-copy-load-dealloc. ValueHandle tmp = alloc(tmpMemRefType(transfer)); IndexedValue local(tmp); - ValueHandle vec = vector_type_cast(tmp, vectorMemRefType(transfer)); + ValueHandle vec = vector_type_cast(tmp); LoopNestBuilder(pivs, lbs, ubs, steps)([&] { // Computes clippedScalarAccessExprs in the loop nest scope (ivs exist). local(ivs) = remote(clip(transfer, view, ivs)); }); - ValueHandle vectorValue = std_load(vec, {constant_index(0)}); + ValueHandle vectorValue = std_load(vec); (dealloc(tmp)); // vexing parse // 3. Propagate. @@ -336,10 +330,10 @@ VectorTransferRewriter<VectorTransferWriteOp>::matchAndRewrite( // 1. Setup all the captures. ScopedContext scope(rewriter, transfer.getLoc()); - IndexedValue remote(transfer.getMemRef()); - MemRefView view(transfer.getMemRef()); - ValueHandle vectorValue(transfer.getVector()); - VectorView vectorView(transfer.getVector()); + IndexedValue remote(transfer.memref()); + MemRefView view(transfer.memref()); + ValueHandle vectorValue(transfer.vector()); + VectorView vectorView(transfer.vector()); SmallVector<IndexHandle, 8> ivs = makeIndexHandles(vectorView.rank()); SmallVector<ValueHandle *, 8> pivs = makeIndexHandlePointers(ivs); coalesceCopy(transfer, &pivs, &vectorView); @@ -354,8 +348,8 @@ VectorTransferRewriter<VectorTransferWriteOp>::matchAndRewrite( // 2. Emit alloc-store-copy-dealloc. ValueHandle tmp = alloc(tmpMemRefType(transfer)); IndexedValue local(tmp); - ValueHandle vec = vector_type_cast(tmp, vectorMemRefType(transfer)); - std_store(vectorValue, vec, {constant_index(0)}); + ValueHandle vec = vector_type_cast(tmp); + std_store(vectorValue, vec); LoopNestBuilder(pivs, lbs, ubs, steps)([&] { // Computes clippedScalarAccessExprs in the loop nest scope (ivs exist). remote(clip(transfer, view, ivs)) = local(ivs); diff --git a/mlir/lib/Transforms/MaterializeVectors.cpp b/mlir/lib/Transforms/MaterializeVectors.cpp index a0b60dd3648..06016da5caa 100644 --- a/mlir/lib/Transforms/MaterializeVectors.cpp +++ b/mlir/lib/Transforms/MaterializeVectors.cpp @@ -465,7 +465,7 @@ static AffineMap projectedPermutationMap(VectorTransferOpTy transfer, ++dim; }, superVectorType.getShape(), *optionalRatio); - auto permutationMap = transfer.getPermutationMap(); + auto permutationMap = transfer.permutation_map(); LLVM_DEBUG(permutationMap.print(dbgs() << "\npermutationMap: ")); if (keep.empty()) { return permutationMap; @@ -486,16 +486,16 @@ static Operation *instantiate(OpBuilder b, VectorTransferReadOp read, ArrayRef<unsigned> hwVectorInstance, DenseMap<Value *, Value *> *substitutionsMap) { SmallVector<Value *, 8> indices = - map(makePtrDynCaster<Value>(), read.getIndices()); + map(makePtrDynCaster<Value>(), read.indices()); auto affineIndices = reindexAffineIndices(b, hwVectorType, hwVectorInstance, indices); auto map = projectedPermutationMap(read, hwVectorType); if (!map) { return nullptr; } - auto cloned = b.create<VectorTransferReadOp>(read.getLoc(), hwVectorType, - read.getMemRef(), affineIndices, - map, read.getPaddingValue()); + auto cloned = b.create<VectorTransferReadOp>( + read.getLoc(), hwVectorType, read.memref(), affineIndices, + AffineMapAttr::get(map), read.padding()); return cloned.getOperation(); } @@ -510,14 +510,14 @@ static Operation *instantiate(OpBuilder b, VectorTransferWriteOp write, ArrayRef<unsigned> hwVectorInstance, DenseMap<Value *, Value *> *substitutionsMap) { SmallVector<Value *, 8> indices = - map(makePtrDynCaster<Value>(), write.getIndices()); + map(makePtrDynCaster<Value>(), write.indices()); auto affineIndices = reindexAffineIndices(b, hwVectorType, hwVectorInstance, indices); auto cloned = b.create<VectorTransferWriteOp>( write.getLoc(), - substitute(write.getVector(), hwVectorType, substitutionsMap), - write.getMemRef(), affineIndices, - projectedPermutationMap(write, hwVectorType)); + substitute(write.vector(), hwVectorType, substitutionsMap), + write.memref(), affineIndices, + AffineMapAttr::get(projectedPermutationMap(write, hwVectorType))); return cloned.getOperation(); } diff --git a/mlir/lib/Transforms/Vectorize.cpp b/mlir/lib/Transforms/Vectorize.cpp index a1e87568745..b3eea35a55f 100644 --- a/mlir/lib/Transforms/Vectorize.cpp +++ b/mlir/lib/Transforms/Vectorize.cpp @@ -35,6 +35,7 @@ #include "mlir/Pass/Pass.h" #include "mlir/Support/Functional.h" #include "mlir/Support/LLVM.h" +#include "mlir/Transforms/FoldUtils.h" #include "mlir/Transforms/Passes.h" #include "llvm/ADT/DenseMap.h" @@ -718,6 +719,8 @@ struct VectorizationState { // Checks that the type of `op` is AffineStoreOp and adds it to the terminals // set. void registerTerminal(Operation *op); + // Folder used to factor out constant creation. + OperationFolder *folder; private: void registerReplacement(Value *key, Value *value); @@ -832,7 +835,11 @@ static LogicalResult vectorizeRootOrTerminal(Value *iv, LLVM_DEBUG(permutationMap.print(dbgs())); auto transfer = b.create<vector::VectorTransferReadOp>( opInst->getLoc(), vectorType, memoryOp.getMemRef(), - map(makePtrDynCaster<Value>(), indices), permutationMap); + map(makePtrDynCaster<Value>(), indices), + AffineMapAttr::get(permutationMap), + // TODO(b/144455320) add a proper padding value, not just 0.0 : f32 + state->folder->create<ConstantFloatOp>( + b, opInst->getLoc(), llvm::APFloat(0.0f), b.getF32Type())); state->registerReplacement(opInst, transfer.getOperation()); } else { state->registerTerminal(opInst); @@ -1058,7 +1065,8 @@ static Operation *vectorizeOneOperation(Operation *opInst, LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ permutationMap: "); LLVM_DEBUG(permutationMap.print(dbgs())); auto transfer = b.create<vector::VectorTransferWriteOp>( - opInst->getLoc(), vectorValue, memRef, indices, permutationMap); + opInst->getLoc(), vectorValue, memRef, indices, + AffineMapAttr::get(permutationMap)); auto *res = transfer.getOperation(); LLVM_DEBUG(dbgs() << "\n[early-vect]+++++ vectorized store: " << *res); // "Terminals" (i.e. AffineStoreOps) are erased on the spot. @@ -1152,8 +1160,10 @@ static LogicalResult vectorizeNonTerminals(VectorizationState *state) { static LogicalResult vectorizeRootMatch(NestedMatch m, VectorizationStrategy *strategy) { auto loop = cast<AffineForOp>(m.getMatchedOperation()); + OperationFolder folder(loop.getContext()); VectorizationState state; state.strategy = strategy; + state.folder = &folder; // Since patterns are recursive, they can very well intersect. // Since we do not want a fully greedy strategy in general, we decouple |

