15 #include "mlir/IR/PatternMatch.h"
18 using namespace circt;
21 #define GET_OP_CLASSES
22 #include "circt/Dialect/AIG/AIG.cpp.inc"
24 OpFoldResult AndInverterOp::fold(FoldAdaptor adaptor) {
25 if (getNumOperands() == 1 && !isInverted(0))
31 PatternRewriter &rewriter) {
33 SmallVector<Value> uniqueValues;
34 SmallVector<bool> uniqueInverts;
37 APInt::getAllOnes(op.getResult().getType().getIntOrFloatBitWidth());
39 bool invertedConstFound =
false;
41 for (
auto [value, inverted] : llvm::zip(op.getInputs(), op.getInverted())) {
44 constValue &= ~constOp.getValue();
45 invertedConstFound =
true;
47 constValue &= constOp.getValue();
52 auto it = seen.find(value);
53 if (it == seen.end()) {
54 seen.insert({value, inverted});
55 uniqueValues.push_back(value);
56 uniqueInverts.push_back(inverted);
57 }
else if (it->second != inverted) {
60 op, APInt::getZero(value.getType().getIntOrFloatBitWidth()));
66 if (constValue.isZero()) {
72 if (uniqueValues.size() == op.getInputs().size() ||
73 (!constValue.isAllOnes() && !invertedConstFound &&
74 uniqueValues.size() + 1 == op.getInputs().size()))
77 if (!constValue.isAllOnes()) {
78 auto constOp = rewriter.create<
hw::ConstantOp>(op.getLoc(), constValue);
79 uniqueInverts.push_back(
false);
80 uniqueValues.push_back(constOp);
84 if (uniqueValues.empty()) {
90 rewriter.replaceOpWithNewOp<aig::AndInverterOp>(op, uniqueValues,
95 ParseResult AndInverterOp::parse(OpAsmParser &parser, OperationState &result) {
96 SmallVector<OpAsmParser::UnresolvedOperand> operands;
97 SmallVector<bool> inverts;
98 auto loc = parser.getCurrentLocation();
101 inverts.push_back(succeeded(parser.parseOptionalKeyword(
"not")));
102 operands.push_back(OpAsmParser::UnresolvedOperand());
104 if (parser.parseOperand(operands.back()))
106 if (parser.parseOptionalComma())
111 if (parser.parseOptionalAttrDict(result.attributes) || parser.parseColon() ||
112 parser.parseCustomTypeWithFallback(type))
115 result.addTypes({type});
116 result.addAttribute(
"inverted",
117 parser.getBuilder().getDenseBoolArrayAttr(inverts));
118 if (parser.resolveOperands(operands, type, loc, result.operands))
123 void AndInverterOp::print(OpAsmPrinter &odsPrinter) {
125 llvm::interleaveComma(llvm::zip(getInverted(), getInputs()), odsPrinter,
127 auto [invert, input] = pair;
129 odsPrinter <<
"not ";
133 odsPrinter.printOptionalAttrDict((*this)->getAttrs(), {
"inverted"});
134 odsPrinter <<
" : " << getResult().getType();
137 APInt AndInverterOp::evaluate(ArrayRef<APInt> inputs) {
138 assert(inputs.size() == getNumOperands() &&
139 "Expected as many inputs as operands");
140 assert(!inputs.empty() &&
"Expected non-empty input list");
141 APInt result = APInt::getAllOnes(inputs.front().getBitWidth());
142 for (
auto [idx, input] : llvm::enumerate(inputs)) {
152 auto *block = getBody();
163 if (getInputs().size() != block->getNumArguments())
164 return emitOpError(
"the number of inputs and the number of block arguments "
165 "do not match. Expected ")
166 << getInputs().size() <<
" but got " << block->getNumArguments();
169 for (
auto [input, arg] : llvm::zip(getInputs(), block->getArguments()))
170 if (input.getType() != arg.getType())
171 return emitOpError(
"input type ")
172 << input.getType() <<
" does not match "
173 <<
"block argument type " << arg.getType();
175 if (getNumResults() != block->getTerminator()->getNumOperands())
176 return emitOpError(
"the number of results and the number of terminator "
177 "operands do not match. Expected ")
178 << getNumResults() <<
" but got "
179 << block->getTerminator()->getNumOperands();
182 for (
auto [result, arg] :
183 llvm::zip(getResults(), block->getTerminator()->getOperands()))
184 if (result.getType() != arg.getType())
185 return emitOpError(
"result type ")
186 << result.getType() <<
" does not match "
187 <<
"terminator operand type " << arg.getType();
assert(baseType &&"element must be base type")
static LogicalResult canonicalize(Op op, PatternRewriter &rewriter)
static LogicalResult verify(Value clock, bool eventExists, mlir::Location loc)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.