[Mlir-commits] [mlir] 8dd8c4a - [mlir][Transforms] Inliner: Extra checks for unstructured control flow
Matthias Springer
llvmlistbot at llvm.org
Wed Aug 30 06:37:12 PDT 2023
Author: Matthias Springer
Date: 2023-08-30T15:28:29+02:00
New Revision: 8dd8c4adba79cdaeeb096cafff6040da9c0a4797
URL: https://github.com/llvm/llvm-project/commit/8dd8c4adba79cdaeeb096cafff6040da9c0a4797
DIFF: https://github.com/llvm/llvm-project/commit/8dd8c4adba79cdaeeb096cafff6040da9c0a4797.diff
LOG: [mlir][Transforms] Inliner: Extra checks for unstructured control flow
Do not inline IR with multiple blocks into ops that may not support unstructured control flow.
This fixes #64978.
Differential Revision: https://reviews.llvm.org/D159072
Added:
Modified:
mlir/lib/Transforms/Inliner.cpp
mlir/test/Transforms/inlining.mlir
Removed:
################################################################################
diff --git a/mlir/lib/Transforms/Inliner.cpp b/mlir/lib/Transforms/Inliner.cpp
index a7dcd2b0e87d23..e6eb483e234000 100644
--- a/mlir/lib/Transforms/Inliner.cpp
+++ b/mlir/lib/Transforms/Inliner.cpp
@@ -451,8 +451,24 @@ static bool shouldInline(ResolvedCall &resolvedCall) {
// Don't allow inlining if the target is an ancestor of the call. This
// prevents inlining recursively.
- if (resolvedCall.targetNode->getCallableRegion()->isAncestor(
- resolvedCall.call->getParentRegion()))
+ Region *callableRegion = resolvedCall.targetNode->getCallableRegion();
+ if (callableRegion->isAncestor(resolvedCall.call->getParentRegion()))
+ return false;
+
+ // Don't allow inlining if the callee has multiple blocks (unstructured
+ // control flow) but we cannot be sure that the caller region supports that.
+ bool calleeHasMultipleBlocks =
+ llvm::hasNItemsOrMore(*callableRegion, /*N=*/2);
+ // If both parent ops have the same type, it is safe to inline. Otherwise,
+ // decide based on whether the op has the SingleBlock trait or not.
+ // Note: This check does currently not account for SizedRegion/MaxSizedRegion.
+ auto callerRegionSupportsMultipleBlocks = [&]() {
+ return callableRegion->getParentOp()->getName() ==
+ resolvedCall.call->getParentOp()->getName() ||
+ !resolvedCall.call->getParentOp()
+ ->mightHaveTrait<OpTrait::SingleBlock>();
+ };
+ if (calleeHasMultipleBlocks && !callerRegionSupportsMultipleBlocks())
return false;
// Otherwise, inline.
diff --git a/mlir/test/Transforms/inlining.mlir b/mlir/test/Transforms/inlining.mlir
index f7eaa478cdbba2..a0b4e0082b5439 100644
--- a/mlir/test/Transforms/inlining.mlir
+++ b/mlir/test/Transforms/inlining.mlir
@@ -227,6 +227,18 @@ func.func @func_with_block_args_location_callee2(%arg0 : i32) {
return
}
+// CHECK-LABEL: func @func_with_block_args_location_callee3
+func.func @func_with_block_args_location_callee3(%arg0 : i32) {
+ "test.dummy_op"() ({
+ // Call cannot be inlined because "test.dummy" may not support unstructured
+ // control flow in its body.
+ // CHECK: call @func_with_block_args_location
+ call @func_with_block_args_location(%arg0) : (i32) -> ()
+ "test.terminator"() : () -> ()
+ }) : () -> ()
+ return
+}
+
// Check that we can handle argument and result attributes.
test.conversion_func_op @handle_attr_callee_fn_multi_arg(%arg0 : i16, %arg1 : i16 {"test.handle_argument"}) -> (i16 {"test.handle_result"}, i16) {
%0 = arith.addi %arg0, %arg1 : i16
More information about the Mlir-commits
mailing list