13#include "../PassDetails.h"
20#include "mlir/IR/BuiltinTypes.h"
21#include "mlir/Interfaces/ControlFlowInterfaces.h"
22#include "mlir/Pass/Pass.h"
23#include "mlir/Transforms/DialectConversion.h"
27#define GEN_PASS_DEF_LOWERESITYPES
28#include "circt/Dialect/ESI/ESIPasses.h.inc"
37struct ESILowerTypesPass
38 :
public circt::esi::impl::LowerESITypesBase<ESILowerTypesPass> {
39 void runOnOperation()
override;
45class LowerTypesConverter :
public TypeConverter {
47 LowerTypesConverter() {
48 addConversion([](Type t) {
return t; });
49 addConversion([](WindowType window) {
return window.getLoweredType(); });
50 addSourceMaterialization(wrapMaterialization);
51 addTargetMaterialization(unwrapMaterialization);
55 static mlir::Value wrapMaterialization(OpBuilder &b, WindowType resultType,
56 ValueRange inputs, Location loc) {
57 if (inputs.size() != 1)
59 return b.createOrFold<WrapWindow>(loc, resultType, inputs[0]);
62 static mlir::Value unwrapMaterialization(OpBuilder &b, Type resultType,
63 ValueRange inputs, Location loc) {
64 if (inputs.size() != 1 || !isa<WindowType>(inputs[0].getType()))
66 return b.createOrFold<UnwrapWindow>(loc, resultType, inputs[0]);
71void ESILowerTypesPass::runOnOperation() {
72 ConversionTarget target(getContext());
75 target.markUnknownOpDynamicallyLegal([](Operation *op) {
76 return TypeSwitch<Operation *, bool>(op)
77 .Case([](igraph::InstanceOpInterface inst) {
79 llvm::any_of(inst->getOperandTypes(), hw::type_isa<WindowType>) ||
80 llvm::any_of(inst->getResultTypes(), hw::type_isa<WindowType>));
82 .Case([](hw::HWMutableModuleLike mod) {
84 return hw::type_isa<WindowType>(p.type);
86 return !(llvm::any_of(mod.getPortList(), isWindowPort));
88 .Default([](Operation *op) {
89 if (op->hasTrait<OpTrait::ReturnLike>())
90 return !llvm::any_of(op->getOperandTypes(),
91 hw::type_isa<WindowType>);
96 LowerTypesConverter types;
97 RewritePatternSet
patterns(&getContext());
100 applyPartialConversion(getOperation(), target, std::move(
patterns))))
105 mlir::ConversionConfig config;
106 config.foldingMode = mlir::DialectConversionFoldingMode::BeforePatterns;
107 ConversionTarget partialCanonicalizedTarget(getContext());
108 RewritePatternSet partialPatterns(&getContext());
109 partialCanonicalizedTarget.addIllegalOp<WrapWindow, UnwrapWindow>();
110 WrapWindow::getCanonicalizationPatterns(partialPatterns, &getContext());
111 UnwrapWindow::getCanonicalizationPatterns(partialPatterns, &getContext());
112 if (failed(mlir::applyPartialConversion(getOperation(),
113 partialCanonicalizedTarget,
114 std::move(partialPatterns), config)))
118std::unique_ptr<OperationPass<ModuleOp>>
120 return std::make_unique<ESILowerTypesPass>();
std::unique_ptr< OperationPass< ModuleOp > > createESITypeLoweringPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Generic pattern which replaces an operation by one of the same operation name, but with converted att...
This holds the name, type, direction of a module's ports.