18 #include "mlir/IR/Builders.h"
19 #include "mlir/IR/PatternMatch.h"
20 #include "mlir/Transforms/DialectConversion.h"
24 using namespace circt;
38 class PruneTypeConverter :
public mlir::TypeConverter {
40 PruneTypeConverter() {
41 addConversion([&](Type type, SmallVectorImpl<Type> &results) {
43 results.push_back(type);
49 template <
typename TOp>
56 matchAndRewrite(TOp op, OpAdaptor adaptor,
57 ConversionPatternRewriter &rewriter)
const override {
67 template <
typename... TOp>
68 static void addNoI0OperandsLegalizationPattern(ConversionTarget &target) {
69 target.addDynamicallyLegalOp<TOp...>(
74 struct NoI0OperandsConversionPattern<
comb::ICmpOp>
85 case circt::comb::ICmpPredicate::eq:
86 case circt::comb::ICmpPredicate::sle:
87 case circt::comb::ICmpPredicate::sge:
88 case circt::comb::ICmpPredicate::ule:
89 case circt::comb::ICmpPredicate::uge:
90 case circt::comb::ICmpPredicate::ceq:
91 case circt::comb::ICmpPredicate::weq:
93 case circt::comb::ICmpPredicate::ne:
94 case circt::comb::ICmpPredicate::slt:
95 case circt::comb::ICmpPredicate::sgt:
96 case circt::comb::ICmpPredicate::ult:
97 case circt::comb::ICmpPredicate::ugt:
98 case circt::comb::ICmpPredicate::cne:
99 case circt::comb::ICmpPredicate::wne:
102 llvm_unreachable(
"unknown comparison predicate");
106 matchAndRewrite(comb::ICmpOp op, OpAdaptor adaptor,
107 ConversionPatternRewriter &rewriter)
const override {
115 op, APInt(1, result,
false));
121 struct NoI0OperandsConversionPattern<
comb::ParityOp>
129 ConversionPatternRewriter &rewriter)
const override {
135 op, APInt(1, 0,
false));
141 struct NoI0OperandsConversionPattern<
comb::ConcatOp>
149 ConversionPatternRewriter &rewriter)
const override {
151 if (op.getType().isInteger(0)) {
153 op, APInt(1, 0,
false));
161 SmallVector<Value> newOperands;
162 llvm::copy_if(op.getOperands(), std::back_inserter(newOperands),
163 [](
auto op) { return !op.getType().isInteger(0); });
172 template <
typename TOp>
173 struct NoI0OperandPruningPattern {
174 using ConversionPattern = NoI0OperandsConversionPattern<TOp>;
175 static void addLegalizer(ConversionTarget &target) {
176 addNoI0OperandsLegalizationPattern<TOp>(target);
183 template <
typename TOp>
190 matchAndRewrite(TOp op, OpAdaptor adaptor,
191 ConversionPatternRewriter &rewriter)
const override {
196 assert(op->getNumResults() == 1 &&
197 "expected single result if using rewriter.replaceOpWith");
199 op, APInt(0, 0,
false));
204 template <
typename... TOp>
205 static void addNoI0ResultsLegalizationPattern(ConversionTarget &target) {
206 target.addDynamicallyLegalOp<TOp...>(
212 template <
typename TOp>
213 struct NoI0ResultPruningPattern {
214 using ConversionPattern = NoI0ResultsConversionPattern<TOp>;
215 static void addLegalizer(ConversionTarget &target) {
216 addNoI0ResultsLegalizationPattern<TOp>(target);
222 template <
typename... TPattern>
223 static void addPruningPattern(ConversionTarget &target,
225 PruneTypeConverter &typeConverter) {
226 (
patterns.add<
typename TPattern::ConversionPattern>(typeConverter,
229 (TPattern::addLegalizer(target), ...);
232 template <
typename... TOp>
233 static void addNoI0ResultPruningPattern(ConversionTarget &target,
235 PruneTypeConverter &typeConverter) {
236 (
patterns.add<
typename NoI0ResultPruningPattern<TOp>::ConversionPattern>(
237 typeConverter,
patterns.getContext()),
239 (NoI0ResultPruningPattern<TOp>::addLegalizer(target), ...);
245 ConversionTarget target(*module->getContext());
246 RewritePatternSet
patterns(module->getContext());
247 PruneTypeConverter typeConverter;
249 target.addLegalDialect<sv::SVDialect, comb::CombDialect, hw::HWDialect>();
250 addPruningPattern<NoI0OperandPruningPattern<sv::PAssignOp>,
251 NoI0OperandPruningPattern<sv::BPAssignOp>,
252 NoI0OperandPruningPattern<sv::AssignOp>,
253 NoI0OperandPruningPattern<comb::ICmpOp>,
254 NoI0OperandPruningPattern<comb::ParityOp>,
255 NoI0OperandPruningPattern<comb::ConcatOp>>(target,
patterns,
258 addNoI0ResultPruningPattern<
267 (void)applyPartialConversion(module, target, std::move(
patterns));
assert(baseType &&"element must be base type")
static bool applyCmpPredicateToEqualOperands(ICmpPredicate predicate)
static bool noI0TypedValue(ValueRange values)
static bool noI0Type(TypeRange types)
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.