[mlir] Add MemoryEffects::Allocate to memref::CloneOp
authorButygin <ivan.butygin@intel.com>
Sat, 26 Jun 2021 10:05:29 +0000 (13:05 +0300)
committerButygin <ivan.butygin@intel.com>
Tue, 29 Jun 2021 10:37:32 +0000 (13:37 +0300)
Without it BufferDeallocationPass process only CloneOps created during pass itself and ignore all CloneOps that were already present in IR.

For our specific usecase:

```
func @dealloc_existing_clones(%arg0: memref<?x?xf64>, %arg1: memref<?x?xf64>) -> memref<?x?xf64> {
  return %arg0 : memref<?x?xf64>
}
```

Input arguments will be freed immediately after return from function and we want to prolong lifetime for the returned argument.
To achieve this we explicitly add clones to all input memrefs and expect that BufferDeallocationPass will add correct deallocs to them (unnessesary clone+dealloc pairs will be canonicalized away later).

Differential Revision: https://reviews.llvm.org/D104973

mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
mlir/test/Transforms/buffer-deallocation.mlir

index 6f358d8..c9df5fc 100644 (file)
@@ -514,6 +514,8 @@ void CloneOp::getEffects(
                        SideEffects::DefaultResource::get());
   effects.emplace_back(MemoryEffects::Write::get(), output(),
                        SideEffects::DefaultResource::get());
+  effects.emplace_back(MemoryEffects::Allocate::get(), output(),
+                       SideEffects::DefaultResource::get());
 }
 
 namespace {
index 7794511..7bc335a 100644 (file)
@@ -1207,3 +1207,18 @@ func @noRegionBranchOpInterface() {
   }) : () -> (i32)
   "test.terminator"() : () -> ()
 }
+
+// -----
+
+// CHECK-LABEL: func @dealloc_existing_clones
+// CHECK: (%[[ARG0:.*]]: memref<?x?xf64>, %[[ARG1:.*]]: memref<?x?xf64>)
+// CHECK: %[[RES0:.*]] = memref.clone %[[ARG0]]
+// CHECK: %[[RES1:.*]] = memref.clone %[[ARG1]]
+// CHECK-NOT: memref.dealloc %[[RES0]]
+// CHECK: memref.dealloc %[[RES1]]
+// CHECK: return %[[RES0]]
+func @dealloc_existing_clones(%arg0: memref<?x?xf64>, %arg1: memref<?x?xf64>) -> memref<?x?xf64> {
+  %0 = memref.clone %arg0 : memref<?x?xf64> to memref<?x?xf64>
+  %1 = memref.clone %arg1 : memref<?x?xf64> to memref<?x?xf64>
+  return %0 : memref<?x?xf64>
+}