Skip to content

Commit 3d693bd

Browse files
committed
[mlir][vector] Add memory effects to transfer_read transfer_write ops
This allow more accurate modeling of the side effects and allow dead code elimination to remove dead transfer ops. Differential Revision: https://reviews.llvm.org/D94318
1 parent 7200d2c commit 3d693bd

File tree

4 files changed

+50
-4
lines changed

4 files changed

+50
-4
lines changed

mlir/include/mlir/Dialect/Vector/VectorOps.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,8 @@ def Vector_ExtractStridedSliceOp :
10551055
def Vector_TransferReadOp :
10561056
Vector_Op<"transfer_read", [
10571057
DeclareOpInterfaceMethods<VectorTransferOpInterface>,
1058-
DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>
1058+
DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>,
1059+
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>
10591060
]>,
10601061
Arguments<(ins AnyShaped:$source, Variadic<Index>:$indices,
10611062
AffineMapAttr:$permutation_map, AnyType:$padding,
@@ -1224,7 +1225,8 @@ def Vector_TransferReadOp :
12241225
def Vector_TransferWriteOp :
12251226
Vector_Op<"transfer_write", [
12261227
DeclareOpInterfaceMethods<VectorTransferOpInterface>,
1227-
DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>
1228+
DeclareOpInterfaceMethods<VectorUnrollOpInterface, ["getShapeForUnroll"]>,
1229+
DeclareOpInterfaceMethods<MemoryEffectsOpInterface>
12281230
]>,
12291231
Arguments<(ins AnyVector:$vector, AnyShaped:$source,
12301232
Variadic<Index>:$indices,

mlir/lib/Dialect/Vector/VectorOps.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,14 @@ Optional<SmallVector<int64_t, 4>> TransferReadOp::getShapeForUnroll() {
22272227
return SmallVector<int64_t, 4>{s.begin(), s.end()};
22282228
}
22292229

2230+
void TransferReadOp::getEffects(
2231+
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
2232+
&effects) {
2233+
if (getShapedType().isa<MemRefType>())
2234+
effects.emplace_back(MemoryEffects::Read::get(), source(),
2235+
SideEffects::DefaultResource::get());
2236+
}
2237+
22302238
//===----------------------------------------------------------------------===//
22312239
// TransferWriteOp
22322240
//===----------------------------------------------------------------------===//
@@ -2341,6 +2349,14 @@ Optional<SmallVector<int64_t, 4>> TransferWriteOp::getShapeForUnroll() {
23412349
return llvm::to_vector<4>(getVectorType().getShape());
23422350
}
23432351

2352+
void TransferWriteOp::getEffects(
2353+
SmallVectorImpl<SideEffects::EffectInstance<MemoryEffects::Effect>>
2354+
&effects) {
2355+
if (getShapedType().isa<MemRefType>())
2356+
effects.emplace_back(MemoryEffects::Write::get(), source(),
2357+
SideEffects::DefaultResource::get());
2358+
}
2359+
23442360
//===----------------------------------------------------------------------===//
23452361
// MaskedLoadOp
23462362
//===----------------------------------------------------------------------===//

mlir/test/Conversion/VectorToSCF/vector-to-loops.mlir

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: mlir-opt %s -convert-vector-to-scf -split-input-file | FileCheck %s
2-
// RUN: mlir-opt %s -convert-vector-to-scf=full-unroll=true -split-input-file | FileCheck %s --check-prefix=FULL-UNROLL
1+
// RUN: mlir-opt %s -convert-vector-to-scf -split-input-file -allow-unregistered-dialect | FileCheck %s
2+
// RUN: mlir-opt %s -convert-vector-to-scf=full-unroll=true -split-input-file -allow-unregistered-dialect | FileCheck %s --check-prefix=FULL-UNROLL
33

44
// CHECK-LABEL: func @materialize_read_1d() {
55
func @materialize_read_1d() {
@@ -22,6 +22,9 @@ func @materialize_read_1d() {
2222
// CHECK-NEXT: else
2323
// CHECK-NEXT: vector.insertelement
2424
// CHECK-NEXT: store
25+
// Add a dummy use to prevent dead code elimination from removing transfer
26+
// read ops.
27+
"dummy_use"(%f1, %f2, %f3, %f4) : (vector<4xf32>, vector<4xf32>, vector<4xf32>, vector<4xf32>) -> ()
2528
}
2629
}
2730
return
@@ -41,6 +44,9 @@ func @materialize_read_1d_partially_specialized(%dyn1 : index, %dyn2 : index, %d
4144
%f1 = vector.transfer_read %A[%i0, %i1, %i2, %i3, %i4], %f0 {permutation_map = affine_map<(d0, d1, d2, d3, d4) -> (d3)>} : memref<7x?x?x42x?xf32>, vector<4xf32>
4245
%i3p1 = affine.apply affine_map<(d0) -> (d0 + 1)> (%i3)
4346
%f2 = vector.transfer_read %A[%i0, %i1, %i2, %i3p1, %i4], %f0 {permutation_map = affine_map<(d0, d1, d2, d3, d4) -> (d3)>} : memref<7x?x?x42x?xf32>, vector<4xf32>
47+
// Add a dummy use to prevent dead code elimination from removing
48+
// transfer read ops.
49+
"dummy_use"(%f1, %f2) : (vector<4xf32>, vector<4xf32>) -> ()
4450
}
4551
}
4652
}
@@ -88,6 +94,9 @@ func @materialize_read(%M: index, %N: index, %O: index, %P: index) {
8894
// CHECK-NEXT: }
8995
// CHECK-NEXT: }
9096
// CHECK-NEXT: }
97+
// CHECK-NEXT: %[[ALLOC_CAST:.*]] = vector.type_cast %[[ALLOC]] : memref<5x4xvector<3xf32>> to memref<vector<5x4x3xf32>>
98+
// CHECK-NEXT: %[[LD:.*]] = load %[[ALLOC_CAST]][] : memref<vector<5x4x3xf32>>
99+
// CHECK-NEXT: "dummy_use"(%[[LD]]) : (vector<5x4x3xf32>) -> ()
91100
// CHECK-NEXT: }
92101
// CHECK-NEXT: }
93102
// CHECK-NEXT: }
@@ -104,6 +113,9 @@ func @materialize_read(%M: index, %N: index, %O: index, %P: index) {
104113
affine.for %i2 = 0 to %O {
105114
affine.for %i3 = 0 to %P step 5 {
106115
%f = vector.transfer_read %A[%i0, %i1, %i2, %i3], %f0 {permutation_map = affine_map<(d0, d1, d2, d3) -> (d3, 0, d0)>} : memref<?x?x?x?xf32>, vector<5x4x3xf32>
116+
// Add a dummy use to prevent dead code elimination from removing
117+
// transfer read ops.
118+
"dummy_use"(%f) : (vector<5x4x3xf32>) -> ()
107119
}
108120
}
109121
}

mlir/test/Dialect/Vector/canonicalize.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,3 +661,19 @@ func @broadcast_to_shapecast(%arg0: vector<4x4xf16>) -> vector<1x4x4xf16> {
661661
return %0 : vector<1x4x4xf16>
662662
}
663663

664+
// -----
665+
666+
// CHECK-LABEL: func @dead_transfer_op
667+
// CHECK-NOT: vector.transfer_read
668+
// CHECK-NOT: vector.transfer_write
669+
// CHECK: return
670+
func @dead_transfer_op(%arg0 : tensor<4x4xf32>, %arg1 : memref<4x4xf32>,
671+
%v0 : vector<1x4xf32>) {
672+
%c0 = constant 0 : index
673+
%cf0 = constant 0.0 : f32
674+
%r = vector.transfer_read %arg1[%c0, %c0], %cf0 :
675+
memref<4x4xf32>, vector<1x4xf32>
676+
%w = vector.transfer_write %v0, %arg0[%c0, %c0] :
677+
vector<1x4xf32>, tensor<4x4xf32>
678+
return
679+
}

0 commit comments

Comments
 (0)