2019-09-05 12:23:45 -07:00
|
|
|
//===- TestInlining.cpp - Pass to inline calls in the test dialect --------===//
|
|
|
|
|
//
|
2020-01-26 03:58:30 +00:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
2019-12-23 09:35:36 -08:00
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2019-09-05 12:23:45 -07:00
|
|
|
//
|
2019-12-23 09:35:36 -08:00
|
|
|
//===----------------------------------------------------------------------===//
|
2019-09-05 12:23:45 -07:00
|
|
|
//
|
2020-07-07 01:35:23 -07:00
|
|
|
// TODO: This pass is only necessary because the main inlining pass
|
2019-09-05 12:23:45 -07:00
|
|
|
// has no abstracted away the call+callee relationship. When the inlining
|
|
|
|
|
// interface has this support, this pass should be removed.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
#include "TestDialect.h"
|
2020-02-21 11:54:49 -08:00
|
|
|
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
2020-06-11 16:45:37 -07:00
|
|
|
#include "mlir/IR/BlockAndValueMapping.h"
|
2019-09-05 12:23:45 -07:00
|
|
|
#include "mlir/IR/Function.h"
|
|
|
|
|
#include "mlir/Pass/Pass.h"
|
|
|
|
|
#include "mlir/Transforms/InliningUtils.h"
|
|
|
|
|
#include "mlir/Transforms/Passes.h"
|
|
|
|
|
#include "llvm/ADT/StringSet.h"
|
|
|
|
|
|
|
|
|
|
using namespace mlir;
|
|
|
|
|
|
|
|
|
|
namespace {
|
2020-04-07 13:56:16 -07:00
|
|
|
struct Inliner : public PassWrapper<Inliner, FunctionPass> {
|
2019-09-05 12:23:45 -07:00
|
|
|
void runOnFunction() override {
|
|
|
|
|
auto function = getFunction();
|
|
|
|
|
|
|
|
|
|
// Collect each of the direct function calls within the module.
|
|
|
|
|
SmallVector<CallIndirectOp, 16> callers;
|
|
|
|
|
function.walk([&](CallIndirectOp caller) { callers.push_back(caller); });
|
|
|
|
|
|
|
|
|
|
// Build the inliner interface.
|
|
|
|
|
InlinerInterface interface(&getContext());
|
|
|
|
|
|
|
|
|
|
// Try to inline each of the call operations.
|
|
|
|
|
for (auto caller : callers) {
|
|
|
|
|
auto callee = dyn_cast_or_null<FunctionalRegionOp>(
|
2020-01-11 08:54:04 -08:00
|
|
|
caller.getCallee().getDefiningOp());
|
2019-09-05 12:23:45 -07:00
|
|
|
if (!callee)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// Inline the functional region operation, but only clone the internal
|
|
|
|
|
// region if there is more than one use.
|
|
|
|
|
if (failed(inlineRegion(
|
2020-04-17 20:14:41 -07:00
|
|
|
interface, &callee.body(), caller, caller.getArgOperands(),
|
2020-04-20 17:13:55 -07:00
|
|
|
caller.getResults(), caller.getLoc(),
|
2020-01-11 08:54:04 -08:00
|
|
|
/*shouldCloneInlinedRegion=*/!callee.getResult().hasOneUse())))
|
2019-09-05 12:23:45 -07:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// If the inlining was successful then erase the call and callee if
|
|
|
|
|
// possible.
|
|
|
|
|
caller.erase();
|
|
|
|
|
if (callee.use_empty())
|
|
|
|
|
callee.erase();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
2020-02-12 09:03:40 +00:00
|
|
|
namespace mlir {
|
|
|
|
|
void registerInliner() {
|
|
|
|
|
PassRegistration<Inliner>("test-inline", "Test inlining region calls");
|
|
|
|
|
}
|
|
|
|
|
} // namespace mlir
|