CIRCT 20.0.0git
Loading...
Searching...
No Matches
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/InliningUtils.h"
22#include "llvm/Support/LogicalResult.h"
23
24namespace circt {
25namespace llhd {
26#define GEN_PASS_DEF_FUNCTIONELIMINATION
27#include "circt/Dialect/LLHD/Transforms/Passes.h.inc"
28} // namespace llhd
29} // namespace circt
30
31using namespace mlir;
32using namespace circt;
33
34namespace {
35
36struct FunctionInliner : public InlinerInterface {
37 FunctionInliner(MLIRContext *context) : InlinerInterface(context) {}
38
39 bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned,
40 IRMapping &valueMapping) const override {
41 return dest->getParentOfType<llhd::ProcessOp>() &&
42 isa<func::FuncOp>(src->getParentOp());
43 }
44 bool isLegalToInline(Operation *op, Region *dest, bool wouldBeCloned,
45 IRMapping &valueMapping) const override {
46 return true;
47 }
48};
49
50struct FunctionEliminationPass
51 : public circt::llhd::impl::FunctionEliminationBase<
52 FunctionEliminationPass> {
53 void runOnOperation() override;
54 LogicalResult runOnModule(hw::HWModuleOp module);
55};
56
57void FunctionEliminationPass::runOnOperation() {
58 for (auto module : getOperation().getOps<hw::HWModuleOp>())
59 if (failed(runOnModule(module)))
60 return signalPassFailure();
61
62 getOperation().walk([&](mlir::func::FuncOp op) {
63 if (op.symbolKnownUseEmpty(getOperation()))
64 op.erase();
65 });
66}
67
68LogicalResult FunctionEliminationPass::runOnModule(hw::HWModuleOp module) {
69 FunctionInliner inliner(&getContext());
70 SymbolTableCollection table;
71
72 SmallVector<CallOpInterface> calls;
73 module.walk([&](func::CallOp op) { calls.push_back(op); });
74
75 for (auto call : calls) {
76 auto symbol = call.getCallableForCallee().dyn_cast<SymbolRefAttr>();
77 if (!symbol)
78 return call.emitError(
79 "functions not referred to by symbol are not supported");
80
81 auto func = cast<CallableOpInterface>(
82 table.lookupNearestSymbolFrom(module, symbol.getLeafReference()));
83
84 if (succeeded(
85 mlir::inlineCall(inliner, call, func, func.getCallableRegion()))) {
86 call->erase();
87 continue;
88 }
89
90 return call.emitError(
91 "Not all functions are inlined, there is at least "
92 "one function call left within a llhd.process or hw.module.");
93 }
94
95 return success();
96}
97} // namespace
98
99std::unique_ptr<OperationPass<ModuleOp>>
101 return std::make_unique<FunctionEliminationPass>();
102}
std::unique_ptr< OperationPass< ModuleOp > > createFunctionEliminationPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition hw.py:1