[Mlir-commits] [mlir] [MLIR][NFC] Retire let constructor for Bufferization (PR #129850)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed Mar 5 00:54:22 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-bufferization

Author: lorenzo chelini (chelini)

<details>
<summary>Changes</summary>

`let constructor` is legacy (do not use in tree!) since the table gen
backend emits most of the glue logic to build a pass.

---

Patch is 30.77 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/129850.diff


13 Files Affected:

- (modified) mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.h (-58) 
- (modified) mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td (+20-36) 
- (modified) mlir/lib/Dialect/Bufferization/Pipelines/BufferizationPipelines.cpp (+4-1) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp (+2-7) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp (+8-26) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/BufferResultsToOutParams.cpp (+3-10) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/Bufferize.cpp (+4-15) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/DropEquivalentBufferResults.cpp (+2-7) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/EmptyTensorElimination.cpp (+3-7) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/EmptyTensorToAllocTensor.cpp (+2-9) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/LowerDeallocations.cpp (+2-6) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/OptimizeAllocationLiveness.cpp (+2-11) 
- (modified) mlir/lib/Dialect/Bufferization/Transforms/OwnershipBasedBufferDeallocation.cpp (+4-18) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.h b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.h
index c5d0853d6ff97..493180cd54e5b 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.h
@@ -30,25 +30,6 @@ using DeallocHelperMap = llvm::DenseMap<Operation *, func::FuncOp>;
 #define GEN_PASS_DECL
 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
 
-/// Creates an instance of the OwnershipBasedBufferDeallocation pass to free all
-/// allocated buffers.
-std::unique_ptr<Pass> createOwnershipBasedBufferDeallocationPass(
-    DeallocationOptions options = DeallocationOptions());
-
-/// Creates a pass that finds all temporary allocations
-/// and attempts to move the deallocation after the last user/dependency
-/// of the allocation, thereby optimizing allocation liveness.
-std::unique_ptr<Pass> createOptimizeAllocationLivenessPass();
-
-/// Creates a pass that optimizes `bufferization.dealloc` operations. For
-/// example, it reduces the number of alias checks needed at runtime using
-/// static alias analysis.
-std::unique_ptr<Pass> createBufferDeallocationSimplificationPass();
-
-/// Creates an instance of the LowerDeallocations pass to lower
-/// `bufferization.dealloc` operations to the `memref` dialect.
-std::unique_ptr<Pass> createLowerDeallocationsPass();
-
 /// Adds the conversion pattern of the `bufferization.dealloc` operation to the
 /// given pattern set for use in other transformation passes.
 void populateBufferizationDeallocLoweringPattern(
@@ -141,14 +122,6 @@ func::FuncOp buildDeallocationLibraryFunction(OpBuilder &builder, Location loc,
 LogicalResult deallocateBuffersOwnershipBased(FunctionOpInterface op,
                                               DeallocationOptions options);
 
-/// Creates a pass that moves allocations upwards to reduce the number of
-/// required copies that are inserted during the BufferDeallocation pass.
-std::unique_ptr<Pass> createBufferHoistingPass();
-
-/// Creates a pass that moves allocations upwards out of loops. This avoids
-/// reallocations inside of loops.
-std::unique_ptr<Pass> createBufferLoopHoistingPass();
-
 // Options struct for BufferResultsToOutParams pass.
 // Note: defined only here, not in tablegen.
 struct BufferResultsToOutParamsOpts {
@@ -192,51 +165,20 @@ struct BufferResultsToOutParamsOpts {
   bool hoistStaticAllocs = false;
 };
 
-/// Creates a pass that converts memref function results to out-params.
-std::unique_ptr<Pass> createBufferResultsToOutParamsPass(
-    const BufferResultsToOutParamsOpts &options = {});
-
 /// Replace buffers that are returned from a function with an out parameter.
 /// Also update all call sites.
 LogicalResult
 promoteBufferResultsToOutParams(ModuleOp module,
                                 const BufferResultsToOutParamsOpts &options);
 
-/// Creates a pass that drops memref function results that are equivalent to a
-/// function argument.
-std::unique_ptr<Pass> createDropEquivalentBufferResultsPass();
-
-/// Create a pass that rewrites tensor.empty to bufferization.alloc_tensor.
-std::unique_ptr<Pass> createEmptyTensorToAllocTensorPass();
-
 /// Drop all memref function results that are equivalent to a function argument.
 LogicalResult dropEquivalentBufferResults(ModuleOp module);
 
-/// Create a pass that bufferizes all ops that implement BufferizableOpInterface
-/// with One-Shot Bufferize.
-std::unique_ptr<Pass> createOneShotBufferizePass();
-
-/// Create a pass that bufferizes all ops that implement BufferizableOpInterface
-/// with One-Shot Bufferize and the specified bufferization options.
-std::unique_ptr<Pass>
-createOneShotBufferizePass(const OneShotBufferizationOptions &options);
-
-/// Creates a pass that promotes heap-based allocations to stack-based ones.
-/// Only buffers smaller than the provided size are promoted.
-/// Dynamic shaped buffers are promoted up to the given rank.
-std::unique_ptr<Pass>
-createPromoteBuffersToStackPass(unsigned maxAllocSizeInBytes = 1024,
-                                unsigned maxRankOfAllocatedMemRef = 1);
-
 /// Creates a pass that promotes heap-based allocations to stack-based ones.
 /// Only buffers smaller with `isSmallAlloc(alloc) == true` are promoted.
 std::unique_ptr<Pass>
 createPromoteBuffersToStackPass(std::function<bool(Value)> isSmallAlloc);
 
-/// Create a pass that tries to eliminate tensor.empty ops that are anchored on
-/// insert_slice ops.
-std::unique_ptr<Pass> createEmptyTensorEliminationPass();
-
 //===----------------------------------------------------------------------===//
 // Registration
 //===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
index f20f177d8443b..9c51935dc3892 100644
--- a/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
+++ b/mlir/include/mlir/Dialect/Bufferization/Transforms/Passes.td
@@ -11,7 +11,7 @@
 
 include "mlir/Pass/PassBase.td"
 
-def OwnershipBasedBufferDeallocation : Pass<
+def OwnershipBasedBufferDeallocationPass : Pass<
     "ownership-based-buffer-deallocation"> {
   let summary = "Adds all required dealloc operations for all allocations in "
                 "the input program";
@@ -144,7 +144,6 @@ def OwnershipBasedBufferDeallocation : Pass<
            "dynamically pass ownership of memrefs to callees. This can enable "
            "earlier deallocations.">,
   ];
-  let constructor = "mlir::bufferization::createOwnershipBasedBufferDeallocationPass()";
 
   let dependentDialects = [
     "mlir::bufferization::BufferizationDialect", "mlir::arith::ArithDialect",
@@ -152,7 +151,7 @@ def OwnershipBasedBufferDeallocation : Pass<
   ];
 }
 
-def BufferDeallocationSimplification :
+def BufferDeallocationSimplificationPass :
     Pass<"buffer-deallocation-simplification"> {
   let summary = "Optimizes `bufferization.dealloc` operation for more "
                 "efficient codegen";
@@ -163,32 +162,28 @@ def BufferDeallocationSimplification :
     some memref isn't deallocated twice (double free).
   }];
 
-  let constructor =
-    "mlir::bufferization::createBufferDeallocationSimplificationPass()";
-
   let dependentDialects = [
     "mlir::bufferization::BufferizationDialect", "mlir::arith::ArithDialect",
     "mlir::memref::MemRefDialect"
   ];
 }
 
-def OptimizeAllocationLiveness
+def OptimizeAllocationLivenessPass
     : Pass<"optimize-allocation-liveness", "func::FuncOp"> {
   let summary = "This pass optimizes the liveness of temp allocations in the "
                 "input function";
-  let description =
-       [{This pass will find all operations that have a memory allocation effect.
-       It will search for the corresponding deallocation and move it right after
-       the last user of the allocation.
-       This will optimize the liveness of the allocations.
-
-       The pass is expected to run after the deallocation pipeline.}];
-  let constructor =
-      "mlir::bufferization::createOptimizeAllocationLivenessPass()";
+  let description = [{
+      This pass will find all operations that have a memory allocation effect.
+      It will search for the corresponding deallocation and move it right after
+      the last user of the allocation.
+      This will optimize the liveness of the allocations.
+
+      The pass is expected to run after the deallocation pipeline.
+  }];
   let dependentDialects = ["mlir::memref::MemRefDialect"];
 }
 
-def LowerDeallocations : Pass<"bufferization-lower-deallocations"> {
+def LowerDeallocationsPass : Pass<"bufferization-lower-deallocations"> {
   let summary = "Lowers `bufferization.dealloc` operations to `memref.dealloc`"
                 "operations";
   let description = [{
@@ -202,36 +197,31 @@ def LowerDeallocations : Pass<"bufferization-lower-deallocations"> {
     library functions to avoid code-size blow-up.
   }];
 
-  let constructor =
-    "mlir::bufferization::createLowerDeallocationsPass()";
-
   let dependentDialects = [
     "arith::ArithDialect", "memref::MemRefDialect", "scf::SCFDialect",
     "func::FuncDialect"
   ];
 }
 
-def BufferHoisting : Pass<"buffer-hoisting", "func::FuncOp"> {
+def BufferHoistingPass : Pass<"buffer-hoisting", "func::FuncOp"> {
   let summary = "Optimizes placement of allocation operations by moving them "
                 "into common dominators and out of nested regions";
   let description = [{
     This pass implements an approach to aggressively move allocations upwards
     into common dominators and out of nested regions.
   }];
-  let constructor = "mlir::bufferization::createBufferHoistingPass()";
 }
 
-def BufferLoopHoisting : Pass<"buffer-loop-hoisting", "func::FuncOp"> {
+def BufferLoopHoistingPass : Pass<"buffer-loop-hoisting", "func::FuncOp"> {
   let summary = "Optimizes placement of allocation operations by moving them "
                 "out of loop nests";
   let description = [{
     This pass implements an approach to aggressively move allocations upwards
     out of loop nests. It does not move allocations into common dominators.
   }];
-  let constructor = "mlir::bufferization::createBufferLoopHoistingPass()";
 }
 
-def BufferResultsToOutParams : Pass<"buffer-results-to-out-params", "ModuleOp">  {
+def BufferResultsToOutParamsPass : Pass<"buffer-results-to-out-params", "ModuleOp">  {
   let summary = "Converts memref-typed function results to out-params";
   let description = [{
     Some calling conventions prefer to pass output memrefs as "out params". The
@@ -266,11 +256,10 @@ def BufferResultsToOutParams : Pass<"buffer-results-to-out-params", "ModuleOp">
        "bool", /*default=*/"false",
        "Hoist static allocations to call sites.">,
   ];
-  let constructor = "mlir::bufferization::createBufferResultsToOutParamsPass()";
   let dependentDialects = ["memref::MemRefDialect"];
 }
 
-def DropEquivalentBufferResults : Pass<"drop-equivalent-buffer-results", "ModuleOp">  {
+def DropEquivalentBufferResultsPass : Pass<"drop-equivalent-buffer-results", "ModuleOp">  {
   let summary = "Remove MemRef return values that are equivalent to a bbArg";
   let description = [{
     This pass removes MemRef return values from functions if they are equivalent
@@ -280,22 +269,20 @@ def DropEquivalentBufferResults : Pass<"drop-equivalent-buffer-results", "Module
     Note: If a bbArg buffer is not returned directly but casted to beforehand,
     the buffer is still considered equivalent.
   }];
-  let constructor = "mlir::bufferization::createDropEquivalentBufferResultsPass()";
   let dependentDialects = ["memref::MemRefDialect"];
 }
 
-def EmptyTensorToAllocTensor : Pass<"empty-tensor-to-alloc-tensor"> {
+def EmptyTensorToAllocTensorPass : Pass<"empty-tensor-to-alloc-tensor"> {
   let summary = "Replace all empty ops by alloc_tensor ops.";
   let description = [{
     tensor.empty ops return a tensor of unspecified contents who's only purpose
     is to carry the tensor shape. This pass converts such ops to
     bufferization.alloc_tensor ops, which bufferize to buffer allocations.
   }];
-  let constructor = "mlir::bufferization::createEmptyTensorToAllocTensorPass()";
   let dependentDialects = ["tensor::TensorDialect"];
 }
 
-def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
+def OneShotBufferizePass : Pass<"one-shot-bufferize", "ModuleOp"> {
   let summary = "One-Shot Bufferize";
   let description = [{
     This pass bufferizes all ops that implement `BufferizableOpInterface`. It
@@ -455,7 +442,6 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
     Option<"bufferAlignment", "buffer-alignment", "uint64_t", /*default=*/"64",
            "Sets the alignment of newly allocated buffers.">,
   ];
-  let constructor = "mlir::bufferization::createOneShotBufferizePass()";
 
   let statistics = [
     Statistic<"numBufferAlloc", "num-buffer-alloc",
@@ -467,7 +453,7 @@ def OneShotBufferize : Pass<"one-shot-bufferize", "ModuleOp"> {
   ];
 }
 
-def PromoteBuffersToStack : Pass<"promote-buffers-to-stack", "func::FuncOp"> {
+def PromoteBuffersToStackPass : Pass<"promote-buffers-to-stack", "func::FuncOp"> {
   let summary = "Promotes heap-based allocations to automatically managed "
                 "stack-based allocations";
   let description = [{
@@ -477,7 +463,6 @@ def PromoteBuffersToStack : Pass<"promote-buffers-to-stack", "func::FuncOp"> {
     shaped buffers that are limited by the rank of the tensor can be
     converted. They are only transformed if they are considered to be small.
   }];
-  let constructor = "mlir::bufferization::createPromoteBuffersToStackPass()";
   let options = [
     Option<"maxAllocSizeInBytes", "max-alloc-size-in-bytes", "unsigned",
            /*default=*/"1024",
@@ -488,7 +473,7 @@ def PromoteBuffersToStack : Pass<"promote-buffers-to-stack", "func::FuncOp"> {
   ];
 }
 
-def EmptyTensorElimination : Pass<"eliminate-empty-tensors"> {
+def EmptyTensorEliminationPass : Pass<"eliminate-empty-tensors"> {
   let summary = "Try to eliminate all tensor.empty ops.";
   let description = [{
     Try to eliminate "tensor.empty" ops inside `op`. This transformation looks
@@ -508,7 +493,6 @@ def EmptyTensorElimination : Pass<"eliminate-empty-tensors"> {
     "tensor.empty" op. The "tensor.empty" op is replaced with a
     "tensor.extract_slice" op.
   }];
-  let constructor = "mlir::bufferization::createEmptyTensorEliminationPass()";
 }
 
 #endif // MLIR_DIALECT_BUFFERIZATION_TRANSFORMS_PASSES
diff --git a/mlir/lib/Dialect/Bufferization/Pipelines/BufferizationPipelines.cpp b/mlir/lib/Dialect/Bufferization/Pipelines/BufferizationPipelines.cpp
index 7124eab882b08..b184265f464d1 100644
--- a/mlir/lib/Dialect/Bufferization/Pipelines/BufferizationPipelines.cpp
+++ b/mlir/lib/Dialect/Bufferization/Pipelines/BufferizationPipelines.cpp
@@ -22,7 +22,10 @@ void mlir::bufferization::buildBufferDeallocationPipeline(
     OpPassManager &pm, const BufferDeallocationPipelineOptions &options) {
   pm.addPass(memref::createExpandReallocPass(/*emitDeallocs=*/false));
   pm.addPass(createCanonicalizerPass());
-  pm.addPass(createOwnershipBasedBufferDeallocationPass(options));
+
+  OwnershipBasedBufferDeallocationPassOptions deallocationOptions{
+      options.privateFunctionDynamicOwnership};
+  pm.addPass(createOwnershipBasedBufferDeallocationPass(deallocationOptions));
   pm.addPass(createCanonicalizerPass());
   pm.addPass(createBufferDeallocationSimplificationPass());
   pm.addPass(createLowerDeallocationsPass());
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp b/mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp
index de3ae82f87086..35f86a62ae592 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/BufferDeallocationSimplification.cpp
@@ -22,7 +22,7 @@
 
 namespace mlir {
 namespace bufferization {
-#define GEN_PASS_DEF_BUFFERDEALLOCATIONSIMPLIFICATION
+#define GEN_PASS_DEF_BUFFERDEALLOCATIONSIMPLIFICATIONPASS
 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
 } // namespace bufferization
 } // namespace mlir
@@ -453,7 +453,7 @@ namespace {
 /// into the right positions. Furthermore, it inserts additional clones if
 /// necessary. It uses the algorithm described at the top of the file.
 struct BufferDeallocationSimplificationPass
-    : public bufferization::impl::BufferDeallocationSimplificationBase<
+    : public bufferization::impl::BufferDeallocationSimplificationPassBase<
           BufferDeallocationSimplificationPass> {
   void runOnOperation() override {
     BufferOriginAnalysis analysis(getOperation());
@@ -477,8 +477,3 @@ struct BufferDeallocationSimplificationPass
 };
 
 } // namespace
-
-std::unique_ptr<Pass>
-mlir::bufferization::createBufferDeallocationSimplificationPass() {
-  return std::make_unique<BufferDeallocationSimplificationPass>();
-}
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp b/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
index 93c1f9a4f2b55..ebd0d827526d7 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/BufferOptimizations.cpp
@@ -24,9 +24,9 @@
 
 namespace mlir {
 namespace bufferization {
-#define GEN_PASS_DEF_BUFFERHOISTING
-#define GEN_PASS_DEF_BUFFERLOOPHOISTING
-#define GEN_PASS_DEF_PROMOTEBUFFERSTOSTACK
+#define GEN_PASS_DEF_BUFFERHOISTINGPASS
+#define GEN_PASS_DEF_BUFFERLOOPHOISTINGPASS
+#define GEN_PASS_DEF_PROMOTEBUFFERSTOSTACKPASS
 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
 } // namespace bufferization
 } // namespace mlir
@@ -416,7 +416,7 @@ class BufferPlacementPromotion : BufferPlacementTransformationBase {
 /// The buffer hoisting pass that hoists allocation nodes into dominating
 /// blocks.
 struct BufferHoistingPass
-    : public bufferization::impl::BufferHoistingBase<BufferHoistingPass> {
+    : public bufferization::impl::BufferHoistingPassBase<BufferHoistingPass> {
 
   void runOnOperation() override {
     // Hoist all allocations into dominator blocks.
@@ -428,7 +428,7 @@ struct BufferHoistingPass
 
 /// The buffer loop hoisting pass that hoists allocation nodes out of loops.
 struct BufferLoopHoistingPass
-    : public bufferization::impl::BufferLoopHoistingBase<
+    : public bufferization::impl::BufferLoopHoistingPassBase<
           BufferLoopHoistingPass> {
 
   void runOnOperation() override {
@@ -440,15 +440,11 @@ struct BufferLoopHoistingPass
 /// The promote buffer to stack pass that tries to convert alloc nodes into
 /// alloca nodes.
 class PromoteBuffersToStackPass
-    : public bufferization::impl::PromoteBuffersToStackBase<
+    : public bufferization::impl::PromoteBuffersToStackPassBase<
           PromoteBuffersToStackPass> {
-public:
-  PromoteBuffersToStackPass(unsigned maxAllocSizeInBytes,
-                            unsigned maxRankOfAllocatedMemRef) {
-    this->maxAllocSizeInBytes = maxAllocSizeInBytes;
-    this->maxRankOfAllocatedMemRef = maxRankOfAllocatedMemRef;
-  }
+  using Base::Base;
 
+public:
   explicit PromoteBuffersToStackPass(std::function<bool(Value)> isSmallAlloc)
       : isSmallAlloc(std::move(isSmallAlloc)) {}
 
@@ -479,20 +475,6 @@ void mlir::bufferization::hoistBuffersFromLoops(Operation *op) {
   optimizer.hoist();
 }
 
-std::unique_ptr<Pass> mlir::bufferization::createBufferHoistingPass() {
-  return std::make_unique<BufferHoistingPass>();
-}
-
-std::unique_ptr<Pass> mlir::bufferization::createBufferLoopHoistingPass() {
-  return std::make_unique<BufferLoopHoistingPass>();
-}
-
-std::unique_ptr<Pass> mlir::bufferization::createPromoteBuffersToStackPass(
-    unsigned maxAllocSizeInBytes, unsigned maxRankOfAllocatedMemRef) {
-  return std::make_unique<PromoteBuffersToStackPass>(maxAllocSizeInBytes,
-                                                     maxRankOfAllocatedMemRef);
-}
-
 std::unique_ptr<Pass> mlir::bufferization::createPromoteBuffersToStackPass(
     std::function<bool(Value)> isSmallAlloc) {
   return std::make_unique<PromoteBuffersToStackPass>(std::move(isSmallAlloc));
diff --git a/mlir/lib/Dialect/Bufferization/Transforms/BufferResultsToOutParams.cpp b/mlir/lib/Dialect/Bufferization/Transforms/BufferResultsToOutParams.cpp
index ce0f112dc2dd2..1c95ab77b9f33 100644
--- a/mlir/lib/Dialect/Bufferization/Transforms/BufferResultsToOutParams.cpp
+++ b/mlir/lib/Dialect/Bufferization/Transforms/BufferResultsToOutParams.cpp
@@ -16,7 +16,7 @@
 
 namespace mlir {
 namespace bufferization {
-#define GEN_PASS_DEF_BUFFERRESULTSTOOUTPARAMS
+#define GEN_PASS_DEF_BUFFERRESULTSTOOUTPARAMSPASS
 #include "mlir/Dialect/Bufferization/Transforms/Passes.h.inc"
 } // namespace bufferization
 } // namespace mlir
@@ -233,11 +233,9 @@ LogicalResult mlir::bufferization::promoteBufferResultsToOutParams(
 
 namespace {
 struct BufferResultsToOutParamsPass
-    : bufferization::impl::BufferResultsToOutParamsBase<
+    : bufferization::impl::BufferResultsToOutParamsPassBase<
           BufferResultsToOutParamsPass> {
-  explicit BufferResultsToOutParamsPass(
-      const bufferization::BufferResultsToOutParamsOpts &options)
-      : options(options) {}
+  using Base::Base;
 
   void runOnOperation() override {
     // Convert from pass options i...
[truncated]

``````````

</details>


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


More information about the Mlir-commits mailing list