[Mlir-commits] [mlir] [MLIR] Add no-inline attribute (PR #117392)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Fri Nov 22 14:45:29 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: William Moses (wsmoses)
<details>
<summary>Changes</summary>
---
Full diff: https://github.com/llvm/llvm-project/pull/117392.diff
4 Files Affected:
- (modified) mlir/include/mlir/Dialect/Func/IR/FuncOps.td (+4)
- (modified) mlir/include/mlir/Interfaces/CallInterfaces.td (+10)
- (modified) mlir/lib/Transforms/Utils/Inliner.cpp (+4)
- (modified) mlir/test/Transforms/inlining.mlir (+9)
``````````diff
diff --git a/mlir/include/mlir/Dialect/Func/IR/FuncOps.td b/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
index 22efe15aa83a50..e0560c8e1e038a 100644
--- a/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
+++ b/mlir/include/mlir/Dialect/Func/IR/FuncOps.td
@@ -98,6 +98,10 @@ def CallOp : Func_Op<"call",
void setCalleeFromCallable(CallInterfaceCallable callee) {
(*this)->setAttr("callee", callee.get<SymbolRefAttr>());
}
+
+ bool legalToInline() {
+ return !(*this)->hasAttr("noinline");
+ }
}];
let assemblyFormat = [{
diff --git a/mlir/include/mlir/Interfaces/CallInterfaces.td b/mlir/include/mlir/Interfaces/CallInterfaces.td
index c6002da0d491ce..35f33bf4797f6a 100644
--- a/mlir/include/mlir/Interfaces/CallInterfaces.td
+++ b/mlir/include/mlir/Interfaces/CallInterfaces.td
@@ -80,6 +80,16 @@ def CallOpInterface : OpInterface<"CallOpInterface"> {
/*methodBody=*/[{}], /*defaultImplementation=*/[{
return ::mlir::call_interface_impl::resolveCallable($_op);
}]
+ >,
+ InterfaceMethod<[{
+ Return whether a given call is legal to inline or not (assuming all other requirements are met,
+ like the callee is direct, the parent region supports multiple blocks and the resolved, etc).
+ This can be used to implement a `noinline`-like attribute.
+ }],
+ "bool", "legalToInline", (ins),
+ /*methodBody=*/[{}], /*defaultImplementation=*/[{
+ return true;
+ }]
>
];
}
diff --git a/mlir/lib/Transforms/Utils/Inliner.cpp b/mlir/lib/Transforms/Utils/Inliner.cpp
index 8acfc96d2b611b..1e329935b7807b 100644
--- a/mlir/lib/Transforms/Utils/Inliner.cpp
+++ b/mlir/lib/Transforms/Utils/Inliner.cpp
@@ -712,6 +712,10 @@ bool Inliner::Impl::shouldInline(ResolvedCall &resolvedCall) {
if (resolvedCall.call->hasTrait<OpTrait::IsTerminator>())
return false;
+ // Don't inline calls which explicitly forbit inlining.
+ if (!resolvedCall.call.legalToInline())
+ return false;
+
// Don't allow inlining if the target is a self-recursive function.
if (llvm::count_if(*resolvedCall.targetNode,
[&](CallGraphNode::Edge const &edge) -> bool {
diff --git a/mlir/test/Transforms/inlining.mlir b/mlir/test/Transforms/inlining.mlir
index 79a2936b104fa1..262047132064c7 100644
--- a/mlir/test/Transforms/inlining.mlir
+++ b/mlir/test/Transforms/inlining.mlir
@@ -19,6 +19,15 @@ func.func @inline_with_arg(%arg0 : i32) -> i32 {
return %0 : i32
}
+// CHECK-LABEL: func @noinline_with_arg
+func.func @noinline_with_arg(%arg0 : i32) -> i32 {
+ // CHECK-NEXT: func_with_arg
+ // CHECK-NEXT: return
+
+ %0 = call @func_with_arg(%arg0) {"noinline"=""} : (i32) -> i32
+ return %0 : i32
+}
+
// Inline a function that has multiple return operations.
func.func @func_with_multi_return(%a : i1) -> (i32) {
cf.cond_br %a, ^bb1, ^bb2
``````````
</details>
https://github.com/llvm/llvm-project/pull/117392
More information about the Mlir-commits
mailing list