Skip to content

Commit 87e07b4

Browse files
committed
[mlir] Use memory effect to detecting allocation
This commit marks AllocLikeOp as MemAlloc in StandardOps. Also in Linalg dependency analysis use memory effect to detect allocation. This allows the dependency analysis to be more general and recognize other allocation-like operations. Differential Revision: https://reviews.llvm.org/D78705
1 parent 4a065a7 commit 87e07b4

File tree

3 files changed

+67
-10
lines changed

3 files changed

+67
-10
lines changed

mlir/include/mlir/Dialect/StandardOps/IR/Ops.td

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,12 @@ class FloatArithmeticOp<string mnemonic, list<OpTrait> traits = []> :
129129
//
130130
// %0 = alloclike(%m)[%s] : memref<8x?xf32, (d0, d1)[s0] -> ((d0 + s0), d1)>
131131
//
132-
class AllocLikeOp<string mnemonic,
133-
list<OpVariableDecorator> resultDecorators = [],
134-
list<OpTrait> traits = []> :
135-
Std_Op<mnemonic, traits> {
132+
class AllocLikeOp<string mnemonic, list<OpTrait> traits = []> :
133+
Std_Op<mnemonic, !listconcat(traits, [MemoryEffects<[MemAlloc]>])> {
136134

137135
let arguments = (ins Variadic<Index>:$value,
138136
Confined<OptionalAttr<I64Attr>, [IntMinValue<0>]>:$alignment);
139-
let results = (outs Arg<AnyMemRef, "", resultDecorators>);
137+
let results = (outs Res<AnyMemRef, "", [MemAlloc]>);
140138

141139
let builders = [OpBuilder<
142140
"OpBuilder &builder, OperationState &result, MemRefType memrefType", [{
@@ -278,7 +276,7 @@ def AddIOp : IntArithmeticOp<"addi", [Commutative]> {
278276
// AllocOp
279277
//===----------------------------------------------------------------------===//
280278

281-
def AllocOp : AllocLikeOp<"alloc", [MemAlloc], [MemoryEffects<[MemAlloc]>]> {
279+
def AllocOp : AllocLikeOp<"alloc"> {
282280
let summary = "memory allocation operation";
283281
let description = [{
284282
The `alloc` operation allocates a region of memory, as specified by its

mlir/lib/Dialect/Linalg/Analysis/DependenceAnalysis.cpp

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,26 @@ Value Aliases::find(Value v) {
3737
while (true) {
3838
if (v.isa<BlockArgument>())
3939
return v;
40+
4041
Operation *defOp = v.getDefiningOp();
41-
if (auto alloc = dyn_cast_or_null<AllocOp>(defOp)) {
42-
if (isStrided(alloc.getType()))
43-
return alloc.getResult();
42+
if (!defOp)
43+
return v;
44+
45+
if (auto memEffect = dyn_cast<MemoryEffectOpInterface>(defOp)) {
46+
// Collect all memory effects on `v`.
47+
SmallVector<MemoryEffects::EffectInstance, 1> effects;
48+
memEffect.getEffectsOnValue(v, effects);
49+
50+
// If we have the 'Allocate' memory effect on `v`, then `v` should be the
51+
// original buffer.
52+
if (llvm::any_of(
53+
effects, [](const MemoryEffects::EffectInstance &instance) {
54+
return isa<MemoryEffects::Allocate>(instance.getEffect());
55+
}))
56+
return v;
4457
}
45-
if (auto viewLikeOp = dyn_cast_or_null<ViewLikeOpInterface>(defOp)) {
58+
59+
if (auto viewLikeOp = dyn_cast<ViewLikeOpInterface>(defOp)) {
4660
auto it =
4761
aliases.insert(std::make_pair(v, find(viewLikeOp.getViewSource())));
4862
return it.first->second;

mlir/test/Dialect/Linalg/fusion.mlir

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,3 +727,48 @@ func @fill_and_conv(%arg0: memref<1x4x5x1xf32>, %arg1: memref<2x3x1x1xf32>, %arg
727727
// CHECK: loop.for
728728
// CHECK: linalg.fill
729729
// CHECK: linalg.conv
730+
731+
// -----
732+
733+
// Test that different allocation-like ops are recognized and properly handled.
734+
func @accept_different_alloc_ops(%dim: index, %s0 : index, %s1: index) {
735+
%c0 = constant 0 : index
736+
%c1 = constant 1 : index
737+
%c2 = constant 2 : index
738+
%c3 = constant 3 : index
739+
%c4 = constant 4 : index
740+
741+
%A = alloca(%dim, %dim)[%s0, %s1] : memref<?x?xf32, offset: 0, strides: [?, ?]>
742+
%B = alloca(%dim, %dim)[%s0, %s1] : memref<?x?xf32, offset: 0, strides: [?, ?]>
743+
%C = alloc(%dim, %dim)[%s0, %s1] : memref<?x?xf32, offset: 0, strides: [?, ?]>
744+
745+
linalg.matmul(%A, %B, %C) :
746+
memref<?x?xf32, offset: 0, strides: [?, ?]>,
747+
memref<?x?xf32, offset: 0, strides: [?, ?]>,
748+
memref<?x?xf32, offset: 0, strides: [?, ?]>
749+
750+
loop.for %i = %c0 to %dim step %c2 {
751+
loop.for %j = %c0 to %dim step %c3 {
752+
loop.for %k = %c0 to %dim step %c4 {
753+
%0 = std.subview %A[%i, %k][%c2, %c4][%c1, %c1] :
754+
memref<?x?xf32, offset: 0, strides: [?, ?]> to
755+
memref<?x?xf32, offset: ?, strides: [?, ?]>
756+
%1 = std.subview %B[%k, %j][%c4, %c3][%c1, %c1] :
757+
memref<?x?xf32, offset: 0, strides: [?, ?]> to
758+
memref<?x?xf32, offset: ?, strides: [?, ?]>
759+
%2 = std.subview %C[%i, %j][%c2, %c3][%c1, %c1] :
760+
memref<?x?xf32, offset: 0, strides: [?, ?]> to
761+
memref<?x?xf32, offset: ?, strides: [?, ?]>
762+
linalg.matmul(%0, %1, %2) :
763+
memref<?x?xf32, offset: ?, strides: [?, ?]>,
764+
memref<?x?xf32, offset: ?, strides: [?, ?]>,
765+
memref<?x?xf32, offset: ?, strides: [?, ?]>
766+
}
767+
}
768+
}
769+
return
770+
}
771+
772+
// CHECK-LABEL: func @accept_different_alloc_ops
773+
// CHECK-COUNT-3: loop.for
774+
// CHECK-COUNT-2: linalg.matmul

0 commit comments

Comments
 (0)