23#include "mlir/IR/PatternMatch.h"
24#include "mlir/Transforms/WalkPatternRewriteDriver.h"
28#define GEN_PASS_DEF_HWBYPASSINNERSYMBOLS
29#include "circt/Dialect/HW/Passes.h.inc"
37struct HWBypassInnerSymbolsPass
38 :
public impl::HWBypassInnerSymbolsBase<HWBypassInnerSymbolsPass> {
39 void runOnOperation()
override;
40 using HWBypassInnerSymbolsBase<
41 HWBypassInnerSymbolsPass>::HWBypassInnerSymbolsBase;
48 LogicalResult matchAndRewrite(WireOp wire,
49 PatternRewriter &rewriter)
const override {
51 if (!wire.getInnerSymAttr() || wire.use_empty())
55 rewriter.modifyOpInPlace(wire, [&] {
56 wire->replaceAllUsesWith(ArrayRef<Value>{wire.getInput()});
63void HWBypassInnerSymbolsPass::runOnOperation() {
64 auto module = getOperation();
69 auto *outputOp =
module.getBodyBlock()->getTerminator();
70 OpBuilder builder(&getContext());
71 bool hasInnerSym =
false;
72 auto moduleType =
module.getModuleType();
73 for (
auto [index, port] :
llvm::enumerate(portList)) {
74 auto sym = port.getSym();
79 if (port.isOutput()) {
80 auto value = outputOp->getOperand(moduleType.getOutputIdForPortId(index));
81 builder.setInsertionPointAfterValue(value);
82 auto wire = WireOp::create(builder, value.getLoc(), value);
83 wire.setInnerSymAttr(sym);
85 auto arg =
module.getBodyBlock()->getArgument(
86 moduleType.getInputIdForPortId(index));
87 builder.setInsertionPointToStart(module.getBodyBlock());
88 auto wire = WireOp::create(builder, arg.getLoc(), arg);
89 wire.setInnerSymAttr(sym);
95 auto innerSymAttr = StringAttr::get(
96 &getContext(), hw::HWModuleLike::getPortSymbolAttrName());
97 SmallVector<Attribute, 0> newAttrs(portList.size(), {});
98 cast<HWModuleLike>(*module).setPortAttrs(innerSymAttr, newAttrs);
101 RewritePatternSet
patterns(&getContext());
102 patterns.add<BypassWireWithInnerSym>(&getContext());
103 mlir::walkAndApplyPatterns(module, std::move(
patterns));
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
This holds a decoded list of input/inout and output ports for a module or instance.