summaryrefslogtreecommitdiff
path: root/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
diff options
context:
space:
mode:
authorStephen Neuendorffer <stephen.neuendorffer@xilinx.com>2021-04-13 12:34:28 -0700
committerStephen Neuendorffer <stephen.neuendorffer@xilinx.com>2021-05-19 10:50:48 -0700
commit29a50c5864ddab283c1ff38694fb5926ce37b39a (patch)
tree08ee4a6029a87754ccfeab84f988982cbd17295d /mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
parente4274cfe06fe48ed8f0c9f965c8b519e30433bf8 (diff)
[MLIR] Update Vector To LLVM conversion to be aware of assume_alignment
vector.transfer_read and vector.transfer_write operations are converted to llvm intrinsics with specific alignment information, however there doesn't seem to be a way in llvm to take information from llvm.assume intrinsics and change this alignment information. In any event, due the to the structure of the llvm.assume instrinsic, applying this information at the llvm level is more cumbersome. Instead, let's generate the masked vector load and store instrinsic with the right alignment information from MLIR in the first place. Since we're bothering to do this, lets just emit the proper alignment for loads, stores, scatter, and gather ops too. Differential Revision: https://reviews.llvm.org/D100444
Diffstat (limited to 'mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp')
-rw-r--r--mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp57
1 files changed, 45 insertions, 12 deletions
diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
index 566559158385..f3909b3e85c6 100644
--- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
+++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
@@ -16,6 +16,7 @@
#include "mlir/Dialect/StandardOps/IR/Ops.h"
#include "mlir/Dialect/Vector/VectorOps.h"
#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/Support/MathExtras.h"
#include "mlir/Target/LLVMIR/TypeTranslation.h"
#include "mlir/Transforms/DialectConversion.h"
@@ -119,6 +120,42 @@ LogicalResult getMemRefAlignment(LLVMTypeConverter &typeConverter,
return success();
}
+// Return the minimal alignment value that satisfies all the AssumeAlignment
+// uses of `value`. If no such uses exist, return 1.
+static unsigned getAssumedAlignment(Value value) {
+ unsigned align = 1;
+ for (auto &u : value.getUses()) {
+ Operation *owner = u.getOwner();
+ if (auto op = dyn_cast<memref::AssumeAlignmentOp>(owner))
+ align = mlir::lcm(align, op.alignment());
+ }
+ return align;
+}
+// Helper that returns data layout alignment of a memref associated with a
+// transfer op, including additional information from assume_alignment calls
+// on the source of the transfer
+LogicalResult getTransferOpAlignment(LLVMTypeConverter &typeConverter,
+ VectorTransferOpInterface xfer,
+ unsigned &align) {
+ if (failed(getMemRefAlignment(
+ typeConverter, xfer.getShapedType().cast<MemRefType>(), align)))
+ return failure();
+ align = std::max(align, getAssumedAlignment(xfer.source()));
+ return success();
+}
+
+// Helper that returns data layout alignment of a memref associated with a
+// load, store, scatter, or gather op, including additional information from
+// assume_alignment calls on the source of the transfer
+template <class OpAdaptor>
+LogicalResult getMemRefOpAlignment(LLVMTypeConverter &typeConverter,
+ OpAdaptor op, unsigned &align) {
+ if (failed(getMemRefAlignment(typeConverter, op.getMemRefType(), align)))
+ return failure();
+ align = std::max(align, getAssumedAlignment(op.base()));
+ return success();
+}
+
// Add an index vector component to a base pointer. This almost always succeeds
// unless the last stride is non-unit or the memory space is not zero.
static LogicalResult getIndexedPtrs(ConversionPatternRewriter &rewriter,
@@ -151,8 +188,7 @@ replaceTransferOpWithLoadOrStore(ConversionPatternRewriter &rewriter,
TransferReadOp xferOp,
ArrayRef<Value> operands, Value dataPtr) {
unsigned align;
- if (failed(getMemRefAlignment(
- typeConverter, xferOp.getShapedType().cast<MemRefType>(), align)))
+ if (failed(getTransferOpAlignment(typeConverter, xferOp, align)))
return failure();
rewriter.replaceOpWithNewOp<LLVM::LoadOp>(xferOp, dataPtr, align);
return success();
@@ -171,10 +207,8 @@ replaceTransferOpWithMasked(ConversionPatternRewriter &rewriter,
Value fill = rewriter.create<SplatOp>(loc, vecTy, adaptor.padding());
unsigned align;
- if (failed(getMemRefAlignment(
- typeConverter, xferOp.getShapedType().cast<MemRefType>(), align)))
+ if (failed(getTransferOpAlignment(typeConverter, xferOp, align)))
return failure();
-
rewriter.replaceOpWithNewOp<LLVM::MaskedLoadOp>(
xferOp, vecTy, dataPtr, mask, ValueRange{fill},
rewriter.getI32IntegerAttr(align));
@@ -187,8 +221,7 @@ replaceTransferOpWithLoadOrStore(ConversionPatternRewriter &rewriter,
TransferWriteOp xferOp,
ArrayRef<Value> operands, Value dataPtr) {
unsigned align;
- if (failed(getMemRefAlignment(
- typeConverter, xferOp.getShapedType().cast<MemRefType>(), align)))
+ if (failed(getTransferOpAlignment(typeConverter, xferOp, align)))
return failure();
auto adaptor = TransferWriteOpAdaptor(operands, xferOp->getAttrDictionary());
rewriter.replaceOpWithNewOp<LLVM::StoreOp>(xferOp, adaptor.vector(), dataPtr,
@@ -202,8 +235,7 @@ replaceTransferOpWithMasked(ConversionPatternRewriter &rewriter,
TransferWriteOp xferOp, ArrayRef<Value> operands,
Value dataPtr, Value mask) {
unsigned align;
- if (failed(getMemRefAlignment(
- typeConverter, xferOp.getShapedType().cast<MemRefType>(), align)))
+ if (failed(getTransferOpAlignment(typeConverter, xferOp, align)))
return failure();
auto adaptor = TransferWriteOpAdaptor(operands, xferOp->getAttrDictionary());
@@ -337,7 +369,8 @@ public:
// Resolve alignment.
unsigned align;
- if (failed(getMemRefAlignment(*this->getTypeConverter(), memRefTy, align)))
+ if (failed(getMemRefOpAlignment(*this->getTypeConverter(), loadOrStoreOp,
+ align)))
return failure();
// Resolve address.
@@ -367,7 +400,7 @@ public:
// Resolve alignment.
unsigned align;
- if (failed(getMemRefAlignment(*getTypeConverter(), memRefType, align)))
+ if (failed(getMemRefOpAlignment(*getTypeConverter(), gather, align)))
return failure();
// Resolve address.
@@ -402,7 +435,7 @@ public:
// Resolve alignment.
unsigned align;
- if (failed(getMemRefAlignment(*getTypeConverter(), memRefType, align)))
+ if (failed(getMemRefOpAlignment(*getTypeConverter(), scatter, align)))
return failure();
// Resolve address.