12 #include "mlir/Transforms/DialectConversion.h"
13 #include "llvm/ADT/TypeSwitch.h"
15 using namespace circt;
20 #define GEN_PASS_DEF_LOWERCOMB
21 #include "circt/Dialect/Comb/Passes.h.inc"
28 using OpConversionPattern::OpConversionPattern;
34 Value getMux(Location loc, OpBuilder &b, Value t, Value f,
35 ArrayRef<bool> table, Operation::operand_range inputs)
const {
36 assert(table.size() == (1ull << inputs.size()));
37 if (table.size() == 1)
38 return table.front() ? t : f;
40 size_t half = table.size() / 2;
42 getMux(loc, b, t, f, table.drop_front(half), inputs.drop_front());
44 getMux(loc, b, t, f, table.drop_back(half), inputs.drop_front());
45 return b.create<MuxOp>(loc, inputs.front(), if1, if0,
false);
49 LogicalResult matchAndRewrite(TruthTableOp op, OpAdaptor adaptor,
50 ConversionPatternRewriter &b)
const override {
51 Location loc = op.getLoc();
52 SmallVector<bool> table(
53 llvm::map_range(op.getLookupTableAttr().getAsValueRange<IntegerAttr>(),
54 [](
const APInt &a) { return !a.isZero(); }));
55 Value t = b.create<
hw::ConstantOp>(loc, b.getIntegerAttr(b.getI1Type(), 1));
58 Value tree = getMux(loc, b, t, f, table, op.getInputs());
59 b.modifyOpInPlace(tree.getDefiningOp(), [&]() {
60 tree.getDefiningOp()->setDialectAttrs(op->getDialectAttrs());
62 b.replaceOp(op, tree);
69 class LowerCombPass :
public impl::LowerCombBase<LowerCombPass> {
71 using LowerCombBase::LowerCombBase;
73 void runOnOperation()
override;
77 void LowerCombPass::runOnOperation() {
78 ModuleOp module = getOperation();
80 ConversionTarget target(getContext());
81 RewritePatternSet
patterns(&getContext());
82 target.markUnknownOpDynamicallyLegal([](Operation *) {
return true; });
83 target.addIllegalOp<TruthTableOp>();
87 if (failed(applyPartialConversion(module, target, std::move(
patterns))))
88 return signalPassFailure();
assert(baseType &&"element must be base type")
def create(data_type, value)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.