[Mlir-commits] [mlir] [mlir][bufferization] Move AllocationOpInterface implementations (PR #65578)

Martin Erhart llvmlistbot at llvm.org
Mon Sep 11 07:26:59 PDT 2023


================
@@ -682,3 +682,59 @@ BufferizationOptions bufferization::getPartialBufferizationOptions() {
   options.opFilter.allowDialect<BufferizationDialect>();
   return options;
 }
+
+//===----------------------------------------------------------------------===//
+// Default AllocationOpInterface implementation and registration
+//===----------------------------------------------------------------------===//
+
+namespace {
+struct DefaultAllocationInterface
+    : public bufferization::AllocationOpInterface::ExternalModel<
+          DefaultAllocationInterface, memref::AllocOp> {
+  static std::optional<Operation *> buildDealloc(OpBuilder &builder,
+                                                 Value alloc) {
+    return builder.create<memref::DeallocOp>(alloc.getLoc(), alloc)
+        .getOperation();
+  }
+  static std::optional<Value> buildClone(OpBuilder &builder, Value alloc) {
+    return builder.create<bufferization::CloneOp>(alloc.getLoc(), alloc)
+        .getResult();
+  }
+  static ::mlir::HoistingKind getHoistingKind() {
+    return HoistingKind::Loop | HoistingKind::Block;
+  }
+  static ::std::optional<::mlir::Operation *>
+  buildPromotedAlloc(OpBuilder &builder, Value alloc) {
+    Operation *definingOp = alloc.getDefiningOp();
+    return builder.create<memref::AllocaOp>(
+        definingOp->getLoc(), cast<MemRefType>(definingOp->getResultTypes()[0]),
+        definingOp->getOperands(), definingOp->getAttrs());
+  }
+};
+
+struct DefaultAutomaticAllocationHoistingInterface
+    : public bufferization::AllocationOpInterface::ExternalModel<
+          DefaultAutomaticAllocationHoistingInterface, memref::AllocaOp> {
+  static ::mlir::HoistingKind getHoistingKind() { return HoistingKind::Loop; }
+};
+
+struct DefaultReallocationInterface
+    : public bufferization::AllocationOpInterface::ExternalModel<
+          DefaultAllocationInterface, memref::ReallocOp> {
+  static std::optional<Operation *> buildDealloc(OpBuilder &builder,
+                                                 Value realloc) {
+    return builder.create<memref::DeallocOp>(realloc.getLoc(), realloc)
+        .getOperation();
+  }
+};
+} // namespace
+
+void bufferization::registerAllocationOpInterfaceExternalModels(
----------------
maerhart wrote:

I wouldn't necessarily say that this is just an interface for the memref dialect. I think it's more an interface to customize various bufferization passes (e.g., buffer hoisting). In the extreme case to make them work on other dialects than just memref.

In the long-term I think it would be better to split this interface into one per bufferization pass (currently that would be one for hoisting and one for buffer promotion, the parts used for deallocation would be removed) and name them accordingly. The implementations would live in the dialect directory of the ops for which it is implemented.

In the short term I can offer to move the interface implementations to `BufferOptimization.cpp` where it is actually used (and not just registered). Ideally, we would move the implementation for `alloc`, `alloca`, and `realloc` in `MemRef/Transforms/AllocationOpInterfaceImpl.cpp` and the implementation of `clone` in `Bufferization/Transforms/AllocationOpInterface.cpp`, however, this is not possible because it would introduce a dependency cycle (`bufferization <-> memref`) unless the interface declaration is moved out of the bufferization dialect build target. But where should it go then? A new `BufferizationInterfaces` target?

What do you think?

https://github.com/llvm/llvm-project/pull/65578


More information about the Mlir-commits mailing list