CIRCT 23.0.0git
Loading...
Searching...
No Matches
SynthToComb.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 is the main Synth to Comb Conversion Pass Implementation.
10//
11//===----------------------------------------------------------------------===//
12
18#include "mlir/Pass/Pass.h"
19#include "mlir/Transforms/DialectConversion.h"
20
21namespace circt {
22#define GEN_PASS_DEF_CONVERTSYNTHTOCOMB
23#include "circt/Conversion/Passes.h.inc"
24} // namespace circt
25
26using namespace circt;
27using namespace comb;
28
29//===----------------------------------------------------------------------===//
30// Conversion patterns
31//===----------------------------------------------------------------------===//
32
33namespace {
34
35// Return a value that represents the inverted input if `inverted` is true,
36static Value materializeInvertedInput(Location loc, Value input, bool inverted,
37 ConversionPatternRewriter &rewriter,
38 hw::ConstantOp &allOnes) {
39 if (!inverted)
40 return input;
41 auto width = input.getType().getIntOrFloatBitWidth();
42 if (!allOnes)
43 allOnes = hw::ConstantOp::create(rewriter, loc, APInt::getAllOnes(width));
44 return rewriter.createOrFold<comb::XorOp>(loc, input, allOnes, true);
45}
46
47struct SynthChoiceOpConversion : OpConversionPattern<synth::ChoiceOp> {
48 using OpConversionPattern<synth::ChoiceOp>::OpConversionPattern;
49 LogicalResult
50 matchAndRewrite(synth::ChoiceOp op, OpAdaptor adaptor,
51 ConversionPatternRewriter &rewriter) const override {
52 // Use the first input as the output, and ignore the rest.
53 rewriter.replaceOp(op, adaptor.getInputs().front());
54 return success();
55 }
56};
57
58template <typename SynthOp>
59struct SynthInverterOpConversion : OpConversionPattern<SynthOp> {
61 // Subclasses provide the target comb op after generic input inversion has
62 // been materialized.
63 virtual Value createOp(Location loc, ArrayRef<Value> inputs,
64 ConversionPatternRewriter &rewriter) const = 0;
65
66 virtual LogicalResult
67 matchAndRewrite(SynthOp op, typename SynthOp::Adaptor adaptor,
68 ConversionPatternRewriter &rewriter) const override {
69 SmallVector<Value> operands;
70 operands.reserve(op.getNumOperands());
71 hw::ConstantOp allOnes;
72 for (auto [input, inverted] :
73 llvm::zip(adaptor.getInputs(), op.getInverted()))
74 operands.push_back(materializeInvertedInput(op.getLoc(), input, inverted,
75 rewriter, allOnes));
76 // `createOp` now only needs to encode the core boolean operator.
77 rewriter.replaceOp(op, createOp(op.getLoc(), operands, rewriter));
78 return success();
79 }
80};
81
82struct SynthAndInverterOpConversion
83 : SynthInverterOpConversion<synth::aig::AndInverterOp> {
84 using SynthInverterOpConversion<
85 synth::aig::AndInverterOp>::SynthInverterOpConversion;
86 Value createOp(Location loc, ArrayRef<Value> inputs,
87 ConversionPatternRewriter &rewriter) const override {
88 return rewriter.createOrFold<comb::AndOp>(loc, inputs, true);
89 }
90};
91
92struct SynthXorInverterOpConversion
93 : SynthInverterOpConversion<synth::XorInverterOp> {
94 using SynthInverterOpConversion<
95 synth::XorInverterOp>::SynthInverterOpConversion;
96 Value createOp(Location loc, ArrayRef<Value> inputs,
97 ConversionPatternRewriter &rewriter) const override {
98 return rewriter.createOrFold<comb::XorOp>(loc, inputs, true);
99 }
100};
101
102} // namespace
103
104//===----------------------------------------------------------------------===//
105// Convert Synth to Comb pass
106//===----------------------------------------------------------------------===//
107
108namespace {
109struct ConvertSynthToCombPass
110 : public impl::ConvertSynthToCombBase<ConvertSynthToCombPass> {
111
112 void runOnOperation() override;
113 using ConvertSynthToCombBase<ConvertSynthToCombPass>::ConvertSynthToCombBase;
114};
115} // namespace
116
117static void populateSynthToCombConversionPatterns(RewritePatternSet &patterns) {
118 patterns.add<SynthChoiceOpConversion, SynthAndInverterOpConversion,
119 SynthXorInverterOpConversion>(patterns.getContext());
120}
121
122void ConvertSynthToCombPass::runOnOperation() {
123 ConversionTarget target(getContext());
124 target.addLegalDialect<comb::CombDialect, hw::HWDialect>();
125 target.addIllegalDialect<synth::SynthDialect>();
126
127 RewritePatternSet patterns(&getContext());
129
130 if (failed(mlir::applyPartialConversion(getOperation(), target,
131 std::move(patterns))))
132 return signalPassFailure();
133}
static Location getLoc(DefSlot slot)
Definition Mem2Reg.cpp:216
static void populateSynthToCombConversionPatterns(RewritePatternSet &patterns)
create(data_type, value)
Definition hw.py:433
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition comb.py:1