Loading [MathJax]/extensions/tex2jax.js
CIRCT 22.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
KanagawaMethodsToContainers.cpp
Go to the documentation of this file.
1//===- KanagawaMethodsToContainers.cpp - Implementation of containerizing -===//
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
11#include "mlir/Pass/Pass.h"
12
17
20#include "mlir/Transforms/DialectConversion.h"
21
22namespace circt {
23namespace kanagawa {
24#define GEN_PASS_DEF_KANAGAWACONVERTMETHODSTOCONTAINERS
25#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
26} // namespace kanagawa
27} // namespace circt
28
29using namespace circt;
30using namespace kanagawa;
31
32namespace {
33
34struct DataflowMethodOpConversion
35 : public OpConversionPattern<DataflowMethodOp> {
36 using OpConversionPattern<DataflowMethodOp>::OpConversionPattern;
37 using OpAdaptor = typename DataflowMethodOp::Adaptor;
38
39 LogicalResult
40 matchAndRewrite(DataflowMethodOp op, OpAdaptor adaptor,
41 ConversionPatternRewriter &rewriter) const override {
42 // Replace the class by a container of the same name.
43 auto newContainer = ContainerOp::create(
44 rewriter, op.getLoc(), op.getInnerSym(), /*isTopLevel=*/false);
45 rewriter.setInsertionPointToStart(newContainer.getBodyBlock());
46
47 // Create in- and output ports.
48 llvm::SmallVector<Value> argValues;
49 for (auto [arg, name] : llvm::zip_equal(
50 op.getArguments(), op.getArgNames().getAsRange<StringAttr>())) {
51 auto port =
52 InputPortOp::create(rewriter, arg.getLoc(),
53 hw::InnerSymAttr::get(name), arg.getType(), name);
54 argValues.push_back(PortReadOp::create(rewriter, arg.getLoc(), port));
55 }
56
57 ReturnOp returnOp = cast<ReturnOp>(op.getBodyBlock()->getTerminator());
58 for (auto [idx, resType] : llvm::enumerate(
59 cast<MethodLikeOpInterface>(op.getOperation()).getResultTypes())) {
60 auto portName = rewriter.getStringAttr("out" + std::to_string(idx));
61 auto port = OutputPortOp::create(rewriter, op.getLoc(),
62 hw::InnerSymAttr::get(portName), resType,
63 portName);
64 PortWriteOp::create(rewriter, op.getLoc(), port,
65 returnOp.getOperand(idx));
66 }
67
68 rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(),
69 argValues);
70 rewriter.eraseOp(op);
71 rewriter.eraseOp(returnOp);
72 return success();
73 }
74};
75
76struct MethodsToContainersPass
77 : public circt::kanagawa::impl::KanagawaConvertMethodsToContainersBase<
78 MethodsToContainersPass> {
79 void runOnOperation() override;
80};
81} // anonymous namespace
82
83void MethodsToContainersPass::runOnOperation() {
84 auto *context = &getContext();
85 ConversionTarget target(*context);
86 target.addLegalDialect<KanagawaDialect>();
87 target.addIllegalOp<DataflowMethodOp>();
88 target.addIllegalOp<ReturnOp>();
89 RewritePatternSet patterns(context);
90
91 patterns.insert<DataflowMethodOpConversion>(context);
92 if (failed(
93 applyPartialConversion(getOperation(), target, std::move(patterns))))
94 signalPassFailure();
95}
96
98 return std::make_unique<MethodsToContainersPass>();
99}
std::unique_ptr< mlir::Pass > createConvertMethodsToContainersPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.