Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 0 additions & 45 deletions include/circt/Dialect/AIG/AIGOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -85,49 +85,4 @@ def AndInverterOp : AIGOp<"and_inv", [SameOperandsAndResultType, Pure]> {
let hasCanonicalizeMethod = 1;
}

def CutOp : AIGOp<"cut", [IsolatedFromAbove, SingleBlock]> {
let summary = "AIG dialect Cut operation";
let description = [{
The `aig.cut` operation represents a cut in the And-Inverter-Graph.
This operation is variadic and can take multiple inputs and outputs,
which corresponds to the input and output edges in AIG conceptually.

```mlir
%0, %1 = aig.cut %a, %b, %c, %d : (i1, i1, i1, i1) -> (i1, i1) {
^bb0(%arg0: i1, %arg1: i1, %arg2: i1, %arg3: i1):
%0 = aig.and_inv not %arg0, %arg1 : i1
%1 = aig.and_inv %arg1, %arg3 : i1
aig.output %0, %1 : i1 }
```

This operation is designed to be particularly useful for progressive LUT
mapping. For instance, a k-input cut can be readily mapped to a k-input LUT.
Consequently, the subsequent stages of the pipeline can concentrate on
replacing combinational logic with k-input Cut operations, simplifying the
overall process.
}];

// TODO: Restrict to HWIntegerType.
let arguments = (ins Variadic<AnyType>:$inputs);
let results = (outs Variadic<AnyType>:$results);
let regions = (region SizedRegion<1>:$bodyRegion);
let assemblyFormat = [{
$inputs attr-dict `:` functional-type($inputs, $results) $bodyRegion
}];

let hasVerifier = 1;
}

def OutputOp : AIGOp<"output", [Terminator,
ReturnLike, ParentOneOf<["CutOp"]>]> {
let summary = "AIG dialect Output operation";
let description = [{
The `aig.output` operation represents out edges of a cut.
}];
let arguments = (ins Variadic<AnyType>:$outputs);
let assemblyFormat = [{
attr-dict ($outputs^ `:` qualified(type($outputs)))?
}];
}

#endif // CIRCT_DIALECT_AIG_OPS_TD
41 changes: 0 additions & 41 deletions lib/Dialect/AIG/AIGOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,44 +159,3 @@ APInt AndInverterOp::evaluate(ArrayRef<APInt> inputs) {
}
return result;
}

LogicalResult CutOp::verify() {
auto *block = getBody();
// NOTE: Currently input and output types of the block must be exactly the
// same. We might want to relax this in the future as a way to represent
// "vectorized" cuts. For example in the following cut, the block arguments
// types are i1, but the cut is batch-applied over 8-bit lanes.
// %0 = aig.cut %a, %b : (i8, i8) -> (i8) {
// ^bb0(%arg0: i1, %arg1: i1):
// %c = aig.and_inv %arg0, not %arg1 : i1
// aig.output %c : i1
// }

if (getInputs().size() != block->getNumArguments())
return emitOpError("the number of inputs and the number of block arguments "
"do not match. Expected ")
<< getInputs().size() << " but got " << block->getNumArguments();

// Check input types.
for (auto [input, arg] : llvm::zip(getInputs(), block->getArguments()))
if (input.getType() != arg.getType())
return emitOpError("input type ")
<< input.getType() << " does not match "
<< "block argument type " << arg.getType();

if (getNumResults() != block->getTerminator()->getNumOperands())
return emitOpError("the number of results and the number of terminator "
"operands do not match. Expected ")
<< getNumResults() << " but got "
<< block->getTerminator()->getNumOperands();

// Check output types.
for (auto [result, arg] :
llvm::zip(getResults(), block->getTerminator()->getOperands()))
if (result.getType() != arg.getType())
return emitOpError("result type ")
<< result.getType() << " does not match "
<< "terminator operand type " << arg.getType();

return success();
}
39 changes: 0 additions & 39 deletions test/Dialect/AIG/errors.mlir

This file was deleted.

19 changes: 0 additions & 19 deletions test/Dialect/AIG/round-trip.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,3 @@ hw.module @And(in %a: i1, in %b: i4) {
%1 = aig.and_inv %b, not %b : i4
%2 = aig.and_inv not %a, not %a : i1
}

// CHECK-LABEL: @Cut
// CHECK-NEXT: %[[RES:.+]]:2 = aig.cut %a, %b : (i1, i1) -> (i1, i1) {
// CHECK-NEXT: ^bb0(%arg0: i1, %arg1: i1):
// CHECK-NEXT: %[[C:.+]] = aig.and_inv %arg0, not %arg1 : i1
// CHECK-NEXT: %[[D:.+]] = aig.and_inv %arg0, %arg1 : i1
// CHECK-NEXT: aig.output %[[C]], %[[D]] : i1, i1
// CHECK-NEXT: }
// CHECK-NEXT: hw.output %[[RES]]#0, %[[RES]]#1 : i1, i1

hw.module @Cut(in %a: i1, in %b: i1, out c: i1, out d: i1) {
%0, %1 = aig.cut %a, %b : (i1, i1) -> (i1, i1) {
^bb0(%arg0: i1, %arg1: i1):
%c = aig.and_inv %arg0, not %arg1 : i1
%d = aig.and_inv %arg0, %arg1 : i1
aig.output %c, %d : i1, i1
}
hw.output %0, %1 : i1, i1
}