Skip to content

[MLIR] Split InlinerConfig into seperate header and add pass overload with it #150413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

WillFroom
Copy link
Contributor

Currently the only way to be able to modify the configuration is to pass as a string to initializeOptions which is quite cumbersome, this helps make that a bit easier.

@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir bazel "Peripheral" support tier build system: utils/bazel labels Jul 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 24, 2025

@llvm/pr-subscribers-mlir

Author: Will Froom (WillFroom)

Changes

Currently the only way to be able to modify the configuration is to pass as a string to initializeOptions which is quite cumbersome, this helps make that a bit easier.


Full diff: https://github.com/llvm/llvm-project/pull/150413.diff

5 Files Affected:

  • (modified) mlir/include/mlir/Transforms/Inliner.h (+1-72)
  • (added) mlir/include/mlir/Transforms/InlinerConfig.h (+98)
  • (modified) mlir/include/mlir/Transforms/Passes.h (+5)
  • (modified) mlir/lib/Transforms/InlinerPass.cpp (+17-20)
  • (modified) utils/bazel/llvm-project-overlay/mlir/BUILD.bazel (+1)
diff --git a/mlir/include/mlir/Transforms/Inliner.h b/mlir/include/mlir/Transforms/Inliner.h
index 0d3d3d1a3f9f2..241ab6f434981 100644
--- a/mlir/include/mlir/Transforms/Inliner.h
+++ b/mlir/include/mlir/Transforms/Inliner.h
@@ -17,6 +17,7 @@
 #include "mlir/Interfaces/CallInterfaces.h"
 #include "mlir/Pass/AnalysisManager.h"
 #include "mlir/Pass/PassManager.h"
+#include "mlir/Transforms/InlinerConfig.h"
 #include "mlir/Transforms/InliningUtils.h"
 #include "llvm/ADT/StringMap.h"
 
