18#include "mlir/IR/PatternMatch.h"
19#include "mlir/Transforms/WalkPatternRewriteDriver.h"
20#include "llvm/Support/LogicalResult.h"
27#define GEN_PASS_DEF_SIMPLIFYTRUTHTABLE
28#include "circt/Dialect/Comb/Passes.h.inc"
36 return llvm::any_of(op->getOperands(), [op](
auto operand) {
37 return operand.getDefiningOp() == op;
43 using OpRewritePattern::OpRewritePattern;
45 LogicalResult matchAndRewrite(TruthTableOp op,
46 PatternRewriter &rewriter)
const override {
50 const auto inputs = op.getInputs();
51 const auto table = op.getLookupTable();
52 size_t numInputs = inputs.size();
53 size_t tableSize = table.size();
59 bool allSame = llvm::all_equal(table);
61 bool firstValue = cast<BoolAttr>(table[0]).getValue();
71 SmallVector<bool> dependsOn(numInputs,
false);
72 int dependentInput = -1;
73 unsigned numDependencies = 0;
75 for (
size_t idx = 0; idx < tableSize; ++idx) {
76 bool currentValue = cast<BoolAttr>(table[idx]).getValue();
78 for (
size_t bitPos = 0; bitPos < numInputs; ++bitPos) {
80 if (dependsOn[bitPos])
84 size_t bitPositionInTable = numInputs - 1 - bitPos;
85 size_t flippedIdx = idx ^ (1ull << bitPositionInTable);
86 bool flippedValue = cast<BoolAttr>(table[flippedIdx]).getValue();
89 if (currentValue != flippedValue) {
90 dependsOn[bitPos] =
true;
91 dependentInput = bitPos;
95 if (numDependencies > 1)
101 if (numDependencies > 1)
106 if (numDependencies != 1)
111 size_t bitPositionInTable = numInputs - 1 - dependentInput;
112 size_t idxWhen1 = 1ull << bitPositionInTable;
113 bool isIdentity = cast<BoolAttr>(table[idxWhen1]).getValue();
116 Value input = inputs[dependentInput];
123 replaceOpWithNewOpAndCopyNamehint<TruthTableOp>(
124 rewriter, op, ValueRange{input},
125 rewriter.getBoolArrayAttr({
true,
false}));
131class SimplifyTruthTablePass
132 :
public impl::SimplifyTruthTableBase<SimplifyTruthTablePass> {
134 using SimplifyTruthTableBase::SimplifyTruthTableBase;
135 void runOnOperation()
override;
140void SimplifyTruthTablePass::runOnOperation() {
141 Operation *op = getOperation();
142 MLIRContext *
context = op->getContext();
145 walkAndApplyPatterns(op, std::move(
patterns));
static bool isOpTriviallyRecursive(Operation *op)
static std::unique_ptr< Context > context
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
void replaceOpAndCopyNamehint(PatternRewriter &rewriter, Operation *op, Value newValue)
A wrapper of PatternRewriter::replaceOp to propagate "sv.namehint" attribute.