23#include "mlir/Transforms/DialectConversion.h"
27#define GEN_PASS_DEF_SIMPLIFYREFS
28#include "circt/Dialect/Moore/MoorePasses.h.inc"
39static void collectOperands(Value operand, SmallVectorImpl<Value> &operands,
40 ConversionPatternRewriter &rewriter) {
41 if (
auto concatRefOp = operand.getDefiningOp<ConcatRefOp>()) {
43 if (std::distance(concatRefOp->getUsers().begin(),
44 concatRefOp->getUsers().end()) == 1) {
45 rewriter.eraseOp(concatRefOp);
47 for (
auto nestedOperand : concatRefOp.getValues())
48 collectOperands(nestedOperand, operands, rewriter);
51 operands.push_back(operand);
54template <
typename OpTy>
57 using OpAdaptor =
typename OpTy::Adaptor;
60 matchAndRewrite(OpTy op, OpAdaptor adaptor,
61 ConversionPatternRewriter &rewriter)
const override {
63 SmallVector<Value, 4> operands;
64 collectOperands(op.getDst(), operands, rewriter);
66 cast<UnpackedType>(op.getSrc().getType()).getBitSize().value();
70 for (
auto operand : operands) {
71 auto type = cast<RefType>(operand.getType()).getNestedType();
72 auto width = type.getBitSize().value();
74 rewriter.setInsertionPoint(op);
79 auto extract = ExtractOp::create(rewriter, op.getLoc(), type, op.getSrc(),
84 srcWidth = srcWidth - width;
86 OpTy::create(rewriter, op.getLoc(), operand, extract);
97 matchAndRewrite(DynQueueRefElementOp op, OpAdaptor adaptor,
98 ConversionPatternRewriter &rewriter)
const override {
101 for (
auto *consumer : op->getUsers()) {
102 if (isa<BlockingAssignOp>(consumer)) {
104 auto assignOp = cast<BlockingAssignOp>(consumer);
106 rewriter.setInsertionPoint(consumer);
107 moore::QueueSetOp::create(rewriter, op->getLoc(), op.getInput(),
108 op.getIndex(), assignOp.getSrc());
110 rewriter.eraseOp(assignOp);
112 return mlir::emitError(op.getLoc())
113 <<
"Queue element reference couldn't be reduced to setting the "
114 "value at an index: consuming op "
115 << consumer <<
" is not supported";
119 rewriter.eraseOp(op);
125struct SimplifyRefsPass
126 :
public circt::moore::impl::SimplifyRefsBase<SimplifyRefsPass> {
127 void runOnOperation()
override;
133 return std::make_unique<SimplifyRefsPass>();
136void SimplifyRefsPass::runOnOperation() {
137 MLIRContext &
context = getContext();
138 ConversionTarget target(
context);
140 target.addDynamicallyLegalOp<ContinuousAssignOp, BlockingAssignOp,
141 NonBlockingAssignOp>([](
auto op) {
142 return !op->getOperand(0).template getDefiningOp<ConcatRefOp>();
145 target.addLegalDialect<MooreDialect>();
146 RewritePatternSet concatRefPatterns(&
context);
147 concatRefPatterns.add<ConcatRefLowering<ContinuousAssignOp>,
148 ConcatRefLowering<BlockingAssignOp>,
149 ConcatRefLowering<NonBlockingAssignOp>>(&
context);
151 if (failed(applyPartialConversion(getOperation(), target,
152 std::move(concatRefPatterns)))) {
159 RewritePatternSet queueRefPatterns(&
context);
160 target.addIllegalOp<DynQueueRefElementOp>();
161 queueRefPatterns.add<QueueRefLowering>(&
context);
162 if (failed(applyPartialConversion(getOperation(), target,
163 std::move(queueRefPatterns))))
static std::unique_ptr< Context > context
std::unique_ptr< mlir::Pass > createSimplifyRefsPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.