@@ -24,78 +25,6 @@ namespace mlir {
 class OpPassManager;
 class Operation;
 
-class InlinerConfig {
-public:
-  using DefaultPipelineTy = std::function<void(OpPassManager &)>;
-  using OpPipelinesTy = llvm::StringMap<OpPassManager>;
-
-  InlinerConfig() = default;
-  InlinerConfig(DefaultPipelineTy defaultPipeline,
-                unsigned maxInliningIterations)
-      : defaultPipeline(std::move(defaultPipeline)),
-        maxInliningIterations(maxInliningIterations) {}
-
-  const DefaultPipelineTy &getDefaultPipeline() const {
-    return defaultPipeline;
-  }
-  const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
-  unsigned getMaxInliningIterations() const { return maxInliningIterations; }
-  const InlinerInterface::CloneCallbackTy &getCloneCallback() const {
-    return cloneCallback;
-  }
-  bool getCanHandleMultipleBlocks() const { return canHandleMultipleBlocks; }
-
-  void setDefaultPipeline(DefaultPipelineTy pipeline) {
-    defaultPipeline = std::move(pipeline);
-  }
-  void setOpPipelines(OpPipelinesTy pipelines) {
-    opPipelines = std::move(pipelines);
-  }
-  void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
-  void setCloneCallback(InlinerInterface::CloneCallbackTy callback) {
-    cloneCallback = std::move(callback);
-  }
-  void setCanHandleMultipleBlocks(bool value = true) {
-    canHandleMultipleBlocks = value;
-  }
-
-private:
-  /// An optional function that constructs an optimization pipeline for
-  /// a given operation. This optimization pipeline is applied
-  /// only to those callable operations that do not have dedicated
-  /// optimization pipeline in opPipelines (based on the operation name).
-  DefaultPipelineTy defaultPipeline;
-  /// A map of operation names to pass pipelines to use when optimizing
-  /// callable operations of these types. This provides a specialized pipeline
-  /// instead of the one produced by defaultPipeline.
-  OpPipelinesTy opPipelines;
-  /// For SCC-based inlining algorithms, specifies maximum number of iterations
-  /// when inlining within an SCC.
-  unsigned maxInliningIterations{0};
-  /// Callback for cloning operations during inlining
-  InlinerInterface::CloneCallbackTy cloneCallback =
-      [](OpBuilder &builder, Region *src, Block *inlineBlock,
-         Block *postInsertBlock, IRMapping &mapper,
-         bool shouldCloneInlinedRegion) {
-        // Check to see if the region is being cloned, or moved inline. In
-        // either case, move the new blocks after the 'insertBlock' to improve
-        // IR readability.
-        Region *insertRegion = inlineBlock->getParent();
-        if (shouldCloneInlinedRegion)
-          src->cloneInto(insertRegion, postInsertBlock->getIterator(), mapper);
-        else
-          insertRegion->getBlocks().splice(postInsertBlock->getIterator(),
-                                           src->getBlocks(), src->begin(),
-                                           src->end());
-      };
-  /// Determine if the inliner can inline a function containing multiple
-  /// blocks into a region that requires a single block. By default, it is
-  /// not allowed. If it is true, cloneCallback should perform the extra
-  /// transformation. see the example in
-  /// mlir/test/lib/Transforms/TestInliningCallback.cpp
-  bool canHandleMultipleBlocks{false};
-};
-
 /// This is an implementation of the inliner
 /// that operates bottom up over the Strongly Connected Components(SCCs)
 /// of the CallGraph. This enables a more incremental propagation
diff --git a/mlir/include/mlir/Transforms/InlinerConfig.h b/mlir/include/mlir/Transforms/InlinerConfig.h
new file mode 100644
index 0000000000000..928869625b647
--- /dev/null
+++ b/mlir/include/mlir/Transforms/InlinerConfig.h
@@ -0,0 +1,98 @@
+//===- InlinerConfig.h - Config for the Inliner pass-------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the config class used by the Inliner class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TRANSFORMS_INLINER_CONFIG_H
+#define MLIR_TRANSFORMS_INLINER_CONFIG_H
+
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Transforms/InliningUtils.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace mlir {
+class OpPassManager;
+class Operation;
+
+class InlinerConfig {
+public:
+  using DefaultPipelineTy = std::function<void(OpPassManager &)>;
+  using OpPipelinesTy = llvm::StringMap<OpPassManager>;
+
+  InlinerConfig() = default;
+  InlinerConfig(DefaultPipelineTy defaultPipeline,
+                unsigned maxInliningIterations)
+      : defaultPipeline(std::move(defaultPipeline)),
+        maxInliningIterations(maxInliningIterations) {}
+
+  const DefaultPipelineTy &getDefaultPipeline() const {
+    return defaultPipeline;
+  }
+  const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
+  unsigned getMaxInliningIterations() const { return maxInliningIterations; }
+  const InlinerInterface::CloneCallbackTy &getCloneCallback() const {
+    return cloneCallback;
+  }
+  bool getCanHandleMultipleBlocks() const { return canHandleMultipleBlocks; }
+
+  void setDefaultPipeline(DefaultPipelineTy pipeline) {
+    defaultPipeline = std::move(pipeline);
+  }
+  void setOpPipelines(OpPipelinesTy pipelines) {
+    opPipelines = std::move(pipelines);
+  }
+  void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
+  void setCloneCallback(InlinerInterface::CloneCallbackTy callback) {
+    cloneCallback = std::move(callback);
+  }
+  void setCanHandleMultipleBlocks(bool value = true) {
+    canHandleMultipleBlocks = value;
+  }
+
+private:
+  /// An optional function that constructs an optimization pipeline for
+  /// a given operation. This optimization pipeline is applied
+  /// only to those callable operations that do not have dedicated
+  /// optimization pipeline in opPipelines (based on the operation name).
+  DefaultPipelineTy defaultPipeline;
+  /// A map of operation names to pass pipelines to use when optimizing
+  /// callable operations of these types. This provides a specialized pipeline
+  /// instead of the one produced by defaultPipeline.
+  OpPipelinesTy opPipelines;
+  /// For SCC-based inlining algorithms, specifies maximum number of iterations
+  /// when inlining within an SCC.
+  unsigned maxInliningIterations{0};
+  /// Callback for cloning operations during inlining
+  InlinerInterface::CloneCallbackTy cloneCallback =
+      [](OpBuilder &builder, Region *src, Block *inlineBlock,
+         Block *postInsertBlock, IRMapping &mapper,
+         bool shouldCloneInlinedRegion) {
+        // Check to see if the region is being cloned, or moved inline. In
+        // either case, move the new blocks after the 'insertBlock' to improve
+        // IR readability.
+        Region *insertRegion = inlineBlock->getParent();
+        if (shouldCloneInlinedRegion)
+          src->cloneInto(insertRegion, postInsertBlock->getIterator(), mapper);
+        else
+          insertRegion->getBlocks().splice(postInsertBlock->getIterator(),
+                                           src->getBlocks(), src->begin(),
+                                           src->end());
+      };
+  /// Determine if the inliner can inline a function containing multiple
+  /// blocks into a region that requires a single block. By default, it is
+  /// not allowed. If it is true, cloneCallback should perform the extra
+  /// transformation. see the example in
+  /// mlir/test/lib/Transforms/TestInliningCallback.cpp
+  bool canHandleMultipleBlocks{false};
+};
+
+} // namespace mlir
+
+#endif // MLIR_TRANSFORMS_INLINER_CONFIG_H
diff --git a/mlir/include/mlir/Transforms/Passes.h b/mlir/include/mlir/Transforms/Passes.h
index 9cd2ef34e15ea..32ffcbe469df0 100644
--- a/mlir/include/mlir/Transforms/Passes.h
+++ b/mlir/include/mlir/Transforms/Passes.h
@@ -17,6 +17,7 @@
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassManager.h"
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+#include "mlir/Transforms/InlinerConfig.h"
 #include "mlir/Transforms/LocationSnapshot.h"
 #include "mlir/Transforms/ViewOpGraph.h"
 #include "llvm/Support/Debug.h"
@@ -111,6 +112,10 @@ createInlinerPass(llvm::StringMap<OpPassManager> opPipelines);
 std::unique_ptr<Pass>
 createInlinerPass(llvm::StringMap<OpPassManager> opPipelines,
                   std::function<void(OpPassManager &)> defaultPipelineBuilder);
+/// Creates an instance of the inliner pass, using the provided config and
+/// threshold.
+std::unique_ptr<Pass> createInlinerPass(const InlinerConfig &inlinerConfig,
+                                        unsigned inliningThreshold = -1);
 
 /// Creates an optimization pass to remove dead values.
 std::unique_ptr<Pass> createRemoveDeadValuesPass();
diff --git a/mlir/lib/Transforms/InlinerPass.cpp b/mlir/lib/Transforms/InlinerPass.cpp
index 703e517d45374..e3326e0fc3410 100644
--- a/mlir/lib/Transforms/InlinerPass.cpp
+++ b/mlir/lib/Transforms/InlinerPass.cpp
@@ -41,10 +41,7 @@ namespace {
 class InlinerPass : public impl::InlinerBase<InlinerPass> {
 public:
   InlinerPass();
-  InlinerPass(const InlinerPass &) = default;
-  InlinerPass(std::function<void(OpPassManager &)> defaultPipeline);
-  InlinerPass(std::function<void(OpPassManager &)> defaultPipeline,
-              llvm::StringMap<OpPassManager> opPipelines);
+  InlinerPass(const InlinerConfig &inlinerConfig, unsigned inliningThreshold);
   void runOnOperation() override;
 
   /// A callback provided to the inliner driver to execute
@@ -73,23 +70,16 @@ class InlinerPass : public impl::InlinerBase<InlinerPass> {
 };
 } // namespace
 
-InlinerPass::InlinerPass() : InlinerPass(defaultInlinerOptPipeline) {}
-
-InlinerPass::InlinerPass(
-    std::function<void(OpPassManager &)> defaultPipelineArg)
-    : InlinerPass(std::move(defaultPipelineArg),
-                  llvm::StringMap<OpPassManager>{}) {}
-
-InlinerPass::InlinerPass(std::function<void(OpPassManager &)> defaultPipeline,
-                         llvm::StringMap<OpPassManager> opPipelines)
-    : config(std::move(defaultPipeline), maxInliningIterations) {
+InlinerPass::InlinerPass(const InlinerConfig &inlinerConfig,
+                         unsigned inliningThreshold)
+    : config(inlinerConfig) {
+  const auto &opPipelines = config.getOpPipelines();
   if (opPipelines.empty())
     return;
 
   // Update the option for the op specific optimization pipelines.
   for (auto &it : opPipelines)
     opPipelineList.addValue(it.second);
-  config.setOpPipelines(std::move(opPipelines));
 }
 
 // Return true if the inlining ratio does not exceed the threshold.
@@ -183,16 +173,23 @@ LogicalResult InlinerPass::initializeOptions(
 }
 
 std::unique_ptr<Pass> mlir::createInlinerPass() {
-  return std::make_unique<InlinerPass>();
+  return createInlinerPass(llvm::StringMap<OpPassManager>{});
 }
 std::unique_ptr<Pass>
 mlir::createInlinerPass(llvm::StringMap<OpPassManager> opPipelines) {
-  return std::make_unique<InlinerPass>(defaultInlinerOptPipeline,
-                                       std::move(opPipelines));
+  return createInlinerPass(std::move(opPipelines), defaultInlinerOptPipeline);
 }
 std::unique_ptr<Pass> mlir::createInlinerPass(
     llvm::StringMap<OpPassManager> opPipelines,
     std::function<void(OpPassManager &)> defaultPipelineBuilder) {
-  return std::make_unique<InlinerPass>(std::move(defaultPipelineBuilder),
-                                       std::move(opPipelines));
+  InlinerConfig config;
+
+  config.setDefaultPipeline(std::move(defaultPipelineBuilder));
+  config.setOpPipelines(std::move(opPipelines));
+
+  return createInlinerPass(config);
+}
+std::unique_ptr<Pass> createInlinerPass(const InlinerConfig &inlinerConfig,
+                                        unsigned inliningThreshold) {
+  return std::make_unique<InlinerPass>(inlinerConfig, inliningThreshold);
 }
diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 9ec7c51da4065..ddf9d91221c18 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -7344,6 +7344,7 @@ cc_library(
         "include/mlir/Transforms/FoldUtils.h",
         "include/mlir/Transforms/GreedyPatternRewriteDriver.h",
         "include/mlir/Transforms/Inliner.h",
+        "include/mlir/Transforms/InlinerConfig.h",
         "include/mlir/Transforms/LoopInvariantCodeMotionUtils.h",
         "include/mlir/Transforms/RegionUtils.h",
         "include/mlir/Transforms/WalkPatternRewriteDriver.h",

@llvmbot
Copy link
Member

llvmbot commented Jul 24, 2025

@llvm/pr-subscribers-mlir-core

Author: Will Froom (WillFroom)

Changes

Currently the only way to be able to modify the configuration is to pass as a string to initializeOptions which is quite cumbersome, this helps make that a bit easier.


Full diff: https://github.com/llvm/llvm-project/pull/150413.diff

5 Files Affected:

  • (modified) mlir/include/mlir/Transforms/Inliner.h (+1-72)
  • (added) mlir/include/mlir/Transforms/InlinerConfig.h (+98)
  • (modified) mlir/include/mlir/Transforms/Passes.h (+5)
  • (modified) mlir/lib/Transforms/InlinerPass.cpp (+17-20)
  • (modified) utils/bazel/llvm-project-overlay/mlir/BUILD.bazel (+1)
diff --git a/mlir/include/mlir/Transforms/Inliner.h b/mlir/include/mlir/Transforms/Inliner.h
index 0d3d3d1a3f9f2..241ab6f434981 100644
--- a/mlir/include/mlir/Transforms/Inliner.h
+++ b/mlir/include/mlir/Transforms/Inliner.h
@@ -17,6 +17,7 @@
 #include "mlir/Interfaces/CallInterfaces.h"
 #include "mlir/Pass/AnalysisManager.h"
 #include "mlir/Pass/PassManager.h"
+#include "mlir/Transforms/InlinerConfig.h"
 #include "mlir/Transforms/InliningUtils.h"
 #include "llvm/ADT/StringMap.h"
 
@@ -24,78 +25,6 @@ namespace mlir {
 class OpPassManager;
 class Operation;
 
-class InlinerConfig {
-public:
-  using DefaultPipelineTy = std::function<void(OpPassManager &)>;
-  using OpPipelinesTy = llvm::StringMap<OpPassManager>;
-
-  InlinerConfig() = default;
-  InlinerConfig(DefaultPipelineTy defaultPipeline,
-                unsigned maxInliningIterations)
-      : defaultPipeline(std::move(defaultPipeline)),
-        maxInliningIterations(maxInliningIterations) {}
-
-  const DefaultPipelineTy &getDefaultPipeline() const {
-    return defaultPipeline;
-  }
-  const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
-  unsigned getMaxInliningIterations() const { return maxInliningIterations; }
-  const InlinerInterface::CloneCallbackTy &getCloneCallback() const {
-    return cloneCallback;
-  }
-  bool getCanHandleMultipleBlocks() const { return canHandleMultipleBlocks; }
-
-  void setDefaultPipeline(DefaultPipelineTy pipeline) {
-    defaultPipeline = std::move(pipeline);
-  }
-  void setOpPipelines(OpPipelinesTy pipelines) {
-    opPipelines = std::move(pipelines);
-  }
-  void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
-  void setCloneCallback(InlinerInterface::CloneCallbackTy callback) {
-    cloneCallback = std::move(callback);
-  }
-  void setCanHandleMultipleBlocks(bool value = true) {
-    canHandleMultipleBlocks = value;
-  }
-
-private:
-  /// An optional function that constructs an optimization pipeline for
-  /// a given operation. This optimization pipeline is applied
-  /// only to those callable operations that do not have dedicated
-  /// optimization pipeline in opPipelines (based on the operation name).
-  DefaultPipelineTy defaultPipeline;
-  /// A map of operation names to pass pipelines to use when optimizing
-  /// callable operations of these types. This provides a specialized pipeline
-  /// instead of the one produced by defaultPipeline.
-  OpPipelinesTy opPipelines;
-  /// For SCC-based inlining algorithms, specifies maximum number of iterations
-  /// when inlining within an SCC.
-  unsigned maxInliningIterations{0};
-  /// Callback for cloning operations during inlining
-  InlinerInterface::CloneCallbackTy cloneCallback =
-      [](OpBuilder &builder, Region *src, Block *inlineBlock,
-         Block *postInsertBlock, IRMapping &mapper,
-         bool shouldCloneInlinedRegion) {
-        // Check to see if the region is being cloned, or moved inline. In
-        // either case, move the new blocks after the 'insertBlock' to improve
-        // IR readability.
-        Region *insertRegion = inlineBlock->getParent();
-        if (shouldCloneInlinedRegion)
-          src->cloneInto(insertRegion, postInsertBlock->getIterator(), mapper);
-        else
-          insertRegion->getBlocks().splice(postInsertBlock->getIterator(),
-                                           src->getBlocks(), src->begin(),
-                                           src->end());
-      };
-  /// Determine if the inliner can inline a function containing multiple
-  /// blocks into a region that requires a single block. By default, it is
-  /// not allowed. If it is true, cloneCallback should perform the extra
-  /// transformation. see the example in
-  /// mlir/test/lib/Transforms/TestInliningCallback.cpp
-  bool canHandleMultipleBlocks{false};
-};
-
 /// This is an implementation of the inliner
 /// that operates bottom up over the Strongly Connected Components(SCCs)
 /// of the CallGraph. This enables a more incremental propagation
diff --git a/mlir/include/mlir/Transforms/InlinerConfig.h b/mlir/include/mlir/Transforms/InlinerConfig.h
new file mode 100644
index 0000000000000..928869625b647
--- /dev/null
+++ b/mlir/include/mlir/Transforms/InlinerConfig.h
@@ -0,0 +1,98 @@
+//===- InlinerConfig.h - Config for the Inliner pass-------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the config class used by the Inliner class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_TRANSFORMS_INLINER_CONFIG_H
+#define MLIR_TRANSFORMS_INLINER_CONFIG_H
+
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Transforms/InliningUtils.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace mlir {
+class OpPassManager;
+class Operation;
+
+class InlinerConfig {
+public:
+  using DefaultPipelineTy = std::function<void(OpPassManager &)>;
+  using OpPipelinesTy = llvm::StringMap<OpPassManager>;
+
+  InlinerConfig() = default;
+  InlinerConfig(DefaultPipelineTy defaultPipeline,
+                unsigned maxInliningIterations)
+      : defaultPipeline(std::move(defaultPipeline)),
+        maxInliningIterations(maxInliningIterations) {}
+
+  const DefaultPipelineTy &getDefaultPipeline() const {
+    return defaultPipeline;
+  }
+  const OpPipelinesTy &getOpPipelines() const { return opPipelines; }
+  unsigned getMaxInliningIterations() const { return maxInliningIterations; }
+  const InlinerInterface::CloneCallbackTy &getCloneCallback() const {
+    return cloneCallback;
+  }
+  bool getCanHandleMultipleBlocks() const { return canHandleMultipleBlocks; }
+
+  void setDefaultPipeline(DefaultPipelineTy pipeline) {
+    defaultPipeline = std::move(pipeline);
+  }
+  void setOpPipelines(OpPipelinesTy pipelines) {
+    opPipelines = std::move(pipelines);
+  }
+  void setMaxInliningIterations(unsigned max) { maxInliningIterations = max; }
+  void setCloneCallback(InlinerInterface::CloneCallbackTy callback) {
+    cloneCallback = std::move(callback);
+  }
+  void setCanHandleMultipleBlocks(bool value = true) {
+    canHandleMultipleBlocks = value;
+  }
+
+private:
+  /// An optional function that constructs an optimization pipeline for
+  /// a given operation. This optimization pipeline is applied
+  /// only to those callable operations that do not have dedicated
+  /// optimization pipeline in opPipelines (based on the operation name).
+  DefaultPipelineTy defaultPipeline;
+  /// A map of operation names to pass pipelines to use when optimizing
+  /// callable operations of these types. This provides a specialized pipeline
+  /// instead of the one produced by defaultPipeline.
+  OpPipelinesTy opPipelines;
+  /// For SCC-based inlining algorithms, specifies maximum number of iterations
+  /// when inlining within an SCC.
+  unsigned maxInliningIterations{0};
+  /// Callback for cloning operations during inlining
+  InlinerInterface::CloneCallbackTy cloneCallback =
+      [](OpBuilder &builder, Region *src, Block *inlineBlock,
+         Block *postInsertBlock, IRMapping &mapper,
+         bool shouldCloneInlinedRegion) {
+        // Check to see if the region is being cloned, or moved inline. In
+        // either case, move the new blocks after the 'insertBlock' to improve
+        // IR readability.
+        Region *insertRegion = inlineBlock->getParent();
+        if (shouldCloneInlinedRegion)
+          src->cloneInto(insertRegion, postInsertBlock->getIterator(), mapper);
+        else
+          insertRegion->getBlocks().splice(postInsertBlock->getIterator(),
+                                           src->getBlocks(), src->begin(),
+                                           src->end());
+      };
+  /// Determine if the inliner can inline a function containing multiple
+  /// blocks into a region that requires a single block. By default, it is
+  /// not allowed. If it is true, cloneCallback should perform the extra
+  /// transformation. see the example in
+  /// mlir/test/lib/Transforms/TestInliningCallback.cpp
+  bool canHandleMultipleBlocks{false};
+};
+
+} // namespace mlir
+
+#endif // MLIR_TRANSFORMS_INLINER_CONFIG_H
diff --git a/mlir/include/mlir/Transforms/Passes.h b/mlir/include/mlir/Transforms/Passes.h
index 9cd2ef34e15ea..32ffcbe469df0 100644
--- a/mlir/include/mlir/Transforms/Passes.h
+++ b/mlir/include/mlir/Transforms/Passes.h
@@ -17,6 +17,7 @@
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassManager.h"
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+#include "mlir/Transforms/InlinerConfig.h"
 #include "mlir/Transforms/LocationSnapshot.h"
 #include "mlir/Transforms/ViewOpGraph.h"
 #include "llvm/Support/Debug.h"
@@ -111,6 +112,10 @@ createInlinerPass(llvm::StringMap<OpPassManager> opPipelines);
 std::unique_ptr<Pass>
 createInlinerPass(llvm::StringMap<OpPassManager> opPipelines,
                   std::function<void(OpPassManager &)> defaultPipelineBuilder);
+/// Creates an instance of the inliner pass, using the provided config and
+/// threshold.
+std::unique_ptr<Pass> createInlinerPass(const InlinerConfig &inlinerConfig,
+                                        unsigned inliningThreshold = -1);
 
 /// Creates an optimization pass to remove dead values.
 std::unique_ptr<Pass> createRemoveDeadValuesPass();
diff --git a/mlir/lib/Transforms/InlinerPass.cpp b/mlir/lib/Transforms/InlinerPass.cpp
index 703e517d45374..e3326e0fc3410 100644
--- a/mlir/lib/Transforms/InlinerPass.cpp
+++ b/mlir/lib/Transforms/InlinerPass.cpp
@@ -41,10 +41,7 @@ namespace {
 class InlinerPass : public impl::InlinerBase<InlinerPass> {
 public:
   InlinerPass();
-  InlinerPass(const InlinerPass &) = default;
-  InlinerPass(std::function<void(OpPassManager &)> defaultPipeline);
-  InlinerPass(std::function<void(OpPassManager &)> defaultPipeline,
-              llvm::StringMap<OpPassManager> opPipelines);
+  InlinerPass(const InlinerConfig &inlinerConfig, unsigned inliningThreshold);
   void runOnOperation() override;
 
   /// A callback provided to the inliner driver to execute
@@ -73,23 +70,16 @@ class InlinerPass : public impl::InlinerBase<InlinerPass> {
 };
 } // namespace
 
-InlinerPass::InlinerPass() : InlinerPass(defaultInlinerOptPipeline) {}
-
-InlinerPass::InlinerPass(
-    std::function<void(OpPassManager &)> defaultPipelineArg)
-    : InlinerPass(std::move(defaultPipelineArg),
-                  llvm::StringMap<OpPassManager>{}) {}
-
-InlinerPass::InlinerPass(std::function<void(OpPassManager &)> defaultPipeline,
-                         llvm::StringMap<OpPassManager> opPipelines)
-    : config(std::move(defaultPipeline), maxInliningIterations) {
+InlinerPass::InlinerPass(const InlinerConfig &inlinerConfig,
+                         unsigned inliningThreshold)
+    : config(inlinerConfig) {
+  const auto &opPipelines = config.getOpPipelines();
   if (opPipelines.empty())
     return;
 
   // Update the option for the op specific optimization pipelines.
   for (auto &it : opPipelines)
     opPipelineList.addValue(it.second);
-  config.setOpPipelines(std::move(opPipelines));
 }
 
 // Return true if the inlining ratio does not exceed the threshold.
@@ -183,16 +173,23 @@ LogicalResult InlinerPass::initializeOptions(
 }
 
 std::unique_ptr<Pass> mlir::createInlinerPass() {
-  return std::make_unique<InlinerPass>();
+  return createInlinerPass(llvm::StringMap<OpPassManager>{});
 }
 std::unique_ptr<Pass>
 mlir::createInlinerPass(llvm::StringMap<OpPassManager> opPipelines) {
-  return std::make_unique<InlinerPass>(defaultInlinerOptPipeline,
-                                       std::move(opPipelines));
+  return createInlinerPass(std::move(opPipelines), defaultInlinerOptPipeline);
 }
 std::unique_ptr<Pass> mlir::createInlinerPass(
     llvm::StringMap<OpPassManager> opPipelines,
     std::function<void(OpPassManager &)> defaultPipelineBuilder) {
-  return std::make_unique<InlinerPass>(std::move(defaultPipelineBuilder),
-                                       std::move(opPipelines));
+  InlinerConfig config;
+
+  config.setDefaultPipeline(std::move(defaultPipelineBuilder));
+  config.setOpPipelines(std::move(opPipelines));
+
+  return createInlinerPass(config);
+}
+std::unique_ptr<Pass> createInlinerPass(const InlinerConfig &inlinerConfig,
+                                        unsigned inliningThreshold) {
+  return std::make_unique<InlinerPass>(inlinerConfig, inliningThreshold);
 }
diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 9ec7c51da4065..ddf9d91221c18 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -7344,6 +7344,7 @@ cc_library(
         "include/mlir/Transforms/FoldUtils.h",
         "include/mlir/Transforms/GreedyPatternRewriteDriver.h",
         "include/mlir/Transforms/Inliner.h",
+        "include/mlir/Transforms/InlinerConfig.h",
         "include/mlir/Transforms/LoopInvariantCodeMotionUtils.h",
         "include/mlir/Transforms/RegionUtils.h",
         "include/mlir/Transforms/WalkPatternRewriteDriver.h",

@WillFroom WillFroom force-pushed the add-options-to-inline-pass branch 2 times, most recently from c7cb259 to 37a0d27 Compare July 24, 2025 13:10
@WillFroom WillFroom force-pushed the add-options-to-inline-pass branch from 37a0d27 to ab50b7c Compare July 29, 2025 08:57
/// Creates an instance of the inliner pass, using the provided config and
/// threshold.
std::unique_ptr<Pass> createInlinerPass(const InlinerConfig &inlinerConfig,
unsigned inliningThreshold = -1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't the threshold part of the config?

InlinerPass(std::function<void(OpPassManager &)> defaultPipeline);
InlinerPass(std::function<void(OpPassManager &)> defaultPipeline,
llvm::StringMap<OpPassManager> opPipelines);
InlinerPass(const InlinerConfig &inlinerConfig, unsigned inliningThreshold_);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we dump the passing configuration? How do I set it from the command line pass-pipeline?
I would think that would require hooking the InlinerConfig into the cl::opt infrastructure (parsing/printing)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bazel "Peripheral" support tier build system: utils/bazel mlir:core MLIR Core Infrastructure mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants