[Mlir-commits] [mlir] 00a5ae1 - [mlir][bufferization] Better propagation of bufferizesToMemoryWrite through regions

Matthias Springer llvmlistbot at llvm.org
Mon Feb 13 07:56:14 PST 2023


Author: Matthias Springer
Date: 2023-02-13T16:52:26+01:00
New Revision: 00a5ae12448e6f33e40c38afd640eafdb7dab212

URL: https://github.com/llvm/llvm-project/commit/00a5ae12448e6f33e40c38afd640eafdb7dab212
DIFF: https://github.com/llvm/llvm-project/commit/00a5ae12448e6f33e40c38afd640eafdb7dab212.diff

LOG: [mlir][bufferization] Better propagation of bufferizesToMemoryWrite through regions

`bufferizesToMemoryWrite(OpResult)` looks for OpOperands that bufferize to memory writes inside the region of the defining op (if it has one). Currently, if the reverse use-def chain stops at any value inside of the region, the OpResult is considered to bufferize to a memory write.

It is always safe to have false positives among `bufferizesToMemoryWrite`, so the previous implementation is also correct. However, it can lead to additional buffer copies.

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td
    mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
    mlir/test/Dialect/SCF/one-shot-bufferize.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td
index 6e796c8aebb0a..4f33425169a51 100644
--- a/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td
+++ b/mlir/include/mlir/Dialect/Bufferization/IR/BufferizableOpInterface.td
@@ -120,8 +120,7 @@ def BufferizableOpInterface : OpInterface<"BufferizableOpInterface"> {
              result also bufferizes to a memory write.
 
           3. At least one aliasing OpOperand's value is defined inside the
-             defining op of the given OpResult and it is a memory write or the
-             reverse SSA use-def chain ends in the defining op.
+             defining op of the given OpResult and it is a memory write.
 
              According to this rule, an aliasing OpOperand value that is defined
              inside this op and is bufferizing to a memory write makes the given

diff  --git a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
index 3e882ba5ed8b0..f25a8eb0cf6c9 100644
--- a/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
+++ b/mlir/lib/Dialect/Bufferization/IR/BufferizableOpInterface.cpp
@@ -896,7 +896,8 @@ bool bufferization::detail::defaultResultBufferizesToMemoryWrite(
     if (!state
              .findValueInReverseUseDefChain(alias.opOperand->get(),
                                             isMemoryWriteInsideOp,
-                                            /*followEquivalentOnly=*/false)
+                                            /*followEquivalentOnly=*/false,
+                                            /*alwaysIncludeLeaves=*/false)
              .empty())
       return true;
   }

diff  --git a/mlir/test/Dialect/SCF/one-shot-bufferize.mlir b/mlir/test/Dialect/SCF/one-shot-bufferize.mlir
index 131f3066ec2c3..e37fe73d01170 100644
--- a/mlir/test/Dialect/SCF/one-shot-bufferize.mlir
+++ b/mlir/test/Dialect/SCF/one-shot-bufferize.mlir
@@ -1,4 +1,5 @@
 // RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="allow-return-allocs bufferize-function-boundaries" -drop-equivalent-buffer-results -buffer-deallocation -split-input-file | FileCheck %s
+// RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="allow-return-allocs bufferize-function-boundaries" -drop-equivalent-buffer-results -split-input-file | FileCheck %s --check-prefix=CHECK-NO-DEALLOC-PASS
 
 // Run fuzzer with 
diff erent seeds.
 // RUN: mlir-opt %s -allow-unregistered-dialect -one-shot-bufferize="allow-return-allocs test-analysis-only analysis-fuzzer-seed=23 bufferize-function-boundaries" -split-input-file -o /dev/null
@@ -950,3 +951,31 @@ func.func @regression_cast_in_loop() -> tensor<2xindex> {
   }
   return %1 : tensor<2xindex>
 }
+
+// -----
+
+// This test does not compute anything meaningful but it tests that
+// bufferizesToMemoryWrite is correctly propagated through regions.
+
+// CHECK-NO-DEALLOC-PASS-LABEL: func @elide_copy_of_non_writing_scf_if(
+func.func @elide_copy_of_non_writing_scf_if(%c: i1, %p1: index, %p2: index, %f: f32)
+  -> (tensor<10xf32>, f32)
+{
+  %r = scf.if %c -> tensor<10xf32> {
+    // CHECK-NO-DEALLOC-PASS: memref.alloc
+    %t1 = bufferization.alloc_tensor() : tensor<10xf32>
+    scf.yield %t1 : tensor<10xf32>
+  } else {
+    // CHECK-NO-DEALLOC-PASS: memref.alloc
+    %t2 = bufferization.alloc_tensor() : tensor<10xf32>
+    scf.yield %t2 : tensor<10xf32>
+  }
+
+  // No copy should be inserted because %r does not bufferize to a memory write.
+  // I.e., %r does not have defined contents and the copy can be elided.
+  // CHECK-NO-DEALLOC-PASS-NOT: memref.alloc
+  // CHECK-NO-DEALLOC-PASS-NOT: memref.copy
+  %r2 = tensor.insert %f into %r[%p1] : tensor<10xf32>
+  %r3 = tensor.extract %r[%p2] : tensor<10xf32>
+  return %r2, %r3 : tensor<10xf32>, f32
+}


        


More information about the Mlir-commits mailing list