Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FunctionEliminationPass.cpp
Go to the documentation of this file.
1//===- FunctionEliminationPass.cpp - Implement Function Elimination Pass --===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// Implement pass to check that all functions got inlined and delete them.
10//
11//===----------------------------------------------------------------------===//
12
16#include "mlir/Dialect/Func/IR/FuncOps.h"
17#include "mlir/IR/SymbolTable.h"
18#include "mlir/IR/Visitors.h"
19#include "mlir/Interfaces/CallInterfaces.h"
20#include "mlir/Pass/Pass.h"
21#include "mlir/Transforms/Inliner.h"
22#include "mlir/Transforms/InliningUtils.h"
23#include "llvm/Support/LogicalResult.h"
24
25namespace circt {
26namespace llhd {
27#define GEN_PASS_DEF_FUNCTIONELIMINATION
28#include "circt/Dialect/LLHD/Transforms/LLHDPasses.h.inc"
29} // namespace llhd
30} // namespace circt
31
32using namespace mlir;
33using namespace circt;
34
35namespace {
36
37struct FunctionInliner : public InlinerInterface {
38 FunctionInliner(MLIRContext *context) : InlinerInterface(context) {}
39
40 bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned,
41 IRMapping &valueMapping) const override {
42 return dest->getParentOfType<llhd::ProcessOp>() &&
43 isa<func::FuncOp>(src->getParentOp());
44 }
45 bool isLegalToInline(Operation *op, Region *dest, bool wouldBeCloned,
46 IRMapping &valueMapping) const override {
47 return true;
48 }
49};
50
51struct FunctionEliminationPass
52 : public circt::llhd::impl::FunctionEliminationBase<
53 FunctionEliminationPass> {
54 void runOnOperation() override;
55 LogicalResult runOnModule(hw::HWModuleOp module);
56};
57
58void FunctionEliminationPass::runOnOperation() {
59 for (auto module : getOperation().getOps<hw::HWModuleOp>())
60 if (failed(runOnModule(module)))
61 return signalPassFailure();
62
63 getOperation().walk([&](mlir::func::FuncOp op) {
64 if (op.symbolKnownUseEmpty(getOperation()))
65 op.erase();
66 });
67}
68
69LogicalResult FunctionEliminationPass::runOnModule(hw::HWModuleOp module) {
70 FunctionInliner inliner(&getContext());
71 SymbolTableCollection table;
72 mlir::InlinerConfig config;
73
74 SmallVector<CallOpInterface> calls;
75 module.walk([&](func::CallOp op) { calls.push_back(op); });
76
77 for (auto call : calls) {
78 auto symbol = call.getCallableForCallee().dyn_cast<SymbolRefAttr>();
79 if (!symbol)
80 return call.emitError(
81 "functions not referred to by symbol are not supported");
82
83 auto func = cast<CallableOpInterface>(
84 table.lookupNearestSymbolFrom(module, symbol.getLeafReference()));
85
86 if (succeeded(mlir::inlineCall(inliner, config.getCloneCallback(), call,
87 func, func.getCallableRegion()))) {
88 call->erase();
89 continue;
90 }
91
92 return call.emitError(
93 "Not all functions are inlined, there is at least "
94 "one function call left within a llhd.process or hw.module.");
95 }
96
97 return success();
98}
99} // namespace
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1