CIRCT 22.0.0git
Loading...
Searching...
No Matches
CombToDatapath.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 Comb to Datapath Conversion Pass Implementation.
10//
11//===----------------------------------------------------------------------===//
12
17#include "mlir/Pass/Pass.h"
18#include "mlir/Transforms/DialectConversion.h"
19
20namespace circt {
21#define GEN_PASS_DEF_CONVERTCOMBTODATAPATH
22#include "circt/Conversion/Passes.h.inc"
23} // namespace circt
24
25using namespace circt;
26using namespace comb;
27
28//===----------------------------------------------------------------------===//
29// Conversion patterns
30//===----------------------------------------------------------------------===//
31
32namespace {
33// add(a1, a2, ...) -> add(compress(a1, a2, ...))
34struct CombAddOpConversion : OpConversionPattern<AddOp> {
36 LogicalResult
37 matchAndRewrite(AddOp op, OpAdaptor adaptor,
38 ConversionPatternRewriter &rewriter) const override {
39
40 auto width = op.getType().getIntOrFloatBitWidth();
41 // Skip a zero width value.
42 if (width == 0) {
43 rewriter.replaceOpWithNewOp<hw::ConstantOp>(op, op.getType(), 0);
44 return success();
45 }
46
47 // Reduce to two values (carry,save)
48 auto results = datapath::CompressOp::create(rewriter, op.getLoc(),
49 op.getOperands(), 2);
50 // carry+saved
51 rewriter.replaceOpWithNewOp<AddOp>(op, results.getResults(), true);
52 return success();
53 }
54};
55
56// mul(a,b) -> add(pp(a,b))
57// multi-input adder will be converted to a compressor by other pattern
58struct CombMulOpConversion : OpConversionPattern<MulOp> {
60 LogicalResult
61 matchAndRewrite(MulOp op, OpAdaptor adaptor,
62 ConversionPatternRewriter &rewriter) const override {
63 // TODO: support for variadic multipliers
64 if (adaptor.getInputs().size() != 2)
65 return failure();
66
67 auto width = op.getType().getIntOrFloatBitWidth();
68 // Create partial product rows - number of rows == width
69 auto pp = datapath::PartialProductOp::create(rewriter, op.getLoc(),
70 op.getInputs(), width);
71 // Sum partial products
72 rewriter.replaceOpWithNewOp<AddOp>(op, pp.getResults(), true);
73 return success();
74 }
75};
76
77} // namespace
78
79//===----------------------------------------------------------------------===//
80// Convert Comb to Datapath pass
81//===----------------------------------------------------------------------===//
82
83namespace {
84struct ConvertCombToDatapathPass
85 : public impl::ConvertCombToDatapathBase<ConvertCombToDatapathPass> {
86 void runOnOperation() override;
87 using ConvertCombToDatapathBase<
88 ConvertCombToDatapathPass>::ConvertCombToDatapathBase;
89};
90} // namespace
91
92static void
94 patterns.add<CombAddOpConversion, CombMulOpConversion>(patterns.getContext());
95}
96
97void ConvertCombToDatapathPass::runOnOperation() {
98 ConversionTarget target(getContext());
99
100 target.addLegalDialect<datapath::DatapathDialect, comb::CombDialect,
101 hw::HWDialect>();
102
103 // Permit 2-input adders (carry-propagate adders)
104 target.addDynamicallyLegalOp<comb::AddOp>(
105 [](comb::AddOp op) { return op.getNumOperands() <= 2; });
106 // TODO: determine lowering of multi-input multipliers
107 target.addDynamicallyLegalOp<comb::MulOp>(
108 [](comb::MulOp op) { return op.getNumOperands() > 2; });
109
110 RewritePatternSet patterns(&getContext());
112
113 if (failed(mlir::applyPartialConversion(getOperation(), target,
114 std::move(patterns))))
115 return signalPassFailure();
116}
static void populateCombToDatapathConversionPatterns(RewritePatternSet &patterns)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition comb.py:1