-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[mlir][builtin] Make unrealized_conversion_cast
inlineable
#139722
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
base: main
Are you sure you want to change the base?
Conversation
Until now, `builtin.unrealized_conversion_cast` ops could not be inlined by the Inliner pass.
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-mlir-core Author: Matthias Springer (matthias-springer) ChangesUntil now, Full diff: https://github.com/llvm/llvm-project/pull/139722.diff 4 Files Affected:
diff --git a/mlir/include/mlir/InitAllDialects.h b/mlir/include/mlir/InitAllDialects.h
index e83be7b40eded..afae5232d1fb0 100644
--- a/mlir/include/mlir/InitAllDialects.h
+++ b/mlir/include/mlir/InitAllDialects.h
@@ -102,6 +102,7 @@
#include "mlir/Target/LLVM/NVVM/Target.h"
#include "mlir/Target/LLVM/ROCDL/Target.h"
#include "mlir/Target/SPIRV/Target.h"
+#include "mlir/Transforms/InliningUtils.h"
namespace mlir {
@@ -166,6 +167,7 @@ inline void registerAllDialects(DialectRegistry ®istry) {
bufferization::func_ext::registerBufferizableOpInterfaceExternalModels(
registry);
builtin::registerCastOpInterfaceExternalModels(registry);
+ builtin::registerBuiltinDialectInlinerInterfaceExternalModel(registry);
cf::registerBufferizableOpInterfaceExternalModels(registry);
cf::registerBufferDeallocationOpInterfaceExternalModels(registry);
gpu::registerBufferDeallocationOpInterfaceExternalModels(registry);
diff --git a/mlir/include/mlir/Transforms/InliningUtils.h b/mlir/include/mlir/Transforms/InliningUtils.h
index ed6413d8cd44c..48c5af2ca7585 100644
--- a/mlir/include/mlir/Transforms/InliningUtils.h
+++ b/mlir/include/mlir/Transforms/InliningUtils.h
@@ -305,6 +305,12 @@ inlineCall(InlinerInterface &interface,
CallOpInterface call, CallableOpInterface callable, Region *src,
bool shouldCloneInlinedRegion = true);
+namespace builtin {
+/// Register the builtin dialect inliner interface external model.
+void registerBuiltinDialectInlinerInterfaceExternalModel(
+ DialectRegistry ®istry);
+} // namespace builtin
+
} // namespace mlir
#endif // MLIR_TRANSFORMS_INLININGUTILS_H
diff --git a/mlir/lib/Transforms/Utils/InliningUtils.cpp b/mlir/lib/Transforms/Utils/InliningUtils.cpp
index 8594136570a76..227d6bc86a75e 100644
--- a/mlir/lib/Transforms/Utils/InliningUtils.cpp
+++ b/mlir/lib/Transforms/Utils/InliningUtils.cpp
@@ -13,6 +13,7 @@
#include "mlir/Transforms/InliningUtils.h"
#include "mlir/IR/Builders.h"
+#include "mlir/IR/BuiltinDialect.h"
#include "mlir/IR/IRMapping.h"
#include "mlir/IR/Operation.h"
#include "mlir/Interfaces/CallInterfaces.h"
@@ -557,3 +558,23 @@ LogicalResult mlir::inlineCall(
return cleanupState();
return success();
}
+
+namespace {
+/// This class defines the interface for handling inlining with builtin
+/// operations.
+struct BuiltinInlinerInterface : public DialectInlinerInterface {
+ using DialectInlinerInterface::DialectInlinerInterface;
+
+ /// All builtin ops can be inlined.
+ bool isLegalToInline(Operation *, Region *, bool, IRMapping &) const final {
+ return true;
+ }
+};
+} // namespace
+
+void mlir::builtin::registerBuiltinDialectInlinerInterfaceExternalModel(
+ DialectRegistry ®istry) {
+ registry.addExtension(+[](MLIRContext *ctx, BuiltinDialect *dialect) {
+ dialect->addInterfaces<BuiltinInlinerInterface>();
+ });
+}
diff --git a/mlir/test/Transforms/inlining.mlir b/mlir/test/Transforms/inlining.mlir
index 1ed08878430b5..d8e10aa4212ba 100644
--- a/mlir/test/Transforms/inlining.mlir
+++ b/mlir/test/Transforms/inlining.mlir
@@ -5,14 +5,18 @@
// RUN: mlir-opt %s -inline='op-pipelines=func.func(canonicalize,cse)' | FileCheck %s --check-prefix INLINE_SIMPLIFY
// Inline a function that takes an argument.
-func.func @func_with_arg(%c : i32) -> i32 {
- %b = arith.addi %c, %c : i32
- return %b : i32
+func.func @func_with_arg(%arg0 : i32) -> i32 {
+ %b = arith.addi %arg0, %arg0 : i32
+ %c = builtin.unrealized_conversion_cast %b : i32 to i64
+ %d = builtin.unrealized_conversion_cast %c : i64 to i32
+ return %d : i32
}
// CHECK-LABEL: func @inline_with_arg
func.func @inline_with_arg(%arg0 : i32) -> i32 {
// CHECK-NEXT: arith.addi
+ // CHECK-NEXT: unrealized_conversion_cast
+ // CHECK-NEXT: unrealized_conversion_cast
// CHECK-NEXT: return
%0 = call @func_with_arg(%arg0) : (i32) -> i32
|
This also makes module {
func.func @foo() {
builtin.module {
func.func @bar() {
return
}
}
return
}
func.func @caller() {
call @foo() : () -> ()
return
}
} |
Oh right, |
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.
LGTM.
One nitpick comment.
@@ -305,6 +305,12 @@ inlineCall(InlinerInterface &interface, | |||
CallOpInterface call, CallableOpInterface callable, Region *src, | |||
bool shouldCloneInlinedRegion = true); | |||
|
|||
namespace builtin { | |||
/// Register the builtin dialect inliner interface external model. |
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.
maybe add .. ' e.g. unrealized_conversion_cast'
Until now,
builtin.unrealized_conversion_cast
ops could not be inlined by the Inliner pass.