10ba00878SRiver Riddle //===- TestInlining.cpp - Pass to inline calls in the test dialect --------===//
20ba00878SRiver Riddle //
330857107SMehdi Amini // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
456222a06SMehdi Amini // See https://llvm.org/LICENSE.txt for license information.
556222a06SMehdi Amini // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60ba00878SRiver Riddle //
756222a06SMehdi Amini //===----------------------------------------------------------------------===//
80ba00878SRiver Riddle //
99db53a18SRiver Riddle // TODO: This pass is only necessary because the main inlining pass
10c7283c26SJaved Absar // has not abstracted away the call+callee relationship. When the inlining
110ba00878SRiver Riddle // interface has this support, this pass should be removed.
120ba00878SRiver Riddle //
130ba00878SRiver Riddle //===----------------------------------------------------------------------===//
140ba00878SRiver Riddle
150ba00878SRiver Riddle #include "TestDialect.h"
16*e95e94adSJeff Niu #include "TestOps.h"
1723aa5a74SRiver Riddle #include "mlir/Dialect/Func/IR/FuncOps.h"
1865fcddffSRiver Riddle #include "mlir/IR/BuiltinOps.h"
194d67b278SJeff Niu #include "mlir/IR/IRMapping.h"
200ba00878SRiver Riddle #include "mlir/Pass/Pass.h"
210ba00878SRiver Riddle #include "mlir/Transforms/InliningUtils.h"
220ba00878SRiver Riddle #include "llvm/ADT/StringSet.h"
230ba00878SRiver Riddle
240ba00878SRiver Riddle using namespace mlir;
257776b19eSStephen Neuendorffer using namespace test;
260ba00878SRiver Riddle
270ba00878SRiver Riddle namespace {
2858ceae95SRiver Riddle struct Inliner : public PassWrapper<Inliner, OperationPass<func::FuncOp>> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anon5d9f85410111::Inliner295e50dd04SRiver Riddle MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(Inliner)
305e50dd04SRiver Riddle
31b5e22e6dSMehdi Amini StringRef getArgument() const final { return "test-inline"; }
getDescription__anon5d9f85410111::Inliner32b5e22e6dSMehdi Amini StringRef getDescription() const final {
33b5e22e6dSMehdi Amini return "Test inlining region calls";
34b5e22e6dSMehdi Amini }
35b5e22e6dSMehdi Amini
runOnOperation__anon5d9f85410111::Inliner3641574554SRiver Riddle void runOnOperation() override {
3741574554SRiver Riddle auto function = getOperation();
380ba00878SRiver Riddle
390ba00878SRiver Riddle // Collect each of the direct function calls within the module.
4023aa5a74SRiver Riddle SmallVector<func::CallIndirectOp, 16> callers;
4123aa5a74SRiver Riddle function.walk(
4223aa5a74SRiver Riddle [&](func::CallIndirectOp caller) { callers.push_back(caller); });
430ba00878SRiver Riddle
440ba00878SRiver Riddle // Build the inliner interface.
450ba00878SRiver Riddle InlinerInterface interface(&getContext());
460ba00878SRiver Riddle
470ba00878SRiver Riddle // Try to inline each of the call operations.
480ba00878SRiver Riddle for (auto caller : callers) {
490ba00878SRiver Riddle auto callee = dyn_cast_or_null<FunctionalRegionOp>(
502bdf33ccSRiver Riddle caller.getCallee().getDefiningOp());
510ba00878SRiver Riddle if (!callee)
520ba00878SRiver Riddle continue;
530ba00878SRiver Riddle
540ba00878SRiver Riddle // Inline the functional region operation, but only clone the internal
550ba00878SRiver Riddle // region if there is more than one use.
560ba00878SRiver Riddle if (failed(inlineRegion(
576a994233SJacques Pienaar interface, &callee.getBody(), caller, caller.getArgOperands(),
58b87531caSRiver Riddle caller.getResults(), caller.getLoc(),
592bdf33ccSRiver Riddle /*shouldCloneInlinedRegion=*/!callee.getResult().hasOneUse())))
600ba00878SRiver Riddle continue;
610ba00878SRiver Riddle
620ba00878SRiver Riddle // If the inlining was successful then erase the call and callee if
630ba00878SRiver Riddle // possible.
640ba00878SRiver Riddle caller.erase();
650ba00878SRiver Riddle if (callee.use_empty())
660ba00878SRiver Riddle callee.erase();
670ba00878SRiver Riddle }
680ba00878SRiver Riddle }
690ba00878SRiver Riddle };
70be0a7e9fSMehdi Amini } // namespace
710ba00878SRiver Riddle
72c6477050SMehdi Amini namespace mlir {
7372c65b69SAlexander Belyaev namespace test {
registerInliner()74b5e22e6dSMehdi Amini void registerInliner() { PassRegistration<Inliner>(); }
7572c65b69SAlexander Belyaev } // namespace test
76c6477050SMehdi Amini } // namespace mlir
77