[Mlir-commits] [llvm] [mlir] [MLIR] Split InlinerConfig into seperate header and add pass overload with it (PR #150413)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu Jul 24 06:05:54 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-core
Author: Will Froom (WillFroom)
<details>
<summary>Changes</summary>
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
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",
``````````
</details>
https://github.com/llvm/llvm-project/pull/150413
More information about the Mlir-commits
mailing list