-
Notifications
You must be signed in to change notification settings - Fork 12k
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
[RFC][mlir] Add profitability callback to the Inliner. #84258
Conversation
Discussion at https://discourse.llvm.org/t/inliner-cost-model/2992 This change adds a callback that reports whether inlining of the particular call site (communicated via ResolvedCall argument) is profitable or not. The default MLIR inliner pass behavior is unchanged, i.e. the callback always returns true. This callback may be used to customize the inliner behavior based on the target specifics (like target instructions costs), profitability of the inlining for further optimizations (e.g. if inlining may enable loop optimizations or scalar optimizations due to object shape propagation), optimization levels (e.g. -Os inlining may be quite different from -Ofast inlining), etc. One of the questions is whether the ResolvedCall entity represents enough of the context for the custom inlining models to come up with the profitability decision. I think we can start with this and extend it as necessary.
@llvm/pr-subscribers-mlir-core @llvm/pr-subscribers-mlir Author: Slava Zakharin (vzakhari) ChangesDiscussion at https://discourse.llvm.org/t/inliner-cost-model/2992 This change adds a callback that reports whether inlining One of the questions is whether the ResolvedCall entity represents Full diff: https://github.com/llvm/llvm-project/pull/84258.diff 3 Files Affected:
diff --git a/mlir/include/mlir/Transforms/Inliner.h b/mlir/include/mlir/Transforms/Inliner.h
index 1fe61fb4bbe7d9..09b06f7c38cf55 100644
--- a/mlir/include/mlir/Transforms/Inliner.h
+++ b/mlir/include/mlir/Transforms/Inliner.h
@@ -69,19 +69,6 @@ class InlinerConfig {
/// of inlining decisions from the leafs to the roots of the callgraph.
class Inliner {
public:
- using RunPipelineHelperTy = std::function<LogicalResult(
- Pass &pass, OpPassManager &pipeline, Operation *op)>;
-
- Inliner(Operation *op, CallGraph &cg, Pass &pass, AnalysisManager am,
- RunPipelineHelperTy runPipelineHelper, const InlinerConfig &config)
- : op(op), cg(cg), pass(pass), am(am),
- runPipelineHelper(std::move(runPipelineHelper)), config(config) {}
- Inliner(Inliner &) = delete;
- void operator=(const Inliner &) = delete;
-
- /// Perform inlining on a OpTrait::SymbolTable operation.
- LogicalResult doInlining();
-
/// This struct represents a resolved call to a given callgraph node. Given
/// that the call does not actually contain a direct reference to the
/// Region(CallGraphNode) that it is dispatching to, we need to resolve them
@@ -94,7 +81,29 @@ class Inliner {
CallGraphNode *sourceNode, *targetNode;
};
-protected:
+ using RunPipelineHelperTy = std::function<LogicalResult(
+ Pass &pass, OpPassManager &pipeline, Operation *op)>;
+
+ /// Type of the callback answering if it is profitable
+ /// to inline a callable operation at a call site.
+ /// It might be the case that the ResolvedCall does not provide
+ /// enough context to make the profitability decision, so
+ /// this hook's interface might need to be extended in future.
+ using ProfitabilityCallbackTy = std::function<bool(ResolvedCall &)>;
+
+ Inliner(Operation *op, CallGraph &cg, Pass &pass, AnalysisManager am,
+ RunPipelineHelperTy runPipelineHelper, const InlinerConfig &config,
+ ProfitabilityCallbackTy isProfitableToInline)
+ : op(op), cg(cg), pass(pass), am(am),
+ runPipelineHelper(std::move(runPipelineHelper)), config(config),
+ isProfitableToInline(std::move(isProfitableToInline)) {}
+ Inliner(Inliner &) = delete;
+ void operator=(const Inliner &) = delete;
+
+ /// Perform inlining on a OpTrait::SymbolTable operation.
+ LogicalResult doInlining();
+
+private:
/// An OpTrait::SymbolTable operation to run the inlining on.
Operation *op;
/// A CallGraph analysis for the given operation.
@@ -108,12 +117,12 @@ class Inliner {
const RunPipelineHelperTy runPipelineHelper;
/// The inliner configuration parameters.
const InlinerConfig &config;
+ /// Returns true, if it is profitable to inline the callable operation
+ /// at the call site.
+ ProfitabilityCallbackTy isProfitableToInline;
-private:
/// Forward declaration of the class providing the actual implementation.
class Impl;
-
-public:
};
} // namespace mlir
diff --git a/mlir/lib/Transforms/InlinerPass.cpp b/mlir/lib/Transforms/InlinerPass.cpp
index c058e8050cd199..faa9a1aef9d353 100644
--- a/mlir/lib/Transforms/InlinerPass.cpp
+++ b/mlir/lib/Transforms/InlinerPass.cpp
@@ -100,9 +100,12 @@ void InlinerPass::runOnOperation() {
return signalPassFailure();
}
+ // By default, assume that any inlining is profitable.
+ auto profitabilityCb = [](Inliner::ResolvedCall &) { return true; };
+
// Get an instance of the inliner.
Inliner inliner(op, cg, *this, getAnalysisManager(), runPipelineHelper,
- config);
+ config, profitabilityCb);
// Run the inlining.
if (failed(inliner.doInlining()))
diff --git a/mlir/lib/Transforms/Utils/Inliner.cpp b/mlir/lib/Transforms/Utils/Inliner.cpp
index 74776a73db9aaa..c24eff7353f6b9 100644
--- a/mlir/lib/Transforms/Utils/Inliner.cpp
+++ b/mlir/lib/Transforms/Utils/Inliner.cpp
@@ -733,6 +733,9 @@ bool Inliner::Impl::shouldInline(ResolvedCall &resolvedCall) {
if (calleeHasMultipleBlocks && !callerRegionSupportsMultipleBlocks())
return false;
+ if (!inliner.isProfitableToInline(resolvedCall))
+ return false;
+
// Otherwise, inline.
return true;
}
|
Friendly ping. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LG, with some nits.
return %v3 : i32 | ||
} | ||
|
||
// CHECK: Callee / caller operation ratio (max: 100): 200 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't test debug output, just remove this check and everything looks good otherwise.
Co-authored-by: Mehdi Amini <joker.eph@gmail.com>
Discussion at https://discourse.llvm.org/t/inliner-cost-model/2992
This change adds a callback that reports whether inlining
of the particular call site (communicated via ResolvedCall argument)
is profitable or not. The default MLIR inliner pass behavior
is unchanged, i.e. the callback always returns true.
This callback may be used to customize the inliner behavior
based on the target specifics (like target instructions costs),
profitability of the inlining for further optimizations
(e.g. if inlining may enable loop optimizations or scalar optimizations
due to object shape propagation), optimization levels (e.g. -Os inlining
may be quite different from -Ofast inlining), etc.
One of the questions is whether the ResolvedCall entity represents
enough of the context for the custom inlining models to come up with
the profitability decision. I think we can start with this and
extend it as necessary.