CIRCT  20.0.0git
KanagawaConvertCFToHandshake.cpp
Go to the documentation of this file.
1 //===- KanagawaConvertCFToHandshakePass.cpp -------------------------------===//
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 
19 #include "mlir/Transforms/DialectConversion.h"
20 
22 
23 namespace circt {
24 namespace kanagawa {
25 #define GEN_PASS_DEF_KANAGAWACONVERTCFTOHANDSHAKE
26 #include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc"
27 } // namespace kanagawa
28 } // namespace circt
29 
30 using namespace mlir;
31 using namespace circt;
32 using namespace kanagawa;
33 
34 namespace {
35 
36 struct ConvertCFToHandshakePass
37  : public circt::kanagawa::impl::KanagawaConvertCFToHandshakeBase<
38  ConvertCFToHandshakePass> {
39  void runOnOperation() override;
40 
41  LogicalResult convertMethod(MethodOp method);
42 };
43 } // anonymous namespace
44 
45 LogicalResult ConvertCFToHandshakePass::convertMethod(MethodOp method) {
46  // Add a control input/output to the method.
47  OpBuilder b(method);
48  llvm::SmallVector<Type> newArgTypes, newResTypes;
49  auto methodLikeOp = cast<MethodLikeOpInterface>(method.getOperation());
50  llvm::copy(methodLikeOp.getArgumentTypes(), std::back_inserter(newArgTypes));
51  llvm::copy(methodLikeOp.getResultTypes(), std::back_inserter(newResTypes));
52  newArgTypes.push_back(b.getNoneType());
53  newResTypes.push_back(b.getNoneType());
54  auto newFuncType = b.getFunctionType(newArgTypes, newResTypes);
55  auto dataflowMethodOp = b.create<DataflowMethodOp>(
56  method.getLoc(), method.getInnerSymAttr(), TypeAttr::get(newFuncType),
57  method.getArgNamesAttr(), method.getArgAttrsAttr(),
58  method.getResAttrsAttr());
59  dataflowMethodOp.getFunctionBody().takeBody(method.getBody());
60  dataflowMethodOp.getBodyBlock()->addArgument(b.getNoneType(),
61  method.getLoc());
62  Value entryCtrl = dataflowMethodOp.getBodyBlock()->getArguments().back();
63  method.erase();
64 
65  handshake::HandshakeLowering fol(dataflowMethodOp.getBody());
66  if (failed(handshake::lowerRegion<kanagawa::ReturnOp, kanagawa::ReturnOp>(
67  fol,
68  /*sourceConstants*/ false, /*disableTaskPipelining*/ false,
69  entryCtrl)))
70  return failure();
71 
72  return success();
73 }
74 
75 void ConvertCFToHandshakePass::runOnOperation() {
76  ClassOp classOp = getOperation();
77  for (auto method : llvm::make_early_inc_range(classOp.getOps<MethodOp>())) {
78  if (failed(convertMethod(method)))
79  return signalPassFailure();
80  }
81 }
82 
84  return std::make_unique<ConvertCFToHandshakePass>();
85 }
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
std::unique_ptr< mlir::Pass > createConvertCFToHandshakePass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21