1 //===- TestInlining.cpp - Pass to inline calls in the test dialect --------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // TODO: This pass is only necessary because the main inlining pass
10 // has not abstracted away the call+callee relationship. When the inlining
11 // interface has this support, this pass should be removed.
13 //===----------------------------------------------------------------------===//
15 #include "TestDialect.h"
17 #include "mlir/Dialect/Func/IR/FuncOps.h"
18 #include "mlir/IR/BuiltinOps.h"
19 #include "mlir/IR/IRMapping.h"
20 #include "mlir/Pass/Pass.h"
21 #include "mlir/Transforms/InliningUtils.h"
22 #include "llvm/ADT/StringSet.h"
28 struct Inliner
: public PassWrapper
<Inliner
, OperationPass
<func::FuncOp
>> {
29 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(Inliner
)
31 StringRef
getArgument() const final
{ return "test-inline"; }
32 StringRef
getDescription() const final
{
33 return "Test inlining region calls";
36 void runOnOperation() override
{
37 auto function
= getOperation();
39 // Collect each of the direct function calls within the module.
40 SmallVector
<func::CallIndirectOp
, 16> callers
;
42 [&](func::CallIndirectOp caller
) { callers
.push_back(caller
); });
44 // Build the inliner interface.
45 InlinerInterface
interface(&getContext());
47 // Try to inline each of the call operations.
48 for (auto caller
: callers
) {
49 auto callee
= dyn_cast_or_null
<FunctionalRegionOp
>(
50 caller
.getCallee().getDefiningOp());
54 // Inline the functional region operation, but only clone the internal
55 // region if there is more than one use.
56 if (failed(inlineRegion(
57 interface
, &callee
.getBody(), caller
, caller
.getArgOperands(),
58 caller
.getResults(), caller
.getLoc(),
59 /*shouldCloneInlinedRegion=*/!callee
.getResult().hasOneUse())))
62 // If the inlining was successful then erase the call and callee if
65 if (callee
.use_empty())
74 void registerInliner() { PassRegistration
<Inliner
>(); }