CIRCT  19.0.0git
IbisMethodsToContainers.cpp
Go to the documentation of this file.
1 //===- IbisMethodsToContainers.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 
9 #include "PassDetails.h"
10 
15 
17 #include "circt/Support/SymCache.h"
18 #include "mlir/Transforms/DialectConversion.h"
19 
20 using namespace circt;
21 using namespace ibis;
22 
23 namespace {
24 
25 struct DataflowMethodOpConversion
26  : public OpConversionPattern<DataflowMethodOp> {
28  using OpAdaptor = typename DataflowMethodOp::Adaptor;
29 
30  LogicalResult
31  matchAndRewrite(DataflowMethodOp op, OpAdaptor adaptor,
32  ConversionPatternRewriter &rewriter) const override {
33  // Replace the class by a container of the same name.
34  auto newContainer = rewriter.create<ContainerOp>(
35  op.getLoc(), op.getInnerSym(), /*isTopLevel=*/false);
36  rewriter.setInsertionPointToStart(newContainer.getBodyBlock());
37 
38  // Create mandatory %this
39  // TODO @mortbopet: this will most likely already be present at the
40  // method.df level soon...
41  rewriter.create<ThisOp>(op.getLoc(), newContainer.getInnerRef());
42 
43  // Create in- and output ports.
44  llvm::SmallVector<Value> argValues;
45  for (auto [arg, name] : llvm::zip_equal(
46  op.getArguments(), op.getArgNames().getAsRange<StringAttr>())) {
47  auto port = rewriter.create<InputPortOp>(
48  arg.getLoc(), name, hw::InnerSymAttr::get(name), arg.getType());
49  argValues.push_back(rewriter.create<PortReadOp>(arg.getLoc(), port));
50  }
51 
52  ReturnOp returnOp = cast<ReturnOp>(op.getBodyBlock()->getTerminator());
53  for (auto [idx, resType] : llvm::enumerate(
54  cast<MethodLikeOpInterface>(op.getOperation()).getResultTypes())) {
55  auto portName = rewriter.getStringAttr("out" + std::to_string(idx));
56  auto port = rewriter.create<OutputPortOp>(
57  op.getLoc(), portName, hw::InnerSymAttr::get(portName), resType);
58  rewriter.create<PortWriteOp>(op.getLoc(), port, returnOp.getOperand(idx));
59  }
60 
61  rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(),
62  argValues);
63  rewriter.eraseOp(op);
64  rewriter.eraseOp(returnOp);
65  return success();
66  }
67 };
68 
69 struct MethodsToContainersPass
70  : public IbisConvertMethodsToContainersBase<MethodsToContainersPass> {
71  void runOnOperation() override;
72 };
73 } // anonymous namespace
74 
75 void MethodsToContainersPass::runOnOperation() {
76  auto *context = &getContext();
77  ConversionTarget target(*context);
78  target.addLegalDialect<IbisDialect>();
79  target.addIllegalOp<DataflowMethodOp>();
80  target.addIllegalOp<ReturnOp>();
81  RewritePatternSet patterns(context);
82 
83  patterns.insert<DataflowMethodOpConversion>(context);
84  if (failed(
85  applyPartialConversion(getOperation(), target, std::move(patterns))))
86  signalPassFailure();
87 }
88 
90  return std::make_unique<MethodsToContainersPass>();
91 }
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:54
std::unique_ptr< mlir::Pass > createConvertMethodsToContainersPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21