CIRCT 21.0.0git
Loading...
Searching...
No Matches
LowerConcatRef.cpp
Go to the documentation of this file.
1//===- LowerConcatRef.cpp - moore.concat_ref lowering ---------------------===//
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 defines the LowerConcatRef pass.
10// It's used to disassemble the moore.concat_ref. Which is tricky to lower
11// directly. For example, disassemble "{a, b} = c" onto "a = c[7:3]"
12// and "b = c[2:0]".
13//
14//===----------------------------------------------------------------------===//
15
18#include "mlir/Transforms/DialectConversion.h"
19
20namespace circt {
21namespace moore {
22#define GEN_PASS_DEF_LOWERCONCATREF
23#include "circt/Dialect/Moore/MoorePasses.h.inc"
24} // namespace moore
25} // namespace circt
26
27using namespace circt;
28using namespace moore;
29using namespace mlir;
30
31namespace {
32
33// A helper function for collecting the non-concatRef operands of concatRef.
34static void collectOperands(Value operand, SmallVectorImpl<Value> &operands) {
35 if (auto concatRefOp = operand.getDefiningOp<ConcatRefOp>())
36 for (auto nestedOperand : concatRefOp.getValues())
37 collectOperands(nestedOperand, operands);
38 else
39 operands.push_back(operand);
40}
41
42template <typename OpTy>
43struct ConcatRefLowering : public OpConversionPattern<OpTy> {
45 using OpAdaptor = typename OpTy::Adaptor;
46
47 LogicalResult
48 matchAndRewrite(OpTy op, OpAdaptor adaptor,
49 ConversionPatternRewriter &rewriter) const override {
50 // Use to collect the operands of concatRef.
51 SmallVector<Value, 4> operands;
52 collectOperands(op.getDst(), operands);
53 auto srcWidth =
54 cast<UnpackedType>(op.getSrc().getType()).getBitSize().value();
55
56 // Disassemble assignments with the LHS is concatRef. And create new
57 // corresponding assignments using non-concatRef LHS.
58 for (auto operand : operands) {
59 auto type = cast<RefType>(operand.getType()).getNestedType();
60 auto width = type.getBitSize().value();
61
62 rewriter.setInsertionPoint(op);
63 // FIXME: Need to estimate whether the bits range is from large to
64 // small or vice versa. Like "logic [7:0] or [0:7]".
65
66 // Only able to correctly handle the situation like "[7:0]" now.
67 auto extract = rewriter.create<ExtractOp>(op.getLoc(), type, op.getSrc(),
68 srcWidth - width);
69
70 // Update the real bit width of RHS of assignment. Like "c" the above
71 // description mentioned.
72 srcWidth = srcWidth - width;
73
74 rewriter.create<OpTy>(op.getLoc(), operand, extract);
75 }
76 rewriter.eraseOp(op);
77 return success();
78 }
79};
80
81struct LowerConcatRefPass
82 : public circt::moore::impl::LowerConcatRefBase<LowerConcatRefPass> {
83 void runOnOperation() override;
84};
85
86} // namespace
87
88std::unique_ptr<mlir::Pass> circt::moore::createLowerConcatRefPass() {
89 return std::make_unique<LowerConcatRefPass>();
90}
91
92void LowerConcatRefPass::runOnOperation() {
93 MLIRContext &context = getContext();
94 ConversionTarget target(context);
95
96 target.addDynamicallyLegalOp<ContinuousAssignOp, BlockingAssignOp,
97 NonBlockingAssignOp>([](auto op) {
98 return !op->getOperand(0).template getDefiningOp<ConcatRefOp>();
99 });
100
101 target.addLegalDialect<MooreDialect>();
102 RewritePatternSet patterns(&context);
103 patterns.add<ConcatRefLowering<ContinuousAssignOp>,
104 ConcatRefLowering<BlockingAssignOp>,
105 ConcatRefLowering<NonBlockingAssignOp>>(&context);
106
107 if (failed(
108 applyPartialConversion(getOperation(), target, std::move(patterns))))
109 signalPassFailure();
110}
std::unique_ptr< mlir::Pass > createLowerConcatRefPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.