[Mlir-commits] [mlir] 98770ec - [mlir][bufferization] Add `buffer_loop_hoisting` transform op

Matthias Springer llvmlistbot at llvm.org
Fri Jul 14 08:09:53 PDT 2023


Author: Matthias Springer
Date: 2023-07-14T17:09:38+02:00
New Revision: 98770ecd76bb9cb1067c78c502be3899a28e5f92

URL: https://github.com/llvm/llvm-project/commit/98770ecd76bb9cb1067c78c502be3899a28e5f92
DIFF: https://github.com/llvm/llvm-project/commit/98770ecd76bb9cb1067c78c502be3899a28e5f92.diff

LOG: [mlir][bufferization] Add `buffer_loop_hoisting` transform op

This op hoists buffer allocation from loops.

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
    mlir/include/mlir/Dialect/Bufferization/Transforms/Transforms.h
    mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp
    mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
    mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td b/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
index 0a32afd0e19fe9..46a95ad8db2a6d 100644
--- a/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
+++ b/mlir/include/mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.td
@@ -19,6 +19,35 @@ include "mlir/IR/OpBase.td"
 def Transform_EmptyOp : Transform_ConcreteOpType<"tensor.empty">;
 def Transform_AllocTensorOp : Transform_ConcreteOpType<"bufferization.alloc_tensor">;
 
+//===----------------------------------------------------------------------===//
+// BufferLoopHoistingOp
+//===----------------------------------------------------------------------===//
+
+def BufferLoopHoistingOp
+    : Op<Transform_Dialect, "bufferization.buffer_loop_hoisting",
+        [DeclareOpInterfaceMethods<MemoryEffectsOpInterface>,
+         TransformEachOpTrait, TransformOpInterface]> {
+  let description = [{
+    Hoist buffer allocations ("memref.alloc" and "memref.alloca") from loops
+    within the targeted op. This transform assumes that there are no buffer
+    deallocation ops in the IR.
+
+    This transform reads the `target` handle and modifies the payload.
+  }];
+
+  let arguments = (ins TransformHandleTypeInterface:$target);
+  let results = (outs);
+  let assemblyFormat = "$target attr-dict `:` type($target)";
+
+  let extraClassDeclaration = [{
+    ::mlir::DiagnosedSilenceableFailure applyToOne(
+        ::mlir::transform::TransformRewriter &rewriter,
+        ::mlir::Operation *target,
+        ::mlir::transform::ApplyToEachResultList &results,
+        ::mlir::transform::TransformState &state);
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // OneShotBufferizeOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/Transforms.h b/mlir/include/mlir/Dialect/Bufferization/Transforms/Transforms.h
index d964be91f9626b..a0cfc811a0b50a 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/Transforms.h
@@ -41,6 +41,10 @@ LogicalResult eliminateEmptyTensors(RewriterBase &rewriter, Operation *op,
                                     AnchorMatchFn anchorMatchFunc,
                                     RewriteFn rewriteFunc);
 
+/// Within the given operation, hoist buffers from loops where possible. See
+/// "BufferLoopHoistingPass" for more information.
+void hoistBuffersFromLoops(Operation *op);
+
 /// Try to eliminate tensor::EmptyOps inside `op` that are anchored on an
 /// InsertSliceOp, i.e., if it is eventually inserted into another tensor
 /// (and some other conditions are met).

diff  --git a/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp b/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp
index f866484f485678..f1233739524d28 100644
--- a/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp
+++ b/mlir/lib/Dialect/Bufferization/TransformOps/BufferizationTransformOps.cpp
@@ -22,6 +22,23 @@ using namespace mlir;
 using namespace mlir::bufferization;
 using namespace mlir::transform;
 
+//===----------------------------------------------------------------------===//
+// BufferLoopHoistingOp
+//===----------------------------------------------------------------------===//
+
+DiagnosedSilenceableFailure transform::BufferLoopHoistingOp::applyToOne(
+    TransformRewriter &rewriter, Operation *target,
+    ApplyToEachResultList &results, TransformState &state) {
+  bufferization::hoistBuffersFromLoops(target);
+  return DiagnosedSilenceableFailure::success();
+}
+
+void transform::BufferLoopHoistingOp::getEffects(
+    SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
+  onlyReadsHandle(getTarget(), effects);
+  modifiesPayload(effects);
+}
+
 //===----------------------------------------------------------------------===//
 // OneShotBufferizeOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp b/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
index 278664abcf49d2..2a2baf39235250 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
@@ -14,6 +14,7 @@
 #include "mlir/Dialect/Bufferization/Transforms/Passes.h"
 
 #include "mlir/Dialect/Bufferization/Transforms/BufferUtils.h"
+#include "mlir/Dialect/Bufferization/Transforms/Transforms.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/MemRef/IR/MemRef.h"
 #include "mlir/IR/Operation.h"
@@ -389,9 +390,7 @@ struct BufferLoopHoistingPass
 
   void runOnOperation() override {
     // Hoist all allocations out of loops.
-    BufferAllocationHoisting<BufferAllocationLoopHoistingState> optimizer(
-        getOperation());
-    optimizer.hoist();
+    hoistBuffersFromLoops(getOperation());
   }
 };
 
@@ -432,6 +431,11 @@ class PromoteBuffersToStackPass
 
 } // namespace
 
+void mlir::bufferization::hoistBuffersFromLoops(Operation *op) {
+  BufferAllocationHoisting<BufferAllocationLoopHoistingState> optimizer(op);
+  optimizer.hoist();
+}
+
 std::unique_ptr<Pass> mlir::bufferization::createBufferHoistingPass() {
   return std::make_unique<BufferHoistingPass>();
 }

diff  --git a/mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir b/mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir
index 94550c8d4374a5..7c8bb422f533d7 100644
--- a/mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir
+++ b/mlir/test/Dialect/Bufferization/Transforms/transform-ops.mlir
@@ -180,3 +180,23 @@ func.func @empty_tensor_elimination(
       : tensor<5xf32> into tensor<10xf32>
   return %2 : tensor<10xf32>
 }
+
+// -----
+
+transform.sequence failures(propagate) {
+^bb0(%arg1: !transform.any_op):
+  %0 = transform.structured.match ops{["func.func"]} in %arg1 : (!transform.any_op) -> !transform.any_op
+  transform.bufferization.buffer_loop_hoisting %0 : !transform.any_op
+}
+
+// CHECK-LABEL: func @buffer_loop_hoisting(
+//       CHECK:   memref.alloca
+//       CHECK:   scf.for
+//       CHECK:     memref.store
+func.func @buffer_loop_hoisting(%lb: index, %ub: index, %step: index, %f: f32, %pos: index) {
+  scf.for %iv = %lb to %ub step %step {
+    %0 = memref.alloca() : memref<5xf32>
+    memref.store %f, %0[%pos] : memref<5xf32>
+  }
+  return
+}


        


More information about the Mlir-commits mailing list