19#include "mlir/IR/Builders.h"
20#include "mlir/IR/PatternMatch.h"
21#include "mlir/Transforms/DialectConversion.h"
37 SmallVector<Value> result;
38 for (
const auto &vals : values)
39 llvm::append_range(result, vals);
45class PruneTypeConverter :
public mlir::TypeConverter {
47 PruneTypeConverter() {
48 addConversion([&](Type type, SmallVectorImpl<Type> &results) {
50 results.push_back(type);
56template <
typename TOp>
59 using OpConversionPattern<TOp>::OpConversionPattern;
60 using OpAdaptor =
typename OpConversionPattern<TOp>::OpAdaptor;
61 using OneToNOpAdaptor =
typename OpConversionPattern<TOp>::OneToNOpAdaptor;
64 matchAndRewrite(TOp op, OneToNOpAdaptor adaptor,
65 ConversionPatternRewriter &rewriter)
const override {
66 SmallVector<Value> flattenedOperands =
flattenValues(adaptor.getOperands());
71 if (!flattenedOperands.empty() &&
noI0TypedValue(flattenedOperands))
80template <
typename... TOp>
82 target.addDynamicallyLegalOp<TOp...>(
87struct NoI0OperandsConversionPattern<
comb::ICmpOp>
90 using OpConversionPattern<comb::ICmpOp>::OpConversionPattern;
91 using OpAdaptor =
typename OpConversionPattern<comb::ICmpOp>::OpAdaptor;
92 using OneToNOpAdaptor =
93 typename OpConversionPattern<comb::ICmpOp>::OneToNOpAdaptor;
100 case circt::comb::ICmpPredicate::eq:
101 case circt::comb::ICmpPredicate::sle:
102 case circt::comb::ICmpPredicate::sge:
103 case circt::comb::ICmpPredicate::ule:
104 case circt::comb::ICmpPredicate::uge:
105 case circt::comb::ICmpPredicate::ceq:
106 case circt::comb::ICmpPredicate::weq:
108 case circt::comb::ICmpPredicate::ne:
109 case circt::comb::ICmpPredicate::slt:
110 case circt::comb::ICmpPredicate::sgt:
111 case circt::comb::ICmpPredicate::ult:
112 case circt::comb::ICmpPredicate::ugt:
113 case circt::comb::ICmpPredicate::cne:
114 case circt::comb::ICmpPredicate::wne:
117 llvm_unreachable(
"unknown comparison predicate");
121 matchAndRewrite(comb::ICmpOp op, OneToNOpAdaptor adaptor,
122 ConversionPatternRewriter &rewriter)
const override {
129 rewriter.replaceOpWithNewOp<hw::ConstantOp>(
130 op, APInt(1, result,
false));
136struct NoI0OperandsConversionPattern<
comb::ParityOp>
139 using OpConversionPattern<comb::ParityOp>::OpConversionPattern;
140 using OpAdaptor =
typename OpConversionPattern<comb::ParityOp>::OpAdaptor;
141 using OneToNOpAdaptor =
142 typename OpConversionPattern<comb::ParityOp>::OneToNOpAdaptor;
145 matchAndRewrite(comb::ParityOp op, OneToNOpAdaptor adaptor,
146 ConversionPatternRewriter &rewriter)
const override {
147 SmallVector<Value> flattenedOperands =
flattenValues(adaptor.getOperands());
148 if (!flattenedOperands.empty() &&
noI0TypedValue(flattenedOperands))
152 rewriter.replaceOpWithNewOp<hw::ConstantOp>(
153 op, APInt(1, 0,
false));
159struct NoI0OperandsConversionPattern<
comb::ConcatOp>
162 using OpConversionPattern<comb::ConcatOp>::OpConversionPattern;
163 using OpAdaptor =
typename OpConversionPattern<comb::ConcatOp>::OpAdaptor;
164 using OneToNOpAdaptor =
165 typename OpConversionPattern<comb::ConcatOp>::OneToNOpAdaptor;
168 matchAndRewrite(comb::ConcatOp op, OneToNOpAdaptor adaptor,
169 ConversionPatternRewriter &rewriter)
const override {
171 if (op.getType().isInteger(0)) {
172 rewriter.replaceOpWithNewOp<hw::ConstantOp>(
173 op, APInt(1, 0,
false));
177 SmallVector<Value> materializedOperands =
184 if (materializedOperands.size() == adaptor.getOperands().size())
188 rewriter.replaceOpWithNewOp<comb::ConcatOp>(op, materializedOperands);
196template <
typename TOp>
197struct NoI0OperandPruningPattern {
198 using ConversionPattern = NoI0OperandsConversionPattern<TOp>;
199 static void addLegalizer(ConversionTarget &target) {
200 addNoI0OperandsLegalizationPattern<TOp>(target);
207template <
typename TOp>
210 using OpConversionPattern<TOp>::OpConversionPattern;
211 using OneToNOpAdaptor =
typename OpConversionPattern<TOp>::OneToNOpAdaptor;
214 matchAndRewrite(TOp op, OneToNOpAdaptor adaptor,
215 ConversionPatternRewriter &rewriter)
const override {
220 assert(op->getNumResults() == 1 &&
221 "expected single result if using rewriter.replaceOpWith");
222 rewriter.replaceOpWithNewOp<hw::ConstantOp>(
223 op, APInt(0, 0,
false));
228template <
typename... TOp>
230 target.addDynamicallyLegalOp<TOp...>(
236template <
typename TOp>
237struct NoI0ResultPruningPattern {
238 using ConversionPattern = NoI0ResultsConversionPattern<TOp>;
239 static void addLegalizer(ConversionTarget &target) {
240 addNoI0ResultsLegalizationPattern<TOp>(target);
246template <
typename... TPattern>
249 PruneTypeConverter &typeConverter) {
250 (
patterns.add<
typename TPattern::ConversionPattern>(typeConverter,
253 (TPattern::addLegalizer(target), ...);
256template <
typename... TOp>
259 PruneTypeConverter &typeConverter) {
260 (
patterns.add<
typename NoI0ResultPruningPattern<TOp>::ConversionPattern>(
261 typeConverter,
patterns.getContext()),
263 (NoI0ResultPruningPattern<TOp>::addLegalizer(target), ...);
270 RewritePatternSet
patterns(module->getContext());
271 PruneTypeConverter typeConverter;
273 target.addLegalDialect<sv::SVDialect, comb::CombDialect, hw::HWDialect>();
274 addPruningPattern<NoI0OperandPruningPattern<sv::PAssignOp>,
275 NoI0OperandPruningPattern<sv::BPAssignOp>,
276 NoI0OperandPruningPattern<sv::AssignOp>,
277 NoI0OperandPruningPattern<comb::ICmpOp>,
278 NoI0OperandPruningPattern<comb::ParityOp>,
279 NoI0OperandPruningPattern<comb::ConcatOp>>(target,
patterns,
282 addNoI0ResultPruningPattern<
291 (void)applyPartialConversion(module, target, std::move(
patterns));
assert(baseType &&"element must be base type")
static bool applyCmpPredicateToEqualOperands(ICmpPredicate predicate)
false return failure()
Parse an optional keyword or string and set instance into 'result'.
static bool noI0TypedValue(ValueRange values)
static bool noI0Type(TypeRange types)
static SmallVector< Value > flattenValues(ArrayRef< ValueRange > values)
Flatten the given value ranges into a single vector of values.
void pruneZeroValuedLogic(hw::HWEmittableModuleLike module)
bool isZeroBitType(Type type)
Return true if this is a zero bit type, e.g.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.