Skip to content

Commit e379b4e

Browse files
committed
[mlir][memref] annotate operand and result of realloc with proper memory attributes
Reviewed By: springerm Differential Revision: https://reviews.llvm.org/D143599
1 parent be6fe95 commit e379b4e

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,16 @@ def MemRef_ReallocOp : MemRef_Op<"realloc"> {
246246
```
247247
}];
248248

249-
let arguments = (ins MemRefRankOf<[AnyType], [1]>:$source,
249+
// Note that we conceptually mark the operands as freeing the incoming
250+
// memref and allocating the outcoming memref, even though this may not
251+
// physically happen on each execution.
252+
253+
let arguments = (ins Arg<MemRefRankOf<[AnyType], [1]>, "", [MemFree]>:$source,
250254
Optional<Index>:$dynamicResultSize,
251255
ConfinedAttr<OptionalAttr<I64Attr>,
252256
[IntMinValue<0>]>:$alignment);
253257

254-
let results = (outs MemRefRankOf<[AnyType], [1]>);
258+
let results = (outs Res<MemRefRankOf<[AnyType], [1]>, "", [MemAlloc<DefaultResource>]>);
255259

256260
let builders = [
257261
OpBuilder<(ins "MemRefType":$resultType,

mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocation.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,16 @@ struct DefaultAllocationInterface
639639
}
640640
};
641641

642+
struct DefaultReallocationInterface
643+
: public bufferization::AllocationOpInterface::ExternalModel<
644+
DefaultAllocationInterface, memref::ReallocOp> {
645+
static std::optional<Operation *> buildDealloc(OpBuilder &builder,
646+
Value realloc) {
647+
return builder.create<memref::DeallocOp>(realloc.getLoc(), realloc)
648+
.getOperation();
649+
}
650+
};
651+
642652
/// The actual buffer deallocation pass that inserts and moves dealloc nodes
643653
/// into the right positions. Furthermore, it inserts additional clones if
644654
/// necessary. It uses the algorithm described at the top of the file.
@@ -703,6 +713,7 @@ void bufferization::registerAllocationOpInterfaceExternalModels(
703713
DialectRegistry &registry) {
704714
registry.addExtension(+[](MLIRContext *ctx, memref::MemRefDialect *dialect) {
705715
memref::AllocOp::attachInterface<DefaultAllocationInterface>(*ctx);
716+
memref::ReallocOp::attachInterface<DefaultReallocationInterface>(*ctx);
706717
});
707718
}
708719

mlir/test/Dialect/Bufferization/Transforms/buffer-deallocation.mlir

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,3 +1418,24 @@ func.func @test_affine_if_4(%arg0 : memref<10xf32>) -> memref<10xf32> {
14181418
// CHECK-NEXT: %[[ALLOC:.*]] = memref.alloc() : memref<10xf32>
14191419
// CHECK-NEXT: memref.dealloc %[[ALLOC]] : memref<10xf32>
14201420
// CHECK-NEXT: affine.if
1421+
1422+
// -----
1423+
1424+
// Ensure we free the realloc, not the alloc.
1425+
1426+
// CHECK-LABEL: func @auto_dealloc()
1427+
func.func @auto_dealloc() {
1428+
%c10 = arith.constant 10 : index
1429+
%c100 = arith.constant 100 : index
1430+
%alloc = memref.alloc(%c10) : memref<?xi32>
1431+
%realloc = memref.realloc %alloc(%c100) : memref<?xi32> to memref<?xi32>
1432+
return
1433+
}
1434+
// CHECK-DAG: %[[C10:.*]] = arith.constant 10 : index
1435+
// CHECK-DAG: %[[C100:.*]] = arith.constant 100 : index
1436+
// CHECK-NEXT: %[[A:.*]] = memref.alloc(%[[C10]]) : memref<?xi32>
1437+
// CHECK-NEXT: %[[R:.*]] = memref.realloc %alloc(%[[C100]]) : memref<?xi32> to memref<?xi32>
1438+
// CHECK-NEXT: memref.dealloc %[[R]] : memref<?xi32>
1439+
// CHECK-NEXT: return
1440+
1441+

0 commit comments

Comments
 (0)