xref: /llvm-project/mlir/test/lib/Transforms/TestInlining.cpp (revision 65fcddff24d68e2b75a5fa820b6664b6ea78b1de)
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
100ba00878SRiver Riddle // has no 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"
1669d757c0SRob Suderman #include "mlir/Dialect/StandardOps/IR/Ops.h"
178472ae17SJacques Pienaar #include "mlir/IR/BlockAndValueMapping.h"
18*65fcddffSRiver Riddle #include "mlir/IR/BuiltinOps.h"
190ba00878SRiver Riddle #include "mlir/Pass/Pass.h"
200ba00878SRiver Riddle #include "mlir/Transforms/InliningUtils.h"
210ba00878SRiver Riddle #include "mlir/Transforms/Passes.h"
220ba00878SRiver Riddle #include "llvm/ADT/StringSet.h"
230ba00878SRiver Riddle 
240ba00878SRiver Riddle using namespace mlir;
2572c65b69SAlexander Belyaev using namespace mlir::test;
260ba00878SRiver Riddle 
270ba00878SRiver Riddle namespace {
2880aca1eaSRiver Riddle struct Inliner : public PassWrapper<Inliner, FunctionPass> {
290ba00878SRiver Riddle   void runOnFunction() override {
300ba00878SRiver Riddle     auto function = getFunction();
310ba00878SRiver Riddle 
320ba00878SRiver Riddle     // Collect each of the direct function calls within the module.
330ba00878SRiver Riddle     SmallVector<CallIndirectOp, 16> callers;
340ba00878SRiver Riddle     function.walk([&](CallIndirectOp caller) { callers.push_back(caller); });
350ba00878SRiver Riddle 
360ba00878SRiver Riddle     // Build the inliner interface.
370ba00878SRiver Riddle     InlinerInterface interface(&getContext());
380ba00878SRiver Riddle 
390ba00878SRiver Riddle     // Try to inline each of the call operations.
400ba00878SRiver Riddle     for (auto caller : callers) {
410ba00878SRiver Riddle       auto callee = dyn_cast_or_null<FunctionalRegionOp>(
422bdf33ccSRiver Riddle           caller.getCallee().getDefiningOp());
430ba00878SRiver Riddle       if (!callee)
440ba00878SRiver Riddle         continue;
450ba00878SRiver Riddle 
460ba00878SRiver Riddle       // Inline the functional region operation, but only clone the internal
470ba00878SRiver Riddle       // region if there is more than one use.
480ba00878SRiver Riddle       if (failed(inlineRegion(
4922219cfcSSean Silva               interface, &callee.body(), caller, caller.getArgOperands(),
50b87531caSRiver Riddle               caller.getResults(), caller.getLoc(),
512bdf33ccSRiver Riddle               /*shouldCloneInlinedRegion=*/!callee.getResult().hasOneUse())))
520ba00878SRiver Riddle         continue;
530ba00878SRiver Riddle 
540ba00878SRiver Riddle       // If the inlining was successful then erase the call and callee if
550ba00878SRiver Riddle       // possible.
560ba00878SRiver Riddle       caller.erase();
570ba00878SRiver Riddle       if (callee.use_empty())
580ba00878SRiver Riddle         callee.erase();
590ba00878SRiver Riddle     }
600ba00878SRiver Riddle   }
610ba00878SRiver Riddle };
620ba00878SRiver Riddle } // end anonymous namespace
630ba00878SRiver Riddle 
64c6477050SMehdi Amini namespace mlir {
6572c65b69SAlexander Belyaev namespace test {
66c6477050SMehdi Amini void registerInliner() {
67c6477050SMehdi Amini   PassRegistration<Inliner>("test-inline", "Test inlining region calls");
68c6477050SMehdi Amini }
6972c65b69SAlexander Belyaev } // namespace test
70c6477050SMehdi Amini } // namespace mlir
71