CIRCT  20.0.0git
HWModuleOpInterface.cpp
Go to the documentation of this file.
1 //===- HWModuleOpInterface.cpp.h - Implement HWModuleLike ------*- C++ -*-===//
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 // This file implements HWModuleLike related functionality.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "mlir/Transforms/DialectConversion.h"
15 
16 using namespace circt;
17 using namespace hw;
18 
19 //===----------------------------------------------------------------------===//
20 // HWModuleLike Signature Conversion
21 //===----------------------------------------------------------------------===//
22 
23 static LogicalResult convertModuleOpTypes(HWModuleLike modOp,
24  const TypeConverter &typeConverter,
25  ConversionPatternRewriter &rewriter) {
26  ModuleType type = modOp.getHWModuleType();
27  if (!type)
28  return failure();
29 
30  // Convert the original port types.
31  // Update the module signature in-place.
32  SmallVector<ModulePort> newPorts;
33  TypeConverter::SignatureConversion result(type.getNumInputs());
34  unsigned atInput = 0;
35  unsigned curInputs = 0;
36  for (auto &p : type.getPorts()) {
37  if (p.dir == ModulePort::Direction::Output) {
38  SmallVector<Type, 1> newResults;
39  if (failed(typeConverter.convertType(p.type, newResults)))
40  return failure();
41  for (auto np : newResults)
42  newPorts.push_back({p.name, np, p.dir});
43  } else {
44  if (failed(typeConverter.convertSignatureArg(
45  atInput++,
46  /* inout ports need to be wrapped in the appropriate type */
47  p.dir == ModulePort::Direction::Input ? p.type
48  : InOutType::get(p.type),
49  result)))
50  return failure();
51  for (auto np : result.getConvertedTypes().drop_front(curInputs))
52  newPorts.push_back({p.name, np, p.dir});
53  curInputs = result.getConvertedTypes().size();
54  }
55  }
56 
57  if (failed(rewriter.convertRegionTypes(&modOp->getRegion(0), typeConverter,
58  &result)))
59  return failure();
60 
61  auto newType = ModuleType::get(rewriter.getContext(), newPorts);
62  rewriter.modifyOpInPlace(modOp, [&] { modOp.setHWModuleType(newType); });
63 
64  return success();
65 }
66 
67 /// Create a default conversion pattern that rewrites the type signature of a
68 /// FunctionOpInterface op. This only supports ops which use FunctionType to
69 /// represent their type.
70 namespace {
71 struct HWModuleLikeSignatureConversion : public ConversionPattern {
72  HWModuleLikeSignatureConversion(StringRef moduleLikeOpName, MLIRContext *ctx,
73  const TypeConverter &converter)
74  : ConversionPattern(converter, moduleLikeOpName, /*benefit=*/1, ctx) {}
75 
76  LogicalResult
77  matchAndRewrite(Operation *op, ArrayRef<Value> /*operands*/,
78  ConversionPatternRewriter &rewriter) const override {
79  HWModuleLike modOp = cast<HWModuleLike>(op);
80  return convertModuleOpTypes(modOp, *typeConverter, rewriter);
81  }
82 };
83 } // namespace
84 
86  StringRef moduleLikeOpName, RewritePatternSet &patterns,
87  TypeConverter &converter) {
88  patterns.add<HWModuleLikeSignatureConversion>(
89  moduleLikeOpName, patterns.getContext(), converter);
90 }
static LogicalResult convertModuleOpTypes(HWModuleLike modOp, const TypeConverter &typeConverter, ConversionPatternRewriter &rewriter)
@ Input
Definition: HW.h:35
@ Output
Definition: HW.h:35
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
Definition: CalyxOps.cpp:55
void populateHWModuleLikeTypeConversionPattern(StringRef moduleLikeOpName, RewritePatternSet &patterns, TypeConverter &converter)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition: DebugAnalysis.h:21
Definition: hw.py:1