aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mlir/docs/Tutorials/transform/ChH.md14
-rw-r--r--mlir/test/Examples/transform/ChH/full.mlir13
2 files changed, 27 insertions, 0 deletions
diff --git a/mlir/docs/Tutorials/transform/ChH.md b/mlir/docs/Tutorials/transform/ChH.md
index 0696853..7c12728 100644
--- a/mlir/docs/Tutorials/transform/ChH.md
+++ b/mlir/docs/Tutorials/transform/ChH.md
@@ -497,6 +497,20 @@ bufferization is directly available as a transform operation.
function_boundary_type_conversion = 1 : i32 }
```
+One-shot bufferization itself does not produce buffer deallocations, which may
+lead to leaks. So we have to run the buffer deallocation pass pipeline to avoid
+them. Note that the transform dialect seamlessly runs named passes and pass
+pipelines: if desired, one could replace complex `--pass-pipeline expressions`
+with operations. Note that we apply the pipeline to functions rather than entire
+module to avoid running it on the transform IR that is contained in the module.
+
+```mlir
+%f = transform.structured.match ops{["func.func"]} in %arg1
+ : (!transform.any_op) -> !transform.any_op
+transform.apply_registered_pass "buffer-deallocation-pipeline" to %f
+ : (!transform.any_op) -> !transform.any_op
+```
+
In this particular case, the transformed IR could be directly bufferized. This
is not always the case in general as some operations, in particular
`tensor.empty` may not be bufferizable. Such operations need to be removed
diff --git a/mlir/test/Examples/transform/ChH/full.mlir b/mlir/test/Examples/transform/ChH/full.mlir
index ed0509f..d90d740 100644
--- a/mlir/test/Examples/transform/ChH/full.mlir
+++ b/mlir/test/Examples/transform/ChH/full.mlir
@@ -1,6 +1,7 @@
// RUN: mlir-opt %s --test-transform-dialect-interpreter \
// RUN: --test-transform-dialect-erase-schedule \
// RUN: --math-uplift-to-fma \
+// RUN: --convert-bufferization-to-memref \
// RUN: --test-lower-to-llvm |\
// RUN: FileCheck %s
@@ -307,10 +308,22 @@ module attributes { transform.with_named_sequence } {
// transformation process, so invalidation is not an issue. However, if
// other transformations, such as loop unrolling, are required after
// bufferization, new handles should be produced using the match operations.
+ //
+ // One-shot bufferization itself does not produce buffer deallocations,
+ // which may lead to leaks. So we have to run the buffer deallocation pass
+ // pipeline to avoid them. Note that the transform dialect seamlessly runs
+ // named passes and pass pipelines: if desired, one could replace complex
+ // --pass-pipeline expressions with operations. Note that we apply the
+ // pipeline to functions rather than entire module to avoid running it
+ // on the transform IR that is contained in the module.
%arg1 = transform.bufferization.one_shot_bufferize %arg0 {
bufferize_function_boundaries = true,
function_boundary_type_conversion = 1 : i32 }
: (!transform.any_op) -> !transform.any_op
+ %f = transform.structured.match ops{["func.func"]} in %arg1
+ : (!transform.any_op) -> !transform.any_op
+ transform.apply_registered_pass "buffer-deallocation-pipeline" to %f
+ : (!transform.any_op) -> !transform.any_op
// Apply general canonicalization and CSE to each function after
// bufferization as new simplification opportunities may have appeared